Skip to content
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

Update minimum.rs #5342

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 127 additions & 75 deletions rust/main/agents/relayer/src/msg/gas_payment/policies/minimum.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
use async_trait::async_trait;
use derive_new::new;
use eyre::Result;

use hyperlane_core::{
HyperlaneMessage, InterchainGasExpenditure, InterchainGasPayment, TxCostEstimate, U256,
};

use crate::msg::gas_payment::GasPaymentPolicy;

/// Policy for checking the minimum gas payment.
#[derive(Debug, new)]
pub struct GasPaymentPolicyMinimum {
/// The minimum payment required to perform an operation.
minimum_payment: U256,
}

#[async_trait]
impl GasPaymentPolicy for GasPaymentPolicyMinimum {
/// Checks if the current gas payment meets the minimum requirements.
///
/// # Arguments
/// - `_message`: The message to be sent.
/// - `current_payment`: The current gas payment.
/// - `_current_expenditure`: The current gas expenditure.
/// - `tx_cost_estimate`: The estimated transaction cost.
///
/// # Returns
/// - `Ok(Some(gas_limit))` if the payment is sufficient.
/// - `Ok(None)` if the payment is insufficient.
async fn message_meets_gas_payment_requirement(
&self,
_message: &HyperlaneMessage,
current_payment: &InterchainGasPayment,
_current_expenditure: &InterchainGasExpenditure,
tx_cost_estimate: &TxCostEstimate,
) -> Result<Option<U256>> {
// Early return if the payment is zero
if current_payment.payment.is_zero() {
return Ok(None);
}

// Check if the payment meets the minimum requirement
if current_payment.payment >= self.minimum_payment {
Ok(Some(tx_cost_estimate.gas_limit))
} else {
Expand All @@ -30,83 +48,117 @@ impl GasPaymentPolicy for GasPaymentPolicyMinimum {
}
}

#[tokio::test]
async fn test_gas_payment_policy_minimum() {
#[cfg(test)]
mod tests {
use super::*;
use hyperlane_core::{HyperlaneMessage, H256};

let min = U256::from(1000u32);
let policy = GasPaymentPolicyMinimum::new(min);
let message = HyperlaneMessage::default();
#[tokio::test]
async fn test_gas_payment_policy_minimum() {
let min = U256::from(1000u32);
let policy = GasPaymentPolicyMinimum::new(min); // Using the automatically implemented new
let message = HyperlaneMessage::default();

// If the payment is less than the minimum, returns false
let current_payment = InterchainGasPayment {
message_id: H256::zero(),
destination: message.destination,
payment: U256::from(999u32),
gas_amount: U256::zero(),
};
// expenditure should make no difference
let current_expenditure = InterchainGasExpenditure {
message_id: H256::zero(),
gas_used: U256::from(1000000000u32),
tokens_used: U256::from(1000000000u32),
};
assert_eq!(
policy
.message_meets_gas_payment_requirement(
&message,
&current_payment,
&current_expenditure,
&TxCostEstimate {
gas_limit: U256::from(100000u32),
gas_price: U256::from(100000u32).try_into().unwrap(),
l2_gas_limit: None,
},
)
.await
.unwrap(),
None
);
// Test case: Payment is less than the minimum
let current_payment = InterchainGasPayment {
message_id: H256::zero(),
destination: message.destination,
payment: U256::from(999u32),
gas_amount: U256::zero(),
};
assert_eq!(
policy
.message_meets_gas_payment_requirement(
&message,
&current_payment,
&InterchainGasExpenditure::default(),
&TxCostEstimate::default(),
)
.await
.unwrap(),
None
);

// If the payment is at least the minimum, returns false
let current_payment = InterchainGasPayment {
message_id: H256::zero(),
destination: message.destination,
payment: U256::from(1000u32),
gas_amount: U256::zero(),
};
assert_eq!(
policy
.message_meets_gas_payment_requirement(
&message,
&current_payment,
&current_expenditure,
&TxCostEstimate {
gas_limit: U256::from(100000u32),
gas_price: U256::from(100001u32).try_into().unwrap(),
l2_gas_limit: None,
},
)
.await
.unwrap(),
Some(U256::from(100000u32))
);
// Test case: Payment is equal to the minimum
let current_payment = InterchainGasPayment {
payment: U256::from(1000u32),
..current_payment
};
assert_eq!(
policy
.message_meets_gas_payment_requirement(
&message,
&current_payment,
&InterchainGasExpenditure::default(),
&TxCostEstimate {
gas_limit: U256::from(100000u32),
..Default::default()
},
)
.await
.unwrap(),
Some(U256::from(100000u32))
);

// Ensure that even if the l2_gas_limit isn't None, the gas_limit is what's returned
assert_eq!(
policy
.message_meets_gas_payment_requirement(
&message,
&current_payment,
&current_expenditure,
&TxCostEstimate {
gas_limit: U256::from(100000u32),
gas_price: U256::from(100001u32).try_into().unwrap(),
l2_gas_limit: Some(U256::from(22222u32)),
},
)
.await
.unwrap(),
Some(U256::from(100000u32))
);
// Test case: Payment is greater than the minimum
let current_payment = InterchainGasPayment {
payment: U256::from(1001u32),
..current_payment
};
assert_eq!(
policy
.message_meets_gas_payment_requirement(
&message,
&current_payment,
&InterchainGasExpenditure::default(),
&TxCostEstimate {
gas_limit: U256::from(100000u32),
..Default::default()
},
)
.await
.unwrap(),
Some(U256::from(100000u32))
);

// Test case: Payment is zero
let current_payment = InterchainGasPayment {
payment: U256::zero(),
..current_payment
};
assert_eq!(
policy
.message_meets_gas_payment_requirement(
&message,
&current_payment,
&InterchainGasExpenditure::default(),
&TxCostEstimate::default(),
)
.await
.unwrap(),
None
);

// Test case: l2_gas_limit present but ignored
let current_payment = InterchainGasPayment {
payment: U256::from(1000u32),
..current_payment
};
assert_eq!(
policy
.message_meets_gas_payment_requirement(
&message,
&current_payment,
&InterchainGasExpenditure::default(),
&TxCostEstimate {
gas_limit: U256::from(100000u32),
l2_gas_limit: Some(U256::from(22222u32)),
..Default::default()
},
)
.await
.unwrap(),
Some(U256::from(100000u32))
);
}
}
Loading