Skip to content

Commit

Permalink
fix: Overhaul the max ack gas loss
Browse files Browse the repository at this point in the history
  • Loading branch information
jsanmigimeno committed Jun 10, 2024
1 parent b64a98b commit 17397b7
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 20 deletions.
6 changes: 4 additions & 2 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ global:
# Evaluation properties
evaluationRetryInterval: 3600000 # Interval at which to reevaluate whether to relay a message.
maxEvaluationDuration: 86400000 # Time after which to drop an undelivered message.
unrewardedDeliveryGas: '100000' # Gas amount that will be unrewarded on delivery submission.
verificationDeliveryGas: '55000' # Gas amount used for packet verification upon delivery.
unrewardedDeliveryGas: '25000' # Gas amount that will be unrewarded on delivery submission.
minDeliveryReward: 0.001 # In the 'pricingDenomination' specified below
relativeMinDeliveryReward: 0.001
unrewardedAckGas: '50000' # Gas amount that will be unrewarded on ack submission.
verificationAckGas: '55000' # Gas amount used for packet verification upon ack.
unrewardedAckGas: '25000' # Gas amount that will be unrewarded on ack submission.
minAckReward: 0.001 # In the 'pricingDenomination' specified below
relativeMinAckReward: 0.001
profitabilityFactor: 1.0 # Profitiability evaluation adjustment factor. A larger
Expand Down
2 changes: 2 additions & 0 deletions src/config/config.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,11 @@ const SUBMITTER_SCHEMA = {
evaluationRetryInterval: { $ref: "positive-number-schema" },
maxEvaluationDuration: { $ref: "positive-number-schema" },
unrewardedDeliveryGas: { $ref: "gas-field-schema" },
verificationDeliveryGas: { $ref: "gas-field-schema" },
minDeliveryReward: { $ref: "positive-number-schema" },
relativeMinDeliveryReward: { $ref: "positive-number-schema" },
unrewardedAckGas: { $ref: "gas-field-schema" },
verificationAckGas: { $ref: "gas-field-schema" },
minAckReward: { $ref: "positive-number-schema" },
relativeMinAckReward: { $ref: "positive-number-schema" },
profitabilityFactor: { $ref: "positive-number-schema" },
Expand Down
6 changes: 6 additions & 0 deletions src/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,15 @@ export class ConfigService {
if (config.unrewardedDeliveryGas != undefined) {
config.unrewardedDeliveryGas = BigInt(config.unrewardedDeliveryGas);
}
if (config.verificationDeliveryGas != undefined) {
config.verificationDeliveryGas = BigInt(config.verificationDeliveryGas);
}
if (config.unrewardedAckGas != undefined) {
config.unrewardedAckGas = BigInt(config.unrewardedAckGas);
}
if (config.verificationAckGas != undefined) {
config.verificationAckGas = BigInt(config.verificationAckGas);
}
return config as SubmitterGlobalConfig;
}

Expand Down
2 changes: 2 additions & 0 deletions src/config/config.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ export interface SubmitterGlobalConfig {
evaluationRetryInterval?: number;
maxEvaluationDuration?: number;
unrewardedDeliveryGas?: bigint;
verificationDeliveryGas?: bigint;
minDeliveryReward?: number;
relativeMinDeliveryReward?: number;
unrewardedAckGas?: bigint;
verificationAckGas?: bigint;
minAckReward?: number;
relativeMinAckReward?: number;
profitabilityFactor?: number;
Expand Down
52 changes: 34 additions & 18 deletions src/submitter/queues/eval-queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,12 +230,10 @@ export class EvalQueue extends ProcessingQueue<EvalOrder, SubmitOrder> {
bounty.priceOfDeliveryGas
);

// Consider the worst 'ack' submission loss, as in that case no one will desire to submit
// the 'ack', and this relayer will have to submit it in order to get the payment for the
// delivery.
const maxAckLoss = this.calcMaxGasLoss( // ! In source chain gas value
sourceGasPrice,
this.evaluationConfig.unrewardedAckGas,
this.evaluationConfig.verificationAckGas,
BigInt(bounty.maxGasAck),
bounty.priceOfAckGas,
);
Expand All @@ -248,7 +246,7 @@ export class EvalQueue extends ProcessingQueue<EvalOrder, SubmitOrder> {
this.chainId
);

const correctedDeliveryReward = deliveryReward - maxAckLoss;
const correctedDeliveryReward = deliveryReward + maxAckLoss;
const deliveryFiatReward = await this.getGasCostFiatPrice(
correctedDeliveryReward,
bounty.fromChainId
Expand Down Expand Up @@ -399,24 +397,42 @@ export class EvalQueue extends ProcessingQueue<EvalOrder, SubmitOrder> {
private calcMaxGasLoss(
gasPrice: bigint,
unrewardedGas: bigint,
verificationGas: bigint,
bountyMaxGas: bigint,
bountyPriceOfGas: bigint,
): bigint {
// Evaluate the worst possible loss of a submission. There are 2 possible scenarios:
// - The provided `bountyPriceOfGas` covers the current gas price: the worst loss
// will occur if no gas is used for the submission logic (and hence there is no bounty
// reward).
// - The provided `bountyPriceOfGas' does *not* cover the current gas price: the
// worst loss will occur if the maximum allowed amount of gas is used for the
// submission logic.

const fixedCost = unrewardedGas * gasPrice;

const worstCaseVariableCost = gasPrice > bountyPriceOfGas
? bountyMaxGas * (gasPrice - bountyPriceOfGas)
: 0n;

return fixedCost + worstCaseVariableCost;
// The gas used for the 'ack' submission is composed of 3 amounts:
// - Logic overhead: is never computed for the reward.
// - Verification logic: is only computed for the reward if the source application's
// 'ack' handler does not use all of the 'ack' gas allowance ('bountyMaxGas').
// - Source application's 'ack' handler: it is always computed for the reward (up to a
// maximum of 'bountyMaxGas').

// Evaluate the minimum expected profit from the 'ack' delivery. There are 2 possible
// scenarios:
// - No gas is used by the source application's 'ack' handler.
// - The maximum allowed amount of gas is used by the source application's 'ack' handler.

// NOTE: strictly speaking, 'verificationGas' should be upperbounded by 'bountyMaxGas' on
// the following line. However, this is not necessary, as in such a case
// 'maximumGasUsageProfit' will always return a smaller profit than 'minimumGasUsageProfit'.
const minimumGasUsageReward = verificationGas * bountyPriceOfGas;
const minimumGasUsageCost = (unrewardedGas + verificationGas) * gasPrice;
const minimumGasUsageProfit = minimumGasUsageReward - minimumGasUsageCost;

const maximumGasUsageReward = bountyMaxGas * bountyPriceOfGas;
const maximumGasUsageCost = (unrewardedGas + verificationGas + bountyMaxGas) * gasPrice;
const maximumGasUsageProfit = maximumGasUsageReward - maximumGasUsageCost;

const worstCaseProfit = minimumGasUsageProfit < maximumGasUsageProfit
? minimumGasUsageProfit
: maximumGasUsageProfit;

// Only return the 'worstCaseProfit' if it's negative.
return worstCaseProfit < 0n
? worstCaseProfit
: 0n;
}

private async getGasPrice(chainId: string): Promise<bigint> {
Expand Down
20 changes: 20 additions & 0 deletions src/submitter/submitter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ const NEW_ORDERS_DELAY_DEFAULT = 0;
const EVALUATION_RETRY_INTERVAL_DEFAULT = 60 * 60 * 1000;
const MAX_EVALUATION_DURATION_DEFAULT = 24 * 60 * 60 * 1000;
const UNREWARDED_DELIVERY_GAS_DEFAULT = 0n;
const VERIFICATION_DELIVERY_GAS_DEFAULT = 0n;
const MIN_DELIVERY_REWARD_DEFAULT = 0;
const RELATIVE_MIN_DELIVERY_REWARD_DEFAULT = 0;
const UNREWARDED_ACK_GAS_DEFAULT = 0n;
const VERIFICATION_ACK_GAS_DEFAULT = 0n;
const MIN_ACK_REWARD_DEFAULT = 0;
const RELATIVE_MIN_ACK_REWARD_DEFAULT = 0;
const PROFITABILITY_FACTOR_DEFAULT = 1;
Expand All @@ -35,9 +37,11 @@ interface GlobalSubmitterConfig {
evaluationRetryInterval: number;
maxEvaluationDuration: number;
unrewardedDeliveryGas: bigint;
verificationDeliveryGas: bigint;
minDeliveryReward: number;
relativeMinDeliveryReward: number;
unrewardedAckGas: bigint;
verificationAckGas: bigint;
minAckReward: number;
relativeMinAckReward: number;
profitabilityFactor: number;
Expand All @@ -57,9 +61,11 @@ export interface SubmitterWorkerData {
evaluationRetryInterval: number;
maxEvaluationDuration: number;
unrewardedDeliveryGas: bigint;
verificationDeliveryGas: bigint;
minDeliveryReward: number;
relativeMinDeliveryReward: number;
unrewardedAckGas: bigint;
verificationAckGas: bigint;
minAckReward: number;
relativeMinAckReward: number;
profitabilityFactor: number;
Expand Down Expand Up @@ -147,12 +153,16 @@ export class SubmitterService {
submitterConfig.maxEvaluationDuration ?? MAX_EVALUATION_DURATION_DEFAULT;
const unrewardedDeliveryGas =
submitterConfig.unrewardedDeliveryGas ?? UNREWARDED_DELIVERY_GAS_DEFAULT;
const verificationDeliveryGas =
submitterConfig.verificationDeliveryGas ?? VERIFICATION_DELIVERY_GAS_DEFAULT;
const minDeliveryReward =
submitterConfig.minDeliveryReward ?? MIN_DELIVERY_REWARD_DEFAULT;
const relativeMinDeliveryReward =
submitterConfig.relativeMinDeliveryReward ?? RELATIVE_MIN_DELIVERY_REWARD_DEFAULT;
const unrewardedAckGas =
submitterConfig.unrewardedAckGas ?? UNREWARDED_ACK_GAS_DEFAULT;
const verificationAckGas =
submitterConfig.verificationAckGas ?? VERIFICATION_ACK_GAS_DEFAULT;
const minAckReward =
submitterConfig.minAckReward ?? MIN_ACK_REWARD_DEFAULT;
const relativeMinAckReward =
Expand All @@ -173,9 +183,11 @@ export class SubmitterService {
evaluationRetryInterval,
maxEvaluationDuration,
unrewardedDeliveryGas,
verificationDeliveryGas,
minDeliveryReward,
relativeMinDeliveryReward,
unrewardedAckGas,
verificationAckGas,
minAckReward,
relativeMinAckReward,
profitabilityFactor,
Expand Down Expand Up @@ -230,6 +242,10 @@ export class SubmitterService {
unrewardedDeliveryGas:
chainConfig.submitter.unrewardedDeliveryGas ??
globalConfig.unrewardedDeliveryGas,

verificationDeliveryGas:
chainConfig.submitter.verificationDeliveryGas ??
globalConfig.verificationDeliveryGas,

maxEvaluationDuration:
chainConfig.submitter.maxEvaluationDuration ??
Expand All @@ -246,6 +262,10 @@ export class SubmitterService {
unrewardedAckGas:
chainConfig.submitter.unrewardedAckGas ??
globalConfig.unrewardedAckGas,

verificationAckGas:
chainConfig.submitter.verificationAckGas ??
globalConfig.verificationAckGas,

minAckReward:
chainConfig.submitter.minAckReward ??
Expand Down
2 changes: 2 additions & 0 deletions src/submitter/submitter.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ export interface BountyEvaluationConfig {
evaluationRetryInterval: number,
maxEvaluationDuration: number,
unrewardedDeliveryGas: bigint;
verificationDeliveryGas: bigint;
minDeliveryReward: number;
relativeMinDeliveryReward: number,
unrewardedAckGas: bigint;
verificationAckGas: bigint;
minAckReward: number;
relativeMinAckReward: number;
profitabilityFactor: number;
Expand Down
2 changes: 2 additions & 0 deletions src/submitter/submitter.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@ class SubmitterWorker {
evaluationRetryInterval: this.config.evaluationRetryInterval,
maxEvaluationDuration: this.config.maxEvaluationDuration,
unrewardedDeliveryGas: this.config.unrewardedDeliveryGas,
verificationDeliveryGas: this.config.verificationDeliveryGas,
minDeliveryReward: this.config.minDeliveryReward,
relativeMinDeliveryReward: this.config.relativeMinDeliveryReward,
unrewardedAckGas: this.config.unrewardedAckGas,
verificationAckGas: this.config.verificationAckGas,
minAckReward: this.config.minAckReward,
relativeMinAckReward: this.config.relativeMinAckReward,
profitabilityFactor: this.config.profitabilityFactor,
Expand Down

0 comments on commit 17397b7

Please sign in to comment.