Skip to content

Commit 67ece40

Browse files
committed
Implement grindname, getproof, and getresource
1 parent 236adc2 commit 67ece40

File tree

3 files changed

+132
-10
lines changed

3 files changed

+132
-10
lines changed

lib/node/http.js

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const Address = require('../primitives/address');
2222
const Network = require('../protocol/network');
2323
const pkg = require('../pkg');
2424
const rules = require('../covenants/rules');
25+
const Resource = require('../dns/resource');
2526

2627
/**
2728
* HTTP
@@ -421,7 +422,7 @@ class HTTP extends Server {
421422
const hash = valid.bhash('hash');
422423

423424
if (!hash)
424-
throw new Error('Invalid parameter.');
425+
throw new Error('Invalid hash.');
425426

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

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

431432
return res.json(200, { name: ns.name.toString('binary') });
432433
});
434+
435+
this.get('/resource/name/:name', async (req, res) => {
436+
const valid = Validator.fromRequest(req);
437+
const name = valid.str('name');
438+
439+
if (!name || !rules.verifyName(name))
440+
throw new Error('Invalid name.');
441+
442+
const nameHash = rules.hashName(name);
443+
const ns = await this.chain.db.getNameState(nameHash);
444+
445+
if (!ns || ns.data.length === 0)
446+
return null;
447+
448+
const resource = Resource.decode(ns.data);
449+
450+
return res.json(200, resource.toJSON());
451+
});
452+
453+
this.get('/proof/name/:name', async (req, res) => {
454+
const valid = Validator.fromRequest(req);
455+
const name = valid.str('name');
456+
457+
if (!name || !rules.verifyName(name))
458+
throw new Error('Invalid name.');
459+
460+
const hash = this.chain.tip.hash;
461+
const height = this.chain.tip.height;
462+
const root = this.chain.tip.treeRoot;
463+
const key = rules.hashName(name);
464+
const proof = await this.chain.db.prove(root, key);
465+
466+
return res.json(200, {
467+
hash: hash.toString('hex'),
468+
height: height,
469+
root: root.toString('hex'),
470+
name: name,
471+
key: key.toString('hex'),
472+
proof: proof.toJSON()
473+
});
474+
});
475+
476+
this.get('/grind', async (req, res) => {
477+
const valid = Validator.fromRequest(req);
478+
const size = valid.u32('size');
479+
480+
if (size < 1 || size > 63)
481+
throw new Error('Invalid length.');
482+
483+
const network = this.network;
484+
const height = this.chain.height;
485+
486+
const name = await rules.grindName(size, height + 1, network);
487+
488+
res.json(200, { name });
489+
});
433490
}
434491

435492
/**

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"bval": "~0.1.6",
4949
"bweb": "~0.1.8",
5050
"goosig": "~0.1.0",
51-
"hs-client": "file:/run/media/wiski/549A5F9E28D6FB4C/hs-client",
51+
"hs-client": "~0.0.6",
5252
"mrmr": "~0.1.8",
5353
"n64": "~0.2.9",
5454
"urkel": "~0.6.3"

test/node-http-test.js

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,8 @@
44
'use strict';
55

66
const assert = require('bsert');
7-
const consensus = require('../lib/protocol/consensus');
87
const Network = require('../lib/protocol/network');
9-
const Coin = require('../lib/primitives/coin');
10-
const Script = require('../lib/script/script');
11-
const Opcode = require('../lib/script/opcode');
128
const FullNode = require('../lib/node/fullnode');
13-
const Wallet = require('../lib/wallet/wallet');
14-
const MTX = require('../lib/primitives/mtx');
15-
const TX = require('../lib/primitives/tx');
16-
const Address = require('../lib/primitives/address');
179
const rules = require('../lib/covenants/rules');
1810
const network = Network.get('regtest');
1911

@@ -151,4 +143,77 @@ describe('Node http', function() {
151143
});
152144
});
153145
});
146+
147+
describe('getNameResource', () => {
148+
const zonefile = { compat: false, version: 0, ttl: 172800, ns: ['[email protected]'] };
149+
it('It should return null when an auction has not been initiated', async () => {
150+
const resource = await nclient.getNameResource(NAME0);
151+
assert.equal(resource, null);
152+
});
153+
154+
describe('When an auction has been initiated', () => {
155+
beforeEach(async () => {
156+
await mineBlocks(250);
157+
await wclient.execute('sendopen', [NAME0]);
158+
// Question: We have to mine ~7 blocks here to get 'getauctioninfo' to work consistently. Will pass w. 4
159+
await mineBlocks(7);
160+
const { stats: { blocksUntilBidding } } = await wclient.execute('getauctioninfo', [NAME0]);
161+
await mineBlocks(blocksUntilBidding);
162+
const sendBid = await wclient.execute('sendbid', [NAME0, 12, 12]);
163+
assert(sendBid);
164+
const { stats: { blocksUntilReveal } } = await wclient.execute('getauctioninfo', [NAME0]);
165+
// Question: We have to mine ~2 blocks here to get 'sendreveal' to work consistently. Will pass w. 1.
166+
await mineBlocks(blocksUntilReveal + 2);
167+
await wclient.execute('sendreveal', [NAME0]);
168+
const { stats: { blocksUntilClose } } = await wclient.execute('getauctioninfo', [NAME0]);
169+
await mineBlocks(blocksUntilClose);
170+
await wclient.execute('sendupdate', [NAME0, zonefile]);
171+
await mineBlocks(1);
172+
});
173+
it('It should return the resource', async () => {
174+
const resource = await nclient.getNameResource(NAME0);
175+
assert.deepEqual(resource, zonefile);
176+
});
177+
});
178+
});
179+
180+
describe('getNameProof', () => {
181+
it('It should return null when an auction has not been initiated', async () => {
182+
const proof = await nclient.getNameProof(NAME0);
183+
assert.equal(proof.proof.type, 'TYPE_DEADEND');
184+
assert.equal(proof.name, NAME0);
185+
});
186+
187+
describe('When an auction has been initiated', () => {
188+
beforeEach(async () => {
189+
await mineBlocks(250);
190+
await wclient.execute('sendopen', [NAME0]);
191+
// Question: We have to mine ~7 blocks here to get 'getauctioninfo' to work consistently. Will pass w. 4
192+
await mineBlocks(7);
193+
const { stats: { blocksUntilBidding } } = await wclient.execute('getauctioninfo', [NAME0]);
194+
await mineBlocks(blocksUntilBidding);
195+
const sendBid = await wclient.execute('sendbid', [NAME0, 12, 12]);
196+
assert(sendBid);
197+
const { stats: { blocksUntilReveal } } = await wclient.execute('getauctioninfo', [NAME0]);
198+
// Question: We have to mine ~2 blocks here to get 'sendreveal' to work consistently. Will pass w. 1.
199+
await mineBlocks(blocksUntilReveal + 2);
200+
await wclient.execute('sendreveal', [NAME0]);
201+
const { stats: { blocksUntilClose } } = await wclient.execute('getauctioninfo', [NAME0]);
202+
await mineBlocks(blocksUntilClose);
203+
await wclient.execute('sendupdate', [NAME0, { compat: false, version: 0, ttl: 172800, ns: ['[email protected]'] }]);
204+
await mineBlocks(1);
205+
});
206+
it('It should return the name\'s proof', async () => {
207+
const proof = await nclient.getNameProof(NAME0);
208+
assert.equal(proof.proof.type, 'TYPE_EXISTS');
209+
assert.equal(proof.name, NAME0);
210+
});
211+
});
212+
});
213+
describe('grindName', () => {
214+
it('It should grind a name', async () => {
215+
const { name } = await nclient.grindName(10);
216+
assert(name);
217+
});
218+
});
154219
});

0 commit comments

Comments
 (0)