Skip to content

Commit

Permalink
integration with evm
Browse files Browse the repository at this point in the history
  • Loading branch information
meaghanfitzgerald committed Dec 16, 2024
1 parent 3e18347 commit 37978e4
Showing 1 changed file with 21 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
---
title: Integration with EVM
description: Avalanche Warp Messaging provides a basic primitive for signing and verifying messages between Blockchains.
description: Avalanche Interchain Messaging provides a basic primitive for signing and verifying messages between Blockchains.
---


Avalanche Warp Messaging offers a basic primitive to enable Cross-Layer 1 communication on the Avalanche Network.
Avalanche Interchain Messaging offers a basic primitive to enable Cross-Layer 1 communication on the Avalanche Network.

It is intended to allow communication between arbitrary Custom Virtual Machines (including, but not limited to Subnet-EVM and Coreth).

## How does Avalanche Warp Messaging Work?
## How does Avalanche Interchain Messaging Work?

Avalanche Warp Messaging uses BLS Multi-Signatures with Public-Key Aggregation where every Avalanche validator registers a public key alongside its NodeID on the Avalanche P-Chain.
Avalanche Interchain Messaging uses BLS Multi-Signatures with Public-Key Aggregation where every Avalanche validator registers a public key alongside its NodeID on the Avalanche P-Chain.

Every node tracking an Avalanche L1 has read access to the Avalanche P-Chain. This provides weighted sets of BLS Public Keys that correspond to the validator sets of each Avalanche L1 on the Avalanche Network. Avalanche Warp Messaging provides a basic primitive for signing and verifying messages between Layer 1s: the receiving network can verify whether an aggregation of signatures from a set of source blockchain validators represents a threshold of stake large enough for the receiving network to process the message.
Every node tracking an Avalanche L1 has read access to the Avalanche P-Chain. This provides weighted sets of BLS Public Keys that correspond to the validator sets of each Avalanche L1 on the Avalanche Network. Avalanche Interchain Messaging provides a basic primitive for signing and verifying messages between Layer 1s: the receiving network can verify whether an aggregation of signatures from a set of source blockchain validators represents a threshold of stake large enough for the receiving network to process the message.

For more details on Avalanche Warp Messaging, see the AvalancheGo [Warp README](/cross-chain/avalanche-warp-messaging/deep-dive).
For more details on Avalanche Interchain Messaging, see the AvalancheGo [ICM README](/cross-chain/avalanche-warp-messaging/deep-dive).

### Flow of Sending / Receiving a Warp Message within the EVM
### Flow of Sending / Receiving an Interchain Message within the EVM

The Avalanche Warp Precompile enables this flow to send a message from blockchain A to blockchain B:

Expand Down Expand Up @@ -48,19 +48,19 @@ Additionally, the `SourceChainID` is excluded because anyone parsing the chain c
- `sender`
- The `messageID` of the unsigned message (sha256 of the unsigned message)

The actual `message` is the entire [Avalanche Warp Unsigned Message](https://github.com/ava-labs/avalanchego/blob/master/vms/platformvm/warp/unsigned_message.go#L14) including an [AddressedCall](https://github.com/ava-labs/avalanchego/tree/master/vms/platformvm/warp/payload#readme). The unsigned message is emitted as the unindexed data in the log.
The actual `message` is the entire [Avalanche Interchain Unsigned Message](https://github.com/ava-labs/avalanchego/blob/master/vms/platformvm/warp/unsigned_message.go#L14) including an [AddressedCall](https://github.com/ava-labs/avalanchego/tree/master/vms/platformvm/warp/payload#readme). The unsigned message is emitted as the unindexed data in the log.

#### getVerifiedMessage

`getVerifiedMessage` is used to read the contents of the delivered Avalanche Warp Message into the expected format.
`getVerifiedMessage` is used to read the contents of the delivered Avalanche Interchain Messaging into the expected format.

It returns the message if present and a boolean indicating if a message is present.

To use this function, the transaction must include the signed Avalanche Warp Message encoded in the [predicate](#predicate-encoding) of the transaction. Prior to executing a block, the VM iterates through transactions and pre-verifies all predicates. If a transaction's predicate is invalid, then it is considered invalid to include in the block and dropped.
To use this function, the transaction must include the signed Avalanche Interchain Messaging encoded in the [predicate](#predicate-encoding) of the transaction. Prior to executing a block, the VM iterates through transactions and pre-verifies all predicates. If a transaction's predicate is invalid, then it is considered invalid to include in the block and dropped.

This leads to the following advantages:

1. The EVM execution does not need to verify the Warp Message at runtime (no signature verification or external calls to the P-Chain)
1. The EVM execution does not need to verify the Interchain Messaging at runtime (no signature verification or external calls to the P-Chain)
2. The EVM can deterministically re-execute and re-verify blocks assuming the predicate was verified by the network (eg., in bootstrapping)

This pre-verification is performed using the ProposerVM Block header during [block verification](https://github.com/ava-labs/coreth/blob/master/plugin/evm/block.go#L220) and [block building](https://github.com/ava-labs/coreth/blob/master/miner/worker.go#L200).
Expand All @@ -75,7 +75,7 @@ The `blockchainID` in Avalanche refers to the txID that created the blockchain o

### Predicate Encoding

Avalanche Warp Messages are encoded as a signed Avalanche [Warp Message](https://github.com/ava-labs/avalanchego/blob/master/vms/platformvm/warp/message.go) where the [UnsignedMessage](https://github.com/ava-labs/avalanchego/blob/master/vms/platformvm/warp/unsigned_message.go)'s payload includes an [AddressedPayload](https://github.com/ava-labs/avalanchego/blob/master/vms/platformvm/warp/payload/payload.go).
Avalanche Interchain Messages are encoded as a signed Avalanche [Interchain Messaging](https://github.com/ava-labs/avalanchego/blob/master/vms/platformvm/warp/message.go) where the [UnsignedMessage](https://github.com/ava-labs/avalanchego/blob/master/vms/platformvm/warp/unsigned_message.go)'s payload includes an [AddressedPayload](https://github.com/ava-labs/avalanchego/blob/master/vms/platformvm/warp/payload/payload.go).

Since the predicate is encoded into the [Transaction Access List](https://eips.ethereum.org/EIPS/eip-2930), it is packed into 32 byte hashes intended to declare storage slots that should be pre-warmed into the cache prior to transaction execution.

Expand All @@ -88,7 +88,7 @@ To support C-Chain to Avalanche L1 communication, or more generally Primary Netw
1. Every Avalanche L1 validator validates the C-Chain
2. The Primary Network has the largest possible number of validators

Since the Primary Network has the largest possible number of validators for any Layer 1 on Avalanche, it would also be the most expensive Layer 1 to receive and verify Avalanche Warp Messages from as it reaching a threshold of stake on the primary network would require many signatures. Luckily, we can do something much smarter.
Since the Primary Network has the largest possible number of validators for any Layer 1 on Avalanche, it would also be the most expensive Layer 1 to receive and verify Avalanche Interchain Messages from as it reaching a threshold of stake on the primary network would require many signatures. Luckily, we can do something much smarter.

When an Avalanche L1 receives a message from a blockchain on the Primary Network, we use the validator set of the receiving Avalanche L1 instead of the entire network when validating the message. This means that the C-Chain sending a message can be the exact same as Avalanche L1 to Avalanche L1 communication.

Expand All @@ -97,34 +97,34 @@ However, when Layer 1 B receives a message from the C-Chain, it changes the sema
1. Read the SourceChainID of the signed message (C-Chain)
2. Look up the SubnetID that validates C-Chain: Primary Network
3. Look up the validator set of Avalanche L1 B (instead of the Primary Network) and the registered BLS Public Keys of Avalanche L1 B at the P-Chain height specified by the ProposerVM header
4. Continue Warp Message verification using the validator set of Avalanche L1 B instead of the Primary Network
4. Continue Interchain Messaging verification using the validator set of Avalanche L1 B instead of the Primary Network

This means that C-Chain to Avalanche L1 communication only requires a threshold of stake on the receiving Avalanche L1 to sign the message instead of a threshold of stake for the entire Primary Network.

This assumes that the security of Layer 1 B already depends on the validators of Layer 1 B to behave virtuously. Therefore, requiring a threshold of stake from the receiving Avalanche L1's validator set instead of the whole Primary Network does not meaningfully change security of the receiving Blockchain.

Note: this special case is ONLY applied during Warp Message verification. The message sent by the Primary Network will still contain the Avalanche C-Chain's blockchainID as the sourceChainID and signatures will be served by querying the C-Chain directly.
Note: this special case is ONLY applied during Interchain Messaging verification. The message sent by the Primary Network will still contain the Avalanche C-Chain's blockchainID as the sourceChainID and signatures will be served by querying the C-Chain directly.

## Design Considerations

### Re-Processing Historical Blocks

Avalanche Warp Messaging depends on the Avalanche P-Chain state at the P-Chain height specified by the ProposerVM block header.
Avalanche Interchain Messaging depends on the Avalanche P-Chain state at the P-Chain height specified by the ProposerVM block header.

Verifying a message requires looking up the validator set of the source Avalanche L1 on the P-Chain. To support this, Avalanche Warp Messaging uses the ProposerVM header, which includes the P-Chain height it was issued at as the canonical point to lookup the source Avalanche L1's validator set.
Verifying a message requires looking up the validator set of the source Avalanche L1 on the P-Chain. To support this, Avalanche Interchain Messaging uses the ProposerVM header, which includes the P-Chain height it was issued at as the canonical point to lookup the source Avalanche L1's validator set.

This means verifying the Warp Message and therefore the state transition on a block depends on state that is external to the blockchain itself: the P-Chain.
This means verifying the Interchain Messaging and therefore the state transition on a block depends on state that is external to the blockchain itself: the P-Chain.

The Avalanche P-Chain tracks only its current state and reverse diff layers (reversing the changes from past blocks) in order to re-calculate the validator set at a historical height. This means calculating a very old validator set that is used to verify a Warp Message in an old block may become prohibitively expensive.
The Avalanche P-Chain tracks only its current state and reverse diff layers (reversing the changes from past blocks) in order to re-calculate the validator set at a historical height. This means calculating a very old validator set that is used to verify an Interchain Messaging in an old block may become prohibitively expensive.

Therefore, we need a heuristic to ensure that the network can correctly re-process old blocks (note: re-processing old blocks is a requirement to perform bootstrapping and is used in some VMs to serve or verify historical data).

As a result, we require that the block itself provides a deterministic hint which determines which Avalanche Warp Messages were considered valid/invalid during the block's execution. This ensures that we can always re-process blocks and use the hint to decide whether an Avalanche Warp Message should be treated as valid/invalid even after the P-Chain state that was used at the original execution time may no longer support fast lookups.
As a result, we require that the block itself provides a deterministic hint which determines which Avalanche Warp Messages were considered valid/invalid during the block's execution. This ensures that we can always re-process blocks and use the hint to decide whether an Avalanche Interchain Messaging should be treated as valid/invalid even after the P-Chain state that was used at the original execution time may no longer support fast lookups.

To provide that hint, we've explored two designs:

1. Include a predicate in the transaction to ensure any referenced message is valid
2. Append the results of checking whether a Warp Message is valid/invalid to the block data itself
2. Append the results of checking whether an Interchain Messaging is valid/invalid to the block data itself

The current implementation uses option (1).

Expand Down

0 comments on commit 37978e4

Please sign in to comment.