Skip to content

Commit

Permalink
add jobs if not exists
Browse files Browse the repository at this point in the history
  • Loading branch information
defi-dev committed Mar 7, 2024
1 parent 9ae2724 commit 2e96f1e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 50 deletions.
3 changes: 2 additions & 1 deletion app/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ export interface IRandaoAgent extends IAgent {
export interface IDataSource {
getType(): string;
getBlocksDelay(): Promise<{ diff: bigint; nodeBlockNumber: bigint; sourceBlockNumber: bigint }>;
getJob(_context, jobKey): Promise<RandaoJob | LightJob>;
getRegisteredJobs(_context): Promise<{ data: Map<string, RandaoJob | LightJob>; meta: SourceMetadata }>;
getOwnersBalances(
context,
Expand Down Expand Up @@ -427,7 +428,7 @@ export interface IAgent {

getBaseFeePerGas(): bigint;

queryPastEvents(eventName: string, from: number, to: number): Promise<any>;
queryPastEvents(eventName: string, from: number, to: number, filters?: [any]): Promise<any>;

buildTx(calldata: string): Promise<UnsignedTransaction>;

Expand Down
75 changes: 44 additions & 31 deletions app/agents/AbstractAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ import {
import { BigNumber, ethers, Wallet } from 'ethers';
import { getEncryptedJson } from '../services/KeyService.js';
import { BN_ZERO, DEFAULT_SYNC_FROM_CHAINS } from '../Constants.js';
import { filterFunctionResultObject, numberToBigInt, toChecksummedAddress, weiValueToEth } from '../Utils.js';
import {

Check failure on line 21 in app/agents/AbstractAgent.ts

View workflow job for this annotation

GitHub Actions / build

Replace `⏎··filterFunctionResultObject,⏎··numberToBigInt,⏎··toChecksummedAddress,⏎··weiValueToEth,⏎` with `·filterFunctionResultObject,·numberToBigInt,·toChecksummedAddress,·weiValueToEth·`
filterFunctionResultObject,
numberToBigInt,
toChecksummedAddress,
weiValueToEth,
} from '../Utils.js';
import { FlashbotsExecutor } from '../executors/FlashbotsExecutor.js';
import { PGAExecutor } from '../executors/PGAExecutor.js';
import { getAgentDefaultSyncFromSafe, getDefaultExecutorConfig, setConfigDefaultValues } from '../ConfigGetters.js';
Expand Down Expand Up @@ -355,8 +360,13 @@ export abstract class AbstractAgent implements IAgent {
return this.blacklistedJobs.has(jobKey);
}

public getJob(jobKey: string): RandaoJob | LightJob | null {
return this.jobs.get(jobKey);
public async getJob(jobKey: string): Promise<RandaoJob | LightJob | null> {
let job = this.jobs.get(jobKey);
if (!job) {
job = await this.dataSource.getJob(this, jobKey);
await this.addJob(job);
}
return job;
}
public getJobsCount(): { total: number; interval: number; resolver: number } {
const counters = {
Expand Down Expand Up @@ -467,24 +477,24 @@ export abstract class AbstractAgent implements IAgent {
}
abstract _buildNewJob(event): LightJob | RandaoJob;

private async addJob(creationEvent: EventWrapper) {
const jobKey = creationEvent.args.jobKey;
const owner = creationEvent.args.owner;
private async addJobByRegisterEvent(creationEvent: EventWrapper) {
return this.addJob(this._buildNewJob(creationEvent));
}

const job = this._buildNewJob(creationEvent);
this.jobs.set(jobKey, job);
private async addJob(job: LightJob | RandaoJob) {
this.jobs.set(job.key, job);

await this.dataSource.addLensFieldsToOneJob(job);
job.clearJobCredits();

if (!this.ownerJobs.has(owner)) {
this.ownerJobs.set(owner, new Set());
if (!this.ownerJobs.has(job.owner)) {
this.ownerJobs.set(job.owner, new Set());
}
const set = this.ownerJobs.get(owner);
set.add(jobKey);
const set = this.ownerJobs.get(job.owner);
set.add(job.key);

if (!this.ownerBalances.has(owner)) {
this.ownerBalances.set(owner, BN_ZERO);
if (!this.ownerBalances.has(job.owner)) {
this.ownerBalances.set(job.owner, BN_ZERO);
}
}

Expand Down Expand Up @@ -723,7 +733,10 @@ export abstract class AbstractAgent implements IAgent {
return await this.contract.ethCall('getKeeper', [keeperId]);
}

public async queryPastEvents(eventName: string, from: number, to: number): Promise<any> {
public async queryPastEvents(eventName: string, from: number, to: number, filters = []): Promise<any> {
if (filters.length) {
eventName = this.contract[eventName](filters);
}
return this.contract.getPastEvents(eventName, from, to);
}

Expand All @@ -733,7 +746,7 @@ export abstract class AbstractAgent implements IAgent {

protected initializeListeners(blockNumber: number) {
// Job events
this.on('DepositJobCredits', event => {
this.on('DepositJobCredits', async event => {
const { jobKey, amount, fee } = event.args;

this.clog(
Expand All @@ -745,17 +758,17 @@ export abstract class AbstractAgent implements IAgent {
this.clog('error', `Ignoring DepositJobCredits event due the job missing: (jobKey=${jobKey})`);
}

const job = this.jobs.get(jobKey);
const job = await this.getJob(jobKey);
job.applyJobCreditsDeposit(BigNumber.from(amount));
job.watch();
});

this.on('WithdrawJobCredits', event => {
this.on('WithdrawJobCredits', async event => {
const { jobKey, amount } = event.args;

this.clog('debug', `'WithdrawJobCredits' event: (block=${event.blockNumber},jobKey=${jobKey},amount=${amount})`);

const job = this.jobs.get(jobKey);
const job = await this.getJob(jobKey);
job.applyJobCreditWithdrawal(BigNumber.from(amount));
job.watch();
});
Expand Down Expand Up @@ -804,15 +817,15 @@ export abstract class AbstractAgent implements IAgent {
}
});

this.on('AcceptJobTransfer', event => {
this.on('AcceptJobTransfer', async event => {
const { jobKey_, to_: ownerAfter } = event.args;

this.clog(
'debug',
`'AcceptJobTransfer' event: (block=${event.blockNumber},jobKey_=${jobKey_},to_=${ownerAfter})`,
);

const job = this.jobs.get(jobKey_);
const job = await this.getJob(jobKey_);
const ownerBefore = job.getOwner();
this.ownerJobs.get(ownerBefore).delete(jobKey_);

Expand All @@ -825,41 +838,41 @@ export abstract class AbstractAgent implements IAgent {
job.watch();
});

this.on('JobUpdate', event => {
this.on('JobUpdate', async event => {
const { jobKey, maxBaseFeeGwei, rewardPct, fixedReward, jobMinCvp, intervalSeconds } = event.args;

this.clog(
'debug',
`'JobUpdate' event: (block=${event.blockNumber},jobKey=${jobKey},maxBaseFeeGwei=${maxBaseFeeGwei},reardPct=${rewardPct},fixedReward=${fixedReward},jobMinCvp=${jobMinCvp},intervalSeconds=${intervalSeconds})`,
);

const job = this.jobs.get(jobKey);
const job = await this.getJob(jobKey);
job.applyUpdate(maxBaseFeeGwei, rewardPct, fixedReward, jobMinCvp, intervalSeconds);
job.watch();
});

this.on('SetJobPreDefinedCalldata', event => {
this.on('SetJobPreDefinedCalldata', async event => {
const { jobKey, preDefinedCalldata } = event.args;

this.clog(
'debug',
`'SetJobPreDefinedCalldata' event: (block=${event.blockNumber},jobKey=${jobKey},preDefinedCalldata=${preDefinedCalldata})`,
);

const job = this.jobs.get(jobKey);
const job = await this.getJob(jobKey);
job.applyPreDefinedCalldata(preDefinedCalldata);
job.watch();
});

this.on('SetJobResolver', event => {
this.on('SetJobResolver', async event => {
const { jobKey, resolverAddress, resolverCalldata } = event.args;

this.clog(
'debug',
`'SetJobResolver' event: (block=${event.blockNumber},jobKey=${jobKey},resolverAddress=${resolverAddress},useJobOwnerCredits_=${resolverCalldata})`,
);

const job = this.jobs.get(jobKey);
const job = await this.getJob(jobKey);
job.applyResolver(resolverAddress, resolverCalldata);
job.watch();
});
Expand All @@ -872,7 +885,7 @@ export abstract class AbstractAgent implements IAgent {
`'SetJobConfig' event: (block=${event.blockNumber},jobKey=${jobKey},isActive=${isActive_},useJobOwnerCredits_=${useJobOwnerCredits_},assertResolverSelector_=${assertResolverSelector_})`,
);

const job = this.jobs.get(jobKey);
const job = await this.getJob(jobKey);
const binJob = await this.network.queryLensJobsRawBytes32(this.address, jobKey);
job.applyBinJobData(binJob);
job.watch();
Expand All @@ -888,10 +901,10 @@ export abstract class AbstractAgent implements IAgent {
},jobKey=${jobKey},jobAddress=${jobAddress},jobId=${jobId},owner=${owner},params=${JSON.stringify(params)})`,
);

await this.addJob(event);
await this.addJobByRegisterEvent(event);
});

this.on('Execute', event => {
this.on('Execute', async event => {
const { jobKey, job: jobAddress, keeperId, gasUsed, baseFee, gasPrice, compensation, binJobAfter } = event.args;

this.clog(
Expand All @@ -905,7 +918,7 @@ export abstract class AbstractAgent implements IAgent {
)}eth/${numberToBigInt(compensation)}wei,binJobAfter=${binJobAfter})`,
);

const job = this.jobs.get(jobKey);
const job = await this.getJob(jobKey);
job.applyBinJobData(binJobAfter);
job.applyWasExecuted();

Expand Down
27 changes: 27 additions & 0 deletions app/dataSources/BlockchainSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,33 @@ export class BlockchainSource extends AbstractSource {
this.type = 'blockchain';
}

/**
* Getting a RegisterJob event and initialise a job.
* Returns Map structure which key is jobKey and value is instance of RandaoJob or LightJob. Await is required.
*
* @param context - agent caller context. This can be Agent.2.2.0.light or Agent.2.3.0.randao
* @param jobKey - Job key
*
* @return Promise<RandaoJob | LightJob>
*/
async getJob(context, jobKey): Promise<RandaoJob | LightJob> {
const latestBock = this.network.getLatestBlockNumber();
// TODO: check latestBlock not null
const registerLog = await this.agent
.queryPastEvents('RegisterJob', context.fullSyncFrom, Number(latestBock), [jobKey])
.then(list => list[0]);
const newJob = context._buildNewJob(registerLog);
// fetching additional fields from lens

const lensJob = await this.network.queryLensJobs(this.agent.address, [jobKey]).then(r => r.results[0]);
newJob.applyJob({
...lensJob,
owner: lensJob.owner,
config: parseConfig(BigNumber.from(lensJob.details.config)),
});
return newJob;
}

/**
* Getting a RegisterJob events and initialise a job.
* Returns Map structure which key is jobKey and value is instance of RandaoJob or LightJob. Await is required.
Expand Down
57 changes: 39 additions & 18 deletions app/dataSources/SubgraphSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import { toChecksummedAddress } from '../Utils.js';
import logger from '../services/Logger.js';
import { getMaxBlocksSubgraphDelay } from '../ConfigGetters.js';

export const QUERY_ALL_JOBS = `{
jobs(first: 1000) {
id
const JOBS_FIELDS = `id
active
jobAddress
jobId
Expand All @@ -38,6 +36,10 @@ export const QUERY_ALL_JOBS = `{
jobNextKeeperId
jobReservedSlasherId
jobSlashingPossibleAfter
`;
export const QUERY_ALL_JOBS = `{
jobs(first: 1000) {
${JOBS_FIELDS}
}
}`;

Expand Down Expand Up @@ -134,6 +136,39 @@ export class SubgraphSource extends AbstractSource {
return this.query(this.subgraphUrl, QUERY_ALL_JOBS).then(res => res.jobs);
}

async queryJob(jobKey) {
return this.query(
this.subgraphUrl,
`{
jobs(where: { id: "${jobKey}" }) {
${JOBS_FIELDS}
}
}`,
).then(res => res.jobs[0]);
}

async getJob(context, jobKey): Promise<RandaoJob | LightJob> {
return this.queryJob(jobKey).then(job => this.buildJob(context, job));
}

buildJob(context, job) {
const newJob = context._buildNewJob({
name: 'RegisterJob',
args: {
jobAddress: job.jobAddress,
jobId: BigNumber.from(job.jobId),
jobKey: job.id,
},
});
const lensJob = this.addLensFieldsToJobs(job);
newJob.applyJob({
...lensJob,
owner: lensJob.owner,
config: lensJob.config,
});
return newJob;
}

/**
* Getting a list of jobs from subgraph and initialise job.
* Returns Map structure which key is jobKey and value is instance of RandaoJob or LightJob. Await is required.
Expand All @@ -153,21 +188,7 @@ export class SubgraphSource extends AbstractSource {
try {
const jobs = await this.queryJobs();
jobs.forEach(job => {
const newJob = context._buildNewJob({
name: 'RegisterJob',
args: {
jobAddress: job.jobAddress,
jobId: BigNumber.from(job.jobId),
jobKey: job.id,
},
});
const lensJob = this.addLensFieldsToJobs(job);
newJob.applyJob({
...lensJob,
owner: lensJob.owner,
config: lensJob.config,
});
newJobs.set(job.id, newJob);
newJobs.set(job.id, this.buildJob(context, job));
});
} catch (e) {
throw this.err(e);
Expand Down

0 comments on commit 2e96f1e

Please sign in to comment.