Split payload types (#383)

* split payloads (inbound/outbound/opaque/dispatch) + fees (inbound/outbound)

* added tests

Co-authored-by: Hernando Castano <castano.ha@gmail.com>
This commit is contained in:
Svyatoslav Nikolsky
2020-09-28 23:48:58 +03:00
committed by Bastian Köcher
parent be050bda84
commit 7f7d62d813
6 changed files with 178 additions and 85 deletions
+7 -4
View File
@@ -39,6 +39,9 @@ pub type MessageNonce = u64;
/// Message id as a tuple.
pub type MessageId = (LaneId, MessageNonce);
/// Opaque message payload. We only decode this payload when it is dispatched.
pub type MessagePayload = Vec<u8>;
/// Message key (unique message identifier) as it is stored in the storage.
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
pub struct MessageKey {
@@ -50,20 +53,20 @@ pub struct MessageKey {
/// Message data as it is stored in the storage.
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
pub struct MessageData<Payload, Fee> {
pub struct MessageData<Fee> {
/// Message payload.
pub payload: Payload,
pub payload: MessagePayload,
/// Message delivery and dispatch fee, paid by the submitter.
pub fee: Fee,
}
/// Message as it is stored in the storage.
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
pub struct Message<Payload, Fee> {
pub struct Message<Fee> {
/// Message key.
pub key: MessageKey,
/// Message data.
pub data: MessageData<Payload, Fee>,
pub data: MessageData<Fee>,
}
/// Inbound lane data.
@@ -16,17 +16,36 @@
//! Primitives of message lane module, that are used on the target chain.
use crate::Message;
use crate::{Message, MessageData, MessageKey};
use frame_support::{weights::Weight, Parameter};
use codec::{Decode, Error as CodecError};
use frame_support::{weights::Weight, Parameter, RuntimeDebug};
use sp_std::{fmt::Debug, prelude::*};
/// Message data with decoded dispatch payload.
#[derive(RuntimeDebug)]
pub struct DispatchMessageData<DispatchPayload, Fee> {
/// Result of dispatch payload decoding.
pub payload: Result<DispatchPayload, CodecError>,
/// Message delivery and dispatch fee, paid by the submitter.
pub fee: Fee,
}
/// Message with decoded dispatch payload.
#[derive(RuntimeDebug)]
pub struct DispatchMessage<DispatchPayload, Fee> {
/// Message key.
pub key: MessageKey,
/// Message data with decoded dispatch payload.
pub data: DispatchMessageData<DispatchPayload, Fee>,
}
/// Source chain API. Used by target chain, to verify source chain proofs.
///
/// All implementations of this trait should only work with finalized data that
/// can't change. Wrong implementation may lead to invalid lane states (i.e. lane
/// that's stuck) and/or processing messages without paying fees.
pub trait SourceHeaderChain<Payload, Fee> {
pub trait SourceHeaderChain<Fee> {
/// Error type.
type Error: Debug + Into<&'static str>;
@@ -37,20 +56,43 @@ pub trait SourceHeaderChain<Payload, Fee> {
///
/// Messages vector is required to be sorted by nonce within each lane. Out-of-order
/// messages will be rejected.
fn verify_messages_proof(proof: Self::MessagesProof) -> Result<Vec<Message<Payload, Fee>>, Self::Error>;
fn verify_messages_proof(proof: Self::MessagesProof) -> Result<Vec<Message<Fee>>, Self::Error>;
}
/// Called when inbound message is received.
pub trait MessageDispatch<Payload, Fee> {
pub trait MessageDispatch<Fee> {
/// Decoded message payload type. Valid message may contain invalid payload. In this case
/// message is delivered, but dispatch fails. Therefore, two separate types of payload
/// (opaque `MessagePayload` used in delivery and this `DispatchPayload` used in dispatch).
type DispatchPayload: Decode;
/// Estimate dispatch weight.
///
/// This function must: (1) be instant and (2) return correct upper bound
/// of dispatch weight.
fn dispatch_weight(message: &Message<Payload, Fee>) -> Weight;
fn dispatch_weight(message: &DispatchMessage<Self::DispatchPayload, Fee>) -> Weight;
/// Called when inbound message is received.
///
/// It is up to the implementers of this trait to determine whether the message
/// is invalid (i.e. improperly encoded, has too large weight, ...) or not.
fn dispatch(message: Message<Payload, Fee>);
fn dispatch(message: DispatchMessage<Self::DispatchPayload, Fee>);
}
impl<DispatchPayload: Decode, Fee> From<Message<Fee>> for DispatchMessage<DispatchPayload, Fee> {
fn from(message: Message<Fee>) -> Self {
DispatchMessage {
key: message.key,
data: message.data.into(),
}
}
}
impl<DispatchPayload: Decode, Fee> From<MessageData<Fee>> for DispatchMessageData<DispatchPayload, Fee> {
fn from(data: MessageData<Fee>) -> Self {
DispatchMessageData {
payload: DispatchPayload::decode(&mut &data.payload[..]),
fee: data.fee,
}
}
}