Comparing version 1.0.6 to 2.0.0
@@ -31,3 +31,6 @@ "use strict"; | ||
if (isRollback || (isReplay && isFirstBlock)) { | ||
yield this.rollbackTo(blockInfo.blockNumber - 1); | ||
const rollbackBlockNumber = blockInfo.blockNumber - 1; | ||
const rollbackCount = this.lastProcessedBlockNumber - rollbackBlockNumber; | ||
console.info(`Rolling back ${rollbackCount} blocks to block ${rollbackBlockNumber}...`); | ||
yield this.rollbackTo(rollbackBlockNumber); | ||
yield this.refreshIndexState(); | ||
@@ -34,0 +37,0 @@ } |
@@ -29,3 +29,3 @@ import { Block } from "./interfaces"; | ||
* Loads the next block with chainInterface after validating, updating all relevant state. | ||
* If block fails validation, rollback will be called, and will update state to last block unseen. | ||
* If block fails validation, resolveFork will be called, and will update state to last block unseen. | ||
*/ | ||
@@ -39,3 +39,3 @@ nextBlock(): Promise<[Block, boolean, boolean]>; | ||
* Incrementally rolls back reader state one block at a time, comparing the blockHistory with | ||
* newly fetched blocks. Rollback is finished when either the current block's previous hash | ||
* newly fetched blocks. Fork resolution is finished when either the current block's previous hash | ||
* matches the previous block's hash, or when history is exhausted. | ||
@@ -45,8 +45,8 @@ * | ||
*/ | ||
protected rollback(): Promise<void>; | ||
protected resolveFork(): Promise<void>; | ||
/** | ||
* When history is exhausted in rollback(), this is run to handle the situation. If left unimplemented, | ||
* When history is exhausted in resolveFork(), this is run to handle the situation. If left unimplemented, | ||
* then only instantiate with `onlyIrreversible` set to true. | ||
*/ | ||
protected rollbackExhausted(): void; | ||
protected historyExhausted(): void; | ||
} |
@@ -27,3 +27,3 @@ "use strict"; | ||
* Loads the next block with chainInterface after validating, updating all relevant state. | ||
* If block fails validation, rollback will be called, and will update state to last block unseen. | ||
* If block fails validation, resolveFork will be called, and will update state to last block unseen. | ||
*/ | ||
@@ -64,6 +64,7 @@ nextBlock() { | ||
// and need to roll back | ||
console.info("!! Fork detected !!"); | ||
console.info(` expected: ${expectedHash}`); | ||
console.info(` received: ${actualHash}`); | ||
yield this.rollback(); | ||
console.info("!! FORK DETECTED !!"); | ||
console.info(` MISMATCH:`); | ||
console.info(` ✓ NEW Block ${unvalidatedBlockData.blockInfo.blockNumber} previous: ${actualHash}`); | ||
console.info(` ✕ OLD Block ${this.currentBlockNumber} id: ${expectedHash}`); | ||
yield this.resolveFork(); | ||
isNewBlock = true; | ||
@@ -123,3 +124,3 @@ isRollback = true; // Signal action handler that we must roll back | ||
* Incrementally rolls back reader state one block at a time, comparing the blockHistory with | ||
* newly fetched blocks. Rollback is finished when either the current block's previous hash | ||
* newly fetched blocks. Fork resolution is finished when either the current block's previous hash | ||
* matches the previous block's hash, or when history is exhausted. | ||
@@ -129,41 +130,31 @@ * | ||
*/ | ||
rollback() { | ||
resolveFork() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let blocksToRewind; | ||
// Rewind at least 1 block back | ||
if (this.blockHistory.length > 0) { | ||
// TODO: | ||
// check and throw error if undefined | ||
const block = this.blockHistory.pop(); | ||
if (block === undefined) { | ||
throw Error("block history should not have undefined entries."); | ||
} | ||
this.currentBlockData = yield this.getBlock(block.blockInfo.blockNumber); | ||
blocksToRewind = 1; | ||
if (this.currentBlockData === null) { | ||
throw Error("`currentBlockData` must not be null when initiating fork resolution."); | ||
} | ||
// Pop off blocks from cached block history and compare them with freshly fetched blocks | ||
while (this.blockHistory.length > 0) { | ||
const [cachedPreviousBlockData] = this.blockHistory.slice(-1); | ||
const previousBlockData = yield this.getBlock(cachedPreviousBlockData.blockInfo.blockNumber); | ||
const currentBlock = this.currentBlockData; | ||
if (currentBlock !== null) { | ||
const { blockInfo: currentBlockInfo } = currentBlock; | ||
const [previousBlockData] = this.blockHistory.slice(-1); | ||
console.info(`Refetching Block ${this.currentBlockData.blockInfo.blockNumber}...`); | ||
this.currentBlockData = yield this.getBlock(this.currentBlockData.blockInfo.blockNumber); | ||
if (this.currentBlockData !== null) { | ||
const { blockInfo: currentBlockInfo } = this.currentBlockData; | ||
const { blockInfo: previousBlockInfo } = previousBlockData; | ||
if (currentBlockInfo.previousBlockHash === previousBlockInfo.blockHash) { | ||
console.info(`✓ BLOCK ${currentBlockInfo.blockNumber} MATCH:`); | ||
console.info(` expected: ${currentBlockInfo.previousBlockHash}`); | ||
console.info(` received: ${previousBlockInfo.blockHash}`); | ||
console.info(`Rolling back ${blocksToRewind} blocks to block ${currentBlockInfo.blockNumber}...`); | ||
console.info(" MATCH:"); | ||
console.info(` ✓ NEW Block ${currentBlockInfo.blockNumber} previous: ${currentBlockInfo.previousBlockHash}`); // tslint:disable-line | ||
console.info(` ✓ OLD Block ${previousBlockInfo.blockNumber} id: ${previousBlockInfo.blockHash}`); | ||
console.info("!! FORK RESOLVED !!"); | ||
break; | ||
} | ||
console.info(`✕ BLOCK ${currentBlockInfo.blockNumber} MISMATCH:`); | ||
console.info(` expected: ${currentBlockInfo.previousBlockHash}`); | ||
console.info(` received: ${previousBlockInfo.blockHash}`); | ||
console.info(" MISMATCH:"); | ||
console.info(` ✓ NEW Block ${currentBlockInfo.blockNumber} previous: ${currentBlockInfo.previousBlockHash}`); | ||
console.info(` ✕ OLD Block ${previousBlockInfo.blockNumber} id: ${previousBlockInfo.blockHash}`); | ||
} | ||
this.currentBlockData = previousBlockData; | ||
this.blockHistory.pop(); | ||
blocksToRewind += 1; | ||
} | ||
if (this.blockHistory.length === 0) { | ||
yield this.rollbackExhausted(); | ||
yield this.historyExhausted(); | ||
} | ||
@@ -174,10 +165,10 @@ this.currentBlockNumber = this.blockHistory[this.blockHistory.length - 1].blockInfo.blockNumber + 1; | ||
/** | ||
* When history is exhausted in rollback(), this is run to handle the situation. If left unimplemented, | ||
* When history is exhausted in resolveFork(), this is run to handle the situation. If left unimplemented, | ||
* then only instantiate with `onlyIrreversible` set to true. | ||
*/ | ||
rollbackExhausted() { | ||
console.info("Rollback history has been exhausted!"); | ||
throw Error("Rollback history has been exhausted, and no rollback exhaustion handling has been implemented."); | ||
historyExhausted() { | ||
console.info("Fork resolution history has been exhausted!"); | ||
throw Error("Fork resolution history has been exhausted, and no history exhaustion handling has been implemented."); | ||
} | ||
} | ||
exports.AbstractActionReader = AbstractActionReader; |
{ | ||
"name": "demux", | ||
"version": "1.0.6", | ||
"version": "2.0.0", | ||
"author": { | ||
@@ -5,0 +5,0 @@ "name": "Julien Heller", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
223281
17
528