Skip to content

Commit

Permalink
test: add reorg test to the mempool claim invalidation.
Browse files Browse the repository at this point in the history
  • Loading branch information
nodech committed May 29, 2023
1 parent 7f0357b commit f857df5
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 11 deletions.
2 changes: 1 addition & 1 deletion lib/mempool/mempool.js
Expand Up @@ -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();
Expand Down
147 changes: 137 additions & 10 deletions test/mempool-invalidation-test.js
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
});
Expand All @@ -140,26 +260,33 @@ 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;

let forBlock = null;

const forBlock = forEvent(node, 'block', 1, 2000);
if (blockWait)
forBlock = forEvent(node, 'block', 1, 2000);

let backupClaims = null;

if (ignoreClaims) {
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();

if (ignoreClaims)
node.mempool.claims = backupClaims;

const block = await job.mineAsync();
await chain.add(block);
await forBlock;
const entry = await chain.add(block);

if (blockWait)
await forBlock;

return block;
return [block, entry];
}

0 comments on commit f857df5

Please sign in to comment.