hyperlane-xyz / hyperlane-monorepo

The home for Hyperlane core contracts, sdk packages, and other infrastructure
https://hyperlane.xyz
Other
334 stars 363 forks source link

Sealevel: Kathy messages are sent to/from sealevel chains #2503

Closed tkporter closed 1 year ago

tkporter commented 1 year ago

Partially blocked by https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/2502 - I think we can start this ticket before that's finished though

### Tasks
- [ ] https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/2587
- [ ] https://github.com/hyperlane-xyz/issues/issues/558
jmrossy commented 1 year ago

Sealevel support proposal

Overview

We've so far taken a somewhat top-down approach to adding Sealevel support; the warp UI, hyp-deploy have been updated before the SDK and Utils packages. We can continue that trend with HelloWorld/Kathy or we can make a bigger upfront investment and redesign the SDK+Utils now.

Option 1: Shortest path

Kathy is built around HelloWorld, which is just a thin wrapper around the App/Deployer/Checker abstractions in the SDK. So updating just HelloWorld to be sealevel compatible wouldn't make sense. Sealevel support for Kathy would require a new, parallel HelloWorld version that live alongside the EVM one.

This option is still less work than Option 2 but feels short-sighted.

Option 2: Multi-env SDK

Updating the common utilities (e.g. address encoder, msg formatter) and SDK primitives (e.g. MultiProvider, App, Checker, Deployer) feels like a daunting task but also seems like the natural next step for Sealevel support.

I won't lay out a complete plan just yet until we have agreement on this direction but structural changes would include:

The new architecture would ideally be a plugin-like architecture with sub-packages. Something that allows SDK users to bundle only the libs for the environments they care about. Otherwise all EVM-only users would be unintentionally including in large libs for Sealevel (and soon Cosmos).

IMHO, this option is tricky but feasible.

jmrossy commented 1 year ago

Continuing on the last post above ^, we decided on Discord to try option 1.5. We will not modify existing classes in SDK but we will add new multi-protocol versions (e.g. MultiProtocolProvider) as needed to get a HelloWorld (and then Kathy) working.

So far I've got a Draft PR open with a new MultiProtocolProvider based partly on the one I made for Warp UI. This introduces a new set of Provider-related types and builders, which allow us to support different libraries (Viem, Ethers6, SolanaWeb3, etc.)

Next I took a stab at a MultiProtocolApp abstraction today but sadly the concept falls apart almost immediately 😭 . Our HyperlaneApp is a fancy map, from chain -> contracts. Sealevel's JS lib (solana/web3.js) doesn't have anything comparable to an Ethers/Viem Contract. Data must be manually (de)serialized with serializers custom defined for each contract. So scrap MultiProtocolApp I think.

Children Apps like RouterApp add some functionality like fetching ISMs or quoting gas. We'll def still want those features somewhere. Another step down, TokenApp adds a transfer method, i.e. a method to translate a user intent into a tx. Like @yorhodes pointed out last week, this is where the TokenApp overlaps with my ITokenAdapter in the Warp UI:

TokenApp = TokenAdapter + ChainMap<Addresses & Ethers Contracts>

I guess it will need to be something like: MultiProtocolTokenApp = TokenAdapter + ChainMap<Addresses & Desired provider types>, where the adapter part needs to do more heavy lifting than it does now for non-EVM chains.

tkporter commented 1 year ago

I deployed a helloworld program onto solanadevnet - here's the current state of things:

  1. At the moment only fuji -> solanadevnet messages via the rc helloworld router contract are deliverable (i.e. from this one https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/typescript/infra/config/environments/testnet3/helloworld/rc/addresses.json#L6). This is just because only fuji validators have been enrolled in the ISM that lives on solanadevnet for now. This is the address of the helloworld contract on solanadevnet https://explorer.solana.com/address/DdTMkk9nuqH5LnD56HLkPiKMV3yB3BNEYSQfgmJHa5i7?cluster=devnet (DdTMkk9nuqH5LnD56HLkPiKMV3yB3BNEYSQfgmJHa5i7 in base58, 0xbba2f483e642449d0a39efe5f9603f7c559423acebd3c854d07560ccd0439228 in hex).
  2. You can find an example of a message from fuji I sent here https://testnet.snowtrace.io/tx/0x3ce33292790db41a4604b4744862acbf5df39bad995ad5ac3711442386c51833 with ID 0x5983bd101129f7c3d717ad2c7bdb81979cf076e8ace97c2096736a1778e33b0e that was delivered by this transaction https://explorer.solana.com/tx/vBTHYuhM2BrWQ7ivFFa5AChpsQQyst7CQNAFt1Ntc6ut77RCCVXusWibYFGUXBvScX2MDAoDMC7ooDseU5dss1j?cluster=devnet (https://explorer.solana.com/address/F2Qpm4DrYVoUg6HKT1foQvjcJSxoZqwUdbutcHSwicrQ?cluster=devnet is the relayer address that delivered the message)
  3. Sending from other evm chains to solanadevnet atm will revert because the IGPs on those EVM chains haven't been configured with a gas oracle for solanadevnet.
  4. Sending from solanadevnet to fuji works on the origin side (i.e. the Solana tx won't revert), but it won't be delivered atm because the solanadevnet validators haven't been enrolled on the ISM that fuji uses

Wanted to share this stuff ASAP though just to unblock you as much as possible

Here's info on how to get the # of sent or received messages and/or the remote routers:

  1. They're stored in the "program storage PDA" of the helloworld program, which is found using these seeds https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/dd7ff727b0d3d393a159afa5f0a364775bde3a58/rust/sealevel/programs/helloworld/src/processor.rs#L44-L59 and the helloworld program ID
  2. The account data layout can be found here https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/dd7ff727b0d3d393a159afa5f0a364775bde3a58/rust/sealevel/programs/helloworld/src/accounts.rs#L17-L44 -- note this also has the first byte as the "initialized" flag like the warp routes do (i.e. pub type HelloWorldStorageAccount = AccountData<HelloWorldStorage>; is what's actually serialized and stored, which inserts that first byte prefix)

And to send a hello world message from solanadevnet:

This is the expected instruction data passed in: https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/dd7ff727b0d3d393a159afa5f0a364775bde3a58/rust/sealevel/programs/helloworld/src/instruction.rs#L44 (note there is no 8-byte prefix here or anything, unlike the warp routes)

The expected accounts passed in can be found here https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/dd7ff727b0d3d393a159afa5f0a364775bde3a58/rust/sealevel/programs/helloworld/src/processor.rs#L157-L174, for clarity I'll explain each one:

/// 0. [writeable] Program storage. /// 1. [executable] The Mailbox program. /// 2. [writeable] Outbox PDA. /// 3. [] This program's dispatch authority. /// 4. [executable] System program. /// 5. [executable] SPL Noop program. /// 6. [signer] Payer. /// 7. [signer] Unique message account. /// 8. [writeable] Dispatched message PDA. An empty message PDA relating to the seeds /// mailbox_dispatched_message_pda_seeds where the message contents will be stored. /// ---- if an IGP is configured ---- /// 9. [executable] The IGP program. /// 10. [writeable] The IGP program data. /// 11. [writeable] The gas payment PDA. /// 12. [] OPTIONAL - The Overhead IGP program, if the configured IGP is an Overhead IGP. /// 13. [writeable] The IGP account. /// ---- end if an IGP is configured ----

  1. [writeable] Program storage. - Same as described above for getting stats or routers - the PDA relating to these seeds https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/dd7ff727b0d3d393a159afa5f0a364775bde3a58/rust/sealevel/programs/helloworld/src/processor.rs#L44-L59 and the helloworld program ID
  2. [executable] The Mailbox program. - The mailbox program ID
  3. [writeable] Outbox PDA. - The mailbox's outbox PDA
  4. [] This program's dispatch authority. - The helloworld program's dispatch authority. I.e. the PDA relating to these seeds https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/trevor/helloworld-program/rust/sealevel/programs/mailbox/src/pda_seeds.rs#L55-L68 and the helloworld program ID.
  5. [executable] System program. - the system program id
  6. [executable] SPL Noop program. - the noop program id
  7. [signer] Payer. - the account that is paying for the tx
  8. [signer] Unique message account. - the unique message account - i.e. the random keypair that needs to be created, just like in warp routes
  9. [writeable] Dispatched message PDA - the PDA relating to the dispatched message, i.e. from these seeds https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/trevor/helloworld-program/rust/sealevel/programs/mailbox/src/pda_seeds.rs#L30-L51, the "unique message account"'s public key passed in there, and the mailbox program ID. Just like in warp routes
  10. This thru account 13 relate to paying for gas and aren't required if the program isn't paying for gas. For now, the deployed helloworld contract doesn't pay for gas (i.e. no IGP is configured on it). I'll be re-deploying things along with an IGP (no IGP has been deployed on solanadevnet yet) soon, at which point I'll move helloworld over to paying for gas. For now I think it's best to just not worry about these accounts and then when I have an IGP deployment up and ready I'll write up some info on the required changes to the warp route UI & this. For helloworld, the only change will be adding some accounts, & for warp routes there will be some new accounts and a new data layout to the HyperlaneToken type
jmrossy commented 1 year ago

Kathy updates for sealevel are now live! We'll monitor Kathy's health over the next few days to confirm everything is okay