Move to estimateRetryableTicket to get L2 gas for arbitrum chains (#1949)

### Description

* Moves to `estimateRetryableTicket` to get Arbitrum L2 gas

### Drive-by changes

none

### Related issues

- Fixes #1728

### Backward compatibility

_Are these changes backward compatible?_

Yes

_Are there any infrastructure implications, e.g. changes that would
prohibit deploying older commits using this infra tooling?_

None


### Testing

_What kind of testing have these changes undergone?_

Unit tests - haven't deployed yet tho
pull/1954/head
Trevor Porter 2 years ago committed by GitHub
parent 2c0b12528b
commit 81ad2295fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      rust/agents/relayer/src/msg/gas_payment/mod.rs
  2. 41
      rust/chains/hyperlane-ethereum/src/mailbox.rs

@ -2,7 +2,7 @@ use std::fmt::Debug;
use async_trait::async_trait; use async_trait::async_trait;
use eyre::Result; use eyre::Result;
use tracing::{error, trace}; use tracing::{debug, error, trace};
use hyperlane_core::{ use hyperlane_core::{
db::HyperlaneDB, HyperlaneMessage, InterchainGasExpenditure, InterchainGasPayment, db::HyperlaneDB, HyperlaneMessage, InterchainGasExpenditure, InterchainGasPayment,
@ -105,6 +105,13 @@ impl GasPaymentEnforcer {
?whitelist, ?whitelist,
"Message matched whitelist for policy" "Message matched whitelist for policy"
); );
debug!(
msg=%message,
?policy,
?current_payment,
?current_expenditure,
"Evaluating if message meets gas payment requirement",
);
return policy return policy
.message_meets_gas_payment_requirement( .message_meets_gas_payment_requirement(
message, message,

@ -27,7 +27,7 @@ use crate::tx::report_tx;
use crate::EthereumProvider; use crate::EthereumProvider;
/// An amount of gas to add to the estimated gas /// An amount of gas to add to the estimated gas
const GAS_ESTIMATE_BUFFER: u32 = 100000; const GAS_ESTIMATE_BUFFER: u32 = 50000;
impl<M> std::fmt::Display for EthereumMailboxInternal<M> impl<M> std::fmt::Display for EthereumMailboxInternal<M>
where where
@ -187,7 +187,7 @@ where
// Arbitrum Nitro based chains are a special case for transaction cost estimation. // Arbitrum Nitro based chains are a special case for transaction cost estimation.
// The gas amount that eth_estimateGas returns considers both L1 and L2 gas costs. // The gas amount that eth_estimateGas returns considers both L1 and L2 gas costs.
// We use the NodeInterface, found at address(0xC8), to isolate the L2 gas costs. // We use the NodeInterface, found at address(0xC8), to isolate the L2 gas costs.
// See https://developer.arbitrum.io/arbos/gas#nodeinterfacesol or https://github.com/OffchainLabs/nitro/blob/master/contracts/src/node-interface/NodeInterface.sol#L110 // See https://developer.arbitrum.io/arbos/gas#nodeinterfacesol or https://github.com/OffchainLabs/nitro/blob/master/contracts/src/node-interface/NodeInterface.sol#L25
let arbitrum_node_interface = locator.domain.is_arbitrum_nitro().then(|| { let arbitrum_node_interface = locator.domain.is_arbitrum_nitro().then(|| {
Arc::new(ArbitrumNodeInterface::new( Arc::new(ArbitrumNodeInterface::new(
H160::from_low_u64_be(0xC8), H160::from_low_u64_be(0xC8),
@ -359,15 +359,21 @@ where
// If we have a ArbitrumNodeInterface, we need to set the l2_gas_limit. // If we have a ArbitrumNodeInterface, we need to set the l2_gas_limit.
let l2_gas_limit = if let Some(arbitrum_node_interface) = &self.arbitrum_node_interface { let l2_gas_limit = if let Some(arbitrum_node_interface) = &self.arbitrum_node_interface {
let (l1_gas_limit, _, _) = arbitrum_node_interface Some(
.gas_estimate_l1_component( arbitrum_node_interface
.estimate_retryable_ticket(
H160::zero(),
// Give the sender a deposit, otherwise it reverts
U256::MAX,
self.contract.address(), self.contract.address(),
false, // Not a contract creation U256::zero(),
H160::zero(),
H160::zero(),
contract_call.calldata().unwrap_or_default(), contract_call.calldata().unwrap_or_default(),
) )
.call() .estimate_gas()
.await?; .await?,
Some(gas_limit.saturating_sub(l1_gas_limit.into())) )
} else { } else {
None None
}; };
@ -410,7 +416,6 @@ mod test {
use std::{str::FromStr, sync::Arc}; use std::{str::FromStr, sync::Arc};
use ethers::{ use ethers::{
abi::{encode, Token},
providers::{MockProvider, Provider}, providers::{MockProvider, Provider},
types::{Block, Transaction}, types::{Block, Transaction},
}; };
@ -455,19 +460,9 @@ mod test {
let gas_price: U256 = ethers::utils::parse_units("15", "gwei").unwrap().into(); let gas_price: U256 = ethers::utils::parse_units("15", "gwei").unwrap().into();
mock_provider.push(gas_price).unwrap(); mock_provider.push(gas_price).unwrap();
// RPC 3: eth_call to the ArbitrumNodeInterface's gasEstimateL1Component function by process_estimate_costs // RPC 3: eth_estimateGas to the ArbitrumNodeInterface's estimateRetryableTicket function by process_estimate_costs
let l1_gas_estimate = U256::from(800000u32); // 800k gas let l2_gas_limit = U256::from(200000); // 200k gas
let base_fee = U256::from(5u32); mock_provider.push(l2_gas_limit).unwrap();
let l1_base_fee = U256::from(6u32);
let return_bytes = encode(&[Token::Tuple(vec![
Token::Uint(l1_gas_estimate),
Token::Uint(base_fee),
Token::Uint(l1_base_fee),
])]);
let encoded_return_hex = hex::encode(return_bytes);
mock_provider
.push::<String, _>(format!("0x{:}", encoded_return_hex))
.unwrap();
// RPC 2: eth_getBlockByNumber from the estimate_eip1559_fees call in process_contract_call // RPC 2: eth_getBlockByNumber from the estimate_eip1559_fees call in process_contract_call
mock_provider.push(Block::<Transaction>::default()).unwrap(); mock_provider.push(Block::<Transaction>::default()).unwrap();
@ -490,7 +485,7 @@ mod test {
TxCostEstimate { TxCostEstimate {
gas_limit: estimated_gas_limit, gas_limit: estimated_gas_limit,
gas_price, gas_price,
l2_gas_limit: Some(estimated_gas_limit.saturating_sub(l1_gas_estimate)), l2_gas_limit: Some(l2_gas_limit),
}, },
); );
} }

Loading…
Cancel
Save