test: add reorg test to the mempool claim invalidation.
This commit is contained in:
parent
7f0357b5cf
commit
f857df5eed
2 changed files with 138 additions and 11 deletions
|
|
@ -295,7 +295,7 @@ class Mempool extends EventEmitter {
|
|||
// when the block one before the height that disables
|
||||
// GooSig is added to the mempool to prevent the
|
||||
// mining of invalid blocks.
|
||||
if (block.height + 1 === this.network.goosigStop) {
|
||||
if (nextHeight === this.network.goosigStop) {
|
||||
for (const [hash, entry] of this.airdrops.entries()) {
|
||||
const airdrop = this.getAirdrop(hash);
|
||||
const key = airdrop.getKey();
|
||||
|
|
|
|||
|
|
@ -87,12 +87,12 @@ describe('Mempool Invalidation', function() {
|
|||
assert.strictEqual(node.mempool.claims.size, 1);
|
||||
|
||||
// retain claim in mempool.
|
||||
block = await mineBlock(node, { ignoreClaims: true });
|
||||
[block] = await mineBlock(node, { ignoreClaims: true });
|
||||
assert.strictEqual(node.mempool.claims.size, 1);
|
||||
assert.strictEqual(block.txs[0].outputs.length, 1);
|
||||
|
||||
// Now we can mine it.
|
||||
block = await mineBlock(node);
|
||||
[block] = await mineBlock(node);
|
||||
assert.strictEqual(node.mempool.claims.size, 0);
|
||||
assert.strictEqual(block.txs[0].outputs.length, 2);
|
||||
assert.strictEqual(block.txs[0].outputs[1].covenant.type, rules.types.CLAIM);
|
||||
|
|
@ -110,7 +110,7 @@ describe('Mempool Invalidation', function() {
|
|||
await mineBlock(node);
|
||||
|
||||
await node.mempool.insertClaim(claim);
|
||||
block = await mineBlock(node, { ignoreClaims: true });
|
||||
[block] = await mineBlock(node, { ignoreClaims: true });
|
||||
|
||||
// Should invalidate the claim, because next block can't have claims.
|
||||
assert.strictEqual(node.mempool.claims.size, 0);
|
||||
|
|
@ -128,7 +128,127 @@ describe('Mempool Invalidation', function() {
|
|||
assert.strictEqual(err.type, 'VerifyError');
|
||||
assert.strictEqual(err.reason, 'invalid-covenant');
|
||||
|
||||
block = await mineBlock(node);
|
||||
[block] = await mineBlock(node);
|
||||
assert.strictEqual(node.mempool.claims.size, 0);
|
||||
assert.strictEqual(block.txs[0].outputs.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Claim Invalidation on reorg (Integration)', function() {
|
||||
this.timeout(50000);
|
||||
|
||||
let node, wallet;
|
||||
|
||||
// copy names
|
||||
const TEST_CLAIMS = NAMES.slice();
|
||||
|
||||
before(async () => {
|
||||
node = new FullNode({
|
||||
memory: true,
|
||||
network: network.type,
|
||||
plugins: [require('../lib/wallet/plugin')]
|
||||
});
|
||||
|
||||
await node.ensure();
|
||||
await node.open();
|
||||
|
||||
// Ignore claim validation
|
||||
ownership.ignore = true;
|
||||
|
||||
const walletPlugin = node.require('walletdb');
|
||||
const wdb = walletPlugin.wdb;
|
||||
wallet = await wdb.get('primary');
|
||||
|
||||
const addr = await wallet.receiveAddress('default');
|
||||
node.miner.addAddress(addr.toString());
|
||||
|
||||
// first interval maturity
|
||||
// second interval mine claim
|
||||
network.names.claimPeriod = treeInterval * 3;
|
||||
|
||||
// third interval last block should invalidate.
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
network.names.claimPeriod = ACTUAL_CLAIM_PERIOD;
|
||||
|
||||
await node.close();
|
||||
});
|
||||
|
||||
it('should mine an interval', async () => {
|
||||
for (let i = 0; i < treeInterval; i++)
|
||||
await mineBlock(node);
|
||||
});
|
||||
|
||||
it('should mine claims before claimPeriod timeout', async () => {
|
||||
const name = TEST_CLAIMS.shift();
|
||||
|
||||
const claim = await wallet.makeFakeClaim(name);
|
||||
let block;
|
||||
|
||||
await node.mempool.insertClaim(claim);
|
||||
assert.strictEqual(node.mempool.claims.size, 1);
|
||||
|
||||
// retain claim in mempool.
|
||||
[block] = await mineBlock(node, { ignoreClaims: true });
|
||||
assert.strictEqual(node.mempool.claims.size, 1);
|
||||
assert.strictEqual(block.txs[0].outputs.length, 1);
|
||||
|
||||
// Now we can mine it.
|
||||
[block] = await mineBlock(node);
|
||||
assert.strictEqual(node.mempool.claims.size, 0);
|
||||
assert.strictEqual(block.txs[0].outputs.length, 2);
|
||||
assert.strictEqual(block.txs[0].outputs[1].covenant.type, rules.types.CLAIM);
|
||||
});
|
||||
|
||||
it('should invalidate claim after claimPeriod timeout', async () => {
|
||||
const name = TEST_CLAIMS.shift();
|
||||
const claim = await wallet.makeFakeClaim(name);
|
||||
|
||||
let block, entry;
|
||||
|
||||
// Mempool treats txs in it as if they were mined in the next block,
|
||||
// so we need next block to still be valid.
|
||||
while (node.chain.tip.height < network.names.claimPeriod - 2)
|
||||
await mineBlock(node);
|
||||
|
||||
await node.mempool.insertClaim(claim);
|
||||
// here we experience a reorg into the claim period.
|
||||
const tip = node.chain.tip;
|
||||
const prev = await node.chain.getPrevious(tip);
|
||||
|
||||
[block, entry] = await mineBlock(node, {
|
||||
ignoreClaims: true,
|
||||
tip: prev,
|
||||
blockWait: false
|
||||
});
|
||||
|
||||
assert.strictEqual(node.mempool.claims.size, 1);
|
||||
assert.strictEqual(block.txs[0].outputs.length, 1);
|
||||
|
||||
// Now reorg.
|
||||
[block, entry] = await mineBlock(node, {
|
||||
ignoreClaims: true,
|
||||
tip: entry
|
||||
});
|
||||
|
||||
// Should invalidate the claim, because next block can't have claims.
|
||||
assert.strictEqual(node.mempool.claims.size, 0);
|
||||
assert.strictEqual(block.txs[0].outputs.length, 1);
|
||||
|
||||
// Should fail to insert claim, as they can't be mined.
|
||||
let err;
|
||||
try {
|
||||
err = await node.mempool.insertClaim(claim);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
assert(err);
|
||||
assert.strictEqual(err.type, 'VerifyError');
|
||||
assert.strictEqual(err.reason, 'invalid-covenant');
|
||||
|
||||
[block] = await mineBlock(node);
|
||||
assert.strictEqual(node.mempool.claims.size, 0);
|
||||
assert.strictEqual(block.txs[0].outputs.length, 1);
|
||||
});
|
||||
|
|
@ -140,9 +260,14 @@ async function mineBlock(node, opts = {}) {
|
|||
const chain = node.chain;
|
||||
const miner = node.miner;
|
||||
|
||||
const ignoreClaims = opts.ignoreClaims || false;
|
||||
const ignoreClaims = opts.ignoreClaims ?? false;
|
||||
const tip = opts.tip || chain.tip;
|
||||
const blockWait = opts.blockWait ?? true;
|
||||
|
||||
const forBlock = forEvent(node, 'block', 1, 2000);
|
||||
let forBlock = null;
|
||||
|
||||
if (blockWait)
|
||||
forBlock = forEvent(node, 'block', 1, 2000);
|
||||
|
||||
let backupClaims = null;
|
||||
|
||||
|
|
@ -150,7 +275,7 @@ async function mineBlock(node, opts = {}) {
|
|||
backupClaims = node.mempool.claims;
|
||||
node.mempool.claims = new BufferMap();
|
||||
}
|
||||
const job = await miner.cpu.createJob(chain.tip);
|
||||
const job = await miner.cpu.createJob(tip);
|
||||
|
||||
job.refresh();
|
||||
|
||||
|
|
@ -158,8 +283,10 @@ async function mineBlock(node, opts = {}) {
|
|||
node.mempool.claims = backupClaims;
|
||||
|
||||
const block = await job.mineAsync();
|
||||
await chain.add(block);
|
||||
await forBlock;
|
||||
const entry = await chain.add(block);
|
||||
|
||||
return block;
|
||||
if (blockWait)
|
||||
await forBlock;
|
||||
|
||||
return [block, entry];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue