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

Sealevel warp route UI: support IGP payments when transferring tokens #2546

Closed
tkporter opened this issue Jul 20, 2023 · 1 comment · Fixed by #2711
Closed

Sealevel warp route UI: support IGP payments when transferring tokens #2546

tkporter opened this issue Jul 20, 2023 · 1 comment · Fixed by #2711

Comments

@tkporter
Copy link
Collaborator

tkporter commented Jul 20, 2023

previously blocked by #2500

Update the accounts required when transferring tokens to remote chains following gas payments being added. Deets to come

@tkporter
Copy link
Collaborator Author

tkporter commented Aug 30, 2023

As promised, the details:

high level

The existing warp routes we've been running with (e.g. the one on mainnet Solana) have the ability to be configured with an IGP or to be configured to not use an IGP. At the moment, they're configured to not use an IGP. So some logic is required when crafting the accounts to pass in that depends on if an IGP is configured / what IGP is configured. The IGP-related accounts are not plugin-specific, and come after the existing non-plugin-specific accounts.

You can determine whether an IGP has been configured and which IGP has been configured by looking at the HyperlaneToken<T> struct's interchain_gas_paymaster field:

pub interchain_gas_paymaster: Option<(Pubkey, InterchainGasPaymasterType)>,

If this is set to None, then no IGP is configured. If it's set to Some, the contained tuple (Pubkey, InterchainGasPaymasterType) includes the IGP program ID as the Pubkey at index 0, and then an enum at index 1 that indicates whether an overhead IGP is being used, or just a normal IGP, and the Pubkey for a data account relating to that type of IGP.

That enum can be found here:

pub enum InterchainGasPaymasterType {
/// An IGP with gas oracles and that receives lamports as payment.
Igp(Pubkey),
/// An overhead IGP that points to an inner IGP and imposes a gas overhead for each destination domain.
OverheadIgp(Pubkey),
}

IGP types

To take a step back - in the EVM world, we also have "overhead IGPs" and "normal IGPs", but an overhead IGP has the exact same interface as a normal IGP. An overhead IGP is just intended to add an amount of gas to the amount of gas passed in, and then call an inner IGP with that new amount of gas. In the EVM world an overhead IGP is its own smart contract. However in Solana, making a cross-program invocation (CPI) is a more costly operation and there's a limit to the size of the CPI call stack, so instead there's a single IGP program that can work with many IGP data accounts or overhead IGP data accounts. This is why two pieces of info are stored in the warp route program -- first, the IGP program ID, and second, what account data to use with the IGP program ID.

If the InterchainGasPaymasterType that's configured is an OverheadIgp, both an OverheadIgp data account and the "inner" IGP data account that it relates to must be passed into the warp route when transferring. Otherwise if just a normal InterchainGasPaymasterType::Igp is configured, just that IGP data account needs to be passed in.

In the OverheadIgp case, you can find what the inner IGP data account is by fetching the account data and decoding it to get the inner. You can find the structure of the OverheadIgp account here (keep in mind this will be prefixed with the one byte initialized flag as well):

pub struct OverheadIgp {
/// The bump seed for the overhead IGP PDA.
pub bump_seed: u8,
/// The salt used to derive the overhead IGP PDA.
pub salt: H256,
/// The owner of the overhead IGP.
pub owner: Option<Pubkey>,
/// The inner IGP account.
pub inner: Pubkey,
/// The gas overheads to impose on gas payments to each destination domain.
pub gas_overheads: HashMap<u32, u64>,
}

accounts

You can find a comment with the accounts here, where accounts 0 through 8 are unchanged, but 9 through 13 are new and are in the case where an IGP is used:

/// Accounts:
/// 0. [executable] The system program.
/// 1. [executable] The spl_noop program.
/// 2. [] The token PDA account.
/// 3. [executable] The mailbox program.
/// 4. [writeable] The mailbox outbox account.
/// 5. [] Message dispatch authority.
/// 6. [signer] The token sender and mailbox payer.
/// 7. [signer] Unique message / gas payment account.
/// 8. [writeable] Message storage PDA.
/// ---- If using an IGP ----
/// 9. [executable] The IGP program.
/// 10. [writeable] The IGP program data.
/// 11. [writeable] Gas payment PDA.
/// 12. [] OPTIONAL - The Overhead IGP program, if the configured IGP is an Overhead IGP.
/// 13. [writeable] The IGP account.
/// ---- End if ----
/// 14..N [??..??] Plugin-specific accounts.

Breakdown of the accounts:

  1. [executable] The IGP program. - Executable, and this is the first Pubkey in the interchain_gas_paymaster tuple.
  2. [writeable] The IGP program data. - Writeable, this is an account relating to the IGP program with some general storage that's accessed by the IGP program. It's a PDA that can be found using the IGP program id and the seeds here https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/rust/sealevel/programs/hyperlane-sealevel-igp/src/pda_seeds.rs#L7
  3. [writeable] Gas payment PDA. - Writeable, this is a similar idea to the "Message storage PDA" we already have. For a particular gas payment, an account is created to record the gas payment occurring. This is a PDA that also depends on the unique signer account that we also use for deriving the message storage PDA. The PDA for this case account is derived using the seeds found here https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/rust/sealevel/programs/hyperlane-sealevel-igp/src/pda_seeds.rs#L64-L70, and the program ID used in the derivation should be the IGP program ID.
  4. [] OPTIONAL - The Overhead IGP program, if the configured IGP is an Overhead IGP. - Not writeable or signer, this is the Overhead IGP data account. This is only for the InterchainGasPaymasterType::OverheadIgp case -- if that's not the case, then this account is omitted entirely
  5. [writeable] The IGP account. - Writeable, this is either the Pubkey in the InterchainGasPaymasterType::Igp case, or in the OverheadIgp case, this is the inner IGP that you need to get from the Overhead IGP's account data.

Example warp route & tx

I deployed a new warp route on devnet with an InterchainGasPaymasterType::OverheadIgp configured that just sends between solanadevnet <> proteustestnet

Info on the warp route deployment:

solanadevnet

program ID: 84DAG9VX5CvefQrBUGh9Gp66kmkat2voaM4MB2YwpGW1
config: (it relates to the same USDC / DUMMY token from https://spl-token-faucet.com/, like we've used in the past)

        "type": "collateral",
        "decimals": 6,
        "remoteDecimals": 18,
        "token": "Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr",
        "splTokenProgram": "token" // (i.e. not 2022 version)

proteus testnet

contract: 0xd77b139de9cb97e891c1715929fcd03ae5867269
warp route type: native, it's funded with 1 testnet ZBC

example tx

Here's an example tx I sent that pays for gas. You can see in the logs "Paid IGP 7hMPEGdgBQFsjEz3aaNwZp8WMFHs615zAM3erXBDJuJR for 44000 gas for message 0xc202…1d48 to 88002" as well

https://explorer.solana.com/tx/4QGCez4UiY42DX5v9QV6dcq55x9HoMzcSLhoYVtSmCT6RqTdMQKhJUnEhmjCFimKUGYz2yhcMYsUQcBABDiJBpYY?cluster=devnet

@jmrossy jmrossy moved this from Sprint to In Progress in Hyperlane Tasks Sep 4, 2023
jmrossy added a commit that referenced this issue Sep 13, 2023
### Description

- Build on #2684, migrates the EvmAdapter and missing utils from the warp UI
- Remove the token App as it's unused and redundant with adapters
- Add IGP serialization code for #2546 
- Simplify multi-protocol adapters in SDK
- Make token adapters extend base adapters
- Move token serialization code to token package

### Drive-by changes

- Update Sepolia RPC which was causing errors

### Related issues

#2652 

### Backward compatibility

Yes

### Testing

Tested these in warp UI

---------

Co-authored-by: Yorke Rhodes <yorke@hyperlane.xyz>
@github-project-automation github-project-automation bot moved this from In Progress to Done in Hyperlane Tasks Sep 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants