Merge pull request #764 from braydonf/checkpoint
blockchain: do not accept forked chain older than last checkpoint
This commit is contained in:
commit
812dc1a6f3
@ -1104,6 +1104,16 @@ class Chain extends AsyncEmitter {
|
||||
*/
|
||||
|
||||
async saveAlternate(entry, block, prev, flags) {
|
||||
// Do not accept forked chain older than the
|
||||
// last checkpoint.
|
||||
if (this.options.checkpoints) {
|
||||
if (prev.height + 1 < this.network.lastCheckpoint)
|
||||
throw new VerifyError(block,
|
||||
'checkpoint',
|
||||
'bad-fork-prior-to-checkpoint',
|
||||
100);
|
||||
}
|
||||
|
||||
try {
|
||||
// Do as much verification
|
||||
// as we can before saving.
|
||||
|
||||
@ -121,17 +121,21 @@ chain.on('disconnect', (entry, block) => {
|
||||
describe('Chain', function() {
|
||||
this.timeout(process.browser ? 1200000 : 60000);
|
||||
|
||||
it('should open chain and miner', async () => {
|
||||
before(async () => {
|
||||
await blocks.open();
|
||||
await chain.open();
|
||||
await miner.open();
|
||||
});
|
||||
|
||||
it('should add addrs to miner', async () => {
|
||||
miner.addresses.length = 0;
|
||||
miner.addAddress(wallet.getReceive());
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await miner.close();
|
||||
await chain.close();
|
||||
await blocks.close();
|
||||
});
|
||||
|
||||
it('should mine 200 blocks', async () => {
|
||||
for (let i = 0; i < 200; i++) {
|
||||
const block = await cpu.mineBlock();
|
||||
@ -900,9 +904,44 @@ describe('Chain', function() {
|
||||
assert(fmt.includes('chainwork'));
|
||||
});
|
||||
|
||||
it('should cleanup', async () => {
|
||||
await miner.close();
|
||||
await chain.close();
|
||||
await blocks.close();
|
||||
describe('Checkpoints', function() {
|
||||
before(async () => {
|
||||
const entry = await chain.getEntry(chain.tip.height - 5);
|
||||
assert(Buffer.isBuffer(entry.hash));
|
||||
assert(Number.isInteger(entry.height));
|
||||
|
||||
network.checkpointMap[entry.height] = entry.hash;
|
||||
network.lastCheckpoint = entry.height;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
network.checkpointMap = {};
|
||||
network.lastCheckpoint = 0;
|
||||
});
|
||||
|
||||
it('will reject blocks before last checkpoint', async () => {
|
||||
const entry = await chain.getEntry(chain.tip.height - 10);
|
||||
const block = await cpu.mineBlock(entry);
|
||||
|
||||
let err = null;
|
||||
|
||||
try {
|
||||
await chain.add(block);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
assert(err);
|
||||
assert.equal(err.type, 'VerifyError');
|
||||
assert.equal(err.reason, 'bad-fork-prior-to-checkpoint');
|
||||
assert.equal(err.score, 100);
|
||||
});
|
||||
|
||||
it('will accept blocks after last checkpoint', async () => {
|
||||
const entry = await chain.getEntry(chain.tip.height - 4);
|
||||
const block = await cpu.mineBlock(entry);
|
||||
|
||||
assert(await chain.add(block));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user