Skip to content

Commit

Permalink
Implement grindname, getproof, and getresource
Browse files Browse the repository at this point in the history
  • Loading branch information
wi-ski committed May 5, 2019
1 parent 236adc2 commit 67ece40
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 10 deletions.
59 changes: 58 additions & 1 deletion lib/node/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const Address = require('../primitives/address');
const Network = require('../protocol/network');
const pkg = require('../pkg');
const rules = require('../covenants/rules');
const Resource = require('../dns/resource');

/**
* HTTP
Expand Down Expand Up @@ -421,7 +422,7 @@ class HTTP extends Server {
const hash = valid.bhash('hash');

if (!hash)
throw new Error('Invalid parameter.');
throw new Error('Invalid hash.');

const ns = await this.chain.db.getNameState(hash);

Expand All @@ -430,6 +431,62 @@ class HTTP extends Server {

return res.json(200, { name: ns.name.toString('binary') });
});

this.get('/resource/name/:name', async (req, res) => {
const valid = Validator.fromRequest(req);
const name = valid.str('name');

if (!name || !rules.verifyName(name))
throw new Error('Invalid name.');

const nameHash = rules.hashName(name);
const ns = await this.chain.db.getNameState(nameHash);

if (!ns || ns.data.length === 0)
return null;

const resource = Resource.decode(ns.data);

return res.json(200, resource.toJSON());
});

this.get('/proof/name/:name', async (req, res) => {
const valid = Validator.fromRequest(req);
const name = valid.str('name');

if (!name || !rules.verifyName(name))
throw new Error('Invalid name.');

const hash = this.chain.tip.hash;
const height = this.chain.tip.height;
const root = this.chain.tip.treeRoot;
const key = rules.hashName(name);
const proof = await this.chain.db.prove(root, key);

return res.json(200, {
hash: hash.toString('hex'),
height: height,
root: root.toString('hex'),
name: name,
key: key.toString('hex'),
proof: proof.toJSON()
});
});

this.get('/grind', async (req, res) => {
const valid = Validator.fromRequest(req);
const size = valid.u32('size');

if (size < 1 || size > 63)
throw new Error('Invalid length.');

const network = this.network;
const height = this.chain.height;

const name = await rules.grindName(size, height + 1, network);

res.json(200, { name });
});
}

/**
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"bval": "~0.1.6",
"bweb": "~0.1.8",
"goosig": "~0.1.0",
"hs-client": "file:/run/media/wiski/549A5F9E28D6FB4C/hs-client",
"hs-client": "~0.0.6",
"mrmr": "~0.1.8",
"n64": "~0.2.9",
"urkel": "~0.6.3"
Expand Down
81 changes: 73 additions & 8 deletions test/node-http-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,8 @@
'use strict';

const assert = require('bsert');
const consensus = require('../lib/protocol/consensus');
const Network = require('../lib/protocol/network');
const Coin = require('../lib/primitives/coin');
const Script = require('../lib/script/script');
const Opcode = require('../lib/script/opcode');
const FullNode = require('../lib/node/fullnode');
const Wallet = require('../lib/wallet/wallet');
const MTX = require('../lib/primitives/mtx');
const TX = require('../lib/primitives/tx');
const Address = require('../lib/primitives/address');
const rules = require('../lib/covenants/rules');
const network = Network.get('regtest');

Expand Down Expand Up @@ -151,4 +143,77 @@ describe('Node http', function() {
});
});
});

describe('getNameResource', () => {
const zonefile = { compat: false, version: 0, ttl: 172800, ns: ['ns1.example.com.@1.2.3.4'] };
it('It should return null when an auction has not been initiated', async () => {
const resource = await nclient.getNameResource(NAME0);
assert.equal(resource, null);
});

describe('When an auction has been initiated', () => {
beforeEach(async () => {
await mineBlocks(250);
await wclient.execute('sendopen', [NAME0]);
// Question: We have to mine ~7 blocks here to get 'getauctioninfo' to work consistently. Will pass w. 4
await mineBlocks(7);
const { stats: { blocksUntilBidding } } = await wclient.execute('getauctioninfo', [NAME0]);
await mineBlocks(blocksUntilBidding);
const sendBid = await wclient.execute('sendbid', [NAME0, 12, 12]);
assert(sendBid);
const { stats: { blocksUntilReveal } } = await wclient.execute('getauctioninfo', [NAME0]);
// Question: We have to mine ~2 blocks here to get 'sendreveal' to work consistently. Will pass w. 1.
await mineBlocks(blocksUntilReveal + 2);
await wclient.execute('sendreveal', [NAME0]);
const { stats: { blocksUntilClose } } = await wclient.execute('getauctioninfo', [NAME0]);
await mineBlocks(blocksUntilClose);
await wclient.execute('sendupdate', [NAME0, zonefile]);
await mineBlocks(1);
});
it('It should return the resource', async () => {
const resource = await nclient.getNameResource(NAME0);
assert.deepEqual(resource, zonefile);
});
});
});

describe('getNameProof', () => {
it('It should return null when an auction has not been initiated', async () => {
const proof = await nclient.getNameProof(NAME0);
assert.equal(proof.proof.type, 'TYPE_DEADEND');
assert.equal(proof.name, NAME0);
});

describe('When an auction has been initiated', () => {
beforeEach(async () => {
await mineBlocks(250);
await wclient.execute('sendopen', [NAME0]);
// Question: We have to mine ~7 blocks here to get 'getauctioninfo' to work consistently. Will pass w. 4
await mineBlocks(7);
const { stats: { blocksUntilBidding } } = await wclient.execute('getauctioninfo', [NAME0]);
await mineBlocks(blocksUntilBidding);
const sendBid = await wclient.execute('sendbid', [NAME0, 12, 12]);
assert(sendBid);
const { stats: { blocksUntilReveal } } = await wclient.execute('getauctioninfo', [NAME0]);
// Question: We have to mine ~2 blocks here to get 'sendreveal' to work consistently. Will pass w. 1.
await mineBlocks(blocksUntilReveal + 2);
await wclient.execute('sendreveal', [NAME0]);
const { stats: { blocksUntilClose } } = await wclient.execute('getauctioninfo', [NAME0]);
await mineBlocks(blocksUntilClose);
await wclient.execute('sendupdate', [NAME0, { compat: false, version: 0, ttl: 172800, ns: ['ns1.example.com.@1.2.3.4'] }]);
await mineBlocks(1);
});
it('It should return the name\'s proof', async () => {
const proof = await nclient.getNameProof(NAME0);
assert.equal(proof.proof.type, 'TYPE_EXISTS');
assert.equal(proof.name, NAME0);
});
});
});
describe('grindName', () => {
it('It should grind a name', async () => {
const { name } = await nclient.grindName(10);
assert(name);
});
});
});

0 comments on commit 67ece40

Please sign in to comment.