Skip to content

Commit

Permalink
test: wallet updating the claims
Browse files Browse the repository at this point in the history
The wallet assumed that `REGISTER` outputs could
only come from `REVEAL` outputs, but they can also
come from `CLAIM` outputs. That prevented users
that have claimed their name to ever update it
using the `sendupdate` API. These changes allow
`CLAIM` outputs to be spent using the `sendupdate`
API.
  • Loading branch information
tynes committed Apr 29, 2020
1 parent 4c3fa8d commit 71a6e0f
Showing 1 changed file with 148 additions and 1 deletion.
149 changes: 148 additions & 1 deletion test/wallet-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const WalletDB = require('../lib/wallet/walletdb');
const WorkerPool = require('../lib/workers/workerpool');
const Address = require('../lib/primitives/address');
const MTX = require('../lib/primitives/mtx');
const ChainEntry = require('../lib/blockchain/chainentry');
const {Resource} = require('../lib/dns/resource');
const Block = require('../lib/primitives/block');
const Coin = require('../lib/primitives/coin');
const KeyRing = require('../lib/primitives/keyring');
const Input = require('../lib/primitives/input');
Expand All @@ -24,6 +27,7 @@ const Script = require('../lib/script/script');
const policy = require('../lib/protocol/policy');
const HDPrivateKey = require('../lib/hd/private');
const Wallet = require('../lib/wallet/wallet');
const rules = require('../lib/covenants/rules');
const {forValue} = require('./util/common');

const KEY1 = 'xprv9s21ZrQH143K3Aj6xQBymM31Zb4BVc7wxqfUhMZrzewdDVCt'
Expand Down Expand Up @@ -70,10 +74,26 @@ function fakeBlock(height) {
time: 500000000 + (height * (10 * 60)),
bits: 0,
nonce: 0,
height: height
height: height,
version: 0,
witnessRoot: Buffer.alloc(32),
treeRoot: Buffer.alloc(32),
reservedRoot: Buffer.alloc(32),
extraNonce: Buffer.alloc(24),
mask: Buffer.alloc(32)
};
}

function curEntry(wdb) {
return new ChainEntry(curBlock(wdb));
}

function nextEntry(wdb) {
const cur = curEntry(wdb);
const next = new Block(nextBlock(wdb));
return ChainEntry.fromBlock(next, cur);
}

function dummyInput() {
const hash = random.randomBytes(32);
return Input.fromOutpoint(new Outpoint(hash, 0));
Expand Down Expand Up @@ -2279,4 +2299,131 @@ describe('Wallet', function() {
assert.equal(confirmedCount, 1);
});
});

describe('Wallet Name Claims', function() {
let wallet, update;
const network = Network.get('regtest');
const workers = new WorkerPool({enabled: false});
const wdb = new WalletDB({network, workers});
const lockup = 6800503496047;
const name = 'cloudflare';
const nameHash = rules.hashString(name);

before(async () => {
await wdb.open();
wallet = await wdb.create();

for (let i = 0; i < 3; i++) {
const entry = nextEntry(wdb);
await wdb.addBlock(entry, []);
}

// Use a fresh wallet.
const bal = await wallet.getBalance();
assert.equal(bal.tx, 0);
assert.equal(bal.coin, 0);
assert.equal(bal.unconfirmed, 0);
assert.equal(bal.confirmed, 0);
assert.equal(bal.ulocked, 0);
assert.equal(bal.clocked, 0);
});

after(async () => {
await wdb.close();
});

it('should not have any cloudflare state', async () => {
const nameinfo = await wallet.getNameState(nameHash);
assert.deepEqual(nameinfo, null);
});

it('should confirm cloudflare CLAIM', async () => {
const claim = await wallet.sendFakeClaim('cloudflare');
assert(claim);

const tx = claim.toTX(network, wdb.state.height + 1);
const entry = nextEntry(wdb);
await wdb.addBlock(entry, [tx]);

const ns = await wallet.getNameState(nameHash);
const json = ns.getJSON(wdb.state.height, network);
assert.equal(json.name, 'cloudflare');
assert.equal(json.state, 'LOCKED');

const bal = await wallet.getBalance();
assert.equal(bal.tx, 1);
assert.equal(bal.coin, 1);
assert.equal(bal.unconfirmed, lockup);
assert.equal(bal.confirmed, lockup);
assert.equal(bal.ulocked, lockup);
assert.equal(bal.clocked, lockup);
});

it('should close the auction', async () => {
const ns = await wallet.getNameState(nameHash);
const json = ns.getJSON(wdb.state.height, network);
const {blocksUntilClosed} = json.stats;

for (let i = 0; i < blocksUntilClosed; i++) {
const entry = nextEntry(wdb);
await wdb.addBlock(entry, []);
}

{
const ns = await wallet.getNameState(nameHash);
const json = ns.getJSON(wdb.state.height, network);
assert.equal(json.name, 'cloudflare');
assert.equal(json.state, 'CLOSED');
}
});

it('should send an update for cloudflare', async () => {
const records = Resource.fromJSON({
records: [{type: 'NS', ns: 'ns1.easyhandshake.com.'}]
});

update = await wallet.sendUpdate('cloudflare', records);
const entry = nextEntry(wdb);
await wdb.addBlock(entry, [update]);

const ns = await wallet.getNameState(nameHash);
const json = ns.getJSON(wdb.state.height, network);
assert.equal(json.name, 'cloudflare');

const resource = Resource.decode(ns.data);
assert.deepEqual(records.toJSON(), resource.toJSON());

// The unconfirmed and confirmed values should
// take into account the transaction fee. Assert
// against the value of the newly created output.
const val = update.output(1).value;
const bal = await wallet.getBalance();
assert.equal(bal.tx, 2);
assert.equal(bal.coin, 2);
assert.equal(bal.unconfirmed, val);
assert.equal(bal.confirmed, val);
assert.equal(bal.ulocked, 0);
assert.equal(bal.clocked, 0);
});

it('should remove a block and update balances correctly', async () => {
const cur = curEntry(wdb);
await wdb.removeBlock(cur);

const bal = await wallet.getBalance();
const val = update.output(1).value;
assert.equal(bal.tx, 2);
assert.equal(bal.coin, 2);

// The unconfirmed balance includes value in the mempool
// and the chain itself. The reorg'd tx can be included
// in another block so the unconfirmed total does not
// include the tx fee. That value has been effectively
// spent already.
assert.equal(bal.unconfirmed, val);
assert.equal(bal.confirmed, lockup);
assert.equal(bal.ulocked, 0);
assert.equal(bal.clocked, lockup);
});
});
});

0 comments on commit 71a6e0f

Please sign in to comment.