From da7b5720a219919b840bd2febf6264dd1a039099 Mon Sep 17 00:00:00 2001 From: jeremy-then Date: Wed, 10 Jan 2024 19:14:29 -0400 Subject: [PATCH] Fixes waitForBlock logic to not stop searching if the blockchain is at least advancing --- lib/rsk-utils.js | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/rsk-utils.js b/lib/rsk-utils.js index 1df0be23..5f47f91d 100644 --- a/lib/rsk-utils.js +++ b/lib/rsk-utils.js @@ -35,27 +35,40 @@ const waitForSync = async (rskTransactionHelpers) => { }; /** - * - * @param {Web3} rskClient web3 client to make calls to the rsk network - * @param {Number} blockNumber block to wait for - * @param {Number} waitTime defaults to 200 milliseconds. Time to wait before checking for the block on every iteration - * @param {Number} maxAttempts defaults to 6000 milliseconds. Attempts to try to get the indicated block number - * @returns {Promise} the latest block number that we were waiting for + * Wait for the rsk blockchain to advance to the specified block number, attempting to find a new block `maxAttempts` times, checking every `waitTime` milliseconds. + * If the blockchain doesn't advance after `maxAttempts` attempts, it will consider the blockchain as stuck and it will throw an error. + * It will reset the attempts counter every time the blockchain advances as least 1 block. + * It will potentially try to find new blocks `maxAttempts` times for every block. + * If the blockchain is at least advancing, we know that some time in the future the `blockNumber` will be reached, so no need to stop trying to find it. + * @param {Web3} rskClient web3 client to make calls to the rsk network. + * @param {Number} blockNumber min block height to wait for. + * @param {Number} waitTime defaults to 200 milliseconds. Time to wait before checking for the block on every iteration. + * @param {Number} maxAttempts defaults to 80 attempts by block. + * @returns {Promise} the latest block number the same or greater than `blockNumber`. */ -const waitForBlock = (rskClient, blockNumber, waitTime = 200, maxAttempts = 600) => { +const waitForBlock = (rskClient, blockNumber, waitTime = 200, maxAttempts = 80) => { return new Promise((resolve, reject) => { - let attempts = 0; + let attempts = 1; + let latestBlockNumber = -1; const checkBlockNumber = () => { - rskClient.eth.getBlockNumber().then(latestBlockNumber => { - if (latestBlockNumber >= blockNumber) { - return resolve(latestBlockNumber); + rskClient.eth.getBlockNumber().then(newLatestBlockNumber => { + const expectedMinBlockHeightReached = newLatestBlockNumber >= blockNumber; + if (expectedMinBlockHeightReached) { + return resolve(newLatestBlockNumber); + } + const isAdvancing = newLatestBlockNumber > latestBlockNumber; + if(isAdvancing) { + latestBlockNumber = newLatestBlockNumber; + attempts = 0; + } else { + if (attempts++ === maxAttempts) { + const message = `Blockchain not advancing after attempting to find a new block ${maxAttempts} times checking every ${waitTime} milliseconds. Couldn't reach block number ${blockNumber}. Last block number seen was: ${newLatestBlockNumber}`; + return reject(new Error(message)); + } } - if (attempts++ === maxAttempts) { - return reject(new Error(`Block number ${blockNumber} never reached, last seen was ${latestBlockNumber}`)); - }; setTimeout(checkBlockNumber, waitTime); - }).catch((ex) => { - reject("waitForBlock " + ex.stack); + }).catch(error => { + reject('[waitForBlock] ' + error.stack); }); }; checkBlockNumber();