Rococo <> Wococo messages relay (#1030)

* MessagesInstance -> BridgedMessagesInstance

* Chain::ID -> Bridge::THIS_CHAIN_ID+Bridge::BRIDGED_CHAIN_ID

* FromBridgedChainEncodedMessageCall<B> -> FromBridgedChainEncodedMessageCall<DecodedCall>

* impl Parameter for ()

* copypaste storage_map_final_key to avoid different runtime references/dummy runtimes

* moved dummy runtime from primitives to relay client

* Rococo <> Wococo messages relays

* send R<>W messages using relay

* fmt

* return Result from get_dispatch_info

* fix benchmarks compilation

* clippy
This commit is contained in:
Svyatoslav Nikolsky
2021-06-25 11:06:14 +03:00
committed by Bastian Köcher
parent c8aeb11b26
commit 165730a2c2
34 changed files with 1090 additions and 242 deletions
@@ -52,7 +52,7 @@ pub type ToRialtoMessageVerifier = messages::source::FromThisChainMessageVerifie
pub type FromRialtoMessagePayload = messages::target::FromBridgedChainMessagePayload<WithRialtoMessageBridge>; pub type FromRialtoMessagePayload = messages::target::FromBridgedChainMessagePayload<WithRialtoMessageBridge>;
/// Encoded Millau Call as it comes from Rialto. /// Encoded Millau Call as it comes from Rialto.
pub type FromRialtoEncodedCall = messages::target::FromBridgedChainEncodedMessageCall<WithRialtoMessageBridge>; pub type FromRialtoEncodedCall = messages::target::FromBridgedChainEncodedMessageCall<crate::Call>;
/// Messages proof for Rialto -> Millau messages. /// Messages proof for Rialto -> Millau messages.
type FromRialtoMessagesProof = messages::target::FromBridgedChainMessagesProof<bp_rialto::Hash>; type FromRialtoMessagesProof = messages::target::FromBridgedChainMessagesProof<bp_rialto::Hash>;
@@ -74,9 +74,12 @@ pub struct WithRialtoMessageBridge;
impl MessageBridge for WithRialtoMessageBridge { impl MessageBridge for WithRialtoMessageBridge {
const RELAYER_FEE_PERCENT: u32 = 10; const RELAYER_FEE_PERCENT: u32 = 10;
const THIS_CHAIN_ID: ChainId = MILLAU_CHAIN_ID;
const BRIDGED_CHAIN_ID: ChainId = RIALTO_CHAIN_ID;
type ThisChain = Millau; type ThisChain = Millau;
type BridgedChain = Rialto; type BridgedChain = Rialto;
type BridgedMessagesInstance = crate::WithRialtoMessagesInstance;
fn bridged_balance_to_this_balance(bridged_balance: bp_rialto::Balance) -> bp_millau::Balance { fn bridged_balance_to_this_balance(bridged_balance: bp_rialto::Balance) -> bp_millau::Balance {
bp_millau::Balance::try_from(RialtoToMillauConversionRate::get().saturating_mul_int(bridged_balance)) bp_millau::Balance::try_from(RialtoToMillauConversionRate::get().saturating_mul_int(bridged_balance))
@@ -89,16 +92,12 @@ impl MessageBridge for WithRialtoMessageBridge {
pub struct Millau; pub struct Millau;
impl messages::ChainWithMessages for Millau { impl messages::ChainWithMessages for Millau {
const ID: ChainId = MILLAU_CHAIN_ID;
type Hash = bp_millau::Hash; type Hash = bp_millau::Hash;
type AccountId = bp_millau::AccountId; type AccountId = bp_millau::AccountId;
type Signer = bp_millau::AccountSigner; type Signer = bp_millau::AccountSigner;
type Signature = bp_millau::Signature; type Signature = bp_millau::Signature;
type Weight = Weight; type Weight = Weight;
type Balance = bp_millau::Balance; type Balance = bp_millau::Balance;
type MessagesInstance = crate::WithRialtoMessagesInstance;
} }
impl messages::ThisChainWithMessages for Millau { impl messages::ThisChainWithMessages for Millau {
@@ -145,16 +144,12 @@ impl messages::ThisChainWithMessages for Millau {
pub struct Rialto; pub struct Rialto;
impl messages::ChainWithMessages for Rialto { impl messages::ChainWithMessages for Rialto {
const ID: ChainId = RIALTO_CHAIN_ID;
type Hash = bp_rialto::Hash; type Hash = bp_rialto::Hash;
type AccountId = bp_rialto::AccountId; type AccountId = bp_rialto::AccountId;
type Signer = bp_rialto::AccountSigner; type Signer = bp_rialto::AccountSigner;
type Signature = bp_rialto::Signature; type Signature = bp_rialto::Signature;
type Weight = Weight; type Weight = Weight;
type Balance = bp_rialto::Balance; type Balance = bp_rialto::Balance;
type MessagesInstance = pallet_bridge_messages::DefaultInstance;
} }
impl messages::BridgedChainWithMessages for Rialto { impl messages::BridgedChainWithMessages for Rialto {
+7 -12
View File
@@ -915,10 +915,10 @@ impl_runtime_apis! {
fn prepare_message_proof( fn prepare_message_proof(
params: MessageProofParams, params: MessageProofParams,
) -> (millau_messages::FromMillauMessagesProof, Weight) { ) -> (millau_messages::FromMillauMessagesProof, Weight) {
use crate::millau_messages::{Millau, WithMillauMessageBridge}; use crate::millau_messages::WithMillauMessageBridge;
use bp_messages::MessageKey; use bp_messages::MessageKey;
use bridge_runtime_common::{ use bridge_runtime_common::{
messages::ChainWithMessages, messages::MessageBridge,
messages_benchmarking::{ed25519_sign, prepare_message_proof}, messages_benchmarking::{ed25519_sign, prepare_message_proof},
}; };
use codec::Encode; use codec::Encode;
@@ -951,13 +951,12 @@ impl_runtime_apis! {
} }
let make_millau_message_key = |message_key: MessageKey| storage_keys::message_key::< let make_millau_message_key = |message_key: MessageKey| storage_keys::message_key::<
Runtime, <WithMillauMessageBridge as MessageBridge>::BridgedMessagesInstance,
<Millau as ChainWithMessages>::MessagesInstance,
>( >(
&message_key.lane_id, message_key.nonce, &message_key.lane_id, message_key.nonce,
).0; ).0;
let make_millau_outbound_lane_data_key = |lane_id| storage_keys::outbound_lane_data_key::< let make_millau_outbound_lane_data_key = |lane_id| storage_keys::outbound_lane_data_key::<
<Millau as ChainWithMessages>::MessagesInstance, <WithMillauMessageBridge as MessageBridge>::BridgedMessagesInstance,
>( >(
&lane_id, &lane_id,
).0; ).0;
@@ -998,18 +997,14 @@ impl_runtime_apis! {
fn prepare_message_delivery_proof( fn prepare_message_delivery_proof(
params: MessageDeliveryProofParams<Self::AccountId>, params: MessageDeliveryProofParams<Self::AccountId>,
) -> millau_messages::ToMillauMessagesDeliveryProof { ) -> millau_messages::ToMillauMessagesDeliveryProof {
use crate::millau_messages::{Millau, WithMillauMessageBridge}; use crate::millau_messages::WithMillauMessageBridge;
use bridge_runtime_common::{ use bridge_runtime_common::{messages_benchmarking::prepare_message_delivery_proof};
messages::ChainWithMessages,
messages_benchmarking::prepare_message_delivery_proof,
};
use sp_runtime::traits::Header; use sp_runtime::traits::Header;
prepare_message_delivery_proof::<WithMillauMessageBridge, bp_millau::Hasher, Runtime, (), _, _>( prepare_message_delivery_proof::<WithMillauMessageBridge, bp_millau::Hasher, Runtime, (), _, _>(
params, params,
|lane_id| pallet_bridge_messages::storage_keys::inbound_lane_data_key::< |lane_id| pallet_bridge_messages::storage_keys::inbound_lane_data_key::<
Runtime, <WithMillauMessageBridge as MessageBridge>::BridgedMessagesInstance,
<Millau as ChainWithMessages>::MessagesInstance,
>( >(
&lane_id, &lane_id,
).0, ).0,
@@ -52,7 +52,7 @@ pub type ToMillauMessageVerifier = messages::source::FromThisChainMessageVerifie
pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload<WithMillauMessageBridge>; pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload<WithMillauMessageBridge>;
/// Encoded Rialto Call as it comes from Millau. /// Encoded Rialto Call as it comes from Millau.
pub type FromMillauEncodedCall = messages::target::FromBridgedChainEncodedMessageCall<WithMillauMessageBridge>; pub type FromMillauEncodedCall = messages::target::FromBridgedChainEncodedMessageCall<crate::Call>;
/// Call-dispatch based message dispatch for Millau -> Rialto messages. /// Call-dispatch based message dispatch for Millau -> Rialto messages.
pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDispatch< pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDispatch<
@@ -74,9 +74,12 @@ pub struct WithMillauMessageBridge;
impl MessageBridge for WithMillauMessageBridge { impl MessageBridge for WithMillauMessageBridge {
const RELAYER_FEE_PERCENT: u32 = 10; const RELAYER_FEE_PERCENT: u32 = 10;
const THIS_CHAIN_ID: ChainId = RIALTO_CHAIN_ID;
const BRIDGED_CHAIN_ID: ChainId = MILLAU_CHAIN_ID;
type ThisChain = Rialto; type ThisChain = Rialto;
type BridgedChain = Millau; type BridgedChain = Millau;
type BridgedMessagesInstance = crate::WithMillauMessagesInstance;
fn bridged_balance_to_this_balance(bridged_balance: bp_millau::Balance) -> bp_rialto::Balance { fn bridged_balance_to_this_balance(bridged_balance: bp_millau::Balance) -> bp_rialto::Balance {
bp_rialto::Balance::try_from(MillauToRialtoConversionRate::get().saturating_mul_int(bridged_balance)) bp_rialto::Balance::try_from(MillauToRialtoConversionRate::get().saturating_mul_int(bridged_balance))
@@ -89,16 +92,12 @@ impl MessageBridge for WithMillauMessageBridge {
pub struct Rialto; pub struct Rialto;
impl messages::ChainWithMessages for Rialto { impl messages::ChainWithMessages for Rialto {
const ID: ChainId = RIALTO_CHAIN_ID;
type Hash = bp_rialto::Hash; type Hash = bp_rialto::Hash;
type AccountId = bp_rialto::AccountId; type AccountId = bp_rialto::AccountId;
type Signer = bp_rialto::AccountSigner; type Signer = bp_rialto::AccountSigner;
type Signature = bp_rialto::Signature; type Signature = bp_rialto::Signature;
type Weight = Weight; type Weight = Weight;
type Balance = bp_rialto::Balance; type Balance = bp_rialto::Balance;
type MessagesInstance = crate::WithMillauMessagesInstance;
} }
impl messages::ThisChainWithMessages for Rialto { impl messages::ThisChainWithMessages for Rialto {
@@ -145,16 +144,12 @@ impl messages::ThisChainWithMessages for Rialto {
pub struct Millau; pub struct Millau;
impl messages::ChainWithMessages for Millau { impl messages::ChainWithMessages for Millau {
const ID: ChainId = MILLAU_CHAIN_ID;
type Hash = bp_millau::Hash; type Hash = bp_millau::Hash;
type AccountId = bp_millau::AccountId; type AccountId = bp_millau::AccountId;
type Signer = bp_millau::AccountSigner; type Signer = bp_millau::AccountSigner;
type Signature = bp_millau::Signature; type Signature = bp_millau::Signature;
type Weight = Weight; type Weight = Weight;
type Balance = bp_millau::Balance; type Balance = bp_millau::Balance;
type MessagesInstance = pallet_bridge_messages::DefaultInstance;
} }
impl messages::BridgedChainWithMessages for Millau { impl messages::BridgedChainWithMessages for Millau {
+36 -43
View File
@@ -49,10 +49,17 @@ pub trait MessageBridge {
/// Relayer interest (in percents). /// Relayer interest (in percents).
const RELAYER_FEE_PERCENT: u32; const RELAYER_FEE_PERCENT: u32;
/// Identifier of this chain.
const THIS_CHAIN_ID: ChainId;
/// Identifier of the Bridged chain.
const BRIDGED_CHAIN_ID: ChainId;
/// This chain in context of message bridge. /// This chain in context of message bridge.
type ThisChain: ThisChainWithMessages; type ThisChain: ThisChainWithMessages;
/// Bridged chain in context of message bridge. /// Bridged chain in context of message bridge.
type BridgedChain: BridgedChainWithMessages; type BridgedChain: BridgedChainWithMessages;
/// Instance of the `pallet-bridge-messages` pallet at the Bridged chain.
type BridgedMessagesInstance: Instance;
/// Convert Bridged chain balance into This chain balance. /// Convert Bridged chain balance into This chain balance.
fn bridged_balance_to_this_balance(bridged_balance: BalanceOf<BridgedChain<Self>>) -> BalanceOf<ThisChain<Self>>; fn bridged_balance_to_this_balance(bridged_balance: BalanceOf<BridgedChain<Self>>) -> BalanceOf<ThisChain<Self>>;
@@ -60,9 +67,6 @@ pub trait MessageBridge {
/// Chain that has `pallet-bridge-messages` and `dispatch` modules. /// Chain that has `pallet-bridge-messages` and `dispatch` modules.
pub trait ChainWithMessages { pub trait ChainWithMessages {
/// Identifier of this chain.
const ID: ChainId;
/// Hash used in the chain. /// Hash used in the chain.
type Hash: Decode; type Hash: Decode;
/// Accound id on the chain. /// Accound id on the chain.
@@ -78,9 +82,6 @@ pub trait ChainWithMessages {
type Weight: From<frame_support::weights::Weight> + PartialOrd; type Weight: From<frame_support::weights::Weight> + PartialOrd;
/// Type of balances that is used on the chain. /// Type of balances that is used on the chain.
type Balance: Encode + Decode + CheckedAdd + CheckedDiv + CheckedMul + PartialOrd + From<u32> + Copy; type Balance: Encode + Decode + CheckedAdd + CheckedDiv + CheckedMul + PartialOrd + From<u32> + Copy;
/// Instance of the `pallet-bridge-messages` pallet.
type MessagesInstance: Instance;
} }
/// Message related transaction parameters estimation. /// Message related transaction parameters estimation.
@@ -147,7 +148,6 @@ pub(crate) type SignerOf<C> = <C as ChainWithMessages>::Signer;
pub(crate) type SignatureOf<C> = <C as ChainWithMessages>::Signature; pub(crate) type SignatureOf<C> = <C as ChainWithMessages>::Signature;
pub(crate) type WeightOf<C> = <C as ChainWithMessages>::Weight; pub(crate) type WeightOf<C> = <C as ChainWithMessages>::Weight;
pub(crate) type BalanceOf<C> = <C as ChainWithMessages>::Balance; pub(crate) type BalanceOf<C> = <C as ChainWithMessages>::Balance;
pub(crate) type MessagesInstanceOf<C> = <C as ChainWithMessages>::MessagesInstance;
pub(crate) type CallOf<C> = <C as ThisChainWithMessages>::Call; pub(crate) type CallOf<C> = <C as ThisChainWithMessages>::Call;
@@ -376,7 +376,6 @@ pub mod source {
) -> Result<ParsedMessagesDeliveryProofFromBridgedChain<B>, &'static str> ) -> Result<ParsedMessagesDeliveryProofFromBridgedChain<B>, &'static str>
where where
ThisRuntime: pallet_bridge_grandpa::Config<GrandpaInstance>, ThisRuntime: pallet_bridge_grandpa::Config<GrandpaInstance>,
ThisRuntime: pallet_bridge_messages::Config<MessagesInstanceOf<BridgedChain<B>>>,
HashOf<BridgedChain<B>>: HashOf<BridgedChain<B>>:
Into<bp_runtime::HashOf<<ThisRuntime as pallet_bridge_grandpa::Config<GrandpaInstance>>::BridgedChain>>, Into<bp_runtime::HashOf<<ThisRuntime as pallet_bridge_grandpa::Config<GrandpaInstance>>::BridgedChain>>,
{ {
@@ -391,10 +390,8 @@ pub mod source {
|storage| { |storage| {
// Messages delivery proof is just proof of single storage key read => any error // Messages delivery proof is just proof of single storage key read => any error
// is fatal. // is fatal.
let storage_inbound_lane_data_key = pallet_bridge_messages::storage_keys::inbound_lane_data_key::< let storage_inbound_lane_data_key =
ThisRuntime, pallet_bridge_messages::storage_keys::inbound_lane_data_key::<B::BridgedMessagesInstance>(&lane);
MessagesInstanceOf<BridgedChain<B>>,
>(&lane);
let raw_inbound_lane_data = storage let raw_inbound_lane_data = storage
.read_value(storage_inbound_lane_data_key.0.as_ref()) .read_value(storage_inbound_lane_data_key.0.as_ref())
.map_err(|_| "Failed to read inbound lane state from storage proof")? .map_err(|_| "Failed to read inbound lane state from storage proof")?
@@ -425,7 +422,7 @@ pub mod target {
AccountIdOf<BridgedChain<B>>, AccountIdOf<BridgedChain<B>>,
SignerOf<ThisChain<B>>, SignerOf<ThisChain<B>>,
SignatureOf<ThisChain<B>>, SignatureOf<ThisChain<B>>,
FromBridgedChainEncodedMessageCall<B>, FromBridgedChainEncodedMessageCall<CallOf<ThisChain<B>>>,
>; >;
/// Messages proof from bridged chain: /// Messages proof from bridged chain:
@@ -463,12 +460,12 @@ pub mod target {
/// Our Call is opaque (`Vec<u8>`) for Bridged chain. So it is encoded, prefixed with /// Our Call is opaque (`Vec<u8>`) for Bridged chain. So it is encoded, prefixed with
/// vector length. Custom decode implementation here is exactly to deal with this. /// vector length. Custom decode implementation here is exactly to deal with this.
#[derive(Decode, Encode, RuntimeDebug, PartialEq)] #[derive(Decode, Encode, RuntimeDebug, PartialEq)]
pub struct FromBridgedChainEncodedMessageCall<B> { pub struct FromBridgedChainEncodedMessageCall<DecodedCall> {
encoded_call: Vec<u8>, encoded_call: Vec<u8>,
_marker: PhantomData<B>, _marker: PhantomData<DecodedCall>,
} }
impl<B: MessageBridge> FromBridgedChainEncodedMessageCall<B> { impl<DecodedCall> FromBridgedChainEncodedMessageCall<DecodedCall> {
/// Create encoded call. /// Create encoded call.
pub fn new(encoded_call: Vec<u8>) -> Self { pub fn new(encoded_call: Vec<u8>) -> Self {
FromBridgedChainEncodedMessageCall { FromBridgedChainEncodedMessageCall {
@@ -478,9 +475,9 @@ pub mod target {
} }
} }
impl<B: MessageBridge> From<FromBridgedChainEncodedMessageCall<B>> for Result<CallOf<ThisChain<B>>, ()> { impl<DecodedCall: Decode> From<FromBridgedChainEncodedMessageCall<DecodedCall>> for Result<DecodedCall, ()> {
fn from(encoded_call: FromBridgedChainEncodedMessageCall<B>) -> Self { fn from(encoded_call: FromBridgedChainEncodedMessageCall<DecodedCall>) -> Self {
CallOf::<ThisChain<B>>::decode(&mut &encoded_call.encoded_call[..]).map_err(drop) DecodedCall::decode(&mut &encoded_call.encoded_call[..]).map_err(drop)
} }
} }
@@ -523,8 +520,8 @@ pub mod target {
) -> MessageDispatchResult { ) -> MessageDispatchResult {
let message_id = (message.key.lane_id, message.key.nonce); let message_id = (message.key.lane_id, message.key.nonce);
pallet_bridge_dispatch::Pallet::<ThisRuntime, ThisDispatchInstance>::dispatch( pallet_bridge_dispatch::Pallet::<ThisRuntime, ThisDispatchInstance>::dispatch(
B::BridgedChain::ID, B::BRIDGED_CHAIN_ID,
B::ThisChain::ID, B::THIS_CHAIN_ID,
message_id, message_id,
message.data.payload.map_err(drop), message.data.payload.map_err(drop),
|dispatch_origin, dispatch_weight| { |dispatch_origin, dispatch_weight| {
@@ -561,7 +558,7 @@ pub mod target {
) -> Result<ProvedMessages<Message<BalanceOf<BridgedChain<B>>>>, &'static str> ) -> Result<ProvedMessages<Message<BalanceOf<BridgedChain<B>>>>, &'static str>
where where
ThisRuntime: pallet_bridge_grandpa::Config<GrandpaInstance>, ThisRuntime: pallet_bridge_grandpa::Config<GrandpaInstance>,
ThisRuntime: pallet_bridge_messages::Config<MessagesInstanceOf<BridgedChain<B>>>, ThisRuntime: pallet_bridge_messages::Config<B::BridgedMessagesInstance>,
HashOf<BridgedChain<B>>: HashOf<BridgedChain<B>>:
Into<bp_runtime::HashOf<<ThisRuntime as pallet_bridge_grandpa::Config<GrandpaInstance>>::BridgedChain>>, Into<bp_runtime::HashOf<<ThisRuntime as pallet_bridge_grandpa::Config<GrandpaInstance>>::BridgedChain>>,
{ {
@@ -574,7 +571,7 @@ pub mod target {
StorageProof::new(bridged_storage_proof), StorageProof::new(bridged_storage_proof),
|storage_adapter| storage_adapter, |storage_adapter| storage_adapter,
) )
.map(|storage| StorageProofCheckerAdapter::<_, B, ThisRuntime> { .map(|storage| StorageProofCheckerAdapter::<_, B> {
storage, storage,
_dummy: Default::default(), _dummy: Default::default(),
}) })
@@ -614,31 +611,29 @@ pub mod target {
fn read_raw_message(&self, message_key: &MessageKey) -> Option<Vec<u8>>; fn read_raw_message(&self, message_key: &MessageKey) -> Option<Vec<u8>>;
} }
struct StorageProofCheckerAdapter<H: Hasher, B, ThisRuntime> { struct StorageProofCheckerAdapter<H: Hasher, B> {
storage: StorageProofChecker<H>, storage: StorageProofChecker<H>,
_dummy: sp_std::marker::PhantomData<(B, ThisRuntime)>, _dummy: sp_std::marker::PhantomData<B>,
} }
impl<H, B, ThisRuntime> MessageProofParser for StorageProofCheckerAdapter<H, B, ThisRuntime> impl<H, B> MessageProofParser for StorageProofCheckerAdapter<H, B>
where where
H: Hasher, H: Hasher,
B: MessageBridge, B: MessageBridge,
ThisRuntime: pallet_bridge_messages::Config<MessagesInstanceOf<BridgedChain<B>>>,
{ {
fn read_raw_outbound_lane_data(&self, lane_id: &LaneId) -> Option<Vec<u8>> { fn read_raw_outbound_lane_data(&self, lane_id: &LaneId) -> Option<Vec<u8>> {
let storage_outbound_lane_data_key = pallet_bridge_messages::storage_keys::outbound_lane_data_key::< let storage_outbound_lane_data_key =
MessagesInstanceOf<BridgedChain<B>>, pallet_bridge_messages::storage_keys::outbound_lane_data_key::<B::BridgedMessagesInstance>(lane_id);
>(lane_id);
self.storage self.storage
.read_value(storage_outbound_lane_data_key.0.as_ref()) .read_value(storage_outbound_lane_data_key.0.as_ref())
.ok()? .ok()?
} }
fn read_raw_message(&self, message_key: &MessageKey) -> Option<Vec<u8>> { fn read_raw_message(&self, message_key: &MessageKey) -> Option<Vec<u8>> {
let storage_message_key = pallet_bridge_messages::storage_keys::message_key::< let storage_message_key = pallet_bridge_messages::storage_keys::message_key::<B::BridgedMessagesInstance>(
ThisRuntime, &message_key.lane_id,
MessagesInstanceOf<BridgedChain<B>>, message_key.nonce,
>(&message_key.lane_id, message_key.nonce); );
self.storage.read_value(storage_message_key.0.as_ref()).ok()? self.storage.read_value(storage_message_key.0.as_ref()).ok()?
} }
} }
@@ -743,9 +738,12 @@ mod tests {
impl MessageBridge for OnThisChainBridge { impl MessageBridge for OnThisChainBridge {
const RELAYER_FEE_PERCENT: u32 = 10; const RELAYER_FEE_PERCENT: u32 = 10;
const THIS_CHAIN_ID: ChainId = *b"this";
const BRIDGED_CHAIN_ID: ChainId = *b"brdg";
type ThisChain = ThisChain; type ThisChain = ThisChain;
type BridgedChain = BridgedChain; type BridgedChain = BridgedChain;
type BridgedMessagesInstance = pallet_bridge_messages::DefaultInstance;
fn bridged_balance_to_this_balance(bridged_balance: BridgedChainBalance) -> ThisChainBalance { fn bridged_balance_to_this_balance(bridged_balance: BridgedChainBalance) -> ThisChainBalance {
ThisChainBalance(bridged_balance.0 * BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE as u32) ThisChainBalance(bridged_balance.0 * BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE as u32)
@@ -758,9 +756,12 @@ mod tests {
impl MessageBridge for OnBridgedChainBridge { impl MessageBridge for OnBridgedChainBridge {
const RELAYER_FEE_PERCENT: u32 = 20; const RELAYER_FEE_PERCENT: u32 = 20;
const THIS_CHAIN_ID: ChainId = *b"brdg";
const BRIDGED_CHAIN_ID: ChainId = *b"this";
type ThisChain = BridgedChain; type ThisChain = BridgedChain;
type BridgedChain = ThisChain; type BridgedChain = ThisChain;
type BridgedMessagesInstance = pallet_bridge_messages::DefaultInstance;
fn bridged_balance_to_this_balance(_this_balance: ThisChainBalance) -> BridgedChainBalance { fn bridged_balance_to_this_balance(_this_balance: ThisChainBalance) -> BridgedChainBalance {
unreachable!() unreachable!()
@@ -857,16 +858,12 @@ mod tests {
struct ThisChain; struct ThisChain;
impl ChainWithMessages for ThisChain { impl ChainWithMessages for ThisChain {
const ID: ChainId = *b"this";
type Hash = (); type Hash = ();
type AccountId = ThisChainAccountId; type AccountId = ThisChainAccountId;
type Signer = ThisChainSigner; type Signer = ThisChainSigner;
type Signature = ThisChainSignature; type Signature = ThisChainSignature;
type Weight = frame_support::weights::Weight; type Weight = frame_support::weights::Weight;
type Balance = ThisChainBalance; type Balance = ThisChainBalance;
type MessagesInstance = pallet_bridge_messages::DefaultInstance;
} }
impl ThisChainWithMessages for ThisChain { impl ThisChainWithMessages for ThisChain {
@@ -917,16 +914,12 @@ mod tests {
struct BridgedChain; struct BridgedChain;
impl ChainWithMessages for BridgedChain { impl ChainWithMessages for BridgedChain {
const ID: ChainId = *b"brdg";
type Hash = (); type Hash = ();
type AccountId = BridgedChainAccountId; type AccountId = BridgedChainAccountId;
type Signer = BridgedChainSigner; type Signer = BridgedChainSigner;
type Signature = BridgedChainSignature; type Signature = BridgedChainSignature;
type Weight = frame_support::weights::Weight; type Weight = frame_support::weights::Weight;
type Balance = BridgedChainBalance; type Balance = BridgedChainBalance;
type MessagesInstance = pallet_bridge_messages::DefaultInstance;
} }
impl ThisChainWithMessages for BridgedChain { impl ThisChainWithMessages for BridgedChain {
@@ -1002,7 +995,7 @@ mod tests {
weight: 100, weight: 100,
origin: bp_message_dispatch::CallOrigin::SourceRoot, origin: bp_message_dispatch::CallOrigin::SourceRoot,
dispatch_fee_payment: DispatchFeePayment::AtTargetChain, dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
call: target::FromBridgedChainEncodedMessageCall::<OnThisChainBridge>::new( call: target::FromBridgedChainEncodedMessageCall::<ThisChainCall>::new(
ThisChainCall::Transfer.encode(), ThisChainCall::Transfer.encode(),
), ),
} }
+24 -10
View File
@@ -755,24 +755,38 @@ impl<T: Config<I>, I: Instance> Pallet<T, I> {
/// trying to avoid here) - by using strings like "Instance2", "OutboundMessages", etc. /// trying to avoid here) - by using strings like "Instance2", "OutboundMessages", etc.
pub mod storage_keys { pub mod storage_keys {
use super::*; use super::*;
use frame_support::storage::generator::StorageMap; use frame_support::{traits::Instance, StorageHasher};
use sp_core::storage::StorageKey; use sp_core::storage::StorageKey;
/// Storage key of the outbound message in the runtime storage. /// Storage key of the outbound message in the runtime storage.
pub fn message_key<T: Config<I>, I: Instance>(lane: &LaneId, nonce: MessageNonce) -> StorageKey { pub fn message_key<I: Instance>(lane: &LaneId, nonce: MessageNonce) -> StorageKey {
let message_key = MessageKey { lane_id: *lane, nonce }; storage_map_final_key::<I>("OutboundMessages", &MessageKey { lane_id: *lane, nonce }.encode())
let raw_storage_key = OutboundMessages::<T, I>::storage_map_final_key(message_key);
StorageKey(raw_storage_key)
} }
/// Storage key of the outbound message lane state in the runtime storage. /// Storage key of the outbound message lane state in the runtime storage.
pub fn outbound_lane_data_key<I: Instance>(lane: &LaneId) -> StorageKey { pub fn outbound_lane_data_key<I: Instance>(lane: &LaneId) -> StorageKey {
StorageKey(OutboundLanes::<I>::storage_map_final_key(*lane)) storage_map_final_key::<I>("OutboundLanes", lane)
} }
/// Storage key of the inbound message lane state in the runtime storage. /// Storage key of the inbound message lane state in the runtime storage.
pub fn inbound_lane_data_key<T: Config<I>, I: Instance>(lane: &LaneId) -> StorageKey { pub fn inbound_lane_data_key<I: Instance>(lane: &LaneId) -> StorageKey {
StorageKey(InboundLanes::<T, I>::storage_map_final_key(*lane)) storage_map_final_key::<I>("InboundLanes", lane)
}
/// This is a copypaste of the `frame_support::storage::generator::StorageMap::storage_map_final_key`.
fn storage_map_final_key<I: Instance>(map_name: &str, key: &[u8]) -> StorageKey {
let module_prefix_hashed = frame_support::Twox128::hash(I::PREFIX.as_bytes());
let storage_prefix_hashed = frame_support::Twox128::hash(map_name.as_bytes());
let key_hashed = frame_support::Blake2_128Concat::hash(key);
let mut final_key =
Vec::with_capacity(module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.len());
final_key.extend_from_slice(&module_prefix_hashed[..]);
final_key.extend_from_slice(&storage_prefix_hashed[..]);
final_key.extend_from_slice(key_hashed.as_ref());
StorageKey(final_key)
} }
} }
@@ -1685,7 +1699,7 @@ mod tests {
fn storage_message_key_computed_properly() { fn storage_message_key_computed_properly() {
// If this test fails, then something has been changed in module storage that is breaking all // If this test fails, then something has been changed in module storage that is breaking all
// previously crafted messages proofs. // previously crafted messages proofs.
let storage_key = storage_keys::message_key::<TestRuntime, DefaultInstance>(&*b"test", 42).0; let storage_key = storage_keys::message_key::<DefaultInstance>(&*b"test", 42).0;
assert_eq!( assert_eq!(
storage_key, storage_key,
hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea79446af0e09063bd4a7874aef8a997cec746573742a00000000000000").to_vec(), hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea79446af0e09063bd4a7874aef8a997cec746573742a00000000000000").to_vec(),
@@ -1711,7 +1725,7 @@ mod tests {
fn inbound_lane_data_key_computed_properly() { fn inbound_lane_data_key_computed_properly() {
// If this test fails, then something has been changed in module storage that is breaking all // If this test fails, then something has been changed in module storage that is breaking all
// previously crafted inbound lane state proofs. // previously crafted inbound lane state proofs.
let storage_key = storage_keys::inbound_lane_data_key::<TestRuntime, DefaultInstance>(&*b"test").0; let storage_key = storage_keys::inbound_lane_data_key::<DefaultInstance>(&*b"test").0;
assert_eq!( assert_eq!(
storage_key, storage_key,
hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fab44a8995dd50b6657a037a7839304535b74657374").to_vec(), hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fab44a8995dd50b6657a037a7839304535b74657374").to_vec(),
@@ -11,7 +11,6 @@ parity-scale-codec = { version = "2.0.0", default-features = false, features = [
smallvec = "1.6" smallvec = "1.6"
# Bridge Dependencies # Bridge Dependencies
bp-header-chain = { path = "../header-chain", default-features = false }
bp-messages = { path = "../messages", default-features = false } bp-messages = { path = "../messages", default-features = false }
bp-polkadot-core = { path = "../polkadot-core", default-features = false } bp-polkadot-core = { path = "../polkadot-core", default-features = false }
bp-runtime = { path = "../runtime", default-features = false } bp-runtime = { path = "../runtime", default-features = false }
@@ -26,7 +25,6 @@ sp-version = { git = "https://github.com/paritytech/substrate", branch = "master
[features] [features]
default = ["std"] default = ["std"]
std = [ std = [
"bp-header-chain/std",
"bp-messages/std", "bp-messages/std",
"bp-polkadot-core/std", "bp-polkadot-core/std",
"bp-runtime/std", "bp-runtime/std",
+11 -40
View File
@@ -21,7 +21,6 @@
#![allow(clippy::unnecessary_mut_passed)] #![allow(clippy::unnecessary_mut_passed)]
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState}; use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
use bp_runtime::Chain;
use frame_support::weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial}; use frame_support::weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial};
use sp_std::prelude::*; use sp_std::prelude::*;
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
@@ -31,7 +30,12 @@ pub use bp_polkadot_core::*;
/// Rococo Chain /// Rococo Chain
pub type Rococo = PolkadotLike; pub type Rococo = PolkadotLike;
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>; /// The target length of a session (how often authorities change) on Westend measured in of number of
/// blocks.
///
/// Note that since this is a target sessions may change before/after this time depending on network
/// conditions.
pub const SESSION_LENGTH: BlockNumber = 10 * time_units::MINUTES;
// NOTE: This needs to be kept up to date with the Rococo runtime found in the Polkadot repo. // NOTE: This needs to be kept up to date with the Rococo runtime found in the Polkadot repo.
pub const VERSION: RuntimeVersion = RuntimeVersion { pub const VERSION: RuntimeVersion = RuntimeVersion {
@@ -61,44 +65,11 @@ impl WeightToFeePolynomial for WeightToFee {
} }
} }
/// Rococo Runtime `Call` enum. // We use this to get the account on Rococo (target) which is derived from Wococo's (source)
/// // account.
/// The enum represents a subset of possible `Call`s we can send to Rococo chain. pub fn derive_account_from_wococo_id(id: bp_runtime::SourceAccount<AccountId>) -> AccountId {
/// Ideally this code would be auto-generated from Metadata, because we want to let encoded_id = bp_runtime::derive_account_id(bp_runtime::WOCOCO_CHAIN_ID, id);
/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s. AccountIdConverter::convert(encoded_id)
///
/// All entries here (like pretty much in the entire file) must be kept in sync with Rococo
/// `construct_runtime`, so that we maintain SCALE-compatibility.
///
/// See: https://github.com/paritytech/polkadot/blob/master/runtime/rococo/src/lib.rs
#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, Debug, PartialEq, Eq, Clone)]
pub enum Call {
/// Wococo bridge pallet.
#[codec(index = 41)]
BridgeGrandpaWococo(BridgeGrandpaWococoCall),
}
#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, Debug, PartialEq, Eq, Clone)]
#[allow(non_camel_case_types)]
pub enum BridgeGrandpaWococoCall {
#[codec(index = 0)]
submit_finality_proof(
<PolkadotLike as Chain>::Header,
bp_header_chain::justification::GrandpaJustification<<PolkadotLike as Chain>::Header>,
),
#[codec(index = 1)]
initialize(bp_header_chain::InitializationData<<PolkadotLike as Chain>::Header>),
}
impl sp_runtime::traits::Dispatchable for Call {
type Origin = ();
type Config = ();
type Info = ();
type PostInfo = ();
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
unimplemented!("The Call is not expected to be dispatched.")
}
} }
/// Name of the `RococoFinalityApi::best_finalized` runtime method. /// Name of the `RococoFinalityApi::best_finalized` runtime method.
@@ -10,7 +10,6 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
parity-scale-codec = { version = "2.0.0", default-features = false, features = ["derive"] } parity-scale-codec = { version = "2.0.0", default-features = false, features = ["derive"] }
# Bridge Dependencies # Bridge Dependencies
bp-header-chain = { path = "../header-chain", default-features = false }
bp-messages = { path = "../messages", default-features = false } bp-messages = { path = "../messages", default-features = false }
bp-polkadot-core = { path = "../polkadot-core", default-features = false } bp-polkadot-core = { path = "../polkadot-core", default-features = false }
bp-rococo = { path = "../chain-rococo", default-features = false } bp-rococo = { path = "../chain-rococo", default-features = false }
@@ -24,7 +23,6 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", d
[features] [features]
default = ["std"] default = ["std"]
std = [ std = [
"bp-header-chain/std",
"bp-messages/std", "bp-messages/std",
"bp-polkadot-core/std", "bp-polkadot-core/std",
"bp-runtime/std", "bp-runtime/std",
+1 -44
View File
@@ -21,58 +21,15 @@
#![allow(clippy::unnecessary_mut_passed)] #![allow(clippy::unnecessary_mut_passed)]
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState}; use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
use bp_runtime::Chain;
use sp_std::prelude::*; use sp_std::prelude::*;
pub use bp_polkadot_core::*; pub use bp_polkadot_core::*;
// Rococo runtime = Wococo runtime // Rococo runtime = Wococo runtime
pub use bp_rococo::{WeightToFee, VERSION}; pub use bp_rococo::{WeightToFee, SESSION_LENGTH, VERSION};
/// Wococo Chain /// Wococo Chain
pub type Wococo = PolkadotLike; pub type Wococo = PolkadotLike;
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
/// Wococo Runtime `Call` enum.
///
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
/// Ideally this code would be auto-generated from Metadata, because we want to
/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s.
///
/// All entries here (like pretty much in the entire file) must be kept in sync with Rococo
/// `construct_runtime`, so that we maintain SCALE-compatibility.
///
/// See: https://github.com/paritytech/polkadot/blob/master/runtime/rococo/src/lib.rs
#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, Debug, PartialEq, Eq, Clone)]
pub enum Call {
/// Rococo bridge pallet.
#[codec(index = 40)]
BridgeGrandpaRococo(BridgeGrandpaRococoCall),
}
#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, Debug, PartialEq, Eq, Clone)]
#[allow(non_camel_case_types)]
pub enum BridgeGrandpaRococoCall {
#[codec(index = 0)]
submit_finality_proof(
<PolkadotLike as Chain>::Header,
bp_header_chain::justification::GrandpaJustification<<PolkadotLike as Chain>::Header>,
),
#[codec(index = 1)]
initialize(bp_header_chain::InitializationData<<PolkadotLike as Chain>::Header>),
}
impl sp_runtime::traits::Dispatchable for Call {
type Origin = ();
type Config = ();
type Info = ();
type PostInfo = ();
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
unimplemented!("The Call is not expected to be dispatched.")
}
}
// We use this to get the account on Wococo (target) which is derived from Rococo's (source) // We use this to get the account on Wococo (target) which is derived from Rococo's (source)
// account. // account.
pub fn derive_account_from_rococo_id(id: bp_runtime::SourceAccount<AccountId>) -> AccountId { pub fn derive_account_from_rococo_id(id: bp_runtime::SourceAccount<AccountId>) -> AccountId {
+4
View File
@@ -64,6 +64,10 @@ pub trait Parameter: frame_support::Parameter {
fn save(&self); fn save(&self);
} }
impl Parameter for () {
fn save(&self) {}
}
/// Lane identifier. /// Lane identifier.
pub type LaneId = [u8; 4]; pub type LaneId = [u8; 4];
@@ -23,7 +23,7 @@ use crate::cli::{
}; };
use bp_message_dispatch::{CallOrigin, MessagePayload}; use bp_message_dispatch::{CallOrigin, MessagePayload};
use codec::Decode; use codec::Decode;
use frame_support::weights::{GetDispatchInfo, Weight}; use frame_support::weights::{DispatchInfo, GetDispatchInfo, Weight};
use relay_millau_client::Millau; use relay_millau_client::Millau;
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
@@ -62,6 +62,10 @@ impl CliEncodeCall for Millau {
}, },
}) })
} }
fn get_dispatch_info(call: &millau_runtime::Call) -> anyhow::Result<DispatchInfo> {
Ok(call.get_dispatch_info())
}
} }
impl CliChain for Millau { impl CliChain for Millau {
@@ -126,20 +126,12 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
} }
/// Millau node as messages source. /// Millau node as messages source.
type MillauSourceClient = SubstrateMessagesSource< type MillauSourceClient =
Millau, SubstrateMessagesSource<Millau, MillauMessagesToRialto, millau_runtime::WithRialtoMessagesInstance>;
MillauMessagesToRialto,
millau_runtime::Runtime,
millau_runtime::WithRialtoMessagesInstance,
>;
/// Rialto node as messages target. /// Rialto node as messages target.
type RialtoTargetClient = SubstrateMessagesTarget< type RialtoTargetClient =
Rialto, SubstrateMessagesTarget<Rialto, MillauMessagesToRialto, rialto_runtime::WithMillauMessagesInstance>;
MillauMessagesToRialto,
rialto_runtime::Runtime,
rialto_runtime::WithMillauMessagesInstance,
>;
/// Run Millau-to-Rialto messages sync. /// Run Millau-to-Rialto messages sync.
pub async fn run( pub async fn run(
@@ -21,8 +21,10 @@ pub mod millau_messages_to_rialto;
pub mod rialto_headers_to_millau; pub mod rialto_headers_to_millau;
pub mod rialto_messages_to_millau; pub mod rialto_messages_to_millau;
pub mod rococo_headers_to_wococo; pub mod rococo_headers_to_wococo;
pub mod rococo_messages_to_wococo;
pub mod westend_headers_to_millau; pub mod westend_headers_to_millau;
pub mod wococo_headers_to_rococo; pub mod wococo_headers_to_rococo;
pub mod wococo_messages_to_rococo;
mod millau; mod millau;
mod rialto; mod rialto;
@@ -271,7 +273,10 @@ mod rococo_tests {
votes_ancestries: vec![], votes_ancestries: vec![],
}; };
let actual = bp_rococo::BridgeGrandpaWococoCall::submit_finality_proof(header.clone(), justification.clone()); let actual = relay_rococo_client::runtime::BridgeGrandpaWococoCall::submit_finality_proof(
header.clone(),
justification.clone(),
);
let expected = millau_runtime::BridgeGrandpaRialtoCall::<millau_runtime::Runtime>::submit_finality_proof( let expected = millau_runtime::BridgeGrandpaRialtoCall::<millau_runtime::Runtime>::submit_finality_proof(
header, header,
justification, justification,
@@ -23,7 +23,7 @@ use crate::cli::{
}; };
use bp_message_dispatch::{CallOrigin, MessagePayload}; use bp_message_dispatch::{CallOrigin, MessagePayload};
use codec::Decode; use codec::Decode;
use frame_support::weights::{GetDispatchInfo, Weight}; use frame_support::weights::{DispatchInfo, GetDispatchInfo, Weight};
use relay_rialto_client::Rialto; use relay_rialto_client::Rialto;
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
@@ -60,6 +60,10 @@ impl CliEncodeCall for Rialto {
}, },
}) })
} }
fn get_dispatch_info(call: &rialto_runtime::Call) -> anyhow::Result<DispatchInfo> {
Ok(call.get_dispatch_info())
}
} }
impl CliChain for Rialto { impl CliChain for Rialto {
@@ -126,20 +126,12 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
} }
/// Rialto node as messages source. /// Rialto node as messages source.
type RialtoSourceClient = SubstrateMessagesSource< type RialtoSourceClient =
Rialto, SubstrateMessagesSource<Rialto, RialtoMessagesToMillau, rialto_runtime::WithMillauMessagesInstance>;
RialtoMessagesToMillau,
rialto_runtime::Runtime,
rialto_runtime::WithMillauMessagesInstance,
>;
/// Millau node as messages target. /// Millau node as messages target.
type MillauTargetClient = SubstrateMessagesTarget< type MillauTargetClient =
Millau, SubstrateMessagesTarget<Millau, RialtoMessagesToMillau, millau_runtime::WithRialtoMessagesInstance>;
RialtoMessagesToMillau,
millau_runtime::Runtime,
millau_runtime::WithRialtoMessagesInstance,
>;
/// Run Rialto-to-Millau messages sync. /// Run Rialto-to-Millau messages sync.
pub async fn run( pub async fn run(
@@ -14,11 +14,70 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>. // along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
use crate::cli::{encode_message, CliChain}; use codec::Decode;
use frame_support::weights::Weight; use frame_support::weights::{DispatchClass, DispatchInfo, Pays, Weight};
use relay_rococo_client::Rococo; use relay_rococo_client::Rococo;
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
use crate::cli::{
bridge,
encode_call::{Call, CliEncodeCall},
encode_message, CliChain,
};
/// Weight of the `system::remark` call at Rococo.
///
/// This weight is larger (x2) than actual weight at current Rooco runtime to avoid unsuccessful
/// calls in the future. But since it is used only in tests (and on test chains), this is ok.
pub(crate) const SYSTEM_REMARK_CALL_WEIGHT: Weight = 2 * 1_345_000;
impl CliEncodeCall for Rococo {
fn max_extrinsic_size() -> u32 {
bp_rococo::max_extrinsic_size()
}
fn encode_call(call: &Call) -> anyhow::Result<Self::Call> {
Ok(match call {
Call::Remark { remark_payload, .. } => {
relay_rococo_client::runtime::Call::System(relay_rococo_client::runtime::SystemCall::remark(
remark_payload.as_ref().map(|x| x.0.clone()).unwrap_or_default(),
))
}
Call::BridgeSendMessage {
lane,
payload,
fee,
bridge_instance_index,
} => match *bridge_instance_index {
bridge::ROCOCO_TO_WOCOCO_INDEX => {
let payload = Decode::decode(&mut &*payload.0)?;
relay_rococo_client::runtime::Call::BridgeMessagesWococo(
relay_rococo_client::runtime::BridgeMessagesWococoCall::send_message(lane.0, payload, fee.0),
)
}
_ => anyhow::bail!(
"Unsupported target bridge pallet with instance index: {}",
bridge_instance_index
),
},
_ => anyhow::bail!("The call is not supported"),
})
}
fn get_dispatch_info(call: &relay_rococo_client::runtime::Call) -> anyhow::Result<DispatchInfo> {
match *call {
relay_rococo_client::runtime::Call::System(relay_rococo_client::runtime::SystemCall::remark(_)) => {
Ok(DispatchInfo {
weight: SYSTEM_REMARK_CALL_WEIGHT,
class: DispatchClass::Normal,
pays_fee: Pays::Yes,
})
}
_ => anyhow::bail!("Unsupported Rococo call: {:?}", call),
}
}
}
impl CliChain for Rococo { impl CliChain for Rococo {
const RUNTIME_VERSION: RuntimeVersion = bp_rococo::VERSION; const RUNTIME_VERSION: RuntimeVersion = bp_rococo::VERSION;
@@ -30,7 +89,7 @@ impl CliChain for Rococo {
} }
fn max_extrinsic_weight() -> Weight { fn max_extrinsic_weight() -> Weight {
0 bp_wococo::max_extrinsic_weight()
} }
fn encode_message(_message: encode_message::MessagePayload) -> Result<Self::MessagePayload, String> { fn encode_message(_message: encode_message::MessagePayload) -> Result<Self::MessagePayload, String> {
@@ -61,10 +61,9 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
header: RococoSyncHeader, header: RococoSyncHeader,
proof: GrandpaJustification<bp_rococo::Header>, proof: GrandpaJustification<bp_rococo::Header>,
) -> Bytes { ) -> Bytes {
let call = bp_wococo::Call::BridgeGrandpaRococo(bp_wococo::BridgeGrandpaRococoCall::submit_finality_proof( let call = relay_wococo_client::runtime::Call::BridgeGrandpaRococo(
header.into_inner(), relay_wococo_client::runtime::BridgeGrandpaRococoCall::submit_finality_proof(header.into_inner(), proof),
proof, );
));
let genesis_hash = *self.target_client.genesis_hash(); let genesis_hash = *self.target_client.genesis_hash();
let transaction = Wococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); let transaction = Wococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call);
@@ -0,0 +1,227 @@
// Copyright 2019-2021 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 <http://www.gnu.org/licenses/>.
//! Rococo-to-Wococo messages sync entrypoint.
use crate::messages_lane::{
select_delivery_transaction_limits, MessagesRelayParams, SubstrateMessageLane, SubstrateMessageLaneToSubstrate,
};
use crate::messages_source::SubstrateMessagesSource;
use crate::messages_target::SubstrateMessagesTarget;
use bp_messages::MessageNonce;
use bp_runtime::{ROCOCO_CHAIN_ID, WOCOCO_CHAIN_ID};
use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof;
use codec::Encode;
use messages_relay::message_lane::MessageLane;
use relay_rococo_client::{HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams};
use relay_substrate_client::{metrics::StorageProofOverheadMetric, Chain, TransactionSignScheme};
use relay_wococo_client::{HeaderId as WococoHeaderId, SigningParams as WococoSigningParams, Wococo};
use sp_core::{Bytes, Pair};
use std::{ops::RangeInclusive, time::Duration};
/// Rococo-to-Wococo message lane.
pub type RococoMessagesToWococo =
SubstrateMessageLaneToSubstrate<Rococo, RococoSigningParams, Wococo, WococoSigningParams>;
impl SubstrateMessageLane for RococoMessagesToWococo {
const OUTBOUND_LANE_MESSAGE_DETAILS_METHOD: &'static str = bp_wococo::TO_WOCOCO_MESSAGE_DETAILS_METHOD;
const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str =
bp_wococo::TO_WOCOCO_LATEST_GENERATED_NONCE_METHOD;
const OUTBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_wococo::TO_WOCOCO_LATEST_RECEIVED_NONCE_METHOD;
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_rococo::FROM_ROCOCO_LATEST_RECEIVED_NONCE_METHOD;
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str =
bp_rococo::FROM_ROCOCO_LATEST_CONFIRMED_NONCE_METHOD;
const INBOUND_LANE_UNREWARDED_RELAYERS_STATE: &'static str = bp_rococo::FROM_ROCOCO_UNREWARDED_RELAYERS_STATE;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_rococo::BEST_FINALIZED_ROCOCO_HEADER_METHOD;
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_wococo::BEST_FINALIZED_WOCOCO_HEADER_METHOD;
type SourceChain = Rococo;
type TargetChain = Wococo;
fn source_transactions_author(&self) -> bp_rococo::AccountId {
(*self.source_sign.public().as_array_ref()).into()
}
fn make_messages_receiving_proof_transaction(
&self,
transaction_nonce: <Rococo as Chain>::Index,
_generated_at_block: WococoHeaderId,
proof: <Self as MessageLane>::MessagesReceivingProof,
) -> Bytes {
let (relayers_state, proof) = proof;
let call = relay_rococo_client::runtime::Call::BridgeMessagesWococo(
relay_rococo_client::runtime::BridgeMessagesWococoCall::receive_messages_delivery_proof(
proof,
relayers_state,
),
);
let genesis_hash = *self.source_client.genesis_hash();
let transaction = Rococo::sign_transaction(genesis_hash, &self.source_sign, transaction_nonce, call);
log::trace!(
target: "bridge",
"Prepared Wococo -> Rococo confirmation transaction. Weight: <unknown>/{}, size: {}/{}",
bp_rococo::max_extrinsic_weight(),
transaction.encode().len(),
bp_rococo::max_extrinsic_size(),
);
Bytes(transaction.encode())
}
fn target_transactions_author(&self) -> bp_wococo::AccountId {
(*self.target_sign.public().as_array_ref()).into()
}
fn make_messages_delivery_transaction(
&self,
transaction_nonce: <Wococo as Chain>::Index,
_generated_at_header: RococoHeaderId,
_nonces: RangeInclusive<MessageNonce>,
proof: <Self as MessageLane>::MessagesProof,
) -> Bytes {
let (dispatch_weight, proof) = proof;
let FromBridgedChainMessagesProof {
ref nonces_start,
ref nonces_end,
..
} = proof;
let messages_count = nonces_end - nonces_start + 1;
let call = relay_wococo_client::runtime::Call::BridgeMessagesRococo(
relay_wococo_client::runtime::BridgeMessagesRococoCall::receive_messages_proof(
self.relayer_id_at_source.clone(),
proof,
messages_count as _,
dispatch_weight,
),
);
let genesis_hash = *self.target_client.genesis_hash();
let transaction = Wococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call);
log::trace!(
target: "bridge",
"Prepared Rococo -> Wococo delivery transaction. Weight: <unknown>/{}, size: {}/{}",
bp_wococo::max_extrinsic_weight(),
transaction.encode().len(),
bp_wococo::max_extrinsic_size(),
);
Bytes(transaction.encode())
}
}
/// Rococo node as messages source.
type RococoSourceClient =
SubstrateMessagesSource<Rococo, RococoMessagesToWococo, relay_rococo_client::runtime::WithWococoMessagesInstance>;
/// Wococo node as messages target.
type WococoTargetClient =
SubstrateMessagesTarget<Wococo, RococoMessagesToWococo, relay_wococo_client::runtime::WithRococoMessagesInstance>;
/// Run Rococo-to-Wococo messages sync.
pub async fn run(
params: MessagesRelayParams<Rococo, RococoSigningParams, Wococo, WococoSigningParams>,
) -> Result<(), String> {
let stall_timeout = Duration::from_secs(5 * 60);
let relayer_id_at_rococo = (*params.source_sign.public().as_array_ref()).into();
let lane_id = params.lane_id;
let source_client = params.source_client;
let lane = RococoMessagesToWococo {
source_client: source_client.clone(),
source_sign: params.source_sign,
target_client: params.target_client.clone(),
target_sign: params.target_sign,
relayer_id_at_source: relayer_id_at_rococo,
};
// 2/3 is reserved for proofs and tx overhead
let max_messages_size_in_single_batch = bp_wococo::max_extrinsic_size() / 3;
// we don't know exact weights of the Wococo runtime. So to guess weights we'll be using
// weights from Rialto and then simply dividing it by x2.
let (max_messages_in_single_batch, max_messages_weight_in_single_batch) =
select_delivery_transaction_limits::<pallet_bridge_messages::weights::RialtoWeight<rialto_runtime::Runtime>>(
bp_wococo::max_extrinsic_weight(),
bp_wococo::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE,
);
let (max_messages_in_single_batch, max_messages_weight_in_single_batch) = (
max_messages_in_single_batch / 2,
max_messages_weight_in_single_batch / 2,
);
log::info!(
target: "bridge",
"Starting Rococo -> Wococo messages relay.\n\t\
Rococo relayer account id: {:?}\n\t\
Max messages in single transaction: {}\n\t\
Max messages size in single transaction: {}\n\t\
Max messages weight in single transaction: {}",
lane.relayer_id_at_source,
max_messages_in_single_batch,
max_messages_size_in_single_batch,
max_messages_weight_in_single_batch,
);
messages_relay::message_lane_loop::run(
messages_relay::message_lane_loop::Params {
lane: lane_id,
source_tick: Rococo::AVERAGE_BLOCK_INTERVAL,
target_tick: Wococo::AVERAGE_BLOCK_INTERVAL,
reconnect_delay: relay_utils::relay_loop::RECONNECT_DELAY,
stall_timeout,
delivery_params: messages_relay::message_lane_loop::MessageDeliveryParams {
max_unrewarded_relayer_entries_at_target: bp_wococo::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE,
max_unconfirmed_nonces_at_target: bp_wococo::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE,
max_messages_in_single_batch,
max_messages_weight_in_single_batch,
max_messages_size_in_single_batch,
relayer_mode: messages_relay::message_lane_loop::RelayerMode::Altruistic,
},
},
RococoSourceClient::new(
source_client.clone(),
lane.clone(),
lane_id,
WOCOCO_CHAIN_ID,
params.target_to_source_headers_relay,
),
WococoTargetClient::new(
params.target_client,
lane,
lane_id,
ROCOCO_CHAIN_ID,
params.source_to_target_headers_relay,
),
relay_utils::relay_metrics(
Some(messages_relay::message_lane_loop::metrics_prefix::<
RococoMessagesToWococo,
>(&lane_id)),
params.metrics_params,
)
.standalone_metric(|registry, prefix| {
StorageProofOverheadMetric::new(
registry,
prefix,
source_client.clone(),
"rococo_storage_proof_overhead".into(),
"Rococo storage proof overhead".into(),
)
})?
.into_params(),
futures::future::pending(),
)
.await
}
@@ -14,11 +14,64 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>. // along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
use crate::cli::{encode_message, CliChain}; use codec::Decode;
use frame_support::weights::Weight; use frame_support::weights::{DispatchClass, DispatchInfo, Pays, Weight};
use relay_wococo_client::Wococo; use relay_wococo_client::Wococo;
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
use crate::cli::{
bridge,
encode_call::{Call, CliEncodeCall},
encode_message, CliChain,
};
impl CliEncodeCall for Wococo {
fn max_extrinsic_size() -> u32 {
bp_wococo::max_extrinsic_size()
}
fn encode_call(call: &Call) -> anyhow::Result<Self::Call> {
Ok(match call {
Call::Remark { remark_payload, .. } => {
relay_wococo_client::runtime::Call::System(relay_wococo_client::runtime::SystemCall::remark(
remark_payload.as_ref().map(|x| x.0.clone()).unwrap_or_default(),
))
}
Call::BridgeSendMessage {
lane,
payload,
fee,
bridge_instance_index,
} => match *bridge_instance_index {
bridge::WOCOCO_TO_ROCOCO_INDEX => {
let payload = Decode::decode(&mut &*payload.0)?;
relay_wococo_client::runtime::Call::BridgeMessagesRococo(
relay_wococo_client::runtime::BridgeMessagesRococoCall::send_message(lane.0, payload, fee.0),
)
}
_ => anyhow::bail!(
"Unsupported target bridge pallet with instance index: {}",
bridge_instance_index
),
},
_ => anyhow::bail!("The call is not supported"),
})
}
fn get_dispatch_info(call: &relay_wococo_client::runtime::Call) -> anyhow::Result<DispatchInfo> {
match *call {
relay_wococo_client::runtime::Call::System(relay_wococo_client::runtime::SystemCall::remark(_)) => {
Ok(DispatchInfo {
weight: crate::chains::rococo::SYSTEM_REMARK_CALL_WEIGHT,
class: DispatchClass::Normal,
pays_fee: Pays::Yes,
})
}
_ => anyhow::bail!("Unsupported Rococo call: {:?}", call),
}
}
}
impl CliChain for Wococo { impl CliChain for Wococo {
const RUNTIME_VERSION: RuntimeVersion = bp_wococo::VERSION; const RUNTIME_VERSION: RuntimeVersion = bp_wococo::VERSION;
@@ -30,7 +83,7 @@ impl CliChain for Wococo {
} }
fn max_extrinsic_weight() -> Weight { fn max_extrinsic_weight() -> Weight {
0 bp_wococo::max_extrinsic_weight()
} }
fn encode_message(_message: encode_message::MessagePayload) -> Result<Self::MessagePayload, String> { fn encode_message(_message: encode_message::MessagePayload) -> Result<Self::MessagePayload, String> {
@@ -67,10 +67,9 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
header: WococoSyncHeader, header: WococoSyncHeader,
proof: GrandpaJustification<bp_wococo::Header>, proof: GrandpaJustification<bp_wococo::Header>,
) -> Bytes { ) -> Bytes {
let call = bp_rococo::Call::BridgeGrandpaWococo(bp_rococo::BridgeGrandpaWococoCall::submit_finality_proof( let call = relay_rococo_client::runtime::Call::BridgeGrandpaWococo(
header.into_inner(), relay_rococo_client::runtime::BridgeGrandpaWococoCall::submit_finality_proof(header.into_inner(), proof),
proof, );
));
let genesis_hash = *self.target_client.genesis_hash(); let genesis_hash = *self.target_client.genesis_hash();
let transaction = Rococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); let transaction = Rococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call);
@@ -0,0 +1,227 @@
// Copyright 2019-2021 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 <http://www.gnu.org/licenses/>.
//! Wococo-to-Rococo messages sync entrypoint.
use crate::messages_lane::{
select_delivery_transaction_limits, MessagesRelayParams, SubstrateMessageLane, SubstrateMessageLaneToSubstrate,
};
use crate::messages_source::SubstrateMessagesSource;
use crate::messages_target::SubstrateMessagesTarget;
use bp_messages::MessageNonce;
use bp_runtime::{ROCOCO_CHAIN_ID, WOCOCO_CHAIN_ID};
use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof;
use codec::Encode;
use messages_relay::message_lane::MessageLane;
use relay_rococo_client::{HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams};
use relay_substrate_client::{metrics::StorageProofOverheadMetric, Chain, TransactionSignScheme};
use relay_wococo_client::{HeaderId as WococoHeaderId, SigningParams as WococoSigningParams, Wococo};
use sp_core::{Bytes, Pair};
use std::{ops::RangeInclusive, time::Duration};
/// Wococo-to-Rococo message lane.
pub type WococoMessagesToRococo =
SubstrateMessageLaneToSubstrate<Wococo, WococoSigningParams, Rococo, RococoSigningParams>;
impl SubstrateMessageLane for WococoMessagesToRococo {
const OUTBOUND_LANE_MESSAGE_DETAILS_METHOD: &'static str = bp_rococo::TO_ROCOCO_MESSAGE_DETAILS_METHOD;
const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str =
bp_rococo::TO_ROCOCO_LATEST_GENERATED_NONCE_METHOD;
const OUTBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_rococo::TO_ROCOCO_LATEST_RECEIVED_NONCE_METHOD;
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_wococo::FROM_WOCOCO_LATEST_RECEIVED_NONCE_METHOD;
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str =
bp_wococo::FROM_WOCOCO_LATEST_CONFIRMED_NONCE_METHOD;
const INBOUND_LANE_UNREWARDED_RELAYERS_STATE: &'static str = bp_wococo::FROM_WOCOCO_UNREWARDED_RELAYERS_STATE;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_wococo::BEST_FINALIZED_WOCOCO_HEADER_METHOD;
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_rococo::BEST_FINALIZED_ROCOCO_HEADER_METHOD;
type SourceChain = Wococo;
type TargetChain = Rococo;
fn source_transactions_author(&self) -> bp_wococo::AccountId {
(*self.source_sign.public().as_array_ref()).into()
}
fn make_messages_receiving_proof_transaction(
&self,
transaction_nonce: <Wococo as Chain>::Index,
_generated_at_block: RococoHeaderId,
proof: <Self as MessageLane>::MessagesReceivingProof,
) -> Bytes {
let (relayers_state, proof) = proof;
let call = relay_wococo_client::runtime::Call::BridgeMessagesRococo(
relay_wococo_client::runtime::BridgeMessagesRococoCall::receive_messages_delivery_proof(
proof,
relayers_state,
),
);
let genesis_hash = *self.source_client.genesis_hash();
let transaction = Wococo::sign_transaction(genesis_hash, &self.source_sign, transaction_nonce, call);
log::trace!(
target: "bridge",
"Prepared Rococo -> Wococo confirmation transaction. Weight: <unknown>/{}, size: {}/{}",
bp_wococo::max_extrinsic_weight(),
transaction.encode().len(),
bp_wococo::max_extrinsic_size(),
);
Bytes(transaction.encode())
}
fn target_transactions_author(&self) -> bp_rococo::AccountId {
(*self.target_sign.public().as_array_ref()).into()
}
fn make_messages_delivery_transaction(
&self,
transaction_nonce: <Rococo as Chain>::Index,
_generated_at_header: WococoHeaderId,
_nonces: RangeInclusive<MessageNonce>,
proof: <Self as MessageLane>::MessagesProof,
) -> Bytes {
let (dispatch_weight, proof) = proof;
let FromBridgedChainMessagesProof {
ref nonces_start,
ref nonces_end,
..
} = proof;
let messages_count = nonces_end - nonces_start + 1;
let call = relay_rococo_client::runtime::Call::BridgeMessagesWococo(
relay_rococo_client::runtime::BridgeMessagesWococoCall::receive_messages_proof(
self.relayer_id_at_source.clone(),
proof,
messages_count as _,
dispatch_weight,
),
);
let genesis_hash = *self.target_client.genesis_hash();
let transaction = Rococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call);
log::trace!(
target: "bridge",
"Prepared Wococo -> Rococo delivery transaction. Weight: <unknown>/{}, size: {}/{}",
bp_rococo::max_extrinsic_weight(),
transaction.encode().len(),
bp_rococo::max_extrinsic_size(),
);
Bytes(transaction.encode())
}
}
/// Wococo node as messages source.
type WococoSourceClient =
SubstrateMessagesSource<Wococo, WococoMessagesToRococo, relay_wococo_client::runtime::WithRococoMessagesInstance>;
/// Rococo node as messages target.
type RococoTargetClient =
SubstrateMessagesTarget<Rococo, WococoMessagesToRococo, relay_rococo_client::runtime::WithWococoMessagesInstance>;
/// Run Wococo-to-Rococo messages sync.
pub async fn run(
params: MessagesRelayParams<Wococo, WococoSigningParams, Rococo, RococoSigningParams>,
) -> Result<(), String> {
let stall_timeout = Duration::from_secs(5 * 60);
let relayer_id_at_wococo = (*params.source_sign.public().as_array_ref()).into();
let lane_id = params.lane_id;
let source_client = params.source_client;
let lane = WococoMessagesToRococo {
source_client: source_client.clone(),
source_sign: params.source_sign,
target_client: params.target_client.clone(),
target_sign: params.target_sign,
relayer_id_at_source: relayer_id_at_wococo,
};
// 2/3 is reserved for proofs and tx overhead
let max_messages_size_in_single_batch = bp_rococo::max_extrinsic_size() / 3;
// we don't know exact weights of the Rococo runtime. So to guess weights we'll be using
// weights from Rialto and then simply dividing it by x2.
let (max_messages_in_single_batch, max_messages_weight_in_single_batch) =
select_delivery_transaction_limits::<pallet_bridge_messages::weights::RialtoWeight<rialto_runtime::Runtime>>(
bp_rococo::max_extrinsic_weight(),
bp_rococo::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE,
);
let (max_messages_in_single_batch, max_messages_weight_in_single_batch) = (
max_messages_in_single_batch / 2,
max_messages_weight_in_single_batch / 2,
);
log::info!(
target: "bridge",
"Starting Wococo -> Rococo messages relay.\n\t\
Wococo relayer account id: {:?}\n\t\
Max messages in single transaction: {}\n\t\
Max messages size in single transaction: {}\n\t\
Max messages weight in single transaction: {}",
lane.relayer_id_at_source,
max_messages_in_single_batch,
max_messages_size_in_single_batch,
max_messages_weight_in_single_batch,
);
messages_relay::message_lane_loop::run(
messages_relay::message_lane_loop::Params {
lane: lane_id,
source_tick: Wococo::AVERAGE_BLOCK_INTERVAL,
target_tick: Rococo::AVERAGE_BLOCK_INTERVAL,
reconnect_delay: relay_utils::relay_loop::RECONNECT_DELAY,
stall_timeout,
delivery_params: messages_relay::message_lane_loop::MessageDeliveryParams {
max_unrewarded_relayer_entries_at_target: bp_rococo::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE,
max_unconfirmed_nonces_at_target: bp_rococo::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE,
max_messages_in_single_batch,
max_messages_weight_in_single_batch,
max_messages_size_in_single_batch,
relayer_mode: messages_relay::message_lane_loop::RelayerMode::Altruistic,
},
},
WococoSourceClient::new(
source_client.clone(),
lane.clone(),
lane_id,
ROCOCO_CHAIN_ID,
params.target_to_source_headers_relay,
),
RococoTargetClient::new(
params.target_client,
lane,
lane_id,
WOCOCO_CHAIN_ID,
params.source_to_target_headers_relay,
),
relay_utils::relay_metrics(
Some(messages_relay::message_lane_loop::metrics_prefix::<
WococoMessagesToRococo,
>(&lane_id)),
params.metrics_params,
)
.standalone_metric(|registry, prefix| {
StorageProofOverheadMetric::new(
registry,
prefix,
source_client.clone(),
"wococo_storage_proof_overhead".into(),
"Wococo storage proof overhead".into(),
)
})?
.into_params(),
futures::future::pending(),
)
.await
}
@@ -22,6 +22,8 @@ arg_enum! {
pub enum FullBridge { pub enum FullBridge {
MillauToRialto, MillauToRialto,
RialtoToMillau, RialtoToMillau,
RococoToWococo,
WococoToRococo,
} }
} }
@@ -31,12 +33,16 @@ impl FullBridge {
match self { match self {
Self::MillauToRialto => MILLAU_TO_RIALTO_INDEX, Self::MillauToRialto => MILLAU_TO_RIALTO_INDEX,
Self::RialtoToMillau => RIALTO_TO_MILLAU_INDEX, Self::RialtoToMillau => RIALTO_TO_MILLAU_INDEX,
Self::RococoToWococo => ROCOCO_TO_WOCOCO_INDEX,
Self::WococoToRococo => WOCOCO_TO_ROCOCO_INDEX,
} }
} }
} }
pub const RIALTO_TO_MILLAU_INDEX: u8 = 0; pub const RIALTO_TO_MILLAU_INDEX: u8 = 0;
pub const MILLAU_TO_RIALTO_INDEX: u8 = 0; pub const MILLAU_TO_RIALTO_INDEX: u8 = 0;
pub const ROCOCO_TO_WOCOCO_INDEX: u8 = 0;
pub const WOCOCO_TO_ROCOCO_INDEX: u8 = 0;
/// The macro allows executing bridge-specific code without going fully generic. /// The macro allows executing bridge-specific code without going fully generic.
/// ///
@@ -89,6 +95,50 @@ macro_rules! select_full_bridge {
#[allow(unused_imports)] #[allow(unused_imports)]
use rialto_runtime::rialto_to_millau_account_ownership_digest as account_ownership_digest; use rialto_runtime::rialto_to_millau_account_ownership_digest as account_ownership_digest;
$generic
}
FullBridge::RococoToWococo => {
type Source = relay_rococo_client::Rococo;
#[allow(dead_code)]
type Target = relay_wococo_client::Wococo;
// Derive-account
#[allow(unused_imports)]
use bp_wococo::derive_account_from_rococo_id as derive_account;
// Relay-messages
#[allow(unused_imports)]
use crate::chains::rococo_messages_to_wococo::run as relay_messages;
// Send-message / Estimate-fee
#[allow(unused_imports)]
use bp_wococo::TO_WOCOCO_ESTIMATE_MESSAGE_FEE_METHOD as ESTIMATE_MESSAGE_FEE_METHOD;
// Send-message
#[allow(unused_imports)]
use relay_rococo_client::runtime::rococo_to_wococo_account_ownership_digest as account_ownership_digest;
$generic
}
FullBridge::WococoToRococo => {
type Source = relay_wococo_client::Wococo;
#[allow(dead_code)]
type Target = relay_rococo_client::Rococo;
// Derive-account
#[allow(unused_imports)]
use bp_rococo::derive_account_from_wococo_id as derive_account;
// Relay-messages
#[allow(unused_imports)]
use crate::chains::wococo_messages_to_rococo::run as relay_messages;
// Send-message / Estimate-fee
#[allow(unused_imports)]
use bp_rococo::TO_ROCOCO_ESTIMATE_MESSAGE_FEE_METHOD as ESTIMATE_MESSAGE_FEE_METHOD;
// Send-message
#[allow(unused_imports)]
use relay_wococo_client::runtime::wococo_to_rococo_account_ownership_digest as account_ownership_digest;
$generic $generic
} }
} }
@@ -17,7 +17,7 @@
use crate::cli::bridge::FullBridge; use crate::cli::bridge::FullBridge;
use crate::cli::{AccountId, Balance, CliChain, ExplicitOrMaximal, HexBytes, HexLaneId}; use crate::cli::{AccountId, Balance, CliChain, ExplicitOrMaximal, HexBytes, HexLaneId};
use crate::select_full_bridge; use crate::select_full_bridge;
use frame_support::dispatch::GetDispatchInfo; use frame_support::weights::DispatchInfo;
use relay_substrate_client::Chain; use relay_substrate_client::Chain;
use structopt::StructOpt; use structopt::StructOpt;
@@ -85,6 +85,9 @@ pub trait CliEncodeCall: Chain {
/// Encode a CLI call. /// Encode a CLI call.
fn encode_call(call: &Call) -> anyhow::Result<Self::Call>; fn encode_call(call: &Call) -> anyhow::Result<Self::Call>;
/// Get dispatch info for the call.
fn get_dispatch_info(call: &Self::Call) -> anyhow::Result<DispatchInfo>;
} }
impl EncodeCall { impl EncodeCall {
@@ -96,7 +99,7 @@ impl EncodeCall {
let encoded = HexBytes::encode(&call); let encoded = HexBytes::encode(&call);
log::info!(target: "bridge", "Generated {} call: {:#?}", Source::NAME, call); log::info!(target: "bridge", "Generated {} call: {:#?}", Source::NAME, call);
log::info!(target: "bridge", "Weight of {} call: {}", Source::NAME, call.get_dispatch_info().weight); log::info!(target: "bridge", "Weight of {} call: {}", Source::NAME, Source::get_dispatch_info(&call)?.weight);
log::info!(target: "bridge", "Encoded {} call: {:?}", Source::NAME, encoded); log::info!(target: "bridge", "Encoded {} call: {:?}", Source::NAME, encoded);
Ok(encoded) Ok(encoded)
@@ -109,7 +109,9 @@ macro_rules! select_bridge {
fn encode_init_bridge( fn encode_init_bridge(
init_data: InitializationData<<Source as ChainBase>::Header>, init_data: InitializationData<<Source as ChainBase>::Header>,
) -> <Target as Chain>::Call { ) -> <Target as Chain>::Call {
bp_wococo::Call::BridgeGrandpaRococo(bp_wococo::BridgeGrandpaRococoCall::initialize(init_data)) relay_wococo_client::runtime::Call::BridgeGrandpaRococo(
relay_wococo_client::runtime::BridgeGrandpaRococoCall::initialize(init_data),
)
} }
$generic $generic
@@ -121,7 +123,9 @@ macro_rules! select_bridge {
fn encode_init_bridge( fn encode_init_bridge(
init_data: InitializationData<<Source as ChainBase>::Header>, init_data: InitializationData<<Source as ChainBase>::Header>,
) -> <Target as Chain>::Call { ) -> <Target as Chain>::Call {
bp_rococo::Call::BridgeGrandpaWococo(bp_rococo::BridgeGrandpaWococoCall::initialize(init_data)) relay_rococo_client::runtime::Call::BridgeGrandpaWococo(
relay_rococo_client::runtime::BridgeGrandpaWococoCall::initialize(init_data),
)
} }
$generic $generic
@@ -35,6 +35,7 @@ use structopt::StructOpt;
#[derive(StructOpt)] #[derive(StructOpt)]
pub enum RelayHeadersAndMessages { pub enum RelayHeadersAndMessages {
MillauRialto(MillauRialtoHeadersAndMessages), MillauRialto(MillauRialtoHeadersAndMessages),
RococoWococo(RococoWococoHeadersAndMessages),
} }
/// Parameters that have the same names across all bridges. /// Parameters that have the same names across all bridges.
@@ -102,6 +103,26 @@ macro_rules! select_bridge {
use crate::chains::millau_messages_to_rialto::run as left_to_right_messages; use crate::chains::millau_messages_to_rialto::run as left_to_right_messages;
use crate::chains::rialto_messages_to_millau::run as right_to_left_messages; use crate::chains::rialto_messages_to_millau::run as right_to_left_messages;
$generic
}
RelayHeadersAndMessages::RococoWococo(_) => {
type Params = RococoWococoHeadersAndMessages;
type Left = relay_rococo_client::Rococo;
type Right = relay_wococo_client::Wococo;
type LeftToRightFinality = crate::chains::rococo_headers_to_wococo::RococoFinalityToWococo;
type RightToLeftFinality = crate::chains::wococo_headers_to_rococo::WococoFinalityToRococo;
type LeftToRightMessages = crate::chains::rococo_messages_to_wococo::RococoMessagesToWococo;
type RightToLeftMessages = crate::chains::wococo_messages_to_rococo::WococoMessagesToRococo;
const MAX_MISSING_LEFT_HEADERS_AT_RIGHT: bp_rococo::BlockNumber = bp_rococo::SESSION_LENGTH;
const MAX_MISSING_RIGHT_HEADERS_AT_LEFT: bp_wococo::BlockNumber = bp_wococo::SESSION_LENGTH;
use crate::chains::rococo_messages_to_wococo::run as left_to_right_messages;
use crate::chains::wococo_messages_to_rococo::run as right_to_left_messages;
$generic $generic
} }
} }
@@ -111,8 +132,11 @@ macro_rules! select_bridge {
// All supported chains. // All supported chains.
declare_chain_options!(Millau, millau); declare_chain_options!(Millau, millau);
declare_chain_options!(Rialto, rialto); declare_chain_options!(Rialto, rialto);
declare_chain_options!(Rococo, rococo);
declare_chain_options!(Wococo, wococo);
// All supported bridges. // All supported bridges.
declare_bridge_options!(Millau, Rialto); declare_bridge_options!(Millau, Rialto);
declare_bridge_options!(Rococo, Wococo);
impl RelayHeadersAndMessages { impl RelayHeadersAndMessages {
/// Run the command. /// Run the command.
@@ -24,7 +24,7 @@ use crate::cli::{
use bp_message_dispatch::{CallOrigin, MessagePayload}; use bp_message_dispatch::{CallOrigin, MessagePayload};
use bp_runtime::messages::DispatchFeePayment; use bp_runtime::messages::DispatchFeePayment;
use codec::Encode; use codec::Encode;
use frame_support::{dispatch::GetDispatchInfo, weights::Weight}; use frame_support::weights::Weight;
use relay_substrate_client::{Chain, TransactionSignScheme}; use relay_substrate_client::{Chain, TransactionSignScheme};
use sp_core::{Bytes, Pair}; use sp_core::{Bytes, Pair};
use sp_runtime::{traits::IdentifyAccount, AccountId32, MultiSignature, MultiSigner}; use sp_runtime::{traits::IdentifyAccount, AccountId32, MultiSignature, MultiSigner};
@@ -89,7 +89,7 @@ impl SendMessage {
let payload = { let payload = {
let target_call_weight = prepare_call_dispatch_weight( let target_call_weight = prepare_call_dispatch_weight(
dispatch_weight, dispatch_weight,
ExplicitOrMaximal::Explicit(target_call.get_dispatch_info().weight), ExplicitOrMaximal::Explicit(Target::get_dispatch_info(&target_call)?.weight),
compute_maximal_message_dispatch_weight(Target::max_extrinsic_weight()), compute_maximal_message_dispatch_weight(Target::max_extrinsic_weight()),
); );
let source_sender_public: MultiSigner = source_sign.public().into(); let source_sender_public: MultiSigner = source_sign.public().into();
@@ -33,7 +33,6 @@ use messages_relay::{
ClientState, MessageDetails, MessageDetailsMap, MessageProofParameters, SourceClient, SourceClientState, ClientState, MessageDetails, MessageDetailsMap, MessageProofParameters, SourceClient, SourceClientState,
}, },
}; };
use pallet_bridge_messages::Config as MessagesConfig;
use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf, HeaderIdOf}; use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf, HeaderIdOf};
use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase, HeaderId}; use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase, HeaderId};
use sp_core::Bytes; use sp_core::Bytes;
@@ -46,16 +45,16 @@ use std::{marker::PhantomData, ops::RangeInclusive};
pub type SubstrateMessagesProof<C> = (Weight, FromBridgedChainMessagesProof<HashOf<C>>); pub type SubstrateMessagesProof<C> = (Weight, FromBridgedChainMessagesProof<HashOf<C>>);
/// Substrate client as Substrate messages source. /// Substrate client as Substrate messages source.
pub struct SubstrateMessagesSource<C: Chain, P: SubstrateMessageLane, R, I> { pub struct SubstrateMessagesSource<C: Chain, P: SubstrateMessageLane, I> {
client: Client<C>, client: Client<C>,
lane: P, lane: P,
lane_id: LaneId, lane_id: LaneId,
instance: ChainId, instance: ChainId,
target_to_source_headers_relay: Option<OnDemandHeadersRelay<P::TargetChain>>, target_to_source_headers_relay: Option<OnDemandHeadersRelay<P::TargetChain>>,
_phantom: PhantomData<(R, I)>, _phantom: PhantomData<I>,
} }
impl<C: Chain, P: SubstrateMessageLane, R, I> SubstrateMessagesSource<C, P, R, I> { impl<C: Chain, P: SubstrateMessageLane, I> SubstrateMessagesSource<C, P, I> {
/// Create new Substrate headers source. /// Create new Substrate headers source.
pub fn new( pub fn new(
client: Client<C>, client: Client<C>,
@@ -75,7 +74,7 @@ impl<C: Chain, P: SubstrateMessageLane, R, I> SubstrateMessagesSource<C, P, R, I
} }
} }
impl<C: Chain, P: SubstrateMessageLane, R, I> Clone for SubstrateMessagesSource<C, P, R, I> { impl<C: Chain, P: SubstrateMessageLane, I> Clone for SubstrateMessagesSource<C, P, I> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client: self.client.clone(), client: self.client.clone(),
@@ -89,11 +88,10 @@ impl<C: Chain, P: SubstrateMessageLane, R, I> Clone for SubstrateMessagesSource<
} }
#[async_trait] #[async_trait]
impl<C, P, R, I> RelayClient for SubstrateMessagesSource<C, P, R, I> impl<C, P, I> RelayClient for SubstrateMessagesSource<C, P, I>
where where
C: Chain, C: Chain,
P: SubstrateMessageLane, P: SubstrateMessageLane,
R: 'static + Send + Sync,
I: Send + Sync + Instance, I: Send + Sync + Instance,
{ {
type Error = SubstrateError; type Error = SubstrateError;
@@ -104,7 +102,7 @@ where
} }
#[async_trait] #[async_trait]
impl<C, P, R, I> SourceClient<P> for SubstrateMessagesSource<C, P, R, I> impl<C, P, I> SourceClient<P> for SubstrateMessagesSource<C, P, I>
where where
C: Chain, C: Chain,
C::Header: DeserializeOwned, C::Header: DeserializeOwned,
@@ -120,7 +118,6 @@ where
P::TargetChain: Chain<Hash = P::TargetHeaderHash, BlockNumber = P::TargetHeaderNumber>, P::TargetChain: Chain<Hash = P::TargetHeaderHash, BlockNumber = P::TargetHeaderNumber>,
P::TargetHeaderNumber: Decode, P::TargetHeaderNumber: Decode,
P::TargetHeaderHash: Decode, P::TargetHeaderHash: Decode,
R: Send + Sync + MessagesConfig<I>,
I: Send + Sync + Instance, I: Send + Sync + Instance,
{ {
async fn state(&self) -> Result<SourceClientState<P>, SubstrateError> { async fn state(&self) -> Result<SourceClientState<P>, SubstrateError> {
@@ -198,7 +195,7 @@ where
let mut storage_keys = Vec::with_capacity(nonces.end().saturating_sub(*nonces.start()) as usize + 1); let mut storage_keys = Vec::with_capacity(nonces.end().saturating_sub(*nonces.start()) as usize + 1);
let mut message_nonce = *nonces.start(); let mut message_nonce = *nonces.start();
while message_nonce <= *nonces.end() { while message_nonce <= *nonces.end() {
let message_key = pallet_bridge_messages::storage_keys::message_key::<R, I>(&self.lane_id, message_nonce); let message_key = pallet_bridge_messages::storage_keys::message_key::<I>(&self.lane_id, message_nonce);
storage_keys.push(message_key); storage_keys.push(message_key);
message_nonce += 1; message_nonce += 1;
} }
@@ -32,7 +32,6 @@ use messages_relay::{
message_lane::{SourceHeaderIdOf, TargetHeaderIdOf}, message_lane::{SourceHeaderIdOf, TargetHeaderIdOf},
message_lane_loop::{TargetClient, TargetClientState}, message_lane_loop::{TargetClient, TargetClientState},
}; };
use pallet_bridge_messages::Config as MessagesConfig;
use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf}; use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf};
use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase}; use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase};
use sp_core::Bytes; use sp_core::Bytes;
@@ -46,16 +45,16 @@ pub type SubstrateMessagesReceivingProof<C> = (
); );
/// Substrate client as Substrate messages target. /// Substrate client as Substrate messages target.
pub struct SubstrateMessagesTarget<C: Chain, P: SubstrateMessageLane, R, I> { pub struct SubstrateMessagesTarget<C: Chain, P: SubstrateMessageLane, I> {
client: Client<C>, client: Client<C>,
lane: P, lane: P,
lane_id: LaneId, lane_id: LaneId,
instance: ChainId, instance: ChainId,
source_to_target_headers_relay: Option<OnDemandHeadersRelay<P::SourceChain>>, source_to_target_headers_relay: Option<OnDemandHeadersRelay<P::SourceChain>>,
_phantom: PhantomData<(R, I)>, _phantom: PhantomData<I>,
} }
impl<C: Chain, P: SubstrateMessageLane, R, I> SubstrateMessagesTarget<C, P, R, I> { impl<C: Chain, P: SubstrateMessageLane, I> SubstrateMessagesTarget<C, P, I> {
/// Create new Substrate headers target. /// Create new Substrate headers target.
pub fn new( pub fn new(
client: Client<C>, client: Client<C>,
@@ -75,7 +74,7 @@ impl<C: Chain, P: SubstrateMessageLane, R, I> SubstrateMessagesTarget<C, P, R, I
} }
} }
impl<C: Chain, P: SubstrateMessageLane, R, I> Clone for SubstrateMessagesTarget<C, P, R, I> { impl<C: Chain, P: SubstrateMessageLane, I> Clone for SubstrateMessagesTarget<C, P, I> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client: self.client.clone(), client: self.client.clone(),
@@ -89,11 +88,10 @@ impl<C: Chain, P: SubstrateMessageLane, R, I> Clone for SubstrateMessagesTarget<
} }
#[async_trait] #[async_trait]
impl<C, P, R, I> RelayClient for SubstrateMessagesTarget<C, P, R, I> impl<C, P, I> RelayClient for SubstrateMessagesTarget<C, P, I>
where where
C: Chain, C: Chain,
P: SubstrateMessageLane, P: SubstrateMessageLane,
R: 'static + Send + Sync,
I: Send + Sync + Instance, I: Send + Sync + Instance,
{ {
type Error = SubstrateError; type Error = SubstrateError;
@@ -104,7 +102,7 @@ where
} }
#[async_trait] #[async_trait]
impl<C, P, R, I> TargetClient<P> for SubstrateMessagesTarget<C, P, R, I> impl<C, P, I> TargetClient<P> for SubstrateMessagesTarget<C, P, I>
where where
C: Chain, C: Chain,
C::Header: DeserializeOwned, C::Header: DeserializeOwned,
@@ -119,7 +117,6 @@ where
P::SourceChain: Chain<Hash = P::SourceHeaderHash, BlockNumber = P::SourceHeaderNumber>, P::SourceChain: Chain<Hash = P::SourceHeaderHash, BlockNumber = P::SourceHeaderNumber>,
P::SourceHeaderNumber: Decode, P::SourceHeaderNumber: Decode,
P::SourceHeaderHash: Decode, P::SourceHeaderHash: Decode,
R: Send + Sync + MessagesConfig<I>,
I: Send + Sync + Instance, I: Send + Sync + Instance,
{ {
async fn state(&self) -> Result<TargetClientState<P>, SubstrateError> { async fn state(&self) -> Result<TargetClientState<P>, SubstrateError> {
@@ -190,7 +187,7 @@ where
id: TargetHeaderIdOf<P>, id: TargetHeaderIdOf<P>,
) -> Result<(TargetHeaderIdOf<P>, P::MessagesReceivingProof), SubstrateError> { ) -> Result<(TargetHeaderIdOf<P>, P::MessagesReceivingProof), SubstrateError> {
let (id, relayers_state) = self.unrewarded_relayers_state(id).await?; let (id, relayers_state) = self.unrewarded_relayers_state(id).await?;
let inbound_data_key = pallet_bridge_messages::storage_keys::inbound_lane_data_key::<R, I>(&self.lane_id); let inbound_data_key = pallet_bridge_messages::storage_keys::inbound_lane_data_key::<I>(&self.lane_id);
let proof = self let proof = self
.client .client
.prove_storage(vec![inbound_data_key], id.1) .prove_storage(vec![inbound_data_key], id.1)
+9
View File
@@ -12,7 +12,16 @@ relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" } relay-utils = { path = "../utils" }
# Bridge dependencies # Bridge dependencies
bridge-runtime-common = { path = "../../bin/runtime-common" }
bp-header-chain = { path = "../../primitives/header-chain" }
bp-message-dispatch = { path = "../../primitives/message-dispatch" }
bp-messages = { path = "../../primitives/messages" }
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-rococo = { path = "../../primitives/chain-rococo" } bp-rococo = { path = "../../primitives/chain-rococo" }
bp-runtime = { path = "../../primitives/runtime" }
bp-wococo = { path = "../../primitives/chain-wococo" }
pallet-bridge-dispatch = { path = "../../modules/dispatch" }
pallet-bridge-messages = { path = "../../modules/messages" }
# Substrate Dependencies # Substrate Dependencies
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
+4 -2
View File
@@ -22,6 +22,8 @@ use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
use std::time::Duration; use std::time::Duration;
pub mod runtime;
/// Rococo header id. /// Rococo header id.
pub type HeaderId = relay_utils::HeaderId<bp_rococo::Hash, bp_rococo::BlockNumber>; pub type HeaderId = relay_utils::HeaderId<bp_rococo::Hash, bp_rococo::BlockNumber>;
@@ -46,7 +48,7 @@ impl Chain for Rococo {
type AccountId = bp_rococo::AccountId; type AccountId = bp_rococo::AccountId;
type Index = bp_rococo::Index; type Index = bp_rococo::Index;
type SignedBlock = bp_rococo::SignedBlock; type SignedBlock = bp_rococo::SignedBlock;
type Call = bp_rococo::Call; type Call = crate::runtime::Call;
type Balance = bp_rococo::Balance; type Balance = bp_rococo::Balance;
} }
@@ -59,7 +61,7 @@ impl ChainWithBalances for Rococo {
impl TransactionSignScheme for Rococo { impl TransactionSignScheme for Rococo {
type Chain = Rococo; type Chain = Rococo;
type AccountKeyPair = sp_core::sr25519::Pair; type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction = bp_rococo::UncheckedExtrinsic; type SignedTransaction = crate::runtime::UncheckedExtrinsic;
fn sign_transaction( fn sign_transaction(
genesis_hash: <Self::Chain as ChainBase>::Hash, genesis_hash: <Self::Chain as ChainBase>::Hash,
+135
View File
@@ -0,0 +1,135 @@
// Copyright 2019-2021 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 <http://www.gnu.org/licenses/>.
//! Types that are specific to the Rococo runtime.
use bp_messages::{LaneId, UnrewardedRelayersState};
use bp_polkadot_core::PolkadotLike;
use bp_runtime::Chain;
use codec::{Decode, Encode};
use frame_support::weights::Weight;
/// Instance of messages pallet that is used to bridge with Wococo chain.
pub type WithWococoMessagesInstance = pallet_bridge_messages::Instance1;
/// Unchecked Rococo extrinsic.
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
/// Wococo account ownership digest from Rococo.
///
/// The byte vector returned by this function should be signed with a Wococo account private key.
/// This way, the owner of `rococo_account_id` on Rococo proves that the Wococo account private key
/// is also under his control.
pub fn rococo_to_wococo_account_ownership_digest<Call, AccountId, SpecVersion>(
wococo_call: &Call,
rococo_account_id: AccountId,
wococo_spec_version: SpecVersion,
) -> Vec<u8>
where
Call: codec::Encode,
AccountId: codec::Encode,
SpecVersion: codec::Encode,
{
pallet_bridge_dispatch::account_ownership_digest(
wococo_call,
rococo_account_id,
wococo_spec_version,
bp_runtime::ROCOCO_CHAIN_ID,
bp_runtime::WOCOCO_CHAIN_ID,
)
}
/// Rococo Runtime `Call` enum.
///
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
/// Ideally this code would be auto-generated from Metadata, because we want to
/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s.
///
/// All entries here (like pretty much in the entire file) must be kept in sync with Rococo
/// `construct_runtime`, so that we maintain SCALE-compatibility.
///
/// See: https://github.com/paritytech/polkadot/blob/master/runtime/rococo/src/lib.rs
#[allow(clippy::large_enum_variant)]
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
pub enum Call {
/// System pallet.
#[codec(index = 0)]
System(SystemCall),
/// Wococo bridge pallet.
#[codec(index = 41)]
BridgeGrandpaWococo(BridgeGrandpaWococoCall),
/// Wococo messages pallet.
#[codec(index = 44)]
BridgeMessagesWococo(BridgeMessagesWococoCall),
}
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
#[allow(non_camel_case_types)]
pub enum SystemCall {
#[codec(index = 1)]
remark(Vec<u8>),
}
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
#[allow(non_camel_case_types)]
pub enum BridgeGrandpaWococoCall {
#[codec(index = 0)]
submit_finality_proof(
<PolkadotLike as Chain>::Header,
bp_header_chain::justification::GrandpaJustification<<PolkadotLike as Chain>::Header>,
),
#[codec(index = 1)]
initialize(bp_header_chain::InitializationData<<PolkadotLike as Chain>::Header>),
}
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
#[allow(non_camel_case_types)]
pub enum BridgeMessagesWococoCall {
#[codec(index = 3)]
send_message(
LaneId,
bp_message_dispatch::MessagePayload<
bp_rococo::AccountId,
bp_wococo::AccountId,
bp_wococo::AccountPublic,
Vec<u8>,
>,
bp_rococo::Balance,
),
#[codec(index = 5)]
receive_messages_proof(
bp_wococo::AccountId,
bridge_runtime_common::messages::target::FromBridgedChainMessagesProof<bp_wococo::Hash>,
u32,
Weight,
),
#[codec(index = 6)]
receive_messages_delivery_proof(
bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof<bp_wococo::Hash>,
UnrewardedRelayersState,
),
}
impl sp_runtime::traits::Dispatchable for Call {
type Origin = ();
type Config = ();
type Info = ();
type PostInfo = ();
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
unimplemented!("The Call is not expected to be dispatched.")
}
}
+9
View File
@@ -12,7 +12,16 @@ relay-substrate-client = { path = "../client-substrate" }
relay-utils = { path = "../utils" } relay-utils = { path = "../utils" }
# Bridge dependencies # Bridge dependencies
bridge-runtime-common = { path = "../../bin/runtime-common" }
bp-header-chain = { path = "../../primitives/header-chain" }
bp-message-dispatch = { path = "../../primitives/message-dispatch" }
bp-messages = { path = "../../primitives/messages" }
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-rococo = { path = "../../primitives/chain-rococo" }
bp-runtime = { path = "../../primitives/runtime" }
bp-wococo = { path = "../../primitives/chain-wococo" } bp-wococo = { path = "../../primitives/chain-wococo" }
pallet-bridge-dispatch = { path = "../../modules/dispatch" }
pallet-bridge-messages = { path = "../../modules/messages" }
# Substrate Dependencies # Substrate Dependencies
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
+4 -2
View File
@@ -22,6 +22,8 @@ use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
use std::time::Duration; use std::time::Duration;
pub mod runtime;
/// Wococo header id. /// Wococo header id.
pub type HeaderId = relay_utils::HeaderId<bp_wococo::Hash, bp_wococo::BlockNumber>; pub type HeaderId = relay_utils::HeaderId<bp_wococo::Hash, bp_wococo::BlockNumber>;
@@ -46,7 +48,7 @@ impl Chain for Wococo {
type AccountId = bp_wococo::AccountId; type AccountId = bp_wococo::AccountId;
type Index = bp_wococo::Index; type Index = bp_wococo::Index;
type SignedBlock = bp_wococo::SignedBlock; type SignedBlock = bp_wococo::SignedBlock;
type Call = bp_wococo::Call; type Call = crate::runtime::Call;
type Balance = bp_wococo::Balance; type Balance = bp_wococo::Balance;
} }
@@ -59,7 +61,7 @@ impl ChainWithBalances for Wococo {
impl TransactionSignScheme for Wococo { impl TransactionSignScheme for Wococo {
type Chain = Wococo; type Chain = Wococo;
type AccountKeyPair = sp_core::sr25519::Pair; type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction = bp_wococo::UncheckedExtrinsic; type SignedTransaction = crate::runtime::UncheckedExtrinsic;
fn sign_transaction( fn sign_transaction(
genesis_hash: <Self::Chain as ChainBase>::Hash, genesis_hash: <Self::Chain as ChainBase>::Hash,
+135
View File
@@ -0,0 +1,135 @@
// Copyright 2019-2021 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 <http://www.gnu.org/licenses/>.
//! Types that are specific to the Wococo runtime.
use bp_messages::{LaneId, UnrewardedRelayersState};
use bp_polkadot_core::PolkadotLike;
use bp_runtime::Chain;
use codec::{Decode, Encode};
use frame_support::weights::Weight;
/// Instance of messages pallet that is used to bridge with Rococo chain.
pub type WithRococoMessagesInstance = pallet_bridge_messages::DefaultInstance;
/// Unchecked Wococo extrinsic.
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
/// Rococo account ownership digest from Wococo.
///
/// The byte vector returned by this function should be signed with a Rococo account private key.
/// This way, the owner of `wococo_account_id` on Rococo proves that the Rococo account private key
/// is also under his control.
pub fn wococo_to_rococo_account_ownership_digest<Call, AccountId, SpecVersion>(
rococo_call: &Call,
wococo_account_id: AccountId,
rococo_spec_version: SpecVersion,
) -> Vec<u8>
where
Call: codec::Encode,
AccountId: codec::Encode,
SpecVersion: codec::Encode,
{
pallet_bridge_dispatch::account_ownership_digest(
rococo_call,
wococo_account_id,
rococo_spec_version,
bp_runtime::WOCOCO_CHAIN_ID,
bp_runtime::ROCOCO_CHAIN_ID,
)
}
/// Wococo Runtime `Call` enum.
///
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
/// Ideally this code would be auto-generated from Metadata, because we want to
/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s.
///
/// All entries here (like pretty much in the entire file) must be kept in sync with Rococo
/// `construct_runtime`, so that we maintain SCALE-compatibility.
///
/// See: https://github.com/paritytech/polkadot/blob/master/runtime/rococo/src/lib.rs
#[allow(clippy::large_enum_variant)]
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
pub enum Call {
/// System pallet.
#[codec(index = 0)]
System(SystemCall),
/// Rococo bridge pallet.
#[codec(index = 40)]
BridgeGrandpaRococo(BridgeGrandpaRococoCall),
/// Rococo messages pallet.
#[codec(index = 43)]
BridgeMessagesRococo(BridgeMessagesRococoCall),
}
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
#[allow(non_camel_case_types)]
pub enum SystemCall {
#[codec(index = 1)]
remark(Vec<u8>),
}
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
#[allow(non_camel_case_types)]
pub enum BridgeGrandpaRococoCall {
#[codec(index = 0)]
submit_finality_proof(
<PolkadotLike as Chain>::Header,
bp_header_chain::justification::GrandpaJustification<<PolkadotLike as Chain>::Header>,
),
#[codec(index = 1)]
initialize(bp_header_chain::InitializationData<<PolkadotLike as Chain>::Header>),
}
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
#[allow(non_camel_case_types)]
pub enum BridgeMessagesRococoCall {
#[codec(index = 3)]
send_message(
LaneId,
bp_message_dispatch::MessagePayload<
bp_rococo::AccountId,
bp_wococo::AccountId,
bp_wococo::AccountPublic,
Vec<u8>,
>,
bp_rococo::Balance,
),
#[codec(index = 5)]
receive_messages_proof(
bp_rococo::AccountId,
bridge_runtime_common::messages::target::FromBridgedChainMessagesProof<bp_rococo::Hash>,
u32,
Weight,
),
#[codec(index = 6)]
receive_messages_delivery_proof(
bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof<bp_rococo::Hash>,
UnrewardedRelayersState,
),
}
impl sp_runtime::traits::Dispatchable for Call {
type Origin = ();
type Config = ();
type Info = ();
type PostInfo = ();
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
unimplemented!("The Call is not expected to be dispatched.")
}
}