Skip to content

Commit

Permalink
fix: keeper bot hardening to better handle many iterations for delaye…
Browse files Browse the repository at this point in the history
…d stakes execution
  • Loading branch information
jaybuidl committed Sep 4, 2023
1 parent 18766cd commit 6b6eaf4
Showing 1 changed file with 42 additions and 16 deletions.
58 changes: 42 additions & 16 deletions contracts/scripts/keeperBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import hre = require("hardhat");
const { ethers } = hre;
const MAX_DRAW_ITERATIONS = 30;
const MAX_EXECUTE_ITERATIONS = 20;
const MAX_DELAYED_STAKES_ITERATIONS = 50;
const WAIT_FOR_RNG_DURATION = 5 * 1000; // 5 seconds
const ITERATIONS_COOLDOWN_PERIOD = 20 * 1000; // 20 seconds
const HIGH_GAS_LIMIT = { gasLimit: 50000000 }; // 50M gas
const ITERATIONS_COOLDOWN_PERIOD = 10 * 1000; // 10 seconds
const HIGH_GAS_LIMIT = { gasLimit: 50_000_000 }; // 50M gas
const HEARTBEAT_URL = env.optionalNoDefault("HEARTBEAT_URL_KEEPER_BOT");
const SUBGRAPH_URL = env.require("SUBGRAPH_URL");
const MAX_JURORS_PER_DISPUTE = 1000; // Skip disputes with more than this number of jurors
Expand Down Expand Up @@ -219,7 +220,7 @@ const drawJurors = async (dispute: { id: string; currentRoundIndex: string }, it
try {
await core.callStatic.draw(dispute.id, iterations, HIGH_GAS_LIMIT);
} catch (e) {
logger.info(`Draw: will fail for ${dispute.id}, skipping`);
logger.error(`Draw: will fail for ${dispute.id}, skipping`);
return success;
}
try {
Expand All @@ -241,7 +242,7 @@ const executeRepartitions = async (dispute: { id: string; currentRoundIndex: str
try {
await core.callStatic.execute(dispute.id, dispute.currentRoundIndex, iterations, HIGH_GAS_LIMIT);
} catch (e) {
logger.info(`Execute: will fail for ${dispute.id}, skipping`);
logger.error(`Execute: will fail for ${dispute.id}, skipping`);
return success;
}
try {
Expand All @@ -260,7 +261,7 @@ const executeRuling = async (dispute: { id: string }) => {
try {
await core.callStatic.executeRuling(dispute.id);
} catch (e) {
logger.info(`ExecuteRuling: will fail for ${dispute.id}, skipping`);
logger.error(`ExecuteRuling: will fail for ${dispute.id}, skipping`);
return success;
}
try {
Expand Down Expand Up @@ -290,7 +291,7 @@ const withdrawAppealContribution = async (
contribution.choice
);
} catch (e) {
logger.info(
logger.warn(
`WithdrawFeesAndRewards: will fail for dispute #${disputeId}, round #${roundId}, choice ${contribution.choice} and beneficiary ${contribution.contributor.id}, skipping`
);
return success;
Expand Down Expand Up @@ -323,6 +324,40 @@ const withdrawAppealContribution = async (
return success;
};

const executeDelayedStakes = async () => {
const { sortition } = await getContracts();

// delayedStakes = 1 + delayedStakeWriteIndex - delayedStakeReadIndex
const delayedStakesRemaining = BigNumber.from(1)
.add(await sortition.delayedStakeWriteIndex())
.sub(await sortition.delayedStakeReadIndex());

const delayedStakes = delayedStakesRemaining.lt(MAX_DELAYED_STAKES_ITERATIONS)
? delayedStakesRemaining
: BigNumber.from(MAX_DELAYED_STAKES_ITERATIONS);

if (delayedStakes.eq(0)) {
logger.info("No delayed stakes to execute");
return true;
}
logger.info(`Executing ${delayedStakes} delayed stakes, ${delayedStakesRemaining} remaining`);
let success = false;
try {
await sortition.callStatic.executeDelayedStakes(delayedStakes);
} catch (e) {
logger.error(`executeDelayedStakes: will fail because of ${JSON.stringify(e)}`);
return success;
}
try {
const gas = (await sortition.estimateGas.executeDelayedStakes(delayedStakes)).mul(150).div(100); // 50% extra gas
const tx = await (await sortition.executeDelayedStakes(delayedStakes, { gasLimit: gas })).wait();
logger.info(`executeDelayedStakes txID: ${tx?.transactionHash}`);
} catch (e) {
handleError(e);
}
return success;
};

const getMissingJurors = async (dispute: { id: string; currentRoundIndex: string }) => {
const { core } = await getContracts();
const { nbVotes, drawnJurors } = await core.getRoundInfo(dispute.id, dispute.currentRoundIndex);
Expand Down Expand Up @@ -594,18 +629,9 @@ async function main() {
// ----------------------------------------------- //
// EXECUTE DELAYED STAKES //
// ----------------------------------------------- //
// delayedStakes = 1 + delayedStakeWriteIndex - delayedStakeReadIndex
const delayedStakes = BigNumber.from(1)
.add(await sortition.delayedStakeWriteIndex())
.sub(await sortition.delayedStakeReadIndex());

if (await isPhaseStaking()) {
if (delayedStakes.gt(0)) {
logger.info("Executing delayed stakes");
await sortition.executeDelayedStakes(delayedStakes);
} else {
logger.info("No delayed stakes to execute");
}
await executeDelayedStakes();
}

await sendHeartbeat();
Expand Down

0 comments on commit 6b6eaf4

Please sign in to comment.