Skip to content

Commit

Permalink
feat: initial automatic relaying doc (#1156)
Browse files Browse the repository at this point in the history
Co-authored-by: Stelios Daveas <[email protected]>
Co-authored-by: Canh Trinh <[email protected]>
Co-authored-by: Stephen Fluin <[email protected]>
  • Loading branch information
4 people authored Sep 20, 2024
1 parent 3f5bb6f commit 8120c1d
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/layouts/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,16 @@ export const getNavigation = (section) => {
},
{
title: "Relay Messages",
href: "/dev/amplifier/chain-integration/relay-messages/",
children: [
{
title: "Automatic Relaying",
href: "/dev/amplifier/chain-integration/relay-messages/automatic/",
},
{
title: "Manual Relaying",
href: "/dev/amplifier/chain-integration/relay-messages/manual/",
},
]
},
{
title: "Add Rewards",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Automated relaying with the Amplifier API

Connecting your chain to Axelar Amplifier requires being able to send transactions from your chain to the Axelar VM and react to events from the Axelar VM to be dispatched back to your chain. To assist your relayer to interact seamlessly with the Axelar VM, Interop Labs has exposed the **Amplifier API**, which is a fault-tolerant REST service that enables your Relayer to do both robustly.

## Relay Architecture

The architecture we recommend for a robust amplifier relayer has three core components:
- The **Subscriber**: the Subscriber’s job is to guarantee that every protocol event on the Amplifier chain is detected and successfully published to the Amplifier API. The relayer detects outgoing GMP messages from the chain to the AVM and publishes them to the GMP API so that they can be verified, routed, signed, and delivered to the destination chain.
- The **Includer**: the Includer’s job is to guarantee that some payload (task) gets included in a transaction in a block on the Amplifier chain. The relayer receives incoming GMP messages from the AVM to the chain and executes them by writing the transaction payloads to a block on the Amplifier chain.
- The **Listener**: the Listener is a built-in part of the Amplifier API and requires the Relayer to poll its endpoints for new events to be processed by the **Includer**.

The primary components then for integrators to build is the Subscriber and Includer that interacts with the Amplifier API.

## Workflows

An Amplifier Relayer operates by performing two distinct workflows

### Subscription

The Subscriber makes sure that every message on the chain is detected and successfully published to the GMP API, thus allowing the GMP API to track a message’s lifecycle and ensure that all messages are delivered through the following steps:

1. A transaction is made on the Amplifier source chain gatewy contract, producing a GMP call event.
1. The subscriber detects the event and publishes it to the GMP API.
1. The GMP API confirms that it has received the event.
1. If the event becomes part of a chain re-org, the Subscriber re-submits it to the API.

### Inclusion

The Includer guarantees that messages (in the form of "tasks") are delivered by making sure that their payloads are included in a transaction in a block on the connected chain through the following steps:

1. The relayer polls the Task API for new tasks and checks to see whether the tasks were already executed.
1. The relayer translates the task payload into a transaction for the destination chain.
1. The transaction is signed and sent to the RPC or node.
1. The Includer monitors the transaction and reprices it if necessary.
1. The relayer persists the task ID to recover from potential crashes.

Relay tasks contain transaction payloads that perform either Approval, Execution, or Refunds for incoming messages on the destination Amplifier chain.
166 changes: 166 additions & 0 deletions src/pages/dev/amplifier/chain-integration/relay-messages/manual.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Manually relay messages through Amplifier

Chains integrated with Amplifier can [pass GMP messages](/dev/general-message-passing/overview) to one another through the following flow:

1. When a user sends a message to the chain, a `callContract` event is emitted.
1. The relayer picks up the event and calls [`verify_messages`](https://github.com/axelarnetwork/axelar-amplifier/blob/f76dc8a775b8bb529cf50147bab9259d1ec7f784/packages/gateway-api/src/msg.rs#L9) on the chain's [Axelar (internal) gateway contract](https://github.com/axelarnetwork/axelar-amplifier/blob/main/doc/src/contracts/gateway.md).
1. For chains that rely on verifier votes, the Axelar gateway calls [`verify_messages`](https://github.com/axelarnetwork/axelar-amplifier/blob/deab56a75209a158c082cbf9b77caf500eb4ec7c/contracts/voting-verifier/src/msg.rs#L50) on the voting verifier, which prompts verifiers to begin voting.
1. Once a threshold of successful votes have been cast for the message, an event is emitted.
1. A relayer listens for this event and calls [`route_messages`](https://github.com/axelarnetwork/axelar-amplifier/blob/f76dc8a775b8bb529cf50147bab9259d1ec7f784/packages/gateway-api/src/msg.rs#L14) on the chain's Axelar gateway.
1. The chain's Axelar gateway passes the messages to the Amplifier router.
1. The router passes the message to the destination chain's Axelar gateway.
1. A relayer calls [`construct_proof`](https://github.com/axelarnetwork/axelar-amplifier/blob/f76dc8a775b8bb529cf50147bab9259d1ec7f784/contracts/multisig-prover/src/msg.rs#L61), which starts the process of creating a signed batch that can be relayed back to the source chain. This method also passes the now-outbound message from the gateway to the prover.
1. The prover starts a signing session with the multisig contract.
1. Verifiers participate in the signing session.
1. Once enough signatures have been submitted, the relayer gets the fully signed proof from the prover and relays the proof to the destination chain to approve the transactions. This relayer can now execute any approved transactions on the destination chain.

## Axelar contract deployments

The following code samples illustrate a transaction from Avalanche to Ethereum Sepolia. Information for other chains can be found on [`testnet.json`](https://github.com/axelarnetwork/axelar-contract-deployments/blob/main/axelar-chains-config/info/testnet.json).

## Verify messages

[`verify_messages`](https://github.com/axelarnetwork/axelar-amplifier/blob/f76dc8a775b8bb529cf50147bab9259d1ec7f784/packages/gateway-api/src/msg.rs#L9) is a command on the gateway that prompts verifiers to begin voting so that a message can be verified and then routed. It takes a vector of messages to be verified.

```bash
export SOURCE_CHAIN_GATEWAY="axelar1vnfn0e4vnn58ydpm05wqcc9zp8t5ztwd5rw5f895lykqaezmuccqujmwl2"
export CHAIN_NAME="avalanche"
export TX_HASH="0x41d08bd627d7be301e0858312b63b3ede840d7fad145a9da333c26adf5d98614"
export TX_EVENT="0"
export DESTINATION_CHAIN="ethereum-sepolia"
export DESTINATION_ADDRESS="0x8f8dedd09E23E22E1555e9D2C25D7c7332291919"
export SOURCE_ADDRESS="0x0a3b8dc7706c47b6dd87d771df63875b1c5cd867"
export PAYLOAD_HASH="220f68445e3cec114bff50cd6b251e3deabc7684b10280c2116b20bcc6795a96"
export RPC="https://tm.axelar-testnet.lava.build:443"
```

```bash
axelard tx wasm execute $SOURCE_CHAIN_GATEWAY \
'{
"verify_messages": [
{
"cc_id": {
"source_chain":"'"$CHAIN_NAME"'",
"message_id":"'"$TX_HASH-$TX_EVENT"'"
},
"destination_chain":"'"$DESTINATION_CHAIN"'",
"destination_address":"'"$DESTINATION_ADDRESS"'",
"source_address":"'"$SOURCE_ADDRESS"'",
"payload_hash":"'"$PAYLOAD_HASH"'"
}
]
}' \
--keyring-backend test \
--from wallet \
--gas auto --gas-adjustment 1.5 --gas-prices 0.007uverifiers \
--chain-id axelar-testnet-lisbon-3 \
--node $RPC
```

## Route messages

[`route_messages`](https://github.com/axelarnetwork/axelar-amplifier/blob/f76dc8a775b8bb529cf50147bab9259d1ec7f784/packages/gateway-api/src/msg.rs#L14) is a command on the gateway that routes successfully verified messages to the destination chain. It takes a vector of verified messages to be routed.

```bash
axelard tx wasm execute $SOURCE_CHAIN_GATEWAY \
'{
"route_messages":[
{
"cc_id": {
"source_chain":"'"$CHAIN_NAME"'",
"message_id":"'"$TX_HASH-$TX_EVENT"'"
},
"destination_chain":"'"$DESTINATION_CHAIN"'",
"destination_address":"'"$DESTINATION_ADDRESS"'",
"source_address":"'"$SOURCE_ADDRESS"'",
"payload_hash":"'"$PAYLOAD_HASH"'"
}
]
}' \
--keyring-backend test \
--from wallet \
--gas auto --gas-adjustment 1.5 --gas-prices 0.007uverifiers \
--chain-id axelar-testnet-lisbon-3 \
--node $RPC
```

## Construct a proof

[`construct_proof`](https://github.com/axelarnetwork/axelar-amplifier/blob/f76dc8a775b8bb529cf50147bab9259d1ec7f784/contracts/multisig-prover/src/msg.rs#L61) takes a vector of `CrossChainID`s and builds a proof that includes the messages to be routed so that the message can be relayed to the destination gateway. It also passes the message from the gateway to the prover.

```bash
export DESTINATION_CHAIN_MULTISIG_PROVER="axelar1xz4cya4qm2ws6nzperhvc40wdjcq4872fl6d3j2s4cytyx8j80eqenv87g"
```

```bash
axelard tx wasm execute $DESTINATION_CHAIN_MULTISIG_PROVER \
'{
"construct_proof":
[
{
"source_chain":"'"$CHAIN_NAME"'",
"message_id":"'"$TX_HASH-$TX_EVENT"'"
}
]
}' \
--keyring-backend test \
--from wallet \
--gas auto --gas-adjustment 1.5 --gas-prices 0.007uverifiers \
--chain-id axelar-testnet-lisbon-3 \
--node $RPC
```

## Get the proof

[`get_proof`](https://github.com/axelarnetwork/axelar-amplifier/blob/f76dc8a775b8bb529cf50147bab9259d1ec7f784/contracts/multisig-prover/src/msg.rs#L81) returns the fully signed proof from the multisig prover after verifiers vote.

```bash
export MULTISIG_SESSION_ID="3457"
```

```bash
axelard q wasm contract-state smart $DESTINATION_CHAIN_MULTISIG_PROVER \
'{
"get_proof":{
"multisig_session_id":"'"$MULTISIG_SESSION_ID"'"
}
}' \
--node $RPC
```

## Send the proof to the destination chain

<tabs>

<tab-item title="<code>cast</code> (Foundry)">

Use the Foundry [`cast`](https://book.getfoundry.sh/cast/) command to send the output of `get_proof` to the destination chain:

```bash
export OUTPUT="0x2A8465a312ebBa54D774972f01D64574a5acFC63 0x64f1d85a000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001600000000000000000000000008f8dedd09e23e22e1555e9d2c25d7c7332291919bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a00000000000000000000000000000000000000000000000000000000000000096176616c616e636865000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000443078343164303862643632376437626533303165303835383331326236336233656465383430643766616431343561396461333333633236616466356439383631342d3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a30783345373746643142346434313736434139643534644236306631333246624238384246413433434100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000212fcc0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000036e007b2f03a6f01af8c99ca1cded439d57007a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000009cc9a35433552080ed235722ff331bcfb533ba700000000000000000000000000000000000000000000000000000000000000010000000000000000000000003a188571605e41ea022304485551dfee11c436d50000000000000000000000000000000000000000000000000000000000000001000000000000000000000000438b7642a57aa47d1a4d290a5e2a046f45c9a6a4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000044b994544df974b36fa75ed80dfb17332dc65fcc0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000467df763dfe6d7608c0d59dff527ad42fe58f29900000000000000000000000000000000000000000000000000000000000000010000000000000000000000004b67ea6cd2728b39e1cc94e48efa988a39cd391f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000005c8d652b996286429c5df2fe604bd5b1299bb26900000000000000000000000000000000000000000000000000000000000000010000000000000000000000006968b2ad7a6d04d57798aebba01ff8bcf5aef5b200000000000000000000000000000000000000000000000000000000000000010000000000000000000000009485acfded01e09aa89d4ae63ec0c4a9f90f42c800000000000000000000000000000000000000000000000000000000000000010000000000000000000000009cd2ebe044c1f87d97d92252507c4363cefdbcf00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a477a38bd7490fe6a54545dc95240492f89803000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a56d4a7c6bb8f83b642e057e97de3061020d06c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ac46ca659582a66fa9f12e47bb204eda021ddb220000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ea21d376c66903d4c99771650f9e55f7fd7a78c90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f1e9b98362820cc9257635b1e86dbf00d0bd92090000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f4848a321f7297e1683d188c1383519cf003415c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fb13d049c9e0f0d433a09e38c009b697b1039c7c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000000056000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006600000000000000000000000000000000000000000000000000000000000000041eba2a31ea0eae246e2c0418b9ce6d4c2e5905fbd7e185df77b513c27f2fc4c477b91205725ec25208b7de0d8000116079629941291b0cbf8c0325e91cc64baf61c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041d1160889bb4c83702f294659a17b9a6191adff62efa9c4d677ce3a77c5367ffb78e238b1d2fc622304b9828ab55812499734b33d5dc6ad89fcbca84385dea1cc1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000411dcd0881bb334167dbe6358263d39b0efe1ab550c384cac620ab2a224e7acf84562eec81fc00ff062ba2077159dd5cc9e89ecfe8eb9356e19dde42a108f0b94f1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000419dfa1468778d46d2c36d33398971f8c05a501c399984ae437640bb22df50c6070e2e73cc51910bf53527e268ca113156685bd0bbe3e020a0e35a5fbc2a17d4f51b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041bef930be7baa161ad6c71274a7bfb992e6c525a5ae30ba241a9d6d24a287949a61dfb1f639950c0e9d94cb375ced32309ac60542e22f0b56a55020451bb5e5b81b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000417f21fc01777a48f51c1ed19f2a11d148acecce644c0d3de4253c4e9d58df2cd4416336eec7e8787c93ec445d3d985cdb9ce3312974f716cd1acc762ed0bf8d3c1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041a02d3135ff391b457bcbe39fb25568e80930e2e4e970cfc488d28cfd876dddd64fdda2def8f09e1fd0a2c4d1c225d27a897035491e763b222a2f16c5dddf4eb31c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041382e2e4cbd9eaff8ce466b17a64829c6fcea9af8cde13c1f75763326f3828a383710b82bbf83345c66bbeb7c6d19ccf85d469d9b7524075b2dc96729196ce7c51c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410c702c068f9a679825aadebb8a25932557550653a101a4832cb334e87a2a8a3818615d5754ebb7aaabaec6eb190a262bd0e06804f06f5a87e154797959505ac91b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041cec4908951da8841f7b7b92ec17ed04e5b95c22e2dbd1101b85842631a1b89dd09dd99506848fd3010adc3daad7ad94d275e5ebf9f391abbfa7608d0051061651b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004148c875c4ee50edc3224de13ee4c2aa0f1ac2b2736a075fe59a8c2af810b3f0383c0fcb4373d4dcacc0aced17cb6ede9f2cb7b8cd56a41502dcccccbkbrukgebdtgekutnlvkgecbgelflgtbgfcgfdl
ef8a848c5a5adb71c00000000000000000000000000000000000000000000000000000000000000"
export RPC="https://rpc.ankr.com/eth_sepolia"
```
```bash
cast send $OUTPUT \
--rpc-url $RPC \
--mnemonic-path ./private.mneumonic
```
</tab-item>
<tab-item title="MetaMask">
Use your [MetaMask wallet](https://metamask.io/) to send the output of `get_proof` to the destination chain:
1. Open your MetaMask wallet.
1. Click **Send**.
1. Get the destination chain's gateway address from [`devnet-amplifier.json`](https://github.com/axelarnetwork/axelar-contract-deployments/blob/main/axelar-chains-config/info/devnet-amplifier.json) and paste it in the **Send to** field.
1. Paste the output from `get_proof` in the **Hex data** field.
1. Click **Next**.
The proof should then be sent to the destination chain.
</tab-item>
</tabs>
5 changes: 5 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"framework": null,
"redirects": [
{
"source": "/dev/amplifier/chain-integration/relay-messages/",
"destination": "/dev/amplifier/chain-integration/relay-messages/manual/",
"permanent": true
},
{
"source": "/dev/send-tokens/interchain-tokens/rate-limit/",
"destination": "/dev/send-tokens/interchain-tokens/flow-limit/",
Expand Down

0 comments on commit 8120c1d

Please sign in to comment.