test: add reorg test to the mempool claim invalidation.

This commit is contained in:
Nodari Chkuaselidze 2023-05-25 16:01:43 +04:00
parent 7f0357b5cf
commit f857df5eed
No known key found for this signature in database
GPG key ID: B018A7BB437D1F05
2 changed files with 138 additions and 11 deletions

View file

@ -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();

View file

@ -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];
}