From a674ab97eedaf8899014aab4ff7e7153b784c211 Mon Sep 17 00:00:00 2001 From: Alex Rea Date: Wed, 26 Jan 2022 09:11:36 +0000 Subject: [PATCH 1/2] MiningClient now accomodates blocks where nothing happens --- .../reputation-miner/ReputationMinerClient.js | 25 ++++++++++++++----- .../client-auto-functionality.js | 10 +++++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/reputation-miner/ReputationMinerClient.js b/packages/reputation-miner/ReputationMinerClient.js index d6b17520a4..bd7b23d3d4 100644 --- a/packages/reputation-miner/ReputationMinerClient.js +++ b/packages/reputation-miner/ReputationMinerClient.js @@ -465,7 +465,8 @@ class ReputationMinerClient { return; } } - await this.updateGasEstimate('average'); + await this.updateGasEstimate('fast'); + this._adapter.log("Invalidating pseudo-opponent in dispute"); await repCycle.invalidateHash(round, oppIndex, {"gasPrice": this._miner.gasPrice}); this.endDoBlockChecks(); return; @@ -483,7 +484,8 @@ class ReputationMinerClient { ); if (responsePossible) { // If so, invalidate them. - await this.updateGasEstimate('average'); + await this.updateGasEstimate('fast'); + this._adapter.log("Invalidating opponent in dispute"); await repCycle.invalidateHash(round, oppIndex, {"gasPrice": this._miner.gasPrice}); this.endDoBlockChecks(); return; @@ -497,7 +499,9 @@ class ReputationMinerClient { const responsePossible = await repCycle.getResponsePossible(disputeStages.CONFIRM_JRH, entry.lastResponseTimestamp); if (responsePossible){ await this.updateGasEstimate('fast'); - await this._miner.confirmJustificationRootHash(); + this._adapter.log("Confirming JRH in dispute"); + const tx = await this._miner.confirmJustificationRootHash(); + await tx.wait(); } // 2. Are we in the middle of a binary search? // Check our opponent has confirmed their JRH, and the binary search is ongoing. @@ -509,7 +513,9 @@ class ReputationMinerClient { const responsePossible = await repCycle.getResponsePossible(disputeStages.BINARY_SEARCH_RESPONSE, entry.lastResponseTimestamp); if (responsePossible){ await this.updateGasEstimate('fast'); - await this._miner.respondToBinarySearchForChallenge(); + this._adapter.log("Responding to binary search in dispute"); + const tx = await this._miner.respondToBinarySearchForChallenge(); + await tx.wait(); } } // 3. Are we at the end of a binary search and need to confirm? @@ -517,18 +523,23 @@ class ReputationMinerClient { } else if ( oppEntry.upperBound.eq(oppEntry.lowerBound) && entry.upperBound.eq(entry.lowerBound) && + entry.challengeStepCompleted.gte(2) && ethers.BigNumber.from(2).pow(entry.challengeStepCompleted.sub(2)).lte(submission.jrhNLeaves) ) { const responsePossible = await repCycle.getResponsePossible(disputeStages.BINARY_SEARCH_CONFIRM, entry.lastResponseTimestamp); if (responsePossible){ await this.updateGasEstimate('fast'); - await this._miner.confirmBinarySearchResult(); + this._adapter.log("Confirming binary search in dispute"); + const tx = await this._miner.confirmBinarySearchResult(); + await tx.wait(); } // 4. Is the binary search confirmed, and we need to respond to challenge? // Check our opponent has confirmed their binary search result, check that we have too, and that we've not responded to this challenge yet } else if ( + oppEntry.challengeStepCompleted.gte(2) && ethers.BigNumber.from(2).pow(oppEntry.challengeStepCompleted.sub(2)).gt(oppSubmission.jrhNLeaves) && + entry.challengeStepCompleted.gte(3) && ethers.BigNumber.from(2).pow(entry.challengeStepCompleted.sub(2)).gt(submission.jrhNLeaves) && ethers.BigNumber.from(2).pow(entry.challengeStepCompleted.sub(3)).lte(submission.jrhNLeaves) ) @@ -536,7 +547,9 @@ class ReputationMinerClient { const responsePossible = await repCycle.getResponsePossible(disputeStages.RESPOND_TO_CHALLENGE, entry.lastResponseTimestamp); if (responsePossible){ await this.updateGasEstimate('fast'); - await this._miner.respondToChallenge(); + this._adapter.log("Responding to challenge in dispute"); + const tx = await this._miner.respondToChallenge(); + await tx.wait(); } } } diff --git a/test/reputation-system/reputation-mining-client/client-auto-functionality.js b/test/reputation-system/reputation-mining-client/client-auto-functionality.js index 1173cf004d..356ffd7ba5 100644 --- a/test/reputation-system/reputation-mining-client/client-auto-functionality.js +++ b/test/reputation-system/reputation-mining-client/client-auto-functionality.js @@ -389,14 +389,16 @@ process.env.SOLIDITY_COVERAGE let badEntry = disputeRound[badIndex]; let goodEntry = disputeRound[goodIndex]; - // Forward time again so clients can start responding to challenges await forwardTimeTo(parseInt(goodEntry.lastResponseTimestamp, 10)); await noEventSeen(repCycleEthers, "JustificationRootHashConfirmed"); await forwardTime(SUBMITTER_ONLY_WINDOW + 1, this); + await mineBlock(); await goodClientConfirmedJRH; + + await mineBlock(); await badClient.confirmJustificationRootHash(); disputeRound = await repCycle.getDisputeRound(0); @@ -420,10 +422,12 @@ process.env.SOLIDITY_COVERAGE } while (badEntry.upperBound !== badEntry.lowerBound) { + await mineBlock(); const goodClientSearchStepPromise = getGoodClientBinarySearchStepPromise(); await forwardTimeTo(parseInt(badEntry.lastResponseTimestamp, 10) + SUBMITTER_ONLY_WINDOW); await goodClientSearchStepPromise; if (parseInt(badEntry.challengeStepCompleted, 10) <= parseInt(goodEntry.challengeStepCompleted, 10)) { + await mineBlock(); await badClient.respondToBinarySearchForChallenge(); } disputeRound = await repCycle.getDisputeRound(0); @@ -439,7 +443,9 @@ process.env.SOLIDITY_COVERAGE await forwardTimeTo(parseInt(badEntry.lastResponseTimestamp, 10) + SUBMITTER_ONLY_WINDOW); + await mineBlock(); await goodClientConfirmedBinarySearch; + await mineBlock(); await badClient.confirmBinarySearchResult(); disputeRound = await repCycle.getDisputeRound(0); @@ -447,6 +453,7 @@ process.env.SOLIDITY_COVERAGE await forwardTimeTo(parseInt(badEntry.lastResponseTimestamp, 10) + SUBMITTER_ONLY_WINDOW); + await mineBlock(); await goodClientCompleteChallenge; const goodClientInvalidateOpponent = new Promise(function (resolve, reject) { @@ -479,6 +486,7 @@ process.env.SOLIDITY_COVERAGE // Good client should now realise it can timeout bad submission await goodClientInvalidateOpponent; + await mineBlock(); // Add a listener to process log for when a new cycle starts, which won't happen yet because the submission window is still open const newCycleStart = new Promise(function (resolve, reject) { From 12730ba61760cd5e1ece2268662a0c5fd1f2fe4e Mon Sep 17 00:00:00 2001 From: Alex Rea Date: Wed, 26 Jan 2022 14:49:43 +0000 Subject: [PATCH 2/2] Practical updates to miner --- packages/reputation-miner/bin/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/reputation-miner/bin/index.js b/packages/reputation-miner/bin/index.js index c3458188fc..17916dab71 100644 --- a/packages/reputation-miner/bin/index.js +++ b/packages/reputation-miner/bin/index.js @@ -42,6 +42,7 @@ class RetryProvider extends ethers.providers.StaticJsonRpcProvider { } static attemptCheck(err, attemptNumber){ + console.log("Retrying RPC request #", attemptNumber); if (attemptNumber === 10){ return false; } @@ -56,7 +57,7 @@ class RetryProvider extends ethers.providers.StaticJsonRpcProvider { // method is the method name (e.g. getBalance) and params is an // object with normalized values passed in, depending on the method perform(method, params) { - return backoff(() => super.perform(method, params), {retry: RetryProvider.attemptCheck}); + return backoff(() => super.perform(method, params), {retry: RetryProvider.attemptCheck, startingDelay: 1000}); } }