Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miner client updates as real world imperfect #1014

Merged
merged 2 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions packages/reputation-miner/ReputationMinerClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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.
Expand All @@ -509,34 +513,43 @@ 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?
// Check that our opponent has finished the binary search, check that we have, and check we've not confirmed yet
} 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)
)
{
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();
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/reputation-miner/bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -439,14 +443,17 @@ 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);
badEntry = disputeRound[badIndex];

await forwardTimeTo(parseInt(badEntry.lastResponseTimestamp, 10) + SUBMITTER_ONLY_WINDOW);

await mineBlock();
await goodClientCompleteChallenge;

const goodClientInvalidateOpponent = new Promise(function (resolve, reject) {
Expand Down Expand Up @@ -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) {
Expand Down