From 6b8bdee78528214cbdbc6f27f69bf52694b9c97b Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 18 Nov 2020 23:18:42 +0300 Subject: [PATCH] Use different chain primitives in Millau (#517) --- bridges/bin/millau/runtime/src/lib.rs | 2 +- .../bin/millau/runtime/src/rialto_messages.rs | 4 +- bridges/bin/rialto/runtime/src/lib.rs | 2 +- .../bin/rialto/runtime/src/millau_messages.rs | 4 +- bridges/primitives/millau/Cargo.toml | 16 ++++++ bridges/primitives/millau/src/lib.rs | 52 ++++++++++++++--- bridges/primitives/millau/src/millau_hash.rs | 57 +++++++++++++++++++ .../relays/headers-relay/src/sync_types.rs | 16 +----- .../relays/messages-relay/src/message_lane.rs | 7 +-- .../substrate-client/src/headers_source.rs | 3 +- .../relays/substrate/src/headers_pipeline.rs | 6 +- .../relays/substrate/src/messages_source.rs | 4 +- .../relays/substrate/src/messages_target.rs | 3 +- bridges/relays/utils/Cargo.toml | 1 + bridges/relays/utils/src/lib.rs | 45 +++++++++++++++ 15 files changed, 182 insertions(+), 40 deletions(-) create mode 100644 bridges/primitives/millau/src/millau_hash.rs diff --git a/bridges/bin/millau/runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs index 7435788acc666..bd340f0a7d3ba 100644 --- a/bridges/bin/millau/runtime/src/lib.rs +++ b/bridges/bin/millau/runtime/src/lib.rs @@ -256,7 +256,7 @@ impl pallet_timestamp::Trait for Runtime { } parameter_types! { - pub const ExistentialDeposit: u128 = 500; + pub const ExistentialDeposit: bp_millau::Balance = 500; // For weight estimation, we assume that the most locks on an individual account will be 50. // This number may need to be adjusted in the future if this assumption no longer holds true. pub const MaxLocks: u32 = 50; diff --git a/bridges/bin/millau/runtime/src/rialto_messages.rs b/bridges/bin/millau/runtime/src/rialto_messages.rs index 7e7317f16152e..5674f738e19e9 100644 --- a/bridges/bin/millau/runtime/src/rialto_messages.rs +++ b/bridges/bin/millau/runtime/src/rialto_messages.rs @@ -110,12 +110,12 @@ impl MessageBridge for WithRialtoMessageBridge { fn bridged_weight_to_bridged_balance(weight: Weight) -> bp_rialto::Balance { // we're using the same weights in both chains now - ::WeightToFee::calc(&weight) + ::WeightToFee::calc(&weight) as _ } fn this_balance_to_bridged_balance(this_balance: bp_millau::Balance) -> bp_rialto::Balance { // 1:1 conversion that will probably change in the future - this_balance + this_balance as _ } } diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs index 4a3855f69e6d6..2ff341427fd1e 100644 --- a/bridges/bin/rialto/runtime/src/lib.rs +++ b/bridges/bin/rialto/runtime/src/lib.rs @@ -365,7 +365,7 @@ impl pallet_timestamp::Trait for Runtime { } parameter_types! { - pub const ExistentialDeposit: u128 = 500; + pub const ExistentialDeposit: bp_rialto::Balance = 500; // For weight estimation, we assume that the most locks on an individual account will be 50. // This number may need to be adjusted in the future if this assumption no longer holds true. pub const MaxLocks: u32 = 50; diff --git a/bridges/bin/rialto/runtime/src/millau_messages.rs b/bridges/bin/rialto/runtime/src/millau_messages.rs index 5a2cfba73da4c..6972a11eef098 100644 --- a/bridges/bin/rialto/runtime/src/millau_messages.rs +++ b/bridges/bin/rialto/runtime/src/millau_messages.rs @@ -110,12 +110,12 @@ impl MessageBridge for WithMillauMessageBridge { fn bridged_weight_to_bridged_balance(weight: Weight) -> bp_millau::Balance { // we're using the same weights in both chains now - ::WeightToFee::calc(&weight) + ::WeightToFee::calc(&weight) as _ } fn this_balance_to_bridged_balance(this_balance: bp_rialto::Balance) -> bp_millau::Balance { // 1:1 conversion that will probably change in the future - this_balance + this_balance as _ } } diff --git a/bridges/primitives/millau/Cargo.toml b/bridges/primitives/millau/Cargo.toml index 545bbd88fc757..db8fbf04feeb7 100644 --- a/bridges/primitives/millau/Cargo.toml +++ b/bridges/primitives/millau/Cargo.toml @@ -12,23 +12,39 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" bp-message-lane = { path = "../message-lane", default-features = false } bp-runtime = { path = "../runtime", default-features = false } +fixed-hash = { version = "0.6.1", default-features = false } +hash256-std-hasher = { version = "0.15.2", default-features = false } +impl-codec = { version = "0.4.2", default-features = false } +impl-serde = { version = "0.3.1", optional = true } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } +serde = { version = "1.0.101", optional = true, features = ["derive"] } # Substrate Based Dependencies frame-support = { version = "2.0", default-features = false } sp-api = { version = "2.0", default-features = false } sp-core = { version = "2.0", default-features = false } +sp-io = { version = "2.0", default-features = false } sp-runtime = { version = "2.0", default-features = false } sp-std = { version = "2.0", default-features = false } +sp-trie = { version = "2.0", default-features = false } [features] default = ["std"] std = [ "bp-message-lane/std", "bp-runtime/std", + "fixed-hash/std", "frame-support/std", + "hash256-std-hasher/std", + "impl-codec/std", + "impl-serde", + "parity-util-mem/std", + "serde", "sp-api/std", "sp-core/std", + "sp-io/std", "sp-runtime/std", "sp-std/std", + "sp-trie/std", ] diff --git a/bridges/primitives/millau/src/lib.rs b/bridges/primitives/millau/src/lib.rs index d8c6f5c3008d1..70eba6832640f 100644 --- a/bridges/primitives/millau/src/lib.rs +++ b/bridges/primitives/millau/src/lib.rs @@ -20,18 +20,56 @@ // Runtime-generated DecodeLimit::decode_all_With_depth_limit #![allow(clippy::unnecessary_mut_passed)] +mod millau_hash; + use bp_message_lane::MessageNonce; use bp_runtime::Chain; use frame_support::{weights::Weight, RuntimeDebug}; use sp_core::Hasher as HasherT; use sp_runtime::{ - traits::{BlakeTwo256, IdentifyAccount, Verify}, + traits::{IdentifyAccount, Verify}, MultiSignature, MultiSigner, }; use sp_std::prelude::*; +use sp_trie::{trie_types::Layout, TrieConfiguration}; + +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; + +pub use millau_hash::MillauHash; + +/// Millau Hasher (Blake2-256 ++ Keccak-256) implementation. +#[derive(PartialEq, Eq, Clone, Copy, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct BlakeTwoAndKeccak256; + +impl sp_core::Hasher for BlakeTwoAndKeccak256 { + type Out = MillauHash; + type StdHasher = hash256_std_hasher::Hash256StdHasher; + const LENGTH: usize = 64; + + fn hash(s: &[u8]) -> Self::Out { + let mut combined_hash = MillauHash::default(); + combined_hash.as_mut()[..32].copy_from_slice(&sp_io::hashing::blake2_256(s)); + combined_hash.as_mut()[32..].copy_from_slice(&sp_io::hashing::keccak_256(s)); + combined_hash + } +} + +impl sp_runtime::traits::Hash for BlakeTwoAndKeccak256 { + type Output = MillauHash; + + fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output { + Layout::::trie_root(input) + } + + fn ordered_trie_root(input: Vec>) -> Self::Output { + Layout::::ordered_trie_root(input) + } +} /// Maximal weight of single Millau block. -pub const MAXIMUM_BLOCK_WEIGHT: Weight = 2_000_000_000_000; +pub const MAXIMUM_BLOCK_WEIGHT: Weight = 10_000_000_000; /// Portion of block reserved for regular transactions. pub const AVAILABLE_BLOCK_RATIO: u32 = 75; /// Maximal weight of single Millau extrinsic (65% of maximum block weight = 75% for regular @@ -39,16 +77,16 @@ pub const AVAILABLE_BLOCK_RATIO: u32 = 75; pub const MAXIMUM_EXTRINSIC_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT / 100 * (AVAILABLE_BLOCK_RATIO as Weight - 10); /// Maximal number of unconfirmed messages at inbound lane. -pub const MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE: MessageNonce = 128; +pub const MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE: MessageNonce = 1024; /// Block number type used in Millau. -pub type BlockNumber = u32; +pub type BlockNumber = u64; /// Hash type used in Millau. -pub type Hash = ::Out; +pub type Hash = ::Out; /// The type of an object that can produce hashes on Millau. -pub type Hasher = BlakeTwo256; +pub type Hasher = BlakeTwoAndKeccak256; /// The header type used by Millau. pub type Header = sp_runtime::generic::Header; @@ -84,7 +122,7 @@ pub type AccountId = <::Signer as IdentifyAccount>::Account pub type AccountSigner = MultiSigner; /// Balance of an account. -pub type Balance = u128; +pub type Balance = u64; sp_api::decl_runtime_apis! { /// API for querying information about Millau headers from the Bridge Pallet instance. diff --git a/bridges/primitives/millau/src/millau_hash.rs b/bridges/primitives/millau/src/millau_hash.rs new file mode 100644 index 0000000000000..521b8997ad603 --- /dev/null +++ b/bridges/primitives/millau/src/millau_hash.rs @@ -0,0 +1,57 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +use parity_util_mem::MallocSizeOf; +use sp_runtime::traits::CheckEqual; + +// `sp_core::H512` can't be used, because it doesn't implement `CheckEqual`, which is required +// by `frame_system::Trait::Hash`. + +fixed_hash::construct_fixed_hash! { + /// Hash type used in Millau chain. + #[derive(MallocSizeOf)] + pub struct MillauHash(64); +} + +#[cfg(feature = "std")] +impl_serde::impl_fixed_hash_serde!(MillauHash, 64); + +impl_codec::impl_fixed_hash_codec!(MillauHash, 64); + +impl CheckEqual for MillauHash { + #[cfg(feature = "std")] + fn check_equal(&self, other: &Self) { + use sp_core::hexdisplay::HexDisplay; + if self != other { + println!( + "Hash: given={}, expected={}", + HexDisplay::from(self.as_fixed_bytes()), + HexDisplay::from(other.as_fixed_bytes()), + ); + } + } + + #[cfg(not(feature = "std"))] + fn check_equal(&self, other: &Self) { + use frame_support::Printable; + + if self != other { + "Hash not equal".print(); + self.as_bytes().print(); + other.as_bytes().print(); + } + } +} diff --git a/bridges/relays/headers-relay/src/sync_types.rs b/bridges/relays/headers-relay/src/sync_types.rs index 958c81dd911ed..7f975100f8edf 100644 --- a/bridges/relays/headers-relay/src/sync_types.rs +++ b/bridges/relays/headers-relay/src/sync_types.rs @@ -52,21 +52,7 @@ pub trait HeadersSyncPipeline: Clone + Send + Sync { /// Headers we're syncing are identified by this hash. type Hash: Eq + Clone + Copy + Send + Sync + std::fmt::Debug + std::fmt::Display + std::hash::Hash; /// Headers we're syncing are identified by this number. - type Number: From - + Ord - + Clone - + Copy - + Send - + Sync - + std::fmt::Debug - + std::fmt::Display - + std::hash::Hash - + std::ops::Add - + std::ops::Sub - + num_traits::Saturating - + num_traits::Zero - + num_traits::One - + Into; + type Number: relay_utils::BlockNumberBase; /// Type of header that we're syncing. type Header: SourceHeader; /// Type of extra data for the header that we're receiving from the source node: diff --git a/bridges/relays/messages-relay/src/message_lane.rs b/bridges/relays/messages-relay/src/message_lane.rs index 5b4a6a97cc858..6abddabb4879c 100644 --- a/bridges/relays/messages-relay/src/message_lane.rs +++ b/bridges/relays/messages-relay/src/message_lane.rs @@ -19,8 +19,7 @@ //! 1) relay new messages from source to target node; //! 2) relay proof-of-delivery from target to source node. -use relay_utils::HeaderId; - +use relay_utils::{BlockNumberBase, HeaderId}; use std::fmt::Debug; /// One-way message lane. @@ -36,12 +35,12 @@ pub trait MessageLane: Clone + Send + Sync { type MessagesReceivingProof: Clone + Send + Sync; /// Number of the source header. - type SourceHeaderNumber: Clone + Debug + Ord + PartialEq + Into + Send + Sync; + type SourceHeaderNumber: BlockNumberBase; /// Hash of the source header. type SourceHeaderHash: Clone + Debug + Default + PartialEq + Send + Sync; /// Number of the target header. - type TargetHeaderNumber: Clone + Debug + Ord + PartialEq + Into + Send + Sync; + type TargetHeaderNumber: BlockNumberBase; /// Hash of the target header. type TargetHeaderHash: Clone + Debug + Default + PartialEq + Send + Sync; } diff --git a/bridges/relays/substrate-client/src/headers_source.rs b/bridges/relays/substrate-client/src/headers_source.rs index b9b46774ce588..33f194322ddea 100644 --- a/bridges/relays/substrate-client/src/headers_source.rs +++ b/bridges/relays/substrate-client/src/headers_source.rs @@ -25,7 +25,6 @@ use headers_relay::{ sync_loop::SourceClient, sync_types::{HeaderIdOf, HeadersSyncPipeline, QueuedHeader, SourceHeader}, }; -use num_traits::Saturating; use sp_runtime::{traits::Header as HeaderT, Justification}; use std::marker::PhantomData; @@ -49,7 +48,7 @@ impl HeadersSource { impl SourceClient

for HeadersSource where C: Chain, - C::BlockNumber: Into + Saturating, + C::BlockNumber: relay_utils::BlockNumberBase, C::Header: Into, P: HeadersSyncPipeline, P::Header: SourceHeader, diff --git a/bridges/relays/substrate/src/headers_pipeline.rs b/bridges/relays/substrate/src/headers_pipeline.rs index b00417da39d0e..adcebbc7a7f43 100644 --- a/bridges/relays/substrate/src/headers_pipeline.rs +++ b/bridges/relays/substrate/src/headers_pipeline.rs @@ -26,8 +26,8 @@ use headers_relay::{ sync::{HeadersSyncParams, TargetTransactionMode}, sync_types::{HeadersSyncPipeline, QueuedHeader, SourceHeader}, }; -use num_traits::Saturating; use relay_substrate_client::{headers_source::HeadersSource, BlockNumberOf, Chain, Client, HashOf}; +use relay_utils::BlockNumberBase; use sp_runtime::Justification; use std::marker::PhantomData; @@ -59,7 +59,7 @@ impl HeadersSyncPipeline for SubstrateHeadersToSubstrate where SourceChain: Clone + Chain, - BlockNumberOf: Saturating + Into, + BlockNumberOf: BlockNumberBase, SourceSyncHeader: SourceHeader, BlockNumberOf> + std::ops::Deref, TargetChain: Clone + Chain, @@ -107,7 +107,7 @@ pub async fn run( P::Header: SourceHeader, BlockNumberOf>, SourceChain: Clone + Chain, SourceChain::Header: Into, - BlockNumberOf: Into + Saturating, + BlockNumberOf: BlockNumberBase, TargetChain: Clone + Chain, { let source_justifications = match source_client.clone().subscribe_justifications().await { diff --git a/bridges/relays/substrate/src/messages_source.rs b/bridges/relays/substrate/src/messages_source.rs index c648289fee147..eb182f8f1edb1 100644 --- a/bridges/relays/substrate/src/messages_source.rs +++ b/bridges/relays/substrate/src/messages_source.rs @@ -28,7 +28,7 @@ use messages_relay::{ message_lane_loop::{ClientState, MessageProofParameters, MessageWeightsMap, SourceClient, SourceClientState}, }; use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf, HeaderIdOf}; -use relay_utils::HeaderId; +use relay_utils::{BlockNumberBase, HeaderId}; use sp_core::Bytes; use sp_runtime::{traits::Header as HeaderT, DeserializeOwned}; use sp_trie::StorageProof; @@ -93,7 +93,7 @@ where C: Chain, C::Header: DeserializeOwned, C::Index: DeserializeOwned, - ::Number: Into, + C::BlockNumber: BlockNumberBase, P: MessageLane< MessagesProof = SubstrateMessagesProof, SourceHeaderNumber = ::Number, diff --git a/bridges/relays/substrate/src/messages_target.rs b/bridges/relays/substrate/src/messages_target.rs index 2569b5e2c9ae5..4ad61caf20e80 100644 --- a/bridges/relays/substrate/src/messages_target.rs +++ b/bridges/relays/substrate/src/messages_target.rs @@ -29,6 +29,7 @@ use messages_relay::{ message_lane_loop::{TargetClient, TargetClientState}, }; use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf}; +use relay_utils::BlockNumberBase; use sp_core::Bytes; use sp_runtime::{traits::Header as HeaderT, DeserializeOwned}; use sp_trie::StorageProof; @@ -89,7 +90,7 @@ where C: Chain, C::Header: DeserializeOwned, C::Index: DeserializeOwned, - ::Number: Into, + ::Number: BlockNumberBase, P: MessageLane< MessagesReceivingProof = (HashOf, StorageProof, LaneId), TargetHeaderNumber = ::Number, diff --git a/bridges/relays/utils/Cargo.toml b/bridges/relays/utils/Cargo.toml index eeb49369f9295..04ceb3ec0dc01 100644 --- a/bridges/relays/utils/Cargo.toml +++ b/bridges/relays/utils/Cargo.toml @@ -12,6 +12,7 @@ backoff = "0.2" env_logger = "0.7.0" futures = "0.3.5" log = "0.4.11" +num-traits = "0.2" sysinfo = "0.15" time = "0.2" diff --git a/bridges/relays/utils/src/lib.rs b/bridges/relays/utils/src/lib.rs index 49f2ae996598e..e81660299becb 100644 --- a/bridges/relays/utils/src/lib.rs +++ b/bridges/relays/utils/src/lib.rs @@ -30,6 +30,51 @@ pub const CONNECTION_ERROR_DELAY: Duration = Duration::from_secs(10); pub mod initialize; pub mod metrics; +/// Block number traits shared by all chains that relay is able to serve. +pub trait BlockNumberBase: + 'static + + From + + Into + + Ord + + Clone + + Copy + + Default + + Send + + Sync + + std::fmt::Debug + + std::fmt::Display + + std::hash::Hash + + std::ops::Add + + std::ops::Sub + + num_traits::CheckedSub + + num_traits::Saturating + + num_traits::Zero + + num_traits::One +{ +} + +impl BlockNumberBase for T where + T: 'static + + From + + Into + + Ord + + Clone + + Copy + + Default + + Send + + Sync + + std::fmt::Debug + + std::fmt::Display + + std::hash::Hash + + std::ops::Add + + std::ops::Sub + + num_traits::CheckedSub + + num_traits::Saturating + + num_traits::Zero + + num_traits::One +{ +} + /// Macro that returns (client, Err(error)) tuple from function if result is Err(error). #[macro_export] macro_rules! bail_on_error {