From 7a1816a3a8949a690874c0a5bf61718676c499a5 Mon Sep 17 00:00:00 2001 From: ohryan Date: Wed, 15 Jul 2020 19:07:25 -0700 Subject: [PATCH] refactor/update nlr function; check nlr for spv wallet --- lib/blockchain/chain.js | 75 ++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index c97e428d..6c8822f0 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -855,36 +855,8 @@ class Chain extends AsyncEmitter { assert(fork, 'No free space or data corruption.'); - // Check NLR (No Large Reorganization) - if (tip.height - fork.height >= this.nlrLimit) { - if (this.nlrLimit !== 0) { - this.logger.warning( - 'NLR Activated: current=%h(%d) fork=%h(%d) reorg_size=%d', - tip.hash, - tip.height, - competitor.hash, - competitor.height, - tip.height - fork.height - ); - - const entryWithMostWork = (tip.height > competitor.height) ? tip : competitor - - // mark invalid_child from tip of fork to second block of fork - while (entryWithMostWork.height > fork.height + 2) { - const previous = await this.getPrevious(entryWithMostWork) - this.invalidate(previous.hash) - } - - // mark invalid first block of fork - const previous = await this.getPrevious(entryWithMostWork) - this.invalidate(previous.hash) - - // check - assert(this.getPrevious(previous), fork) - - return true - } - } + // Check NLR + if (this.noLongReorg(tip, fork, competitor)) return true // Blocks to disconnect. const disconnect = []; @@ -943,6 +915,9 @@ class Chain extends AsyncEmitter { assert(fork, 'No free space or data corruption.'); + // Check NLR + if (this.noLongReorg(tip, fork, competitor)) return true + // Buffer disconnected blocks. const disconnect = []; let entry = tip; @@ -981,6 +956,46 @@ class Chain extends AsyncEmitter { return this.emitAsync('reorganize', tip, competitor); } + /** + * Checks if a reorganization breaks the set nlrLimit, + * if it does, it invalidates necessary blocks and returns true + * else return false + * @param {ChainEntry} tip - Current tip of this chain. + * @param {ChainEntry} fork - The tip of the fork. + * @param {ChainEntry} competitor - The competing chain's tip. + * @returns {Promise} + */ + async noLongReorg (tip, fork, competitor) { + if (tip.height - fork.height >= this.network.nlrLimit) { + if (this.network.nlrLimit !== 0) { + this.logger.warning( + 'NLR Activated: current=%h(%d) fork=%h(%d) reorg_size=%d', + tip.hash, + tip.height, + competitor.hash, + competitor.height, + tip.height - fork.height + ); + + // mark invalid_child from tip of fork to second block of fork + while (competitor.height > fork.height + 2) { + const previous = await this.getPrevious(competitor) + this.invalidate(previous.hash) + } + + // mark invalid first block of fork + const previous = await this.getPrevious(competitor) + this.invalidate(previous.hash) + + // check + assert(this.getPrevious(previous), fork) + + return true + } + } + return false + } + /** * Disconnect an entry from the chain (updates the tip). * @param {ChainEntry} entry