Skip to content

Commit e5cf1df

Browse files
authored
Merge pull request #2002 from kleros/fix/keeper-bot-useless-draws
fix: avoid unnecessary calls draw() when no juror is available
2 parents 30382a0 + 9e8aa9e commit e5cf1df

File tree

5 files changed

+22
-7
lines changed

5 files changed

+22
-7
lines changed

contracts/deploy/upgrade-all.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ const deployUpgradeAll: DeployFunction = async (hre: HardhatRuntimeEnvironment)
8181
await upgrade(disputeKitClassic, "initialize6", []);
8282
await upgrade(disputeTemplateRegistry, "initialize2", []);
8383
await upgrade(evidence, "initialize2", []);
84-
await upgrade(core, "initialize4", []);
84+
await upgrade(core, "initialize5", []);
8585
await upgrade(policyRegistry, "initialize2", []);
8686
await upgrade(sortition, "initialize3", []);
8787
};

contracts/scripts/keeperBot.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Cores, getContracts as getContractsForCoreType } from "./utils/contract
77

88
let request: <T>(url: string, query: string) => Promise<T>; // Workaround graphql-request ESM import
99
const { ethers } = hre;
10+
const MAX_DRAW_CALLS_WITHOUT_JURORS = 10;
1011
const MAX_DRAW_ITERATIONS = 30;
1112
const MAX_EXECUTE_ITERATIONS = 20;
1213
const MAX_DELAYED_STAKES_ITERATIONS = 50;
@@ -248,7 +249,19 @@ const drawJurors = async (dispute: { id: string; currentRoundIndex: string }, it
248249
const { core } = await getContracts();
249250
let success = false;
250251
try {
251-
await core.draw.staticCall(dispute.id, iterations, HIGH_GAS_LIMIT);
252+
const simulatedIterations = iterations * MAX_DRAW_CALLS_WITHOUT_JURORS; // Drawing will be skipped as long as no juror is available in the next MAX_DRAW_CALLS_WITHOUT_JURORS calls to draw() given this nb of iterations.
253+
const { drawnJurors: drawnJurorsBefore } = await core.getRoundInfo(dispute.id, dispute.currentRoundIndex);
254+
const nbDrawnJurors = (await core.draw.staticCall(dispute.id, simulatedIterations, HIGH_GAS_LIMIT)) as bigint;
255+
const extraJurors = nbDrawnJurors - BigInt(drawnJurorsBefore.length);
256+
logger.debug(
257+
`Draw: ${extraJurors} jurors available in the next ${simulatedIterations} iterations for dispute ${dispute.id}`
258+
);
259+
if (extraJurors <= 0n) {
260+
logger.warn(
261+
`Draw: skipping, no jurors available in the next ${simulatedIterations} iterations for dispute ${dispute.id}`
262+
);
263+
return success;
264+
}
252265
} catch (e) {
253266
logger.error(`Draw: will fail for ${dispute.id}, skipping`);
254267
return success;

contracts/src/arbitration/KlerosCore.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from "./KlerosCor
88
/// Core arbitrator contract for Kleros v2.
99
/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.
1010
contract KlerosCore is KlerosCoreBase {
11-
string public constant override version = "0.9.3";
11+
string public constant override version = "0.9.4";
1212

1313
// ************************************* //
1414
// * Constructor * //
@@ -56,7 +56,7 @@ contract KlerosCore is KlerosCoreBase {
5656
);
5757
}
5858

59-
function initialize4() external reinitializer(4) {
59+
function initialize5() external reinitializer(5) {
6060
// NOP
6161
}
6262

contracts/src/arbitration/KlerosCoreBase.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,8 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
593593
/// @dev Draws jurors for the dispute. Can be called in parts.
594594
/// @param _disputeID The ID of the dispute.
595595
/// @param _iterations The number of iterations to run.
596-
function draw(uint256 _disputeID, uint256 _iterations) external {
596+
/// @return nbDrawnJurors The total number of jurors drawn in the round.
597+
function draw(uint256 _disputeID, uint256 _iterations) external returns (uint256 nbDrawnJurors) {
597598
Dispute storage dispute = disputes[_disputeID];
598599
uint256 currentRound = dispute.rounds.length - 1;
599600
Round storage round = dispute.rounds[currentRound];
@@ -616,6 +617,7 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
616617
}
617618
}
618619
round.drawIterations += i;
620+
return round.drawnJurors.length;
619621
}
620622

621623
/// @dev Appeals the ruling of a specified dispute.

contracts/src/arbitration/KlerosCoreNeo.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
99
/// Core arbitrator contract for Kleros v2.
1010
/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.
1111
contract KlerosCoreNeo is KlerosCoreBase {
12-
string public constant override version = "0.8.0";
12+
string public constant override version = "0.9.4";
1313

1414
// ************************************* //
1515
// * Storage * //
@@ -67,7 +67,7 @@ contract KlerosCoreNeo is KlerosCoreBase {
6767
jurorNft = _jurorNft;
6868
}
6969

70-
function initialize4() external reinitializer(4) {
70+
function initialize5() external reinitializer(5) {
7171
// NOP
7272
}
7373

0 commit comments

Comments
 (0)