indexer: check that blocks are connected
There was a rare case that a block could be incorrectly added to the indexer if the indexer was disabled during a reorg to a height that matched the height that was expected, and the `sync` method for the indexer wasn't called that would detect the reorg.
This commit is contained in:
parent
cede31d86f
commit
ed06c2184d
@ -286,9 +286,20 @@ class Indexer extends EventEmitter {
|
||||
// instead of reading that information again.
|
||||
if (meta && block && view) {
|
||||
if (meta.height === this.height + 1) {
|
||||
// Make sure that the block is connected to
|
||||
// the indexer chain.
|
||||
const prev = await this.getBlockMeta(this.height);
|
||||
if (prev.hash.compare(block.prevBlock) !== 0)
|
||||
return false;
|
||||
|
||||
await this._addBlock(meta, block, view);
|
||||
return true;
|
||||
} else if (meta.height === this.height) {
|
||||
// Make sure that this is the current block.
|
||||
const current = await this.getBlockMeta(this.height);
|
||||
if (current.hash.compare(block.hash()) !== 0)
|
||||
return false;
|
||||
|
||||
await this._removeBlock(meta, block, view);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -119,6 +119,122 @@ describe('Indexer', function() {
|
||||
});
|
||||
|
||||
describe('Unit', function() {
|
||||
it('should connect block', async () => {
|
||||
const indexer = new AddrIndexer({
|
||||
blocks: {},
|
||||
chain: {}
|
||||
});
|
||||
|
||||
indexer.height = 9;
|
||||
|
||||
indexer.getBlockMeta = (height) => {
|
||||
return {
|
||||
hash: Buffer.alloc(32, 0x00),
|
||||
height: height
|
||||
};
|
||||
};
|
||||
|
||||
let called = false;
|
||||
indexer._addBlock = async () => {
|
||||
called = true;
|
||||
};
|
||||
|
||||
const meta = {height: 10};
|
||||
const block = {prevBlock: Buffer.alloc(32, 0x00)};
|
||||
const view = {};
|
||||
|
||||
const connected = await indexer._syncBlock(meta, block, view);
|
||||
assert.equal(connected, true);
|
||||
assert.equal(called, true);
|
||||
});
|
||||
|
||||
it('should not connect block', async () => {
|
||||
const indexer = new AddrIndexer({
|
||||
blocks: {},
|
||||
chain: {}
|
||||
});
|
||||
|
||||
indexer.height = 9;
|
||||
|
||||
indexer.getBlockMeta = (height) => {
|
||||
return {
|
||||
hash: Buffer.alloc(32, 0x02),
|
||||
height: height
|
||||
};
|
||||
};
|
||||
|
||||
let called = false;
|
||||
indexer._addBlock = async () => {
|
||||
called = true;
|
||||
};
|
||||
|
||||
const meta = {height: 10};
|
||||
const block = {prevBlock: Buffer.alloc(32, 0x01)};
|
||||
const view = {};
|
||||
|
||||
const connected = await indexer._syncBlock(meta, block, view);
|
||||
assert.equal(connected, false);
|
||||
assert.equal(called, false);
|
||||
});
|
||||
|
||||
it('should disconnect block', async () => {
|
||||
const indexer = new AddrIndexer({
|
||||
blocks: {},
|
||||
chain: {}
|
||||
});
|
||||
|
||||
indexer.height = 9;
|
||||
|
||||
indexer.getBlockMeta = (height) => {
|
||||
return {
|
||||
hash: Buffer.alloc(32, 0x00),
|
||||
height: height
|
||||
};
|
||||
};
|
||||
|
||||
let called = false;
|
||||
indexer._removeBlock = async () => {
|
||||
called = true;
|
||||
};
|
||||
|
||||
const meta = {height: 9};
|
||||
const block = {hash: () => Buffer.alloc(32, 0x00)};
|
||||
const view = {};
|
||||
|
||||
const connected = await indexer._syncBlock(meta, block, view);
|
||||
assert.equal(connected, true);
|
||||
assert.equal(called, true);
|
||||
});
|
||||
|
||||
it('should not disconnect block', async () => {
|
||||
const indexer = new AddrIndexer({
|
||||
blocks: {},
|
||||
chain: {}
|
||||
});
|
||||
|
||||
indexer.height = 9;
|
||||
|
||||
indexer.getBlockMeta = (height) => {
|
||||
return {
|
||||
hash: Buffer.alloc(32, 0x01),
|
||||
height: height
|
||||
};
|
||||
};
|
||||
|
||||
let called = false;
|
||||
indexer._removeBlock = async () => {
|
||||
called = true;
|
||||
};
|
||||
|
||||
const meta = {height: 9};
|
||||
const block = {hash: () => Buffer.alloc(32, 0x02)};
|
||||
const view = {};
|
||||
|
||||
const connected = await indexer._syncBlock(meta, block, view);
|
||||
assert.equal(connected, false);
|
||||
assert.equal(called, false);
|
||||
});
|
||||
|
||||
it('should not index transaction w/ invalid address', async () => {
|
||||
const indexer = new AddrIndexer({
|
||||
blocks: {},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user