diff --git a/app/Network.ts b/app/Network.ts index 03f581f..d0edd41 100644 --- a/app/Network.ts +++ b/app/Network.ts @@ -374,7 +374,12 @@ export class Network { public registerTimeout(key: string, triggerCallbackAfter: number, callback: (blockTimestamp: number) => void) { this._validateKeyLength(key, 'interval'); this._validateKeyNotInMap(key, this.timeoutData, 'interval'); - this.clog('SET Timeout', key, `at: ${triggerCallbackAfter}`, `now: ${nowS()}`); + this.clog( + 'SET Timeout', + key, + `at: ${triggerCallbackAfter}`, + `now: ${nowS()}, in: ${triggerCallbackAfter - nowS()}`, + ); this.timeoutData[key] = { triggerCallbackAfter, callback, diff --git a/app/agents/AbstractAgent.ts b/app/agents/AbstractAgent.ts index 02069bd..c22ef65 100644 --- a/app/agents/AbstractAgent.ts +++ b/app/agents/AbstractAgent.ts @@ -47,7 +47,7 @@ export abstract class AbstractAgent implements IAgent { private keeperConfig: number; protected jobs: Map; - private ownerBalances: Map; + protected ownerBalances: Map; private ownerJobs: Map>; private keyAddress: string; private keyPass: string; diff --git a/app/agents/Agent.2.3.0.randao.ts b/app/agents/Agent.2.3.0.randao.ts index fd21fa4..6b290ed 100644 --- a/app/agents/Agent.2.3.0.randao.ts +++ b/app/agents/Agent.2.3.0.randao.ts @@ -185,6 +185,30 @@ export class AgentRandao_2_3_0 extends AbstractAgent implements IRandaoAgent { } _afterInitializeListeners() { + this.contract.on('ExecutionReverted', event => { + const { actualKeeperId, compensation, executionReturndata, jobKey } = event.args; + + this.clog( + `'ExecutionReverted' event 🔈: (block=${event.blockNumber},jobKey=${jobKey},actualKeeperId=${actualKeeperId},compensation=${compensation},executionReturndata=${executionReturndata})`, + ); + + const job = this.jobs.get(jobKey); + job.applyWasExecuted(); + + if (job.creditsSourceIsJobOwner()) { + const ownerCreditsBefore = this.ownerBalances.get(job.getOwner()); + const ownerCreditsAfter = ownerCreditsBefore.sub(compensation); + this.clog( + `Owner balance credited: (jobOwner=${job.getOwner()},amount=${compensation.toString()},before=${ownerCreditsBefore},after=${ownerCreditsAfter}`, + ); + this.ownerBalances.set(job.getOwner(), ownerCreditsAfter); + } else { + job.applyJobCreditsCredit(compensation); + } + + // The keeper was unassigned earlier with JobKeeperChanged event, thus no need to call watch() here + }); + this.contract.on(['JobKeeperChanged'], async event => { const { keeperFrom, keeperTo, jobKey } = event.args; diff --git a/app/jobs/AbstractJob.ts b/app/jobs/AbstractJob.ts index 9775246..9f1409a 100644 --- a/app/jobs/AbstractJob.ts +++ b/app/jobs/AbstractJob.ts @@ -247,6 +247,10 @@ export abstract class AbstractJob { this.details.credits = this.details.credits.sub(credits); } + public applyJobCreditsCredit(credits: BigNumber) { + this.details.credits = this.details.credits.sub(credits); + } + public applyResolver(resolverAddress: string, resolverCalldata: string) { this.resolver = { resolverAddress, resolverCalldata }; } @@ -422,7 +426,7 @@ export abstract class AbstractJob { }); } - private nextExecutionTimestamp(): number { + protected nextExecutionTimestamp(): number { if (this.details.intervalSeconds === 0) { throw this.err(`Unexpected nextExecutionTimestamp() callback for job ${this.key}`); } diff --git a/app/jobs/RandaoJob.ts b/app/jobs/RandaoJob.ts index dca3d38..e6f3312 100644 --- a/app/jobs/RandaoJob.ts +++ b/app/jobs/RandaoJob.ts @@ -112,13 +112,23 @@ export class RandaoJob extends AbstractJob { this._unlockInitiateSlashing(); } + protected nextExecutionTimestamp(): number { + if (this.details.intervalSeconds === 0) { + throw this.err(`Unexpected nextExecutionTimestamp() callback for job ${this.key}`); + } + + return (this.details.lastExecutionAt || this.createdAt) + this.details.intervalSeconds; + } + private intervalPeriod2StartsAt(): number { if (this.details.intervalSeconds === 0) { throw this.err(`Unexpected slashingAvailableTimestamp() callback for job ${this.key}`); } return ( - this.details.lastExecutionAt + this.details.intervalSeconds + (this.agent as IRandaoAgent).getPeriod1Duration() + (this.details.lastExecutionAt || this.createdAt) + + this.details.intervalSeconds + + (this.agent as IRandaoAgent).getPeriod1Duration() ); }