From a64baab811c0dcca63aeb2dda4c59fd822b14a9d Mon Sep 17 00:00:00 2001 From: Jorge Sanmiguel <8038323+jsanmigimeno@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:12:25 +0000 Subject: [PATCH] feat: Allow for AMB payment (basic implementation) --- src/config/config.schema.ts | 3 ++- src/submitter/queues/eval-queue.ts | 35 +++++++++++++++++++--------- src/submitter/queues/submit-queue.ts | 2 ++ src/submitter/submitter.service.ts | 17 ++++++++++++++ src/submitter/submitter.types.ts | 1 + src/submitter/submitter.worker.ts | 3 +++ 6 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/config/config.schema.ts b/src/config/config.schema.ts index 2c4d80e..0042e0a 100644 --- a/src/config/config.schema.ts +++ b/src/config/config.schema.ts @@ -199,7 +199,8 @@ const AMBS_SCHEMA = { enabled: { type: "boolean" }, - incentivesAddress: { $ref: "address-field-schema" } + incentivesAddress: { $ref: "address-field-schema" }, + packetCost: { $ref: "gas-field-schema" } }, required: ["name"], additionalProperties: true, diff --git a/src/submitter/queues/eval-queue.ts b/src/submitter/queues/eval-queue.ts index 541ac90..0d1d243 100644 --- a/src/submitter/queues/eval-queue.ts +++ b/src/submitter/queues/eval-queue.ts @@ -19,6 +19,7 @@ export class EvalQueue extends ProcessingQueue { maxTries: number, private readonly store: Store, private readonly incentivesContracts: Map, + private readonly packetCosts: Map, private readonly chainId: string, private readonly gasLimitBuffer: Record, relayerAddress: string, @@ -32,11 +33,11 @@ export class EvalQueue extends ProcessingQueue { order: EvalOrder, _retryCount: number, ): Promise | null> { - const gasLimit = await this.evaluateBounty(order); + const transactionParameters = await this.evaluateBounty(order); - if (gasLimit > 0) { + if (transactionParameters != null) { // Move the order to the submit queue - return { result: { ...order, gasLimit } }; + return { result: { ...order, ...transactionParameters } }; } else { return null; } @@ -114,7 +115,7 @@ export class EvalQueue extends ProcessingQueue { return this.store.getBounty(messageIdentifier); } - private async evaluateBounty(order: EvalOrder): Promise { + private async evaluateBounty(order: EvalOrder): Promise<{ gasLimit: bigint, value?: bigint} | null> { const messageIdentifier = order.messageIdentifier; const bounty = await this.queryBountyInfo(messageIdentifier); if (bounty === null || bounty === undefined) { @@ -132,7 +133,7 @@ export class EvalQueue extends ProcessingQueue { { messageIdentifier }, `Bounty evaluation (source to destination). Bounty already delivered.`, ); - return 0n; // Do not relay packet + return null; // Do not relay packet } } else { // Destination to Source @@ -141,15 +142,21 @@ export class EvalQueue extends ProcessingQueue { { messageIdentifier }, `Bounty evaluation (destination to source). Bounty already acked.`, ); - return 0n; // Do not relay packet + return null; // Do not relay packet } } const contract = this.incentivesContracts.get(order.amb)!; //TODO handle undefined case + + const value = isDelivery + ? this.packetCosts.get(order.amb) + : 0n; + const gasEstimation = await contract.processPacket.estimateGas( order.messageCtx, order.message, this.relayerAddress, + { value } ); const gasLimitBuffer = this.getGasLimitBuffer(order.amb); @@ -173,8 +180,11 @@ export class EvalQueue extends ProcessingQueue { const isGasLimitEnough = gasLimit >= gasEstimation; const relayDelivery = order.priority || isGasLimitEnough; return relayDelivery - ? (isGasLimitEnough ? gasLimit : gasEstimation) // Return the largest of gasLimit and gasEstimation - : 0n; + ? { + gasLimit:(isGasLimitEnough ? gasLimit : gasEstimation), // Return the largest of gasLimit and gasEstimation + value, + } + : null; } else { // Destination to Source const gasLimit = BigInt(bounty.maxGasAck + gasLimitBuffer); @@ -193,11 +203,14 @@ export class EvalQueue extends ProcessingQueue { const isGasLimitEnough = gasLimit >= gasEstimation; const relayAck = order.priority || isGasLimitEnough; return relayAck - ? (isGasLimitEnough ? gasLimit : gasEstimation) // Return the largest of gasLimit and gasEstimation - : 0n; + ? { + gasLimit: (isGasLimitEnough ? gasLimit : gasEstimation), // Return the largest of gasLimit and gasEstimation + value, + } + : null; } - return 0n; // Do not relay packet + return null; // Do not relay packet } private getGasLimitBuffer(amb: string): number { diff --git a/src/submitter/queues/submit-queue.ts b/src/submitter/queues/submit-queue.ts index 738d1bd..81b003a 100644 --- a/src/submitter/queues/submit-queue.ts +++ b/src/submitter/queues/submit-queue.ts @@ -46,6 +46,7 @@ export class SubmitQueue extends ProcessingQueue< order.message, this.relayerAddress, { + value: order.value, gasLimit: order.gasLimit, }, ); @@ -61,6 +62,7 @@ export class SubmitQueue extends ProcessingQueue< const txRequest: TransactionRequest = { to: await contract.getAddress(), data: txData, + value: order.value, gasLimit: order.gasLimit, }; diff --git a/src/submitter/submitter.service.ts b/src/submitter/submitter.service.ts index ab8df54..d89c448 100644 --- a/src/submitter/submitter.service.ts +++ b/src/submitter/submitter.service.ts @@ -31,6 +31,7 @@ export interface SubmitterWorkerData { rpc: string; relayerPrivateKey: string; incentivesAddresses: Map; + packetCosts: Map; newOrdersDelay: number; retryInterval: number; processingInterval: number; @@ -151,11 +152,27 @@ export class SubmitterService { } }); + const packetCosts = new Map(); + this.configService.ambsConfig.forEach((amb) => { + const packetCost: string = this.configService.getAMBConfig( + amb.name, + 'packetCost', + chainConfig.chainId + ); + if (packetCost != undefined) { + packetCosts.set( + amb.name, + BigInt(packetCost), //TODO add log error if this fails + ); + } + }); + return { chainId, rpc, relayerPrivateKey, incentivesAddresses, + packetCosts, newOrdersDelay: chainConfig.submitter.newOrdersDelay ?? globalConfig.newOrdersDelay, diff --git a/src/submitter/submitter.types.ts b/src/submitter/submitter.types.ts index 9c40270..34e0125 100644 --- a/src/submitter/submitter.types.ts +++ b/src/submitter/submitter.types.ts @@ -13,6 +13,7 @@ export interface EvalOrder extends Order { export interface SubmitOrder extends Order { priority: boolean; + value?: bigint; gasLimit: bigint | undefined; requeueCount?: number; } diff --git a/src/submitter/submitter.worker.ts b/src/submitter/submitter.worker.ts index 3fb2ffd..766faa6 100644 --- a/src/submitter/submitter.worker.ts +++ b/src/submitter/submitter.worker.ts @@ -59,6 +59,7 @@ class SubmitterWorker { this.config.maxTries, this.store, this.loadIncentivesContracts(this.config.incentivesAddresses), + this.config.packetCosts, this.config.chainId, this.config.gasLimitBuffer, this.config.walletPublicKey, @@ -86,6 +87,7 @@ class SubmitterWorker { maxTries: number, store: Store, incentivesContracts: Map, + packetCosts: Map, chainId: string, gasLimitBuffer: Record, walletPublicKey: string, @@ -97,6 +99,7 @@ class SubmitterWorker { maxTries, store, incentivesContracts, + packetCosts, chainId, gasLimitBuffer, walletPublicKey,