Skip to content

Commit

Permalink
chain: enable syncTree() to process multiple tree intervals
Browse files Browse the repository at this point in the history
  • Loading branch information
pinheadmz committed Dec 9, 2021
1 parent 52cf446 commit 0cd895b
Showing 1 changed file with 21 additions and 10 deletions.
31 changes: 21 additions & 10 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,28 @@ class Chain extends AsyncEmitter {
// The tree root in this block header will be the first block that
// commits to the new tree root hash, but the transactions it contains
// have not yet been added to the tree.
const last = this.height - (this.height % treeInterval);
const entry = await this.db.getEntryByHeight(last + 1);

// Require that tree is less than one tree interval behind the chain.
// We can skip this check only if the blockchain is less than
let last = this.height - (this.height % treeInterval);
let entry = await this.db.getEntryByHeight(last + 1);

// Using the current tree root hash, rewind the blockchain to the beginning
// of the corresponding tree interval. If the tree has been compacted,
// this may be SEVERAL tree intervals behind the current chain tip
// (this is required to support chain reorgs to a limited depth,
// similar to pruning nodes keeping the last 288 blocks on disk).
// We can skip this only if the blockchain is less than
// one tree interval old, OR the chain is already at the tree interval,
// meaning the tree is already in sync with the chain and there is no delta.
if (entry) {
assert(entry.treeRoot.equals(currentRoot));
} else {
if (!entry) {
assert(last === 0 || last === this.height);
} else {
for (;;) {
if (entry.treeRoot.equals(currentRoot))
break;

last -= treeInterval;
entry = await this.db.getEntryByHeight(last + 1);
assert(entry);
}
}

// Replay all blocks since the last tree interval to rebuild
Expand All @@ -171,8 +182,8 @@ class Chain extends AsyncEmitter {
for (const tx of block.txs)
await this.verifyCovenants(tx, view, height, hardened);

assert((height % this.network.names.treeInterval) !== 0);

// If the chain replay crosses a tree interval, it will commit
// and write to disk in saveNames(), resetting the `txn` like usual.
await this.db.saveNames(view, entry, false);
}

Expand Down

0 comments on commit 0cd895b

Please sign in to comment.