Merge pull request #764 from braydonf/checkpoint

blockchain: do not accept forked chain older than last checkpoint
This commit is contained in:
Javed Khan 2019-05-07 00:23:19 +05:30 committed by GitHub
commit 812dc1a6f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 7 deletions

View File

@ -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.

View File

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