-
Notifications
You must be signed in to change notification settings - Fork 439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Gas Policy Minimum Handling to Prevent Unexpected Behavior #5517
base: main
Are you sure you want to change the base?
fix: Gas Policy Minimum Handling to Prevent Unexpected Behavior #5517
Conversation
|
@christianangelopoulos put fix: as prefix to pass linter |
added comments clarifying the requirements of each gas policy per request from @daniel-savu |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great, thank you for taking the time to look into this! Left mostly nits
payment: U256::from(1), | ||
gas_amount: U256::from(1), | ||
}; | ||
hyperlane_db.process_gas_payment(payment, &LogMeta::random()); | ||
|
||
let enforcer = GasPaymentEnforcer::new( | ||
// Require a payment | ||
vec![GasPaymentEnforcementConf { | ||
policy: GasPaymentEnforcementPolicy::Minimum { | ||
payment: U256::from(1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we test for the zero payment edge case here since that's the goal of this PR. So with these params and some changes below as well, and the policy should still be met
payment: U256::from(1), | |
gas_amount: U256::from(1), | |
}; | |
hyperlane_db.process_gas_payment(payment, &LogMeta::random()); | |
let enforcer = GasPaymentEnforcer::new( | |
// Require a payment | |
vec![GasPaymentEnforcementConf { | |
policy: GasPaymentEnforcementPolicy::Minimum { | |
payment: U256::from(1), | |
payment: U256::zero(), | |
gas_amount: U256::zero(), | |
}; | |
hyperlane_db.process_gas_payment(payment, &LogMeta::random()); | |
let enforcer = GasPaymentEnforcer::new( | |
// Require a payment | |
vec![GasPaymentEnforcementConf { | |
policy: GasPaymentEnforcementPolicy::Minimum { | |
payment: U256::zero(), |
let payment = InterchainGasPayment { | ||
message_id: HyperlaneMessage::default().id(), | ||
destination: HyperlaneMessage::default().destination, | ||
payment: U256::from(100), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be anything so I'd set it to like 1 to make it easier to understand it's not related to the 100 in TxCostEstimate
message_id: HyperlaneMessage::default().id(), | ||
destination: HyperlaneMessage::default().destination, | ||
payment: U256::from(100), | ||
gas_amount: U256::from(100), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the test uses a numerator of 1 and a denominator of 2 let's set this to 50 to test the edge case
gas_amount: U256::from(100), | |
gas_amount: U256::from(50), |
/// Minimum requires a message to exist on the IGP specified in the config, | ||
/// even if the payment is zero. For example, a policy of Minimum { payment: 0 } | ||
/// will only relay messages that are processed by the IGP specified in the config. | ||
/// If you want to relay all messages regardless of payment and IGP, use `None`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
/// Minimum requires a message to exist on the IGP specified in the config, | |
/// even if the payment is zero. For example, a policy of Minimum { payment: 0 } | |
/// will only relay messages that are processed by the IGP specified in the config. | |
/// If you want to relay all messages regardless of payment and IGP, use `None`. | |
/// `Minimum` requires a payment to exist on the IGP specified in the config, | |
/// even if the payment is zero. For example, a policy of Minimum { payment: 0 } | |
/// will only relay messages that send a zero payment to the IGP specified in the config. | |
/// This is different from not requiring message senders to make any payment at all to the configured IGP to get relayed. To relay regardless of the existence of a payment, the `None` IGP policy should be used. |
|
||
/// OnChainFeeQuoting requires the user to pay a specified fraction of the | ||
/// estimated gas. Like the Minimum policy, OnChainFeeQuoting requires a | ||
/// message to exist on the IGP specified in the config. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
/// message to exist on the IGP specified in the config. | |
/// payment to exist on the IGP specified in the config. |
@@ -81,12 +81,17 @@ pub struct GasPaymentEnforcementConf { | |||
#[derive(Debug, Clone, Default)] | |||
pub enum GasPaymentEnforcementPolicy { | |||
/// No requirement - all messages are processed regardless of gas payment | |||
/// and regardless of whether the message was processed by the specified IGP. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
/// and regardless of whether the message was processed by the specified IGP. | |
/// and regardless of whether a payment for the message was processed by the specified IGP. |
/// even if the payment is zero. For example, a policy of Minimum { payment: 0 } | ||
/// will only relay messages that are processed by the IGP specified in the config. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto as for message_meets_gas_payment_requirement
Description
Prior to this change, configuring the
gaspaymentenforcement
parameter in the config to a minimum of 0 resulted in unexpected behavior. With this configuration, the relayer would relay any message from the designated relay chains, whether or not the message paid the specified IGP, resulting in the same behavior asgaspaymentenforcement
of None.This is due to
fn message_meets_gas_payment_requirement
inrust/main/agents/relayer/src/msg/gas_payment/mod.rs
.If the payment does not exist (because it was not indexed on the specified IGP),
current_payment
is set toInterchainGasPayment::from_gas_payment_key(gas_payment_key)
which creates an InterchainGasPayment with a default payment value of 0. As a result, payments to other IGPs appeared to be 0 payments to the specified IGP. Therefore, in the loop later in the function, the message matches withGasPolicyStatus::PolicyMet(gas_limit)
and the relayer relays it.These changes create the desired behavior, namely, that setting
gaspaymentenforcement
to a minimum of 0 should only relay messages that hooked / emitted from the specified IGP.Changes
The desired functionality is implemented by modifying the
message_meets_gas_payment_requirement
function inrust/main/agents/relayer/src/msg/gas_payment/mod.rs
. The change adds a check in that function to ensure that theself.db.retrieve_gas_payment_by_gas_payment_key(gas_payment_key)?;
did in fact return a payment on the IGP from the database.The check also calls a new function added to the
GasPaymentPolicy
trait calledrequires_payment_found
. By default, this is set to returnfalse
, which allows thenone.rs
gas policy to skip this logic and continue relaying all messages. For theminimum.rs
andon_chain_fee_quoting.rs
gas policies, this is set to returntrue
which requires a gas payment event to have been found on the specified IGP to continue.Related issues
N/A
Backward compatibility
Unsure, as I am not as familiar with the history associated with this codebase.
Testing
Added unit tests and am currently running manual tests to ensure only messages that were emitted from the specified IGP were relayed.