Skip to content

Commit

Permalink
Implement sendopen http interface for node. Requires updated hs-clien…
Browse files Browse the repository at this point in the history
…t lib to work
  • Loading branch information
wi-ski committed May 5, 2019
1 parent 28a3877 commit 236adc2
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 1 deletion.
47 changes: 47 additions & 0 deletions lib/node/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const Claim = require('../primitives/claim');
const Address = require('../primitives/address');
const Network = require('../protocol/network');
const pkg = require('../pkg');
const rules = require('../covenants/rules');

/**
* HTTP
Expand Down Expand Up @@ -383,6 +384,52 @@ class HTTP extends Server {

res.json(200, { success: true });
});

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

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

const network = this.network;
const height = this.chain.height;
const nameHash = rules.hashName(name);
const reserved = rules.isReserved(nameHash, height + 1, network);
const [start, week] = rules.getRollout(nameHash, network);
const ns = await this.chain.db.getNameState(nameHash);

let info = null;

if (ns) {
if (!ns.isExpired(height, network))
info = ns.getJSON(height, network);
}

return res.json(200, {
start: {
reserved: reserved,
week: week,
start: start
},
info
});
});

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

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

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

if (!ns)
return res.json(404);

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

/**
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": "~0.0.6",
"hs-client": "file:/run/media/wiski/549A5F9E28D6FB4C/hs-client",
"mrmr": "~0.1.8",
"n64": "~0.2.9",
"urkel": "~0.6.3"
Expand Down
154 changes: 154 additions & 0 deletions test/node-http-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/* eslint-env mocha */
/* eslint prefer-arrow-callback: 'off' */

'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');

const { NodeClient, WalletClient } = require('hs-client');

const nclient = new NodeClient({
port: network.rpcPort,
apiKey: 'foo'
});

const wclient = new WalletClient({
port: network.walletPort,
apiKey: 'foo'
});

describe('Node http', function() {
this.timeout(5000);
let NAME0;
let node;
let miner;
let chain;
let NAME1;

const mineBlocks = async (n = 1) => {
for (let i = 0; i < n; i++) {
const block = await miner.mineBlock();
await chain.add(block);
}
};

beforeEach(async () => {
node = new FullNode({
memory: true,
apiKey: 'foo',
network: 'regtest',
workers: true,
plugins: [require('../lib/wallet/plugin')]
});
miner = node.miner;
chain = node.chain;
NAME0 = await rules.grindName(10, 0, network);
NAME1 = await rules.grindName(10, 20, network);
await node.open();
await mineBlocks(network.names.auctionStart);
assert.equal(network.names.auctionStart, 0);
await mineBlocks(1);
});

afterEach(async () => {
await node.close();
});

describe('getNameInfo', () => {
describe('For names that are available at height 0', () => {
it('It should return null when there hasn\'t been an auction initiated', async () => {
const nameInfo = await nclient.getNameInfo(NAME0);
assert.deepEqual(nameInfo, {
info: null,
start: {
reserved: false,
start: 0,
week: 0
}
});
});
it('It should start an auction on the first day', async () => {
await mineBlocks(1);
const nameInfo = await nclient.getNameInfo(NAME0);
assert.deepEqual(nameInfo, {
info: null,
start: {
reserved: false,
start: 0,
week: 0
}
});
const open = await wclient.execute('sendopen', [NAME0]);
assert(open);
});
it('It should start an auction on the 2nd day', async () => {
// Question: This test passes non-deterministically. Why?
// Note: Keeping this test as proof that the behavior of grindName
// isnt working as one would expect.
await mineBlocks(175); // Note: This number seems to pass consistently. \o.o/
const nameInfo = await nclient.getNameInfo(NAME0);
assert.deepEqual(nameInfo, {
info: null,
start: {
reserved: false,
start: 0,
week: 0
}
});
const open = await wclient.execute('sendopen', [NAME0]);
assert(open);
const nameInfoBefore = await nclient.getNameInfo(NAME0);
assert.equal(nameInfoBefore.info, null);
await mineBlocks(1);
const nameInfoAfter = await nclient.getNameInfo(NAME0);
assert.equal(nameInfoAfter.info.name, NAME0);
assert.equal(nameInfoAfter.info.state, 'OPENING');
});
});

describe('For names that are available at height 20', () => {
it('It should getNameInfo for an opening name', async () => {
await mineBlocks(20);
await wclient.execute('sendopen', [NAME1]);
await mineBlocks(1);
const nameInfo = await nclient.getNameInfo(NAME1);
assert(nameInfo.start.start < 20);
assert.equal(nameInfo.start.reserved, false);
assert.equal(nameInfo.info.state, 'OPENING');
});
});
});

describe('getNameByHash', () => {
it('It should return null when an auction has not been initiated', async () => {
const nameHash = rules.hashName(NAME0);
const name = await nclient.getNameByHash(nameHash.toString('hex'));
assert.equal(name, null);
});

describe('When an auction has been initiated', () => {
beforeEach(async () => {
await mineBlocks(250);
await wclient.execute('sendopen', [NAME0]);
await mineBlocks(1);
});
it('It should return the name', async () => {
const nameHash = rules.hashName(NAME0);
const { name } = await nclient.getNameByHash(nameHash.toString('hex'));
assert.equal(name, NAME0);
});
});
});
});

0 comments on commit 236adc2

Please sign in to comment.