Sealevel IGP debugging, temporarily change Sealevel gas payment policy (#2758)

### Description

- Some small changes to help with debugging sealevel IGP
- Turns out the GasPaymentAccount data format onchain is different from
the one in `main`. This causes IGP indexing to not work in the wild, but
it works in e2e. Because we were planning to change the IGP anyways as
we transfer ownership to Zebec, this isn't so bad - so temporarily just
not enforcing ZBC warp route Solana -> Nautilus gas payments. In
practice, we're still effectively enforcing gas payments because the
warp route will pay for gas

### Drive-by changes

- Also added the new BSC POSE addy

### Related issues

n/a

### Backward compatibility

yes

### Testing

Deployed, poked around, used cmds
pull/2764/head
Trevor Porter 1 year ago committed by GitHub
parent 024058116e
commit 62ab488db9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      rust/chains/hyperlane-sealevel/src/interchain_gas.rs
  2. 63
      rust/sealevel/client/src/main.rs
  3. 6
      rust/utils/run-locally/src/solana.rs
  4. 11
      typescript/infra/config/environments/mainnet2/agent.ts

@ -23,7 +23,9 @@ use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey};
use derive_new::new;
/// The offset to get the `unique_gas_payment_pubkey` field from the serialized GasPaymentData
/// The offset to get the `unique_gas_payment_pubkey` field from the serialized GasPaymentData.
/// The account data includes prefixes that are accounted for here: a 1 byte initialized flag
/// and an 8 byte discriminator.
const UNIQUE_GAS_PAYMENT_PUBKEY_OFFSET: usize = 1 + 8 + 8 + 32 + 4 + 32 + 8 + 8;
/// A reference to an IGP contract on some Sealevel chain
@ -126,6 +128,7 @@ impl SealevelInterchainGasPaymasterIndexer {
Ok(Self { rpc_client, igp })
}
#[instrument(err, skip(self))]
async fn get_payment_with_sequence(
&self,
sequence_number: u64,
@ -163,12 +166,15 @@ impl SealevelInterchainGasPaymasterIndexer {
},
with_context: Some(false),
};
tracing::debug!(config=?config, "Fetching program accounts");
let accounts = self
.rpc_client
.get_program_accounts_with_config(&self.igp.program_id, config)
.await
.map_err(ChainCommunicationError::from_other)?;
tracing::debug!(accounts=?accounts, "Fetched program accounts");
// Now loop through matching accounts and find the one with a valid account pubkey
// that proves it's an actual gas payment PDA.
let mut valid_payment_pda_pubkey = Option::<Pubkey>::None;
@ -208,6 +214,8 @@ impl SealevelInterchainGasPaymasterIndexer {
.map_err(ChainCommunicationError::from_other)?
.into_inner();
tracing::debug!(gas_payment_account=?gas_payment_account, "Found gas payment account");
let igp_payment = InterchainGasPayment {
message_id: gas_payment_account.message_id,
payment: gas_payment_account.payment.into(),
@ -250,6 +258,8 @@ impl Indexer<InterchainGasPayment> for SealevelInterchainGasPaymasterIndexer {
let igp_account_filter = self.igp.igp_account;
if igp_account_filter == sealevel_payment.igp_account_pubkey {
payments.push((sealevel_payment.payment, sealevel_payment.log_meta));
} else {
tracing::debug!(sealevel_payment=?sealevel_payment, igp_account_filter=?igp_account_filter, "Found interchain gas payment for a different IGP account, skipping");
}
}
}

@ -24,7 +24,8 @@ use hyperlane_core::{Encode, HyperlaneMessage, H160, H256};
use hyperlane_sealevel_connection_client::router::RemoteRouterConfig;
use hyperlane_sealevel_igp::{
accounts::{
GasOracle, IgpAccount, InterchainGasPaymasterType, OverheadIgpAccount, RemoteGasData,
GasOracle, GasPaymentAccount, IgpAccount, InterchainGasPaymasterType, OverheadIgpAccount,
ProgramDataAccount as IgpProgramDataAccount, RemoteGasData,
},
igp_gas_payment_pda_seeds, igp_program_data_pda_seeds,
instruction::{GasOracleConfig, GasOverheadConfig},
@ -386,6 +387,7 @@ struct IgpCmd {
#[derive(Subcommand)]
enum IgpSubCmd {
Query(IgpQueryArgs),
PayForGas(PayForGasArgs),
GasOracleConfig(GasOracleConfigArgs),
DestinationGasOverhead(DestinationGasOverheadArgs),
@ -393,6 +395,16 @@ enum IgpSubCmd {
TransferOverheadIgpOwnership(TransferIgpOwnership),
}
#[derive(Args)]
struct IgpQueryArgs {
#[arg(long)]
program_id: Pubkey,
#[arg(long)]
igp_account: Pubkey,
#[arg(long)]
gas_payment_account: Option<Pubkey>,
}
#[derive(Args)]
struct TransferIgpOwnership {
#[arg(long, short)]
@ -406,8 +418,14 @@ struct TransferIgpOwnership {
#[derive(Args)]
struct PayForGasArgs {
#[arg(long)]
program_id: Pubkey,
#[arg(long)]
message_id: String,
#[arg(long)]
destination_domain: u32,
#[arg(long)]
gas: u64,
}
#[derive(Args)]
@ -1337,6 +1355,45 @@ fn process_multisig_ism_message_id_cmd(ctx: Context, cmd: MultisigIsmMessageIdCm
fn process_igp_cmd(ctx: Context, cmd: IgpCmd) {
match cmd.cmd {
IgpSubCmd::Query(query) => {
let (program_data_account_pda, _program_data_account_bump) =
Pubkey::find_program_address(igp_program_data_pda_seeds!(), &query.program_id);
let accounts = ctx
.client
.get_multiple_accounts_with_commitment(
&[program_data_account_pda, query.igp_account],
ctx.commitment,
)
.unwrap()
.value;
let igp_program_data =
IgpProgramDataAccount::fetch(&mut &accounts[0].as_ref().unwrap().data[..])
.unwrap()
.into_inner();
println!("IGP program data: {:?}", igp_program_data);
let igp = IgpAccount::fetch(&mut &accounts[1].as_ref().unwrap().data[..])
.unwrap()
.into_inner();
println!("IGP account: {:?}", igp);
if let Some(gas_payment_account_pubkey) = query.gas_payment_account {
let account = ctx
.client
.get_account_with_commitment(&gas_payment_account_pubkey, ctx.commitment)
.unwrap()
.value
.unwrap();
let gas_payment_account = GasPaymentAccount::fetch(&mut &account.data[..])
.unwrap()
.into_inner();
println!("Gas payment account: {:?}", gas_payment_account);
}
}
IgpSubCmd::PayForGas(payment_details) => {
let unique_gas_payment_keypair = Keypair::new();
let salt = H256::zero();
@ -1357,8 +1414,8 @@ fn process_igp_cmd(ctx: Context, cmd: IgpCmd) {
Some(overhead_igp_account),
unique_gas_payment_keypair.pubkey(),
H256::from_str(&payment_details.message_id).unwrap(),
13376,
100000,
payment_details.destination_domain,
payment_details.gas,
)
.unwrap();

@ -314,8 +314,10 @@ pub fn initiate_solana_hyperlane_transfer(
sealevel_client(&solana_cli_tools_path, &solana_config_path)
.cmd("igp")
.cmd("pay-for-gas")
.cmd("GwHaw8ewMyzZn9vvrZEnTEAAYpLdkGYs195XWcLDCN4U")
.cmd(message_id)
.arg("program-id", "GwHaw8ewMyzZn9vvrZEnTEAAYpLdkGYs195XWcLDCN4U")
.arg("message-id", message_id)
.arg("destination-domain", SOLANA_REMOTE_CHAIN_ID)
.arg("gas", "100000")
.run()
.join();
}

@ -50,6 +50,7 @@ const contextBase = {
} as const;
const bscNautilusWarpRoutes: Array<{ router: string }> = [
// ZBC
{
router: '0xC27980812E2E66491FD457D488509b7E04144b98',
},
@ -71,7 +72,7 @@ const bscNautilusWarpRoutes: Array<{ router: string }> = [
},
// POSE
{
router: '0x807D2C6c3d64873Cc729dfC65fB717C3E05e682f',
router: '0x97a2D58d30A2c838946194494207F7Cf50c25815',
},
];
@ -90,6 +91,14 @@ const gasPaymentEnforcement: GasPaymentEnforcementConfig[] = [
destinationDomain: '*',
recipientAddress: '*',
},
// Temporarily don't charge gas for the Solana -> Nautilus ZBC warp route,
// as IGP indexing in the agents is currently incompatible with the deployed IGP.
{
originDomain: [getDomainId(chainMetadata.solana)],
senderAddress: ['EJqwFjvVJSAxH8Ur2PYuMfdvoJeutjmH6GkoEFQ4MdSa'],
destinationDomain: [getDomainId(chainMetadata.nautilus)],
recipientAddress: '*',
},
],
},
{

Loading…
Cancel
Save