diff --git a/rust/main/agents/relayer/src/settings/mod.rs b/rust/main/agents/relayer/src/settings/mod.rs index dc4c1e543e..df28d03dee 100644 --- a/rust/main/agents/relayer/src/settings/mod.rs +++ b/rust/main/agents/relayer/src/settings/mod.rs @@ -125,16 +125,50 @@ impl FromRawConf for RelayerSettings { .parse_from_str("Expected database path") .unwrap_or_else(|| std::env::current_dir().unwrap().join("hyperlane_db")); - let (raw_gas_payment_enforcement_path, raw_gas_payment_enforcement) = p - .get_opt_key("gasPaymentEnforcement") - .take_config_err_flat(&mut err) - .and_then(parse_json_array) - .unwrap_or_else(|| (&p.cwp + "gas_payment_enforcement", Value::Array(vec![]))); + // is_gas_payment_enforcement_set determines if we should be checking if the correct gas payment enforcement policy has been provided with "gasPaymentEnforcement" key + let ( + raw_gas_payment_enforcement_path, + raw_gas_payment_enforcement, + is_gas_payment_enforcement_set, + ) = { + match p.get_opt_key("gasPaymentEnforcement") { + Ok(Some(parser)) => match parse_json_array(parser) { + Some((path, value)) => (path, value, true), + None => ( + &p.cwp + "gas_payment_enforcement", + Value::Array(vec![]), + true, + ), + }, + Ok(None) => ( + &p.cwp + "gas_payment_enforcement", + Value::Array(vec![]), + false, + ), + Err(_) => ( + &p.cwp + "gas_payment_enforcement", + Value::Array(vec![]), + false, + ), + } + }; let gas_payment_enforcement_parser = ValueParser::new( raw_gas_payment_enforcement_path, &raw_gas_payment_enforcement, ); + + if is_gas_payment_enforcement_set + && gas_payment_enforcement_parser + .val + .as_array() + .unwrap() + .is_empty() + { + Err::<(), eyre::Report>(eyre!("GASPAYMENTENFORCEMENT policy cannot be parsed")) + .take_err(&mut err, || cwp + "gas_payment_enforcement"); + } + let mut gas_payment_enforcement = gas_payment_enforcement_parser.into_array_iter().map(|itr| { itr.filter_map(|policy| { let policy_type = policy.chain(&mut err).get_opt_key("type").parse_string().end(); diff --git a/rust/main/utils/run-locally/src/main.rs b/rust/main/utils/run-locally/src/main.rs index 4686c15446..a7e03b4094 100644 --- a/rust/main/utils/run-locally/src/main.rs +++ b/rust/main/utils/run-locally/src/main.rs @@ -227,7 +227,7 @@ fn main() -> ExitCode { "GASPAYMENTENFORCEMENT", r#"[{ "type": "minimum", - "payment": "1", + "payment": "1" }]"#, ) .arg( diff --git a/typescript/infra/scripts/send-test-messages.ts b/typescript/infra/scripts/send-test-messages.ts index d028263982..6775ac5534 100644 --- a/typescript/infra/scripts/send-test-messages.ts +++ b/typescript/infra/scripts/send-test-messages.ts @@ -1,9 +1,16 @@ import { Provider } from '@ethersproject/providers'; -import { Wallet } from 'ethers'; +import { BigNumber, Wallet } from 'ethers'; import fs from 'fs'; import yargs from 'yargs'; -import { Mailbox, TestSendReceiver__factory } from '@hyperlane-xyz/core'; +import { + InterchainGasPaymaster, + InterchainGasPaymaster__factory, + Mailbox, + StorageGasOracle, + StorageGasOracle__factory, + TestSendReceiver__factory, +} from '@hyperlane-xyz/core'; import { ChainName, HookType, @@ -11,7 +18,7 @@ import { MultiProvider, TestChainName, } from '@hyperlane-xyz/sdk'; -import { addressToBytes32, sleep } from '@hyperlane-xyz/utils'; +import { addressToBytes32, formatMessage, sleep } from '@hyperlane-xyz/utils'; const ANVIL_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; @@ -47,6 +54,44 @@ async function setMailboxHook( console.log(`set the ${mailboxHookType} hook on ${local} to ${hook}`); } +async function setIgpConfig( + remoteId: number, + signer: Wallet, + provider: Provider, + mailbox: Mailbox, + addresses: any, + local: ChainName, +) { + const storageGasOracleF = new StorageGasOracle__factory( + signer.connect(provider), + ); + const storageGasOracle = await storageGasOracleF.deploy(); + await storageGasOracle.deployTransaction.wait(); + + const oracleConfigs: Array = []; + oracleConfigs.push({ + remoteDomain: remoteId, + tokenExchangeRate: '10000000000', + gasPrice: '1000000000', + }); + await storageGasOracle.setRemoteGasDataConfigs(oracleConfigs); + + const gasParamsToSet: InterchainGasPaymaster.GasParamStruct[] = []; + gasParamsToSet.push({ + remoteDomain: remoteId, + config: { + gasOracle: storageGasOracle.address, + gasOverhead: 1000000, + }, + }); + + const igpHook = InterchainGasPaymaster__factory.connect( + addresses[local].interchainGasPaymaster, + signer.connect(provider), + ); + await igpHook.setDestinationGasConfigs(gasParamsToSet); +} + const chainSummary = async (core: HyperlaneCore, chain: ChainName) => { const coreContracts = core.getContracts(chain); const mailbox = coreContracts.mailbox; @@ -157,15 +202,33 @@ async function main() { MailboxHookType.REQUIRED, requiredHook, ); + + if ( + defaultHook === HookType.AGGREGATION || + defaultHook === HookType.INTERCHAIN_GAS_PAYMASTER + ) { + console.log('Setting IGP config for message ...'); + await setIgpConfig(remoteId, signer, provider, mailbox, addresses, local); + } + + const message = formatMessage( + 1, + 0, + multiProvider.getDomainId(local), + recipient.address, + multiProvider.getDomainId(remote), + recipient.address, + '0x1234', + ); const quote = await mailbox['quoteDispatch(uint32,bytes32,bytes)']( remoteId, addressToBytes32(recipient.address), - '0x1234', + message, ); - await recipient['dispatchToSelf(address,uint32,bytes)']( - mailbox.address, + await mailbox['dispatch(uint32,bytes32,bytes)']( remoteId, - '0x1234', + addressToBytes32(recipient.address), + message, { value: quote, }, @@ -173,7 +236,9 @@ async function main() { console.log( `send to ${recipient.address} on ${remote} via mailbox ${ mailbox.address - } on ${local} with nonce ${(await mailbox.nonce()) - 1}`, + } on ${local} with nonce ${ + (await mailbox.nonce()) - 1 + } and quote ${quote.toString()}`, ); console.log(await chainSummary(core, local)); console.log(await chainSummary(core, remote));