General Message Passing (GMP) Precompile
Abstract
Moonbeam is at the forefront of two important inter-chain messaging systems:
- XCM connects blockchains within the Polkadot ecosystem. Being built on Substrate and having connectivity through its relay chain are all Moonbeam needs to be a part of this network.
- GMP (General Message Passing) protocols connect many blockchains more broadly. These are often written for multiple protocols and in multiple languages, but they usually include the EVM in their implementation, which makes Moonbeam a trivial deployment for them.
These each create their own well-connected network but they remain disjoint. Moonbeam solves this with its EVM and precompiles like xtokens, allowing users to receive GMP messages and send XCM messages or vice-versa. This is possible today, although it generally requires multiple user-interactions.
Executive Summary
We can take this a step further by hooking the two technologies together within the EVM such that a single call can both receive one type of message and send the other. By doing so, we allow a user to use Moonbeam as a bridge between these two networks with a single interaction. The pitch: One click Moonbeam Liquidity Routing.
Solution
The Moonbeam team has created a proof-of-concept which focuses on a narrow set of functionality: receiving a GMP message containing tokens (using the Wormhole protocol) and forwarding these tokens on to another parachain (or relay) via XCM.
Briefly, Wormhole’s Contract Controlled Transfer feature works by having the recipient of a token transfer call its own bridge contract’s completeTransferWithPayload()
function. This design lets the caller be either an EOA or a smart contract, and also removes complexity from the protocol. completeTransferWithPayload()
takes a message blob which includes everything the bridge needs to validate the transfer and also includes an arbitrary payload, something we use in the design to encode the XCM destination in this PoC.
The PoC is accomplished by creating a precompile with a single function which takes the protocol’s VAA payload and calls completeTransferWithPayload()
with it. This causes the bridge to send tokens to the precompile address itself. Once this occurs, the precompile looks for the XCM destination inside the payload. Specifically, the VAA payload
includes an inner arbitrary payload, and we require that this payload be a SCALE-encoded struct representing its XCM destination. xtokens
pallet is then used to forward these tokens on via XCM.
A Dapp could implement this UX in such a way that the user would only need to select a token to send and a destination chain/account to receive it. The “hop” on Moonbeam (the interaction with this precompile) can be completely transparent to the user.
Future Work
This feature would potentially require a lot more work beyond this initial PoC. I’ll briefly discuss the more significant tasks here.
- There are many other protocols beyond Wormhole which we could support. While I haven’t looked at them in much detail yet, I can say that they all work differently, so each one may be a considerable amount of work.
- No fee mechanism currently exists. Wormhole does have a fee mechanism, but it does not support the way we use the protocol. Even if it did, it may not cover fees associated with XCM.
- Inverse use case: receive a XCM transfer and initiate a GMP interaction
- Other, non-XCM cases: there may be other use cases (staking?) which a user might want to do instead of an XCM transfer.
- Testing: not much was done in this PoC, and it would be hard to overstate just how much test coverage this could have.
Status
A first draft of the PoC has been deployed to Alphanet. We are treating this as experimental and do not have plans yet to deploy to Moonriver or Moonbeam.
Specifically, RT2300 included the initial PR and RT2301 included a small but important fix for it.