messages bridge between RialtoParachain and Millau (#1218)

This commit is contained in:
Svyatoslav Nikolsky
2022-05-20 12:03:45 +03:00
committed by Bastian Köcher
parent 03c2f06a27
commit 5f2f61ced5
33 changed files with 1658 additions and 75 deletions
@@ -18,19 +18,32 @@
// RuntimeApi generated functions
#![allow(clippy::too_many_arguments)]
use bp_messages::{LaneId, MessageDetails, MessageNonce};
use bp_runtime::Chain;
use frame_support::{
weights::{constants::WEIGHT_PER_SECOND, DispatchClass, IdentityFee, Weight},
RuntimeDebug,
Parameter, RuntimeDebug,
};
use frame_system::limits;
use sp_core::Hasher as HasherT;
use sp_runtime::{
traits::{BlakeTwo256, IdentifyAccount, Verify},
MultiSignature, MultiSigner, Perbill,
traits::{BlakeTwo256, Convert, IdentifyAccount, Verify},
FixedU128, MultiSignature, MultiSigner, Perbill,
};
use sp_std::vec::Vec;
/// Maximal weight of single Rialto parachain block.
/// Number of extra bytes (excluding size of storage value itself) of storage proof, built at
/// RialtoParachain chain. This mostly depends on number of entries (and their density) in the
/// storage trie. Some reserve is reserved to account future chain growth.
pub const EXTRA_STORAGE_PROOF_SIZE: u32 = 1024;
/// Can be computed by subtracting encoded call size from raw transaction size.
pub const TX_EXTRA_BYTES: u32 = 104;
/// Maximal size (in bytes) of encoded (using `Encode::encode()`) account id.
pub const MAXIMAL_ENCODED_ACCOUNT_ID_SIZE: u32 = 32;
/// Maximal weight of single RialtoParachain block.
///
/// This represents two seconds of compute assuming a target block time of six seconds.
pub const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND;
@@ -42,6 +55,44 @@ pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
/// Represents the portion of a block that will be used by Normal extrinsics.
pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
/// Maximal number of unrewarded relayer entries in Rialto confirmation transaction.
pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024;
/// Maximal number of unconfirmed messages in Rialto confirmation transaction.
pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 1024;
/// Weight of single regular message delivery transaction on RialtoParachain chain.
///
/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_proof_weight()` call
/// for the case when single message of `pallet_bridge_messages::EXPECTED_DEFAULT_MESSAGE_LENGTH`
/// bytes is delivered. The message must have dispatch weight set to zero. The result then must be
/// rounded up to account possible future runtime upgrades.
pub const DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT: Weight = 1_500_000_000;
/// Increase of delivery transaction weight on RialtoParachain chain with every additional message
/// byte.
///
/// This value is a result of
/// `pallet_bridge_messages::WeightInfoExt::storage_proof_size_overhead(1)` call. The result then
/// must be rounded up to account possible future runtime upgrades.
pub const ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT: Weight = 25_000;
/// Maximal weight of single message delivery confirmation transaction on RialtoParachain chain.
///
/// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_delivery_proof`
/// weight formula computation for the case when single message is confirmed. The result then must
/// be rounded up to account possible future runtime upgrades.
pub const MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT: Weight = 2_000_000_000;
/// Weight of pay-dispatch-fee operation for inbound messages at Rialto chain.
///
/// This value corresponds to the result of
/// `pallet_bridge_messages::WeightInfoExt::pay_inbound_dispatch_fee_overhead()` call for your
/// chain. Don't put too much reserve there, because it is used to **decrease**
/// `DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT` cost. So putting large reserve would make delivery
/// transactions cheaper.
pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = 600_000_000;
/// Block number type used in Rialto.
pub type BlockNumber = u32;
@@ -103,6 +154,15 @@ impl Chain for RialtoParachain {
}
}
/// Convert a 256-bit hash into an AccountId.
pub struct AccountIdConverter;
impl Convert<sp_core::H256, AccountId> for AccountIdConverter {
fn convert(hash: sp_core::H256) -> AccountId {
hash.to_fixed_bytes().into()
}
}
frame_support::parameter_types! {
pub BlockLength: limits::BlockLength =
limits::BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
@@ -122,3 +182,93 @@ frame_support::parameter_types! {
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
.build_or_panic();
}
/// Name of the With-Rialto-Parachain messages pallet instance that is deployed at bridged chains.
pub const WITH_RIALTO_PARACHAIN_MESSAGES_PALLET_NAME: &str = "BridgeRialtoParachainMessages";
/// Name of the Millau->Rialto (actually KSM->DOT) conversion rate stored in the Rialto parachain
/// runtime.
pub const MILLAU_TO_RIALTO_CONVERSION_RATE_PARAMETER_NAME: &str = "MillauToRialtoConversionRate";
/// Name of the `RialtoParachainFinalityApi::best_finalized` runtime method.
pub const BEST_FINALIZED_RIALTO_PARACHAIN_HEADER_METHOD: &str =
"RialtoParachainFinalityApi_best_finalized";
/// Name of the `ToRialtoParachainOutboundLaneApi::estimate_message_delivery_and_dispatch_fee`
/// runtime method.
pub const TO_RIALTO_PARACHAIN_ESTIMATE_MESSAGE_FEE_METHOD: &str =
"ToRialtoParachainOutboundLaneApi_estimate_message_delivery_and_dispatch_fee";
/// Name of the `ToRialtoParachainOutboundLaneApi::message_details` runtime method.
pub const TO_RIALTO_PARACHAIN_MESSAGE_DETAILS_METHOD: &str =
"ToRialtoParachainOutboundLaneApi_message_details";
// We use this to get the account on RialtoParachain (target) which is derived from Millau's
// (source) account. We do this so we can fund the derived account on RialtoParachain at Genesis to
// it can pay transaction fees.
//
// The reason we can use the same `AccountId` type for both chains is because they share the same
// development seed phrase.
//
// Note that this should only be used for testing.
pub fn derive_account_from_millau_id(id: bp_runtime::SourceAccount<AccountId>) -> AccountId {
let encoded_id = bp_runtime::derive_account_id(bp_runtime::MILLAU_CHAIN_ID, id);
AccountIdConverter::convert(encoded_id)
}
sp_api::decl_runtime_apis! {
/// API for querying information about the finalized RialtoParachain headers.
///
/// This API is implemented by runtimes that are bridging with the RialtoParachain chain, not the
/// RialtoParachain runtime itself.
pub trait RialtoParachainFinalityApi {
/// Returns number and hash of the best finalized header known to the bridge module.
fn best_finalized() -> (BlockNumber, Hash);
}
/// Outbound message lane API for messages that are sent to RialtoParachain chain.
///
/// This API is implemented by runtimes that are sending messages to RialtoParachain chain, not the
/// RialtoParachain runtime itself.
pub trait ToRialtoParachainOutboundLaneApi<OutboundMessageFee: Parameter, OutboundPayload: Parameter> {
/// Estimate message delivery and dispatch fee that needs to be paid by the sender on
/// this chain.
///
/// Returns `None` if message is too expensive to be sent to RialtoParachain from this chain.
///
/// Please keep in mind that this method returns the lowest message fee required for message
/// to be accepted to the lane. It may be good idea to pay a bit over this price to account
/// future exchange rate changes and guarantee that relayer would deliver your message
/// to the target chain.
fn estimate_message_delivery_and_dispatch_fee(
lane_id: LaneId,
payload: OutboundPayload,
rialto_parachain_to_this_conversion_rate: Option<FixedU128>,
) -> Option<OutboundMessageFee>;
/// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all
/// messages in given inclusive range.
///
/// If some (or all) messages are missing from the storage, they'll also will
/// be missing from the resulting vector. The vector is ordered by the nonce.
fn message_details(
lane: LaneId,
begin: MessageNonce,
end: MessageNonce,
) -> Vec<MessageDetails<OutboundMessageFee>>;
}
}
#[cfg(test)]
mod tests {
use super::*;
use sp_runtime::codec::Encode;
#[test]
fn maximal_account_size_does_not_overflow_constant() {
assert!(
MAXIMAL_ENCODED_ACCOUNT_ID_SIZE as usize >= AccountId::from([0u8; 32]).encode().len(),
"Actual maximal size of encoded AccountId ({}) overflows expected ({})",
AccountId::from([0u8; 32]).encode().len(),
MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
);
}
}