Andromeda Messaging Protocol

The Andromeda Messaging Protocol (AMP) is an advanced messaging system tailored for Andromeda ADOs. It has been designed to optimize communication between ADOs, addressing common issues present in existing CosmWasm messaging protocols.

All ADO communication can be done through AMP. This means that ADOs would send their messages to AMP (The kernel) which relays it to the intended ADO. The AMP layer also interacts with the rest of the OS systems such as the Virtual File System (VFS), economics engine, ADO database.

This messaging system is primarily handled by our Kernel ADO and is aimed to solve the following problems:

Although not recommended, we have kept the option of sending messages directly from one ADO to another without passing through the AMP layer.

Message Tracking

As you may know, standard messaging protocols on CosmWasm are limited when it comes to providing traceability of messages. This means that if contract A wants to send a message to contract C through one or more intermediate contracts, such as A->B->C, contract C has no way of knowing the original sender of the message, which in this case is A. This can lead to complications in verifying the origin of messages, and can make it difficult to accurately track the path a message has taken.

AMP takes care of this by keeping a record of the previous and original sender of a message.

Security

The Andromeda Messaging Protocol has been designed to enhance the security of the system, providing an extra layer of verification to ensure that messages are only relayed through AMP by authenticated, Andromeda-certified ADOs. This guarantee helps protect the system from potentially malicious contracts, while allowing contracts instantiated using a certified ADO to securely and reliably send and receive messages.

The Andromeda ADODB keeps a mapping of ADOs and code Ids. To be a certified Andromeda ADO and interact with AMP, an ADO needs to be instantiated by one of the code Ids found in the ADODB.

Additional Control

Our AMP messages offer senders added control over their messages. Each AMP message can have two key parameters specified by the sender, including reply_on and gas_limit. The reply_on field defines when the message should deliver a callback to the contract, while the gas_limit feature allows the sender to set an upper limit for the amount of gas to be used.

Inter Blockchain Communication

The AMP layer also handles IBC calls between ADOs.

The Kernel ADO of each chain is responsible for handling and relaying IBC messages. When the Kernel receives an AMP packet So for example, if ADO 1 (On the Andromeda chain) wishes to send a message to ADO 5 (On another Cosmos chain) :

  1. ADO 1 sends an AMP packet to the kernel on the Andromeda Chain.

  2. The Kernel receives the packet, verifies it, and forwards it to the kernel on the receiving chain through a channel via IBC-hooks.

  3. The Kernel on the second chain receives the packet,verifies it, and then forwards it to ADO 5.

It is important to note that every time the Kernel ADO receives a packet, it makes sure to verify that it is coming from a trusted and wanted source ensuring security and preventing malicious messages to be passed through the system.

AMP Structures

ADOs use an Andromeda packet structure to communicate with the AMP layer. This AMPPkt structure stores details about the message sender and origin, as well as a vector of AMPMsg struct containing the execute messages that require relaying to the intended ADO recipient.

AMPPkt

The packet may contain several messages which allows for message batching. The messags are processed sequentially.

pub struct AMPPkt {
    pub messages: Vec<AMPMsg>,
    pub ctx: AMPCtx,
}
NameTypeDescription

messages

Vec<AMPMsg>

Any AMP messages associated with the packet.

ctx

Additional context to be sent along with the messages.

AMPMsg

This struct defines how the kernel parses and relays messages between ADOs. It contains a simple recipient string which may use our namespacing implementation or a simple contract address.

If the desired recipient is via IBC, then namespacing (VFS) must be employed.

The attached message must be a binary encoded execute message for the receiving ADO.

Funds can be added for an individual message and will be attached accordingly.

pub struct AMPMsg {
    pub recipient: AndrAddr,
    pub message: Binary,
    pub funds: Vec<Coin>,
    pub config: AMPMsgConfig,
}
NameTypeDescription

recipient

The message recipient. Can be a contract/wallet address or a namespaced URI.

message

Binary

The message to be sent to the recipient.

funds

Vec<Coin>

Any funds attached to the message, defaults to an empty vector.

config

Some additional configurations for the message to be sent.

AMPMsgConfig

The configuration of the message to be sent.

Used when a sub message is generated for the given AMP Msg.

Only used in the case of Wasm Messages

pub struct AMPMsgConfig {
    pub reply_on: ReplyOn,
    pub exit_at_error: bool,
    pub gas_limit: Option<u64>,
    pub direct: bool,
    pub ibc_config: Option<IBCConfig>,
}
NameTypeDescription

reply_on

When the message should reply, defaults to Always.

exit_at_error

bool

Determines whether the operation should terminate or proceed upon a failed message.

gas_limit

Option<u64>

An optional imposed gas limit (maximum) for the message.

direct

bool

Whether to send the message directly to the given recipient or go through the kernel.

ibc_config

Option<IBCConfig>

Contains a recovery address which will receive back funds in case an IBC message failed.

IBCConfig

Specifies an address that will receive funds back in case an IBC message is sent and failed.

In case this address is not set, the funds will be returned to the original sender of the message.

To recover funds, the user must call the Recover execute message found in the Kernel ADO.

pub struct IBCConfig {
    pub recovery_addr: Option<AndrAddr>,
}
NameTypeDescription

recovery_addr

Option<AndrAddr>

The address to receive funds in case the IBC message failed.

ReplyOn

pub enum ReplyOn {
    Always,
    Error,
    Success,
    Never,
}
TypeDescription

Always

Always perform a callback after a SubMsg is processed.

Error

Only callback if SubMsg returned an error. No callback on success case.

Success

Only callback if SubMsg was successful. No callback on error case.

Never

Never perform a callback.

AMPCtx

The origin and origin_username are not public to prevent disguised attacks.

pub struct AMPCtx {
    origin: String,
    origin_username: Option<AndrAddr>,
    pub previous_sender: String,
    pub id: u64,
}
NameTypeDescription

origin

String

The original sender of the packet. Is immutable.

origin_username

Option<AndrAddr>

The username or VFS name of the original sender.

previous sender

String

The previous sender of the packet.

id

u64

The id of the packet provided by the kernel.

  1. When the AMPPkt is received by the Kernel, it first checks that the sender of the message is an Andromeda ADO.

  2. Then it checks the id of the packet making sure that it was provided by the kernel.

  3. It then sends the AMPPkt to the first ADO recipient specified in the first AMPMsg from the Vec<AMPMsg>.

  4. When the ADO receives this packet, it is unpacked and executed. Once executed, this AMPMsg is removed from the Vec<AMPMsg> and the rest of the AMPPkt is sent back to the Kernel.

  5. The Kernel then recieves the AMPPkt and repeats the same operation, relaying it to the next recipient in the next AMPMsg until all the messages have been executed.

AMPReceive

All our ADOs have a common execute message to handle receiving an AMP packet from the kernel. When a packet is received by an ADO, it verifies it and proceeds to execute the attached messages.

Last updated

Additional Resources

GithubWebsite