Update bridges subtree (#2996)

Update bridges subtree
This commit is contained in:
Serban Iorga
2024-01-19 17:50:24 +01:00
committed by GitHub
parent 2e9b4405ed
commit 320b52892e
53 changed files with 565 additions and 533 deletions
+1
View File
@@ -16,6 +16,7 @@
//! Common types/functions that may be used by runtimes of all bridged chains. //! Common types/functions that may be used by runtimes of all bridged chains.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use crate::messages_call_ext::MessagesCallSubType; use crate::messages_call_ext::MessagesCallSubType;
+2 -39
View File
@@ -24,7 +24,7 @@ pub use bp_runtime::{RangeInclusiveExt, UnderlyingChainOf, UnderlyingChainProvid
use bp_header_chain::HeaderChain; use bp_header_chain::HeaderChain;
use bp_messages::{ use bp_messages::{
source_chain::{LaneMessageVerifier, TargetHeaderChain}, source_chain::TargetHeaderChain,
target_chain::{ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, target_chain::{ProvedLaneMessages, ProvedMessages, SourceHeaderChain},
InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData,
VerificationError, VerificationError,
@@ -120,42 +120,6 @@ pub mod source {
pub type ParsedMessagesDeliveryProofFromBridgedChain<B> = pub type ParsedMessagesDeliveryProofFromBridgedChain<B> =
(LaneId, InboundLaneData<AccountIdOf<ThisChain<B>>>); (LaneId, InboundLaneData<AccountIdOf<ThisChain<B>>>);
/// Message verifier that is doing all basic checks.
///
/// This verifier assumes following:
///
/// - all message lanes are equivalent, so all checks are the same;
///
/// Following checks are made:
///
/// - message is rejected if its lane is currently blocked;
/// - message is rejected if there are too many pending (undelivered) messages at the outbound
/// lane;
/// - check that the sender has rights to dispatch the call on target chain using provided
/// dispatch origin;
/// - check that the sender has paid enough funds for both message delivery and dispatch.
#[derive(RuntimeDebug)]
pub struct FromThisChainMessageVerifier<B>(PhantomData<B>);
impl<B> LaneMessageVerifier<FromThisChainMessagePayload> for FromThisChainMessageVerifier<B>
where
B: MessageBridge,
{
fn verify_message(
_lane: &LaneId,
_lane_outbound_data: &OutboundLaneData,
_payload: &FromThisChainMessagePayload,
) -> Result<(), VerificationError> {
// IMPORTANT: any error that is returned here is fatal for the bridge, because
// this code is executed at the bridge hub and message sender actually lives
// at some sibling parachain. So we are failing **after** the message has been
// sent and we can't report it back to sender (unless error report mechanism is
// embedded into message and its dispatcher).
Ok(())
}
}
/// Return maximal message size of This -> Bridged chain message. /// Return maximal message size of This -> Bridged chain message.
pub fn maximal_message_size<B: MessageBridge>() -> u32 { pub fn maximal_message_size<B: MessageBridge>() -> u32 {
super::target::maximal_incoming_message_size( super::target::maximal_incoming_message_size(
@@ -185,8 +149,7 @@ pub mod source {
/// Do basic Bridged-chain specific verification of This -> Bridged chain message. /// Do basic Bridged-chain specific verification of This -> Bridged chain message.
/// ///
/// Ok result from this function means that the delivery transaction with this message /// Ok result from this function means that the delivery transaction with this message
/// may be 'mined' by the target chain. But the lane may have its own checks (e.g. fee /// may be 'mined' by the target chain.
/// check) that would reject message (see `FromThisChainMessageVerifier`).
pub fn verify_chain_message<B: MessageBridge>( pub fn verify_chain_message<B: MessageBridge>(
payload: &FromThisChainMessagePayload, payload: &FromThisChainMessagePayload,
) -> Result<(), VerificationError> { ) -> Result<(), VerificationError> {
@@ -14,6 +14,9 @@
// 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/>.
//! Signed extension for the `pallet-bridge-messages` that is able to reject obsolete
//! (and some other invalid) transactions.
use crate::messages::{ use crate::messages::{
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
}; };
@@ -116,7 +119,9 @@ impl ReceiveMessagesDeliveryProofInfo {
/// which tries to update a single lane. /// which tries to update a single lane.
#[derive(PartialEq, RuntimeDebug)] #[derive(PartialEq, RuntimeDebug)]
pub enum CallInfo { pub enum CallInfo {
/// Messages delivery call info.
ReceiveMessagesProof(ReceiveMessagesProofInfo), ReceiveMessagesProof(ReceiveMessagesProofInfo),
/// Messages delivery confirmation call info.
ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo), ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo),
} }
@@ -132,7 +137,7 @@ impl CallInfo {
/// Helper struct that provides methods for working with a call supported by `CallInfo`. /// Helper struct that provides methods for working with a call supported by `CallInfo`.
pub struct CallHelper<T: Config<I>, I: 'static> { pub struct CallHelper<T: Config<I>, I: 'static> {
pub _phantom_data: sp_std::marker::PhantomData<(T, I)>, _phantom_data: sp_std::marker::PhantomData<(T, I)>,
} }
impl<T: Config<I>, I: 'static> CallHelper<T, I> { impl<T: Config<I>, I: 'static> CallHelper<T, I> {
@@ -40,11 +40,14 @@ use sp_std::{fmt::Debug, marker::PhantomData};
use xcm::prelude::*; use xcm::prelude::*;
use xcm_builder::{DispatchBlob, DispatchBlobError}; use xcm_builder::{DispatchBlob, DispatchBlobError};
/// Message dispatch result type for single message /// Message dispatch result type for single message.
#[derive(CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, Debug, TypeInfo)] #[derive(CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, Debug, TypeInfo)]
pub enum XcmBlobMessageDispatchResult { pub enum XcmBlobMessageDispatchResult {
/// We've been unable to decode message payload.
InvalidPayload, InvalidPayload,
/// Message has been dispatched.
Dispatched, Dispatched,
/// Message has **NOT** been dispatched because of given error.
NotDispatched(#[codec(skip)] Option<DispatchBlobError>), NotDispatched(#[codec(skip)] Option<DispatchBlobError>),
} }
+7 -2
View File
@@ -21,7 +21,7 @@
use crate::messages::{ use crate::messages::{
source::{ source::{
FromThisChainMaximalOutboundPayloadSize, FromThisChainMessagePayload, FromThisChainMaximalOutboundPayloadSize, FromThisChainMessagePayload,
FromThisChainMessageVerifier, TargetHeaderChainAdapter, TargetHeaderChainAdapter,
}, },
target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter},
BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages,
@@ -213,7 +213,6 @@ impl pallet_bridge_messages::Config for TestRuntime {
type DeliveryPayments = (); type DeliveryPayments = ();
type TargetHeaderChain = TargetHeaderChainAdapter<OnThisChainBridge>; type TargetHeaderChain = TargetHeaderChainAdapter<OnThisChainBridge>;
type LaneMessageVerifier = FromThisChainMessageVerifier<OnThisChainBridge>;
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
TestRuntime, TestRuntime,
(), (),
@@ -315,6 +314,8 @@ impl From<BridgedChainOrigin>
pub struct ThisUnderlyingChain; pub struct ThisUnderlyingChain;
impl Chain for ThisUnderlyingChain { impl Chain for ThisUnderlyingChain {
const ID: ChainId = *b"tuch";
type BlockNumber = ThisChainBlockNumber; type BlockNumber = ThisChainBlockNumber;
type Hash = ThisChainHash; type Hash = ThisChainHash;
type Hasher = ThisChainHasher; type Hasher = ThisChainHasher;
@@ -355,6 +356,8 @@ pub struct BridgedUnderlyingParachain;
pub struct BridgedChainCall; pub struct BridgedChainCall;
impl Chain for BridgedUnderlyingChain { impl Chain for BridgedUnderlyingChain {
const ID: ChainId = *b"buch";
type BlockNumber = BridgedChainBlockNumber; type BlockNumber = BridgedChainBlockNumber;
type Hash = BridgedChainHash; type Hash = BridgedChainHash;
type Hasher = BridgedChainHasher; type Hasher = BridgedChainHasher;
@@ -381,6 +384,8 @@ impl ChainWithGrandpa for BridgedUnderlyingChain {
} }
impl Chain for BridgedUnderlyingParachain { impl Chain for BridgedUnderlyingParachain {
const ID: ChainId = *b"bupc";
type BlockNumber = BridgedChainBlockNumber; type BlockNumber = BridgedChainBlockNumber;
type Hash = BridgedChainHash; type Hash = BridgedChainHash;
type Hasher = BridgedChainHasher; type Hasher = BridgedChainHasher;
@@ -84,5 +84,5 @@ where
let (relay_block_number, relay_block_hash) = let (relay_block_number, relay_block_hash) =
insert_header_to_grandpa_pallet::<R, R::BridgesGrandpaPalletInstance>(state_root); insert_header_to_grandpa_pallet::<R, R::BridgesGrandpaPalletInstance>(state_root);
(relay_block_number, relay_block_hash, ParaHeadsProof(proof), parachain_heads) (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof: proof }, parachain_heads)
} }
@@ -116,7 +116,7 @@ where
/// Refund calculator. /// Refund calculator.
pub trait RefundCalculator { pub trait RefundCalculator {
// The underlying integer type in which the refund is calculated. /// The underlying integer type in which the refund is calculated.
type Balance; type Balance;
/// Compute refund for given transaction. /// Compute refund for given transaction.
@@ -986,7 +986,7 @@ mod tests {
ParaId(TestParachain::get()), ParaId(TestParachain::get()),
[parachain_head_at_relay_header_number as u8; 32].into(), [parachain_head_at_relay_header_number as u8; 32].into(),
)], )],
parachain_heads_proof: ParaHeadsProof(vec![]), parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] },
}) })
} }
@@ -1732,7 +1732,7 @@ mod tests {
(ParaId(TestParachain::get()), [1u8; 32].into()), (ParaId(TestParachain::get()), [1u8; 32].into()),
(ParaId(TestParachain::get() + 1), [1u8; 32].into()), (ParaId(TestParachain::get() + 1), [1u8; 32].into()),
], ],
parachain_heads_proof: ParaHeadsProof(vec![]), parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] },
}), }),
message_delivery_call(200), message_delivery_call(200),
], ],
+3 -2
View File
@@ -32,9 +32,8 @@
//! Shall the fork occur on the bridged chain governance intervention will be required to //! Shall the fork occur on the bridged chain governance intervention will be required to
//! re-initialize the bridge and track the right fork. //! re-initialize the bridge and track the right fork.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Runtime-generated enums
#![allow(clippy::large_enum_variant)]
pub use storage_types::StoredAuthoritySet; pub use storage_types::StoredAuthoritySet;
@@ -408,7 +407,9 @@ pub mod pallet {
pub enum Event<T: Config<I>, I: 'static = ()> { pub enum Event<T: Config<I>, I: 'static = ()> {
/// Best finalized chain header has been updated to the header with given number and hash. /// Best finalized chain header has been updated to the header with given number and hash.
UpdatedBestFinalizedHeader { UpdatedBestFinalizedHeader {
/// Number of the new best finalized header.
number: BridgedBlockNumber<T, I>, number: BridgedBlockNumber<T, I>,
/// Hash of the new best finalized header.
hash: BridgedBlockHash<T, I>, hash: BridgedBlockHash<T, I>,
/// The Grandpa info associated to the new best finalized header. /// The Grandpa info associated to the new best finalized header.
grandpa_info: StoredHeaderGrandpaInfo<BridgedHeader<T, I>>, grandpa_info: StoredHeaderGrandpaInfo<BridgedHeader<T, I>>,
+4 -2
View File
@@ -18,7 +18,7 @@
#![allow(clippy::from_over_into)] #![allow(clippy::from_over_into)]
use bp_header_chain::ChainWithGrandpa; use bp_header_chain::ChainWithGrandpa;
use bp_runtime::Chain; use bp_runtime::{Chain, ChainId};
use frame_support::{ use frame_support::{
construct_runtime, derive_impl, parameter_types, traits::Hooks, weights::Weight, construct_runtime, derive_impl, parameter_types, traits::Hooks, weights::Weight,
}; };
@@ -64,7 +64,9 @@ impl grandpa::Config for TestRuntime {
pub struct TestBridgedChain; pub struct TestBridgedChain;
impl Chain for TestBridgedChain { impl Chain for TestBridgedChain {
type BlockNumber = TestNumber; const ID: ChainId = *b"tbch";
type BlockNumber = frame_system::pallet_prelude::BlockNumberFor<TestRuntime>;
type Hash = <TestRuntime as frame_system::Config>::Hash; type Hash = <TestRuntime as frame_system::Config>::Hash;
type Hasher = <TestRuntime as frame_system::Config>::Hashing; type Hasher = <TestRuntime as frame_system::Config>::Hashing;
type Header = TestHeader; type Header = TestHeader;
+6 -20
View File
@@ -116,26 +116,12 @@ maximal possible transaction size of the chain and so on. And when the relayer s
implementation must be able to parse and verify the proof of messages delivery. Normally, you would reuse the same implementation must be able to parse and verify the proof of messages delivery. Normally, you would reuse the same
(configurable) type on all chains that are sending messages to the same bridged chain. (configurable) type on all chains that are sending messages to the same bridged chain.
The `pallet_bridge_messages::Config::LaneMessageVerifier` defines a single callback to verify outbound messages. The The last type is the `pallet_bridge_messages::Config::DeliveryConfirmationPayments`. When confirmation
simplest callback may just accept all messages. But in this case you'll need to answer many questions first. Who will transaction is received, we call the `pay_reward()` method, passing the range of delivered messages.
pay for the delivery and confirmation transaction? Are we sure that someone will ever deliver this message to the You may use the [`pallet-bridge-relayers`](../relayers/) pallet and its
bridged chain? Are we sure that we don't bloat our runtime storage by accepting this message? What if the message is [`DeliveryConfirmationPaymentsAdapter`](../relayers/src/payment_adapter.rs) adapter as a possible
improperly encoded or has some fields set to invalid values? Answering all those (and similar) questions would lead to implementation. It allows you to pay fixed reward for relaying the message and some of its portion
correct implementation. for confirming delivery.
There's another thing to consider when implementing type for use in
`pallet_bridge_messages::Config::LaneMessageVerifier`. It is whether we treat all message lanes identically, or they'll
have different sets of verification rules? For example, you may reserve lane#1 for messages coming from some
'wrapped-token' pallet - then you may verify in your implementation that the origin is associated with this pallet.
Lane#2 may be reserved for 'system' messages and you may charge zero fee for such messages. You may have some rate
limiting for messages sent over the lane#3. Or you may just verify the same rules set for all outbound messages - it is
all up to the `pallet_bridge_messages::Config::LaneMessageVerifier` implementation.
The last type is the `pallet_bridge_messages::Config::DeliveryConfirmationPayments`. When confirmation transaction is
received, we call the `pay_reward()` method, passing the range of delivered messages. You may use the
[`pallet-bridge-relayers`](../relayers/) pallet and its
[`DeliveryConfirmationPaymentsAdapter`](../relayers/src/payment_adapter.rs) adapter as a possible implementation. It
allows you to pay fixed reward for relaying the message and some of its portion for confirming delivery.
### I have a Messages Module in my Runtime, but I Want to Reject all Outbound Messages. What shall I do? ### I have a Messages Module in my Runtime, but I Want to Reject all Outbound Messages. What shall I do?
+2 -2
View File
@@ -31,7 +31,7 @@ use codec::Decode;
use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_benchmarking::{account, benchmarks_instance_pallet};
use frame_support::weights::Weight; use frame_support::weights::Weight;
use frame_system::RawOrigin; use frame_system::RawOrigin;
use sp_runtime::traits::TrailingZeroInput; use sp_runtime::{traits::TrailingZeroInput, BoundedVec};
use sp_std::{ops::RangeInclusive, prelude::*}; use sp_std::{ops::RangeInclusive, prelude::*};
const SEED: u32 = 0; const SEED: u32 = 0;
@@ -443,7 +443,7 @@ benchmarks_instance_pallet! {
fn send_regular_message<T: Config<I>, I: 'static>() { fn send_regular_message<T: Config<I>, I: 'static>() {
let mut outbound_lane = outbound_lane::<T, I>(T::bench_lane_id()); let mut outbound_lane = outbound_lane::<T, I>(T::bench_lane_id());
outbound_lane.send_message(vec![]).expect("We craft valid messages"); outbound_lane.send_message(BoundedVec::try_from(vec![]).expect("We craft valid messages"));
} }
fn receive_messages<T: Config<I>, I: 'static>(nonce: MessageNonce) { fn receive_messages<T: Config<I>, I: 'static>(nonce: MessageNonce) {
+110 -121
View File
@@ -33,9 +33,8 @@
//! If this test fails with your weights, then either weights are computed incorrectly, //! If this test fails with your weights, then either weights are computed incorrectly,
//! or some benchmarks assumptions are broken for your runtime. //! or some benchmarks assumptions are broken for your runtime.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Generated by `decl_event!`
#![allow(clippy::unused_unit)]
pub use inbound_lane::StoredInboundLaneData; pub use inbound_lane::StoredInboundLaneData;
pub use outbound_lane::StoredMessagePayload; pub use outbound_lane::StoredMessagePayload;
@@ -53,8 +52,7 @@ use crate::{
use bp_messages::{ use bp_messages::{
source_chain::{ source_chain::{
DeliveryConfirmationPayments, LaneMessageVerifier, OnMessagesDelivered, DeliveryConfirmationPayments, OnMessagesDelivered, SendMessageArtifacts, TargetHeaderChain,
SendMessageArtifacts, TargetHeaderChain,
}, },
target_chain::{ target_chain::{
DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages,
@@ -155,8 +153,6 @@ pub mod pallet {
/// Target header chain. /// Target header chain.
type TargetHeaderChain: TargetHeaderChain<Self::OutboundPayload, Self::AccountId>; type TargetHeaderChain: TargetHeaderChain<Self::OutboundPayload, Self::AccountId>;
/// Message payload verifier.
type LaneMessageVerifier: LaneMessageVerifier<Self::OutboundPayload>;
/// Delivery confirmation payments. /// Delivery confirmation payments.
type DeliveryConfirmationPayments: DeliveryConfirmationPayments<Self::AccountId>; type DeliveryConfirmationPayments: DeliveryConfirmationPayments<Self::AccountId>;
/// Delivery confirmation callback. /// Delivery confirmation callback.
@@ -517,16 +513,28 @@ pub mod pallet {
#[pallet::generate_deposit(pub(super) fn deposit_event)] #[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> { pub enum Event<T: Config<I>, I: 'static = ()> {
/// Message has been accepted and is waiting to be delivered. /// Message has been accepted and is waiting to be delivered.
MessageAccepted { lane_id: LaneId, nonce: MessageNonce }, MessageAccepted {
/// Lane, which has accepted the message.
lane_id: LaneId,
/// Nonce of accepted message.
nonce: MessageNonce,
},
/// Messages have been received from the bridged chain. /// Messages have been received from the bridged chain.
MessagesReceived( MessagesReceived(
/// Result of received messages dispatch.
Vec<ReceivedMessages<<T::MessageDispatch as MessageDispatch>::DispatchLevelResult>>, Vec<ReceivedMessages<<T::MessageDispatch as MessageDispatch>::DispatchLevelResult>>,
), ),
/// Messages in the inclusive range have been delivered to the bridged chain. /// Messages in the inclusive range have been delivered to the bridged chain.
MessagesDelivered { lane_id: LaneId, messages: DeliveredMessages }, MessagesDelivered {
/// Lane for which the delivery has been confirmed.
lane_id: LaneId,
/// Delivered messages.
messages: DeliveredMessages,
},
} }
#[pallet::error] #[pallet::error]
#[derive(PartialEq, Eq)]
pub enum Error<T, I = ()> { pub enum Error<T, I = ()> {
/// Pallet is not in Normal operating mode. /// Pallet is not in Normal operating mode.
NotOperatingNormally, NotOperatingNormally,
@@ -536,8 +544,6 @@ pub mod pallet {
MessageDispatchInactive, MessageDispatchInactive,
/// Message has been treated as invalid by chain verifier. /// Message has been treated as invalid by chain verifier.
MessageRejectedByChainVerifier(VerificationError), MessageRejectedByChainVerifier(VerificationError),
/// Message has been treated as invalid by lane verifier.
MessageRejectedByLaneVerifier(VerificationError),
/// Message has been treated as invalid by the pallet logic. /// Message has been treated as invalid by the pallet logic.
MessageRejectedByPallet(VerificationError), MessageRejectedByPallet(VerificationError),
/// Submitter has failed to pay fee for delivering and dispatching messages. /// Submitter has failed to pay fee for delivering and dispatching messages.
@@ -683,80 +689,72 @@ pub mod pallet {
} }
} }
/// Structure, containing a validated message payload and all the info required
/// to send it on the bridge.
#[derive(Debug, PartialEq, Eq)]
pub struct SendMessageArgs<T: Config<I>, I: 'static> {
lane_id: LaneId,
payload: StoredMessagePayload<T, I>,
}
impl<T, I> bp_messages::source_chain::MessagesBridge<T::OutboundPayload> for Pallet<T, I> impl<T, I> bp_messages::source_chain::MessagesBridge<T::OutboundPayload> for Pallet<T, I>
where where
T: Config<I>, T: Config<I>,
I: 'static, I: 'static,
{ {
type Error = sp_runtime::DispatchErrorWithPostInfo<PostDispatchInfo>; type Error = Error<T, I>;
type SendMessageArgs = SendMessageArgs<T, I>;
fn send_message( fn validate_message(
lane: LaneId, lane: LaneId,
message: T::OutboundPayload, message: &T::OutboundPayload,
) -> Result<SendMessageArtifacts, Self::Error> { ) -> Result<SendMessageArgs<T, I>, Self::Error> {
crate::send_message::<T, I>(lane, message) ensure_normal_operating_mode::<T, I>()?;
// let's check if outbound lane is active
ensure!(T::ActiveOutboundLanes::get().contains(&lane), Error::<T, I>::InactiveOutboundLane);
// let's first check if message can be delivered to target chain
T::TargetHeaderChain::verify_message(message).map_err(|err| {
log::trace!(
target: LOG_TARGET,
"Message to lane {:?} is rejected by target chain: {:?}",
lane,
err,
);
Error::<T, I>::MessageRejectedByChainVerifier(err)
})?;
Ok(SendMessageArgs {
lane_id: lane,
payload: StoredMessagePayload::<T, I>::try_from(message.encode()).map_err(|_| {
Error::<T, I>::MessageRejectedByPallet(VerificationError::MessageTooLarge)
})?,
})
} }
}
/// Function that actually sends message. fn send_message(args: SendMessageArgs<T, I>) -> SendMessageArtifacts {
fn send_message<T: Config<I>, I: 'static>( // save message in outbound storage and emit event
lane_id: LaneId, let mut lane = outbound_lane::<T, I>(args.lane_id);
payload: T::OutboundPayload, let message_len = args.payload.len();
) -> sp_std::result::Result< let nonce = lane.send_message(args.payload);
SendMessageArtifacts,
sp_runtime::DispatchErrorWithPostInfo<PostDispatchInfo>,
> {
ensure_normal_operating_mode::<T, I>()?;
// let's check if outbound lane is active // return number of messages in the queue to let sender know about its state
ensure!(T::ActiveOutboundLanes::get().contains(&lane_id), Error::<T, I>::InactiveOutboundLane,); let enqueued_messages = lane.data().queued_messages().saturating_len();
// let's first check if message can be delivered to target chain
T::TargetHeaderChain::verify_message(&payload).map_err(|err| {
log::trace!( log::trace!(
target: LOG_TARGET, target: LOG_TARGET,
"Message to lane {:?} is rejected by target chain: {:?}", "Accepted message {} to lane {:?}. Message size: {:?}",
lane_id, nonce,
err, args.lane_id,
message_len,
); );
Error::<T, I>::MessageRejectedByChainVerifier(err) Pallet::<T, I>::deposit_event(Event::MessageAccepted { lane_id: args.lane_id, nonce });
})?;
// now let's enforce any additional lane rules SendMessageArtifacts { nonce, enqueued_messages }
let mut lane = outbound_lane::<T, I>(lane_id); }
T::LaneMessageVerifier::verify_message(&lane_id, &lane.data(), &payload).map_err(|err| {
log::trace!(
target: LOG_TARGET,
"Message to lane {:?} is rejected by lane verifier: {:?}",
lane_id,
err,
);
Error::<T, I>::MessageRejectedByLaneVerifier(err)
})?;
// finally, save message in outbound storage and emit event
let encoded_payload = payload.encode();
let encoded_payload_len = encoded_payload.len();
let nonce = lane
.send_message(encoded_payload)
.map_err(Error::<T, I>::MessageRejectedByPallet)?;
// return number of messages in the queue to let sender know about its state
let enqueued_messages = lane.data().queued_messages().saturating_len();
log::trace!(
target: LOG_TARGET,
"Accepted message {} to lane {:?}. Message size: {:?}",
nonce,
lane_id,
encoded_payload_len,
);
Pallet::<T, I>::deposit_event(Event::MessageAccepted { lane_id, nonce });
Ok(SendMessageArtifacts { nonce, enqueued_messages })
} }
/// Ensure that the pallet is in normal operational mode. /// Ensure that the pallet is in normal operational mode.
@@ -857,6 +855,8 @@ struct RuntimeOutboundLaneStorage<T, I = ()> {
} }
impl<T: Config<I>, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorage<T, I> { impl<T: Config<I>, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorage<T, I> {
type StoredMessagePayload = StoredMessagePayload<T, I>;
fn id(&self) -> LaneId { fn id(&self) -> LaneId {
self.lane_id self.lane_id
} }
@@ -870,22 +870,15 @@ impl<T: Config<I>, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag
} }
#[cfg(test)] #[cfg(test)]
fn message(&self, nonce: &MessageNonce) -> Option<MessagePayload> { fn message(&self, nonce: &MessageNonce) -> Option<Self::StoredMessagePayload> {
OutboundMessages::<T, I>::get(MessageKey { lane_id: self.lane_id, nonce: *nonce }) OutboundMessages::<T, I>::get(MessageKey { lane_id: self.lane_id, nonce: *nonce })
.map(Into::into)
} }
fn save_message( fn save_message(&mut self, nonce: MessageNonce, message_payload: Self::StoredMessagePayload) {
&mut self,
nonce: MessageNonce,
message_payload: MessagePayload,
) -> Result<(), VerificationError> {
OutboundMessages::<T, I>::insert( OutboundMessages::<T, I>::insert(
MessageKey { lane_id: self.lane_id, nonce }, MessageKey { lane_id: self.lane_id, nonce },
StoredMessagePayload::<T, I>::try_from(message_payload) message_payload,
.map_err(|_| VerificationError::MessageTooLarge)?,
); );
Ok(())
} }
fn remove_message(&mut self, nonce: &MessageNonce) { fn remove_message(&mut self, nonce: &MessageNonce) {
@@ -932,7 +925,10 @@ mod tests {
}, },
outbound_lane::ReceivalConfirmationError, outbound_lane::ReceivalConfirmationError,
}; };
use bp_messages::{BridgeMessagesCall, UnrewardedRelayer, UnrewardedRelayersState}; use bp_messages::{
source_chain::MessagesBridge, BridgeMessagesCall, UnrewardedRelayer,
UnrewardedRelayersState,
};
use bp_test_utils::generate_owned_bridge_module_tests; use bp_test_utils::generate_owned_bridge_module_tests;
use frame_support::{ use frame_support::{
assert_noop, assert_ok, assert_noop, assert_ok,
@@ -949,14 +945,15 @@ mod tests {
System::<TestRuntime>::reset_events(); System::<TestRuntime>::reset_events();
} }
fn send_regular_message() { fn send_regular_message(lane_id: LaneId) {
get_ready_for_events(); get_ready_for_events();
let outbound_lane = outbound_lane::<TestRuntime, ()>(TEST_LANE_ID); let outbound_lane = outbound_lane::<TestRuntime, ()>(lane_id);
let message_nonce = outbound_lane.data().latest_generated_nonce + 1; let message_nonce = outbound_lane.data().latest_generated_nonce + 1;
let prev_enqueud_messages = outbound_lane.data().queued_messages().saturating_len(); let prev_enqueud_messages = outbound_lane.data().queued_messages().saturating_len();
let artifacts = send_message::<TestRuntime, ()>(TEST_LANE_ID, REGULAR_PAYLOAD) let valid_message = Pallet::<TestRuntime, ()>::validate_message(lane_id, &REGULAR_PAYLOAD)
.expect("send_message has failed"); .expect("validate_message has failed");
let artifacts = Pallet::<TestRuntime, ()>::send_message(valid_message);
assert_eq!(artifacts.enqueued_messages, prev_enqueud_messages + 1); assert_eq!(artifacts.enqueued_messages, prev_enqueud_messages + 1);
// check event with assigned nonce // check event with assigned nonce
@@ -965,7 +962,7 @@ mod tests {
vec![EventRecord { vec![EventRecord {
phase: Phase::Initialization, phase: Phase::Initialization,
event: TestEvent::Messages(Event::MessageAccepted { event: TestEvent::Messages(Event::MessageAccepted {
lane_id: TEST_LANE_ID, lane_id,
nonce: message_nonce nonce: message_nonce
}), }),
topics: vec![], topics: vec![],
@@ -1016,14 +1013,14 @@ mod tests {
fn pallet_rejects_transactions_if_halted() { fn pallet_rejects_transactions_if_halted() {
run_test(|| { run_test(|| {
// send message first to be able to check that delivery_proof fails later // send message first to be able to check that delivery_proof fails later
send_regular_message(); send_regular_message(TEST_LANE_ID);
PalletOperatingMode::<TestRuntime, ()>::put(MessagesOperatingMode::Basic( PalletOperatingMode::<TestRuntime, ()>::put(MessagesOperatingMode::Basic(
BasicOperatingMode::Halted, BasicOperatingMode::Halted,
)); ));
assert_noop!( assert_noop!(
send_message::<TestRuntime, ()>(TEST_LANE_ID, REGULAR_PAYLOAD,), Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, &REGULAR_PAYLOAD),
Error::<TestRuntime, ()>::NotOperatingNormally, Error::<TestRuntime, ()>::NotOperatingNormally,
); );
@@ -1066,14 +1063,14 @@ mod tests {
fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() { fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() {
run_test(|| { run_test(|| {
// send message first to be able to check that delivery_proof fails later // send message first to be able to check that delivery_proof fails later
send_regular_message(); send_regular_message(TEST_LANE_ID);
PalletOperatingMode::<TestRuntime, ()>::put( PalletOperatingMode::<TestRuntime, ()>::put(
MessagesOperatingMode::RejectingOutboundMessages, MessagesOperatingMode::RejectingOutboundMessages,
); );
assert_noop!( assert_noop!(
send_message::<TestRuntime, ()>(TEST_LANE_ID, REGULAR_PAYLOAD,), Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, &REGULAR_PAYLOAD),
Error::<TestRuntime, ()>::NotOperatingNormally, Error::<TestRuntime, ()>::NotOperatingNormally,
); );
@@ -1109,7 +1106,7 @@ mod tests {
#[test] #[test]
fn send_message_works() { fn send_message_works() {
run_test(|| { run_test(|| {
send_regular_message(); send_regular_message(TEST_LANE_ID);
}); });
} }
@@ -1123,7 +1120,7 @@ mod tests {
.extra .extra
.extend_from_slice(&[0u8; MAX_OUTBOUND_PAYLOAD_SIZE as usize]); .extend_from_slice(&[0u8; MAX_OUTBOUND_PAYLOAD_SIZE as usize]);
assert_noop!( assert_noop!(
send_message::<TestRuntime, ()>(TEST_LANE_ID, message_payload.clone(),), Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, &message_payload.clone(),),
Error::<TestRuntime, ()>::MessageRejectedByPallet( Error::<TestRuntime, ()>::MessageRejectedByPallet(
VerificationError::MessageTooLarge VerificationError::MessageTooLarge
), ),
@@ -1134,7 +1131,11 @@ mod tests {
message_payload.extra.pop(); message_payload.extra.pop();
} }
assert_eq!(message_payload.encoded_size() as u32, MAX_OUTBOUND_PAYLOAD_SIZE); assert_eq!(message_payload.encoded_size() as u32, MAX_OUTBOUND_PAYLOAD_SIZE);
assert_ok!(send_message::<TestRuntime, ()>(TEST_LANE_ID, message_payload,),);
let valid_message =
Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID, &message_payload)
.expect("validate_message has failed");
Pallet::<TestRuntime, ()>::send_message(valid_message);
}) })
} }
@@ -1143,7 +1144,10 @@ mod tests {
run_test(|| { run_test(|| {
// messages with this payload are rejected by target chain verifier // messages with this payload are rejected by target chain verifier
assert_noop!( assert_noop!(
send_message::<TestRuntime, ()>(TEST_LANE_ID, PAYLOAD_REJECTED_BY_TARGET_CHAIN,), Pallet::<TestRuntime, ()>::validate_message(
TEST_LANE_ID,
&PAYLOAD_REJECTED_BY_TARGET_CHAIN,
),
Error::<TestRuntime, ()>::MessageRejectedByChainVerifier(VerificationError::Other( Error::<TestRuntime, ()>::MessageRejectedByChainVerifier(VerificationError::Other(
mock::TEST_ERROR mock::TEST_ERROR
)), )),
@@ -1151,21 +1155,6 @@ mod tests {
}); });
} }
#[test]
fn lane_verifier_rejects_invalid_message_in_send_message() {
run_test(|| {
// messages with zero fee are rejected by lane verifier
let mut message = REGULAR_PAYLOAD;
message.reject_by_lane_verifier = true;
assert_noop!(
send_message::<TestRuntime, ()>(TEST_LANE_ID, message,),
Error::<TestRuntime, ()>::MessageRejectedByLaneVerifier(VerificationError::Other(
mock::TEST_ERROR
)),
);
});
}
#[test] #[test]
fn receive_messages_proof_works() { fn receive_messages_proof_works() {
run_test(|| { run_test(|| {
@@ -1318,7 +1307,7 @@ mod tests {
#[test] #[test]
fn receive_messages_delivery_proof_works() { fn receive_messages_delivery_proof_works() {
run_test(|| { run_test(|| {
send_regular_message(); send_regular_message(TEST_LANE_ID);
receive_messages_delivery_proof(); receive_messages_delivery_proof();
assert_eq!( assert_eq!(
@@ -1331,8 +1320,8 @@ mod tests {
#[test] #[test]
fn receive_messages_delivery_proof_rewards_relayers() { fn receive_messages_delivery_proof_rewards_relayers() {
run_test(|| { run_test(|| {
assert_ok!(send_message::<TestRuntime, ()>(TEST_LANE_ID, REGULAR_PAYLOAD,)); send_regular_message(TEST_LANE_ID);
assert_ok!(send_message::<TestRuntime, ()>(TEST_LANE_ID, REGULAR_PAYLOAD,)); send_regular_message(TEST_LANE_ID);
// this reports delivery of message 1 => reward is paid to TEST_RELAYER_A // this reports delivery of message 1 => reward is paid to TEST_RELAYER_A
let single_message_delivery_proof = TestMessagesDeliveryProof(Ok(( let single_message_delivery_proof = TestMessagesDeliveryProof(Ok((
@@ -1718,9 +1707,9 @@ mod tests {
#[test] #[test]
fn messages_delivered_callbacks_are_called() { fn messages_delivered_callbacks_are_called() {
run_test(|| { run_test(|| {
send_regular_message(); send_regular_message(TEST_LANE_ID);
send_regular_message(); send_regular_message(TEST_LANE_ID);
send_regular_message(); send_regular_message(TEST_LANE_ID);
// messages 1+2 are confirmed in 1 tx, message 3 in a separate tx // messages 1+2 are confirmed in 1 tx, message 3 in a separate tx
// dispatch of message 2 has failed // dispatch of message 2 has failed
@@ -1779,7 +1768,7 @@ mod tests {
) { ) {
run_test(|| { run_test(|| {
// send message first to be able to check that delivery_proof fails later // send message first to be able to check that delivery_proof fails later
send_regular_message(); send_regular_message(TEST_LANE_ID);
// 1) InboundLaneData declares that the `last_confirmed_nonce` is 1; // 1) InboundLaneData declares that the `last_confirmed_nonce` is 1;
// 2) InboundLaneData has no entries => `InboundLaneData::last_delivered_nonce()` // 2) InboundLaneData has no entries => `InboundLaneData::last_delivered_nonce()`
@@ -1846,10 +1835,10 @@ mod tests {
#[test] #[test]
fn on_idle_callback_respects_remaining_weight() { fn on_idle_callback_respects_remaining_weight() {
run_test(|| { run_test(|| {
send_regular_message(); send_regular_message(TEST_LANE_ID);
send_regular_message(); send_regular_message(TEST_LANE_ID);
send_regular_message(); send_regular_message(TEST_LANE_ID);
send_regular_message(); send_regular_message(TEST_LANE_ID);
assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof(
RuntimeOrigin::signed(1), RuntimeOrigin::signed(1),
@@ -1928,10 +1917,10 @@ mod tests {
fn on_idle_callback_is_rotating_lanes_to_prune() { fn on_idle_callback_is_rotating_lanes_to_prune() {
run_test(|| { run_test(|| {
// send + receive confirmation for lane 1 // send + receive confirmation for lane 1
send_regular_message(); send_regular_message(TEST_LANE_ID);
receive_messages_delivery_proof(); receive_messages_delivery_proof();
// send + receive confirmation for lane 2 // send + receive confirmation for lane 2
assert_ok!(send_message::<TestRuntime, ()>(TEST_LANE_ID_2, REGULAR_PAYLOAD,)); send_regular_message(TEST_LANE_ID_2);
assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof( assert_ok!(Pallet::<TestRuntime>::receive_messages_delivery_proof(
RuntimeOrigin::signed(1), RuntimeOrigin::signed(1),
TestMessagesDeliveryProof(Ok(( TestMessagesDeliveryProof(Ok((
@@ -2007,7 +1996,7 @@ mod tests {
fn outbound_message_from_unconfigured_lane_is_rejected() { fn outbound_message_from_unconfigured_lane_is_rejected() {
run_test(|| { run_test(|| {
assert_noop!( assert_noop!(
send_message::<TestRuntime, ()>(TEST_LANE_ID_3, REGULAR_PAYLOAD,), Pallet::<TestRuntime, ()>::validate_message(TEST_LANE_ID_3, &REGULAR_PAYLOAD,),
Error::<TestRuntime, ()>::InactiveOutboundLane, Error::<TestRuntime, ()>::InactiveOutboundLane,
); );
}); });
+6 -30
View File
@@ -17,19 +17,17 @@
// From construct_runtime macro // From construct_runtime macro
#![allow(clippy::from_over_into)] #![allow(clippy::from_over_into)]
use crate::Config; use crate::{Config, StoredMessagePayload};
use bp_messages::{ use bp_messages::{
calc_relayers_rewards, calc_relayers_rewards,
source_chain::{ source_chain::{DeliveryConfirmationPayments, OnMessagesDelivered, TargetHeaderChain},
DeliveryConfirmationPayments, LaneMessageVerifier, OnMessagesDelivered, TargetHeaderChain,
},
target_chain::{ target_chain::{
DeliveryPayments, DispatchMessage, DispatchMessageData, MessageDispatch, DeliveryPayments, DispatchMessage, DispatchMessageData, MessageDispatch,
ProvedLaneMessages, ProvedMessages, SourceHeaderChain, ProvedLaneMessages, ProvedMessages, SourceHeaderChain,
}, },
DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce,
OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, VerificationError, UnrewardedRelayer, UnrewardedRelayersState, VerificationError,
}; };
use bp_runtime::{messages::MessageDispatchResult, Size}; use bp_runtime::{messages::MessageDispatchResult, Size};
use codec::{Decode, Encode}; use codec::{Decode, Encode};
@@ -50,8 +48,6 @@ pub type Balance = u64;
pub struct TestPayload { pub struct TestPayload {
/// Field that may be used to identify messages. /// Field that may be used to identify messages.
pub id: u64, pub id: u64,
/// Reject this message by lane verifier?
pub reject_by_lane_verifier: bool,
/// Dispatch weight that is declared by the message sender. /// Dispatch weight that is declared by the message sender.
pub declared_weight: Weight, pub declared_weight: Weight,
/// Message dispatch result. /// Message dispatch result.
@@ -120,7 +116,6 @@ impl Config for TestRuntime {
type DeliveryPayments = TestDeliveryPayments; type DeliveryPayments = TestDeliveryPayments;
type TargetHeaderChain = TestTargetHeaderChain; type TargetHeaderChain = TestTargetHeaderChain;
type LaneMessageVerifier = TestLaneMessageVerifier;
type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments; type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments;
type OnMessagesDelivered = TestOnMessagesDelivered; type OnMessagesDelivered = TestOnMessagesDelivered;
@@ -268,24 +263,6 @@ impl TargetHeaderChain<TestPayload, TestRelayer> for TestTargetHeaderChain {
} }
} }
/// Lane message verifier that is used in tests.
#[derive(Debug, Default)]
pub struct TestLaneMessageVerifier;
impl LaneMessageVerifier<TestPayload> for TestLaneMessageVerifier {
fn verify_message(
_lane: &LaneId,
_lane_outbound_data: &OutboundLaneData,
payload: &TestPayload,
) -> Result<(), VerificationError> {
if !payload.reject_by_lane_verifier {
Ok(())
} else {
Err(VerificationError::Other(TEST_ERROR))
}
}
}
/// Reward payments at the target chain during delivery transaction. /// Reward payments at the target chain during delivery transaction.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct TestDeliveryPayments; pub struct TestDeliveryPayments;
@@ -425,8 +402,8 @@ pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message {
} }
/// Return valid outbound message data, constructed from given payload. /// Return valid outbound message data, constructed from given payload.
pub fn outbound_message_data(payload: TestPayload) -> MessagePayload { pub fn outbound_message_data(payload: TestPayload) -> StoredMessagePayload<TestRuntime, ()> {
payload.encode() StoredMessagePayload::<TestRuntime, ()>::try_from(payload.encode()).expect("payload too large")
} }
/// Return valid inbound (dispatch) message data, constructed from given payload. /// Return valid inbound (dispatch) message data, constructed from given payload.
@@ -438,7 +415,6 @@ pub fn inbound_message_data(payload: TestPayload) -> DispatchMessageData<TestPay
pub const fn message_payload(id: u64, declared_weight: u64) -> TestPayload { pub const fn message_payload(id: u64, declared_weight: u64) -> TestPayload {
TestPayload { TestPayload {
id, id,
reject_by_lane_verifier: false,
declared_weight: Weight::from_parts(declared_weight, 0), declared_weight: Weight::from_parts(declared_weight, 0),
dispatch_result: dispatch_result(0), dispatch_result: dispatch_result(0),
extra: Vec::new(), extra: Vec::new(),
+25 -33
View File
@@ -18,10 +18,7 @@
use crate::{Config, LOG_TARGET}; use crate::{Config, LOG_TARGET};
use bp_messages::{ use bp_messages::{DeliveredMessages, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer};
DeliveredMessages, LaneId, MessageNonce, MessagePayload, OutboundLaneData, UnrewardedRelayer,
VerificationError,
};
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use frame_support::{ use frame_support::{
weights::{RuntimeDbWeight, Weight}, weights::{RuntimeDbWeight, Weight},
@@ -34,6 +31,8 @@ use sp_std::collections::vec_deque::VecDeque;
/// Outbound lane storage. /// Outbound lane storage.
pub trait OutboundLaneStorage { pub trait OutboundLaneStorage {
type StoredMessagePayload;
/// Lane id. /// Lane id.
fn id(&self) -> LaneId; fn id(&self) -> LaneId;
/// Get lane data from the storage. /// Get lane data from the storage.
@@ -42,13 +41,9 @@ pub trait OutboundLaneStorage {
fn set_data(&mut self, data: OutboundLaneData); fn set_data(&mut self, data: OutboundLaneData);
/// Returns saved outbound message payload. /// Returns saved outbound message payload.
#[cfg(test)] #[cfg(test)]
fn message(&self, nonce: &MessageNonce) -> Option<MessagePayload>; fn message(&self, nonce: &MessageNonce) -> Option<Self::StoredMessagePayload>;
/// Save outbound message in the storage. /// Save outbound message in the storage.
fn save_message( fn save_message(&mut self, nonce: MessageNonce, message_payload: Self::StoredMessagePayload);
&mut self,
nonce: MessageNonce,
message_payload: MessagePayload,
) -> Result<(), VerificationError>;
/// Remove outbound message from the storage. /// Remove outbound message from the storage.
fn remove_message(&mut self, nonce: &MessageNonce); fn remove_message(&mut self, nonce: &MessageNonce);
} }
@@ -91,18 +86,15 @@ impl<S: OutboundLaneStorage> OutboundLane<S> {
/// Send message over lane. /// Send message over lane.
/// ///
/// Returns new message nonce. /// Returns new message nonce.
pub fn send_message( pub fn send_message(&mut self, message_payload: S::StoredMessagePayload) -> MessageNonce {
&mut self,
message_payload: MessagePayload,
) -> Result<MessageNonce, VerificationError> {
let mut data = self.storage.data(); let mut data = self.storage.data();
let nonce = data.latest_generated_nonce + 1; let nonce = data.latest_generated_nonce + 1;
data.latest_generated_nonce = nonce; data.latest_generated_nonce = nonce;
self.storage.save_message(nonce, message_payload)?; self.storage.save_message(nonce, message_payload);
self.storage.set_data(data); self.storage.set_data(data);
Ok(nonce) nonce
} }
/// Confirm messages delivery. /// Confirm messages delivery.
@@ -218,7 +210,7 @@ mod tests {
}, },
outbound_lane, outbound_lane,
}; };
use frame_support::{assert_ok, weights::constants::RocksDbWeight}; use frame_support::weights::constants::RocksDbWeight;
use sp_std::ops::RangeInclusive; use sp_std::ops::RangeInclusive;
fn unrewarded_relayers( fn unrewarded_relayers(
@@ -239,9 +231,9 @@ mod tests {
) -> Result<Option<DeliveredMessages>, ReceivalConfirmationError> { ) -> Result<Option<DeliveredMessages>, ReceivalConfirmationError> {
run_test(|| { run_test(|| {
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID); let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_generated_nonce, 3);
assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!(lane.storage.data().latest_received_nonce, 0);
let result = lane.confirm_delivery(3, latest_received_nonce, relayers); let result = lane.confirm_delivery(3, latest_received_nonce, relayers);
@@ -256,7 +248,7 @@ mod tests {
run_test(|| { run_test(|| {
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID); let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
assert_eq!(lane.storage.data().latest_generated_nonce, 0); assert_eq!(lane.storage.data().latest_generated_nonce, 0);
assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(1)); assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1);
assert!(lane.storage.message(&1).is_some()); assert!(lane.storage.message(&1).is_some());
assert_eq!(lane.storage.data().latest_generated_nonce, 1); assert_eq!(lane.storage.data().latest_generated_nonce, 1);
}); });
@@ -266,9 +258,9 @@ mod tests {
fn confirm_delivery_works() { fn confirm_delivery_works() {
run_test(|| { run_test(|| {
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID); let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(1)); assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1);
assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(2)); assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 2);
assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(3)); assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3);
assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_generated_nonce, 3);
assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!(lane.storage.data().latest_received_nonce, 0);
assert_eq!( assert_eq!(
@@ -284,9 +276,9 @@ mod tests {
fn confirm_delivery_rejects_nonce_lesser_than_latest_received() { fn confirm_delivery_rejects_nonce_lesser_than_latest_received() {
run_test(|| { run_test(|| {
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID); let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_generated_nonce, 3);
assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!(lane.storage.data().latest_received_nonce, 0);
assert_eq!( assert_eq!(
@@ -368,9 +360,9 @@ mod tests {
); );
assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1);
// when nothing is confirmed, nothing is pruned // when nothing is confirmed, nothing is pruned
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert!(lane.storage.message(&1).is_some()); assert!(lane.storage.message(&1).is_some());
assert!(lane.storage.message(&2).is_some()); assert!(lane.storage.message(&2).is_some());
assert!(lane.storage.message(&3).is_some()); assert!(lane.storage.message(&3).is_some());
@@ -412,9 +404,9 @@ mod tests {
fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() { fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() {
run_test(|| { run_test(|| {
let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID); let mut lane = outbound_lane::<TestRuntime, _>(TEST_LANE_ID);
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); lane.send_message(outbound_message_data(REGULAR_PAYLOAD));
assert_eq!( assert_eq!(
lane.confirm_delivery(0, 3, &unrewarded_relayers(1..=3)), lane.confirm_delivery(0, 3, &unrewarded_relayers(1..=3)),
Err(ReceivalConfirmationError::TryingToConfirmMoreMessagesThanExpected), Err(ReceivalConfirmationError::TryingToConfirmMoreMessagesThanExpected),
+1 -1
View File
@@ -178,7 +178,7 @@ mod tests {
RuntimeCall::Parachains(crate::Call::<TestRuntime, ()>::submit_parachain_heads { RuntimeCall::Parachains(crate::Call::<TestRuntime, ()>::submit_parachain_heads {
at_relay_block: (num, Default::default()), at_relay_block: (num, Default::default()),
parachains, parachains,
parachain_heads_proof: ParaHeadsProof(Vec::new()), parachain_heads_proof: ParaHeadsProof { storage_proof: Vec::new() },
}) })
.check_obsolete_submit_parachain_heads() .check_obsolete_submit_parachain_heads()
.is_ok() .is_ok()
+29 -5
View File
@@ -21,6 +21,7 @@
//! accepts storage proof of some parachain `Heads` entries from bridged relay chain. //! accepts storage proof of some parachain `Heads` entries from bridged relay chain.
//! It requires corresponding relay headers to be already synced. //! It requires corresponding relay headers to be already synced.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
pub use weights::WeightInfo; pub use weights::WeightInfo;
@@ -98,27 +99,49 @@ pub mod pallet {
#[pallet::generate_deposit(pub(super) fn deposit_event)] #[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> { pub enum Event<T: Config<I>, I: 'static = ()> {
/// The caller has provided head of parachain that the pallet is not configured to track. /// The caller has provided head of parachain that the pallet is not configured to track.
UntrackedParachainRejected { parachain: ParaId }, UntrackedParachainRejected {
/// Identifier of the parachain that is not tracked by the pallet.
parachain: ParaId,
},
/// The caller has declared that he has provided given parachain head, but it is missing /// The caller has declared that he has provided given parachain head, but it is missing
/// from the storage proof. /// from the storage proof.
MissingParachainHead { parachain: ParaId }, MissingParachainHead {
/// Identifier of the parachain with missing head.
parachain: ParaId,
},
/// The caller has provided parachain head hash that is not matching the hash read from the /// The caller has provided parachain head hash that is not matching the hash read from the
/// storage proof. /// storage proof.
IncorrectParachainHeadHash { IncorrectParachainHeadHash {
/// Identifier of the parachain with incorrect head hast.
parachain: ParaId, parachain: ParaId,
/// Specified parachain head hash.
parachain_head_hash: ParaHash, parachain_head_hash: ParaHash,
/// Actual parachain head hash.
actual_parachain_head_hash: ParaHash, actual_parachain_head_hash: ParaHash,
}, },
/// The caller has provided obsolete parachain head, which is already known to the pallet. /// The caller has provided obsolete parachain head, which is already known to the pallet.
RejectedObsoleteParachainHead { parachain: ParaId, parachain_head_hash: ParaHash }, RejectedObsoleteParachainHead {
/// Identifier of the parachain with obsolete head.
parachain: ParaId,
/// Obsolete parachain head hash.
parachain_head_hash: ParaHash,
},
/// The caller has provided parachain head that exceeds the maximal configured head size. /// The caller has provided parachain head that exceeds the maximal configured head size.
RejectedLargeParachainHead { RejectedLargeParachainHead {
/// Identifier of the parachain with rejected head.
parachain: ParaId, parachain: ParaId,
/// Parachain head hash.
parachain_head_hash: ParaHash, parachain_head_hash: ParaHash,
/// Parachain head size.
parachain_head_size: u32, parachain_head_size: u32,
}, },
/// Parachain head has been updated. /// Parachain head has been updated.
UpdatedParachainHead { parachain: ParaId, parachain_head_hash: ParaHash }, UpdatedParachainHead {
/// Identifier of the parachain that has been updated.
parachain: ParaId,
/// Parachain head hash.
parachain_head_hash: ParaHash,
},
} }
#[pallet::error] #[pallet::error]
@@ -137,6 +160,7 @@ pub mod pallet {
pub trait BoundedBridgeGrandpaConfig<I: 'static>: pub trait BoundedBridgeGrandpaConfig<I: 'static>:
pallet_bridge_grandpa::Config<I, BridgedChain = Self::BridgedRelayChain> pallet_bridge_grandpa::Config<I, BridgedChain = Self::BridgedRelayChain>
{ {
/// Type of the bridged relay chain.
type BridgedRelayChain: Chain< type BridgedRelayChain: Chain<
BlockNumber = RelayBlockNumber, BlockNumber = RelayBlockNumber,
Hash = RelayBlockHash, Hash = RelayBlockHash,
@@ -336,7 +360,7 @@ pub mod pallet {
let mut storage = GrandpaPalletOf::<T, I>::storage_proof_checker( let mut storage = GrandpaPalletOf::<T, I>::storage_proof_checker(
relay_block_hash, relay_block_hash,
parachain_heads_proof.0, parachain_heads_proof.storage_proof,
) )
.map_err(Error::<T, I>::HeaderChainStorageProof)?; .map_err(Error::<T, I>::HeaderChainStorageProof)?;
+13 -1
View File
@@ -16,7 +16,7 @@
use bp_header_chain::ChainWithGrandpa; use bp_header_chain::ChainWithGrandpa;
use bp_polkadot_core::parachains::ParaId; use bp_polkadot_core::parachains::ParaId;
use bp_runtime::{Chain, Parachain}; use bp_runtime::{Chain, ChainId, Parachain};
use frame_support::{ use frame_support::{
construct_runtime, derive_impl, parameter_types, traits::ConstU32, weights::Weight, construct_runtime, derive_impl, parameter_types, traits::ConstU32, weights::Weight,
}; };
@@ -49,6 +49,8 @@ pub type BigParachainHeader = sp_runtime::generic::Header<u128, BlakeTwo256>;
pub struct Parachain1; pub struct Parachain1;
impl Chain for Parachain1 { impl Chain for Parachain1 {
const ID: ChainId = *b"pch1";
type BlockNumber = u64; type BlockNumber = u64;
type Hash = H256; type Hash = H256;
type Hasher = RegularParachainHasher; type Hasher = RegularParachainHasher;
@@ -73,6 +75,8 @@ impl Parachain for Parachain1 {
pub struct Parachain2; pub struct Parachain2;
impl Chain for Parachain2 { impl Chain for Parachain2 {
const ID: ChainId = *b"pch2";
type BlockNumber = u64; type BlockNumber = u64;
type Hash = H256; type Hash = H256;
type Hasher = RegularParachainHasher; type Hasher = RegularParachainHasher;
@@ -97,6 +101,8 @@ impl Parachain for Parachain2 {
pub struct Parachain3; pub struct Parachain3;
impl Chain for Parachain3 { impl Chain for Parachain3 {
const ID: ChainId = *b"pch3";
type BlockNumber = u64; type BlockNumber = u64;
type Hash = H256; type Hash = H256;
type Hasher = RegularParachainHasher; type Hasher = RegularParachainHasher;
@@ -122,6 +128,8 @@ impl Parachain for Parachain3 {
pub struct BigParachain; pub struct BigParachain;
impl Chain for BigParachain { impl Chain for BigParachain {
const ID: ChainId = *b"bpch";
type BlockNumber = u128; type BlockNumber = u128;
type Hash = H256; type Hash = H256;
type Hasher = RegularParachainHasher; type Hasher = RegularParachainHasher;
@@ -229,6 +237,8 @@ impl pallet_bridge_parachains::benchmarking::Config<()> for TestRuntime {
pub struct TestBridgedChain; pub struct TestBridgedChain;
impl Chain for TestBridgedChain { impl Chain for TestBridgedChain {
const ID: ChainId = *b"tbch";
type BlockNumber = crate::RelayBlockNumber; type BlockNumber = crate::RelayBlockNumber;
type Hash = crate::RelayBlockHash; type Hash = crate::RelayBlockHash;
type Hasher = crate::RelayBlockHasher; type Hasher = crate::RelayBlockHasher;
@@ -260,6 +270,8 @@ impl ChainWithGrandpa for TestBridgedChain {
pub struct OtherBridgedChain; pub struct OtherBridgedChain;
impl Chain for OtherBridgedChain { impl Chain for OtherBridgedChain {
const ID: ChainId = *b"obch";
type BlockNumber = u64; type BlockNumber = u64;
type Hash = crate::RelayBlockHash; type Hash = crate::RelayBlockHash;
type Hasher = crate::RelayBlockHasher; type Hasher = crate::RelayBlockHasher;
+34 -37
View File
@@ -42,12 +42,13 @@ type MessagesPallet<T, I> = BridgeMessagesPallet<T, <T as Config<I>>::BridgeMess
impl<T: Config<I>, I: 'static> ExportXcm for Pallet<T, I> impl<T: Config<I>, I: 'static> ExportXcm for Pallet<T, I>
where where
T: BridgeMessagesConfig< T: BridgeMessagesConfig<T::BridgeMessagesPalletInstance, OutboundPayload = XcmAsPlainPayload>,
<T as Config<I>>::BridgeMessagesPalletInstance,
OutboundPayload = XcmAsPlainPayload,
>,
{ {
type Ticket = (SenderAndLane, XcmAsPlainPayload, XcmHash); type Ticket = (
SenderAndLane,
<MessagesPallet<T, I> as MessagesBridge<T::OutboundPayload>>::SendMessageArgs,
XcmHash,
);
fn validate( fn validate(
network: NetworkId, network: NetworkId,
@@ -74,42 +75,38 @@ where
message, message,
)?; )?;
Ok(((sender_and_lane, blob, id), price)) let bridge_message = MessagesPallet::<T, I>::validate_message(sender_and_lane.lane, &blob)
} .map_err(|e| {
fn deliver(
(sender_and_lane, blob, id): (SenderAndLane, XcmAsPlainPayload, XcmHash),
) -> Result<XcmHash, SendError> {
let lane_id = sender_and_lane.lane;
let send_result = MessagesPallet::<T, I>::send_message(lane_id, blob);
match send_result {
Ok(artifacts) => {
log::info!(
target: LOG_TARGET,
"XCM message {:?} has been enqueued at bridge {:?} with nonce {}",
id,
lane_id,
artifacts.nonce,
);
// notify XCM queue manager about updated lane state
LocalXcmQueueManager::<T::LanesSupport>::on_bridge_message_enqueued(
&sender_and_lane,
artifacts.enqueued_messages,
);
},
Err(error) => {
log::debug!( log::debug!(
target: LOG_TARGET, target: LOG_TARGET,
"XCM message {:?} has been dropped because of bridge error {:?} on bridge {:?}", "XCM message {:?} cannot be exported because of bridge error {:?} on bridge {:?}",
id, id,
error, e,
lane_id, sender_and_lane.lane,
); );
return Err(SendError::Transport("BridgeSendError")) SendError::Transport("BridgeValidateError")
}, })?;
}
Ok(((sender_and_lane, bridge_message, id), price))
}
fn deliver((sender_and_lane, bridge_message, id): Self::Ticket) -> Result<XcmHash, SendError> {
let lane_id = sender_and_lane.lane;
let artifacts = MessagesPallet::<T, I>::send_message(bridge_message);
log::info!(
target: LOG_TARGET,
"XCM message {:?} has been enqueued at bridge {:?} with nonce {}",
id,
lane_id,
artifacts.nonce,
);
// notify XCM queue manager about updated lane state
LocalXcmQueueManager::<T::LanesSupport>::on_bridge_message_enqueued(
&sender_and_lane,
artifacts.enqueued_messages,
);
Ok(id) Ok(id)
} }
+4 -18
View File
@@ -19,11 +19,10 @@
use crate as pallet_xcm_bridge_hub; use crate as pallet_xcm_bridge_hub;
use bp_messages::{ use bp_messages::{
source_chain::LaneMessageVerifier,
target_chain::{DispatchMessage, MessageDispatch}, target_chain::{DispatchMessage, MessageDispatch},
LaneId, OutboundLaneData, VerificationError, LaneId,
}; };
use bp_runtime::{messages::MessageDispatchResult, Chain, UnderlyingChainProvider}; use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, UnderlyingChainProvider};
use bridge_runtime_common::{ use bridge_runtime_common::{
messages::{ messages::{
source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter,
@@ -78,20 +77,6 @@ impl pallet_balances::Config for TestRuntime {
type AccountStore = System; type AccountStore = System;
} }
/// Lane message verifier that is used in tests.
#[derive(Debug, Default)]
pub struct TestLaneMessageVerifier;
impl LaneMessageVerifier<Vec<u8>> for TestLaneMessageVerifier {
fn verify_message(
_lane: &LaneId,
_lane_outbound_data: &OutboundLaneData,
_payload: &Vec<u8>,
) -> Result<(), VerificationError> {
Ok(())
}
}
parameter_types! { parameter_types! {
pub const ActiveOutboundLanes: &'static [LaneId] = &[TEST_LANE_ID]; pub const ActiveOutboundLanes: &'static [LaneId] = &[TEST_LANE_ID];
} }
@@ -110,7 +95,6 @@ impl pallet_bridge_messages::Config for TestRuntime {
type InboundRelayer = (); type InboundRelayer = ();
type DeliveryPayments = (); type DeliveryPayments = ();
type TargetHeaderChain = TargetHeaderChainAdapter<OnThisChainBridge>; type TargetHeaderChain = TargetHeaderChainAdapter<OnThisChainBridge>;
type LaneMessageVerifier = TestLaneMessageVerifier;
type DeliveryConfirmationPayments = (); type DeliveryConfirmationPayments = ();
type OnMessagesDelivered = (); type OnMessagesDelivered = ();
type SourceHeaderChain = SourceHeaderChainAdapter<OnThisChainBridge>; type SourceHeaderChain = SourceHeaderChainAdapter<OnThisChainBridge>;
@@ -217,6 +201,7 @@ impl XcmBlobHauler for TestXcmBlobHauler {
pub struct ThisChain; pub struct ThisChain;
impl Chain for ThisChain { impl Chain for ThisChain {
const ID: ChainId = *b"tuch";
type BlockNumber = u64; type BlockNumber = u64;
type Hash = H256; type Hash = H256;
type Hasher = BlakeTwo256; type Hasher = BlakeTwo256;
@@ -240,6 +225,7 @@ pub type BridgedHeaderHash = H256;
pub type BridgedChainHeader = SubstrateHeader; pub type BridgedChainHeader = SubstrateHeader;
impl Chain for BridgedChain { impl Chain for BridgedChain {
const ID: ChainId = *b"tuch";
type BlockNumber = u64; type BlockNumber = u64;
type Hash = BridgedHeaderHash; type Hash = BridgedHeaderHash;
type Hasher = BlakeTwo256; type Hasher = BlakeTwo256;
@@ -14,6 +14,9 @@
// 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/>.
//! Primitives of all Cumulus-based bridge hubs.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
pub use bp_polkadot_core::{ pub use bp_polkadot_core::{
@@ -61,6 +64,7 @@ const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(constants::WEIGHT_REF_TI
pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
parameter_types! { parameter_types! {
/// Size limit of the Cumulus-based bridge hub blocks.
pub BlockLength: limits::BlockLength = limits::BlockLength::max_with_normal_ratio( pub BlockLength: limits::BlockLength = limits::BlockLength::max_with_normal_ratio(
5 * 1024 * 1024, 5 * 1024 * 1024,
NORMAL_DISPATCH_RATIO, NORMAL_DISPATCH_RATIO,
@@ -73,6 +77,7 @@ parameter_types! {
pub const ExtrinsicBaseWeight: Weight = Weight::from_parts(constants::WEIGHT_REF_TIME_PER_NANOS, 0) pub const ExtrinsicBaseWeight: Weight = Weight::from_parts(constants::WEIGHT_REF_TIME_PER_NANOS, 0)
.saturating_mul(125_000); .saturating_mul(125_000);
/// Weight limit of the Cumulus-based bridge hub blocks.
pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder() pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder()
.base_block(BlockExecutionWeight::get()) .base_block(BlockExecutionWeight::get())
.for_class(DispatchClass::all(), |weights| { .for_class(DispatchClass::all(), |weights| {
@@ -17,12 +17,13 @@
//! Module with configuration which reflects BridgeHubKusama runtime setup (AccountId, Headers, //! Module with configuration which reflects BridgeHubKusama runtime setup (AccountId, Headers,
//! Hashes...) //! Hashes...)
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
pub use bp_bridge_hub_cumulus::*; pub use bp_bridge_hub_cumulus::*;
use bp_messages::*; use bp_messages::*;
use bp_runtime::{ use bp_runtime::{
decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain,
}; };
use frame_support::{ use frame_support::{
dispatch::DispatchClass, dispatch::DispatchClass,
@@ -35,6 +36,8 @@ use sp_runtime::RuntimeDebug;
pub struct BridgeHubKusama; pub struct BridgeHubKusama;
impl Chain for BridgeHubKusama { impl Chain for BridgeHubKusama {
const ID: ChainId = *b"bhks";
type BlockNumber = BlockNumber; type BlockNumber = BlockNumber;
type Hash = Hash; type Hash = Hash;
type Hasher = Hasher; type Hasher = Hasher;
@@ -61,6 +64,15 @@ impl Parachain for BridgeHubKusama {
const PARACHAIN_ID: u32 = BRIDGE_HUB_KUSAMA_PARACHAIN_ID; const PARACHAIN_ID: u32 = BRIDGE_HUB_KUSAMA_PARACHAIN_ID;
} }
impl ChainWithMessages for BridgeHubKusama {
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
WITH_BRIDGE_HUB_KUSAMA_MESSAGES_PALLET_NAME;
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
}
/// Public key of the chain account that may be used to verify signatures. /// Public key of the chain account that may be used to verify signatures.
pub type AccountSigner = MultiSigner; pub type AccountSigner = MultiSigner;
@@ -17,12 +17,13 @@
//! Module with configuration which reflects BridgeHubPolkadot runtime setup //! Module with configuration which reflects BridgeHubPolkadot runtime setup
//! (AccountId, Headers, Hashes...) //! (AccountId, Headers, Hashes...)
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
pub use bp_bridge_hub_cumulus::*; pub use bp_bridge_hub_cumulus::*;
use bp_messages::*; use bp_messages::*;
use bp_runtime::{ use bp_runtime::{
decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain,
}; };
use frame_support::dispatch::DispatchClass; use frame_support::dispatch::DispatchClass;
use sp_runtime::RuntimeDebug; use sp_runtime::RuntimeDebug;
@@ -32,6 +33,8 @@ use sp_runtime::RuntimeDebug;
pub struct BridgeHubPolkadot; pub struct BridgeHubPolkadot;
impl Chain for BridgeHubPolkadot { impl Chain for BridgeHubPolkadot {
const ID: ChainId = *b"bhpd";
type BlockNumber = BlockNumber; type BlockNumber = BlockNumber;
type Hash = Hash; type Hash = Hash;
type Hasher = Hasher; type Hasher = Hasher;
@@ -58,6 +61,16 @@ impl Parachain for BridgeHubPolkadot {
const PARACHAIN_ID: u32 = BRIDGE_HUB_POLKADOT_PARACHAIN_ID; const PARACHAIN_ID: u32 = BRIDGE_HUB_POLKADOT_PARACHAIN_ID;
} }
impl ChainWithMessages for BridgeHubPolkadot {
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME;
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
}
/// Identifier of BridgeHubPolkadot in the Polkadot relay chain. /// Identifier of BridgeHubPolkadot in the Polkadot relay chain.
pub const BRIDGE_HUB_POLKADOT_PARACHAIN_ID: u32 = 1002; pub const BRIDGE_HUB_POLKADOT_PARACHAIN_ID: u32 = 1002;
@@ -17,12 +17,13 @@
//! Module with configuration which reflects BridgeHubRococo runtime setup (AccountId, Headers, //! Module with configuration which reflects BridgeHubRococo runtime setup (AccountId, Headers,
//! Hashes...) //! Hashes...)
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
pub use bp_bridge_hub_cumulus::*; pub use bp_bridge_hub_cumulus::*;
use bp_messages::*; use bp_messages::*;
use bp_runtime::{ use bp_runtime::{
decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain,
}; };
use frame_support::dispatch::DispatchClass; use frame_support::dispatch::DispatchClass;
use sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug}; use sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug};
@@ -32,6 +33,8 @@ use sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug};
pub struct BridgeHubRococo; pub struct BridgeHubRococo;
impl Chain for BridgeHubRococo { impl Chain for BridgeHubRococo {
const ID: ChainId = *b"bhro";
type BlockNumber = BlockNumber; type BlockNumber = BlockNumber;
type Hash = Hash; type Hash = Hash;
type Hasher = Hasher; type Hasher = Hasher;
@@ -58,6 +61,16 @@ impl Parachain for BridgeHubRococo {
const PARACHAIN_ID: u32 = BRIDGE_HUB_ROCOCO_PARACHAIN_ID; const PARACHAIN_ID: u32 = BRIDGE_HUB_ROCOCO_PARACHAIN_ID;
} }
impl ChainWithMessages for BridgeHubRococo {
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME;
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
}
/// Public key of the chain account that may be used to verify signatures. /// Public key of the chain account that may be used to verify signatures.
pub type AccountSigner = MultiSigner; pub type AccountSigner = MultiSigner;
@@ -14,8 +14,8 @@ workspace = true
# Bridge Dependencies # Bridge Dependencies
bp-bridge-hub-cumulus = { path = "../chain-bridge-hub-cumulus", default-features = false } bp-bridge-hub-cumulus = { path = "../chain-bridge-hub-cumulus", default-features = false }
bp-runtime = { path = "../../primitives/runtime", default-features = false } bp-runtime = { path = "../runtime", default-features = false }
bp-messages = { path = "../../primitives/messages", default-features = false } bp-messages = { path = "../messages", default-features = false }
# Substrate Based Dependencies # Substrate Based Dependencies
@@ -22,7 +22,7 @@
pub use bp_bridge_hub_cumulus::*; pub use bp_bridge_hub_cumulus::*;
use bp_messages::*; use bp_messages::*;
use bp_runtime::{ use bp_runtime::{
decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain,
}; };
use frame_support::dispatch::DispatchClass; use frame_support::dispatch::DispatchClass;
use sp_runtime::RuntimeDebug; use sp_runtime::RuntimeDebug;
@@ -32,6 +32,8 @@ use sp_runtime::RuntimeDebug;
pub struct BridgeHubWestend; pub struct BridgeHubWestend;
impl Chain for BridgeHubWestend { impl Chain for BridgeHubWestend {
const ID: ChainId = *b"bhwd";
type BlockNumber = BlockNumber; type BlockNumber = BlockNumber;
type Hash = Hash; type Hash = Hash;
type Hasher = Hasher; type Hasher = Hasher;
@@ -58,6 +60,16 @@ impl Parachain for BridgeHubWestend {
const PARACHAIN_ID: u32 = BRIDGE_HUB_WESTEND_PARACHAIN_ID; const PARACHAIN_ID: u32 = BRIDGE_HUB_WESTEND_PARACHAIN_ID;
} }
impl ChainWithMessages for BridgeHubWestend {
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
WITH_BRIDGE_HUB_WESTEND_MESSAGES_PALLET_NAME;
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
}
/// Identifier of BridgeHubWestend in the Westend relay chain. /// Identifier of BridgeHubWestend in the Westend relay chain.
pub const BRIDGE_HUB_WESTEND_PARACHAIN_ID: u32 = 1002; pub const BRIDGE_HUB_WESTEND_PARACHAIN_ID: u32 = 1002;
+16 -13
View File
@@ -14,36 +14,39 @@
// 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/>.
//! Primitives of the Kusama chain.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// RuntimeApi generated functions
#![allow(clippy::too_many_arguments)]
pub use bp_polkadot_core::*; pub use bp_polkadot_core::*;
use bp_header_chain::ChainWithGrandpa; use bp_header_chain::ChainWithGrandpa;
use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId};
use frame_support::weights::Weight; use frame_support::weights::Weight;
/// Kusama Chain /// Kusama Chain
pub struct Kusama; pub struct Kusama;
impl Chain for Kusama { impl Chain for Kusama {
type BlockNumber = <PolkadotLike as Chain>::BlockNumber; const ID: ChainId = *b"ksma";
type Hash = <PolkadotLike as Chain>::Hash;
type Hasher = <PolkadotLike as Chain>::Hasher;
type Header = <PolkadotLike as Chain>::Header;
type AccountId = <PolkadotLike as Chain>::AccountId; type BlockNumber = BlockNumber;
type Balance = <PolkadotLike as Chain>::Balance; type Hash = Hash;
type Nonce = <PolkadotLike as Chain>::Nonce; type Hasher = Hasher;
type Signature = <PolkadotLike as Chain>::Signature; type Header = Header;
type AccountId = AccountId;
type Balance = Balance;
type Nonce = Nonce;
type Signature = Signature;
fn max_extrinsic_size() -> u32 { fn max_extrinsic_size() -> u32 {
PolkadotLike::max_extrinsic_size() max_extrinsic_size()
} }
fn max_extrinsic_weight() -> Weight { fn max_extrinsic_weight() -> Weight {
PolkadotLike::max_extrinsic_weight() max_extrinsic_weight()
} }
} }
@@ -20,14 +20,14 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use bp_header_chain::ChainWithGrandpa; use bp_header_chain::ChainWithGrandpa;
use bp_messages::MessageNonce; use bp_messages::{ChainWithMessages, MessageNonce};
use bp_runtime::{ use bp_runtime::{
decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis,
extensions::{ extensions::{
CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion, CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion,
CheckWeight, GenericSignedExtension, GenericSignedExtensionSchema, CheckWeight, GenericSignedExtension, GenericSignedExtensionSchema,
}, },
Chain, TransactionEra, Chain, ChainId, TransactionEra,
}; };
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use frame_support::{ use frame_support::{
@@ -177,6 +177,8 @@ parameter_types! {
pub struct PolkadotBulletin; pub struct PolkadotBulletin;
impl Chain for PolkadotBulletin { impl Chain for PolkadotBulletin {
const ID: ChainId = *b"pdbc";
type BlockNumber = BlockNumber; type BlockNumber = BlockNumber;
type Hash = Hash; type Hash = Hash;
type Hasher = Hasher; type Hasher = Hasher;
@@ -211,5 +213,15 @@ impl ChainWithGrandpa for PolkadotBulletin {
const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE;
} }
impl ChainWithMessages for PolkadotBulletin {
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
WITH_POLKADOT_BULLETIN_MESSAGES_PALLET_NAME;
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
}
decl_bridge_finality_runtime_apis!(polkadot_bulletin, grandpa); decl_bridge_finality_runtime_apis!(polkadot_bulletin, grandpa);
decl_bridge_messages_runtime_apis!(polkadot_bulletin); decl_bridge_messages_runtime_apis!(polkadot_bulletin);
+18 -13
View File
@@ -14,36 +14,41 @@
// 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/>.
//! Primitives of the Polkadot chain.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// RuntimeApi generated functions
#![allow(clippy::too_many_arguments)]
pub use bp_polkadot_core::*; pub use bp_polkadot_core::*;
use bp_header_chain::ChainWithGrandpa; use bp_header_chain::ChainWithGrandpa;
use bp_runtime::{decl_bridge_finality_runtime_apis, extensions::PrevalidateAttests, Chain}; use bp_runtime::{
decl_bridge_finality_runtime_apis, extensions::PrevalidateAttests, Chain, ChainId,
};
use frame_support::weights::Weight; use frame_support::weights::Weight;
/// Polkadot Chain /// Polkadot Chain
pub struct Polkadot; pub struct Polkadot;
impl Chain for Polkadot { impl Chain for Polkadot {
type BlockNumber = <PolkadotLike as Chain>::BlockNumber; const ID: ChainId = *b"pdot";
type Hash = <PolkadotLike as Chain>::Hash;
type Hasher = <PolkadotLike as Chain>::Hasher;
type Header = <PolkadotLike as Chain>::Header;
type AccountId = <PolkadotLike as Chain>::AccountId; type BlockNumber = BlockNumber;
type Balance = <PolkadotLike as Chain>::Balance; type Hash = Hash;
type Nonce = <PolkadotLike as Chain>::Nonce; type Hasher = Hasher;
type Signature = <PolkadotLike as Chain>::Signature; type Header = Header;
type AccountId = AccountId;
type Balance = Balance;
type Nonce = Nonce;
type Signature = Signature;
fn max_extrinsic_size() -> u32 { fn max_extrinsic_size() -> u32 {
PolkadotLike::max_extrinsic_size() max_extrinsic_size()
} }
fn max_extrinsic_weight() -> Weight { fn max_extrinsic_weight() -> Weight {
PolkadotLike::max_extrinsic_weight() max_extrinsic_weight()
} }
} }
+17 -18
View File
@@ -14,36 +14,39 @@
// 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/>.
//! Primitives of the Rococo chain.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// RuntimeApi generated functions
#![allow(clippy::too_many_arguments)]
pub use bp_polkadot_core::*; pub use bp_polkadot_core::*;
use bp_header_chain::ChainWithGrandpa; use bp_header_chain::ChainWithGrandpa;
use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId};
use frame_support::{parameter_types, weights::Weight}; use frame_support::weights::Weight;
/// Rococo Chain /// Rococo Chain
pub struct Rococo; pub struct Rococo;
impl Chain for Rococo { impl Chain for Rococo {
type BlockNumber = <PolkadotLike as Chain>::BlockNumber; const ID: ChainId = *b"roco";
type Hash = <PolkadotLike as Chain>::Hash;
type Hasher = <PolkadotLike as Chain>::Hasher;
type Header = <PolkadotLike as Chain>::Header;
type AccountId = <PolkadotLike as Chain>::AccountId; type BlockNumber = BlockNumber;
type Balance = <PolkadotLike as Chain>::Balance; type Hash = Hash;
type Nonce = <PolkadotLike as Chain>::Nonce; type Hasher = Hasher;
type Signature = <PolkadotLike as Chain>::Signature; type Header = Header;
type AccountId = AccountId;
type Balance = Balance;
type Nonce = Nonce;
type Signature = Signature;
fn max_extrinsic_size() -> u32 { fn max_extrinsic_size() -> u32 {
PolkadotLike::max_extrinsic_size() max_extrinsic_size()
} }
fn max_extrinsic_weight() -> Weight { fn max_extrinsic_weight() -> Weight {
PolkadotLike::max_extrinsic_weight() max_extrinsic_weight()
} }
} }
@@ -56,10 +59,6 @@ impl ChainWithGrandpa for Rococo {
const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE;
} }
parameter_types! {
pub const SS58Prefix: u8 = 42;
}
// The SignedExtension used by Rococo. // The SignedExtension used by Rococo.
pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; pub use bp_polkadot_core::CommonSignedExtension as SignedExtension;
+17 -18
View File
@@ -14,36 +14,39 @@
// 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/>.
//! Primitives of the Westend chain.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// RuntimeApi generated functions
#![allow(clippy::too_many_arguments)]
pub use bp_polkadot_core::*; pub use bp_polkadot_core::*;
use bp_header_chain::ChainWithGrandpa; use bp_header_chain::ChainWithGrandpa;
use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId};
use frame_support::{parameter_types, weights::Weight}; use frame_support::weights::Weight;
/// Westend Chain /// Westend Chain
pub struct Westend; pub struct Westend;
impl Chain for Westend { impl Chain for Westend {
type BlockNumber = <PolkadotLike as Chain>::BlockNumber; const ID: ChainId = *b"wend";
type Hash = <PolkadotLike as Chain>::Hash;
type Hasher = <PolkadotLike as Chain>::Hasher;
type Header = <PolkadotLike as Chain>::Header;
type AccountId = <PolkadotLike as Chain>::AccountId; type BlockNumber = BlockNumber;
type Balance = <PolkadotLike as Chain>::Balance; type Hash = Hash;
type Nonce = <PolkadotLike as Chain>::Nonce; type Hasher = Hasher;
type Signature = <PolkadotLike as Chain>::Signature; type Header = Header;
type AccountId = AccountId;
type Balance = Balance;
type Nonce = Nonce;
type Signature = Signature;
fn max_extrinsic_size() -> u32 { fn max_extrinsic_size() -> u32 {
PolkadotLike::max_extrinsic_size() max_extrinsic_size()
} }
fn max_extrinsic_weight() -> Weight { fn max_extrinsic_weight() -> Weight {
PolkadotLike::max_extrinsic_weight() max_extrinsic_weight()
} }
} }
@@ -56,10 +59,6 @@ impl ChainWithGrandpa for Westend {
const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE;
} }
parameter_types! {
pub const SS58Prefix: u8 = 42;
}
// The SignedExtension used by Westend. // The SignedExtension used by Westend.
pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; pub use bp_polkadot_core::CommonSignedExtension as SignedExtension;
+13 -1
View File
@@ -17,6 +17,7 @@
//! Defines traits which represent a common interface for Substrate pallets which want to //! Defines traits which represent a common interface for Substrate pallets which want to
//! incorporate bridge functionality. //! incorporate bridge functionality.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use crate::justification::{ use crate::justification::{
@@ -145,6 +146,7 @@ pub trait ConsensusLogReader {
pub struct GrandpaConsensusLogReader<Number>(sp_std::marker::PhantomData<Number>); pub struct GrandpaConsensusLogReader<Number>(sp_std::marker::PhantomData<Number>);
impl<Number: Codec> GrandpaConsensusLogReader<Number> { impl<Number: Codec> GrandpaConsensusLogReader<Number> {
/// Find and return scheduled (regular) change digest item.
pub fn find_scheduled_change( pub fn find_scheduled_change(
digest: &Digest, digest: &Digest,
) -> Option<sp_consensus_grandpa::ScheduledChange<Number>> { ) -> Option<sp_consensus_grandpa::ScheduledChange<Number>> {
@@ -158,6 +160,8 @@ impl<Number: Codec> GrandpaConsensusLogReader<Number> {
}) })
} }
/// Find and return forced change digest item. Or light client can't do anything
/// with forced changes, so we can't accept header with the forced change digest.
pub fn find_forced_change( pub fn find_forced_change(
digest: &Digest, digest: &Digest,
) -> Option<(Number, sp_consensus_grandpa::ScheduledChange<Number>)> { ) -> Option<(Number, sp_consensus_grandpa::ScheduledChange<Number>)> {
@@ -229,12 +233,17 @@ pub enum BridgeGrandpaCall<Header: HeaderT> {
/// `pallet-bridge-grandpa::Call::submit_finality_proof` /// `pallet-bridge-grandpa::Call::submit_finality_proof`
#[codec(index = 0)] #[codec(index = 0)]
submit_finality_proof { submit_finality_proof {
/// The header that we are going to finalize.
finality_target: Box<Header>, finality_target: Box<Header>,
/// Finality justification for the `finality_target`.
justification: justification::GrandpaJustification<Header>, justification: justification::GrandpaJustification<Header>,
}, },
/// `pallet-bridge-grandpa::Call::initialize` /// `pallet-bridge-grandpa::Call::initialize`
#[codec(index = 1)] #[codec(index = 1)]
initialize { init_data: InitializationData<Header> }, initialize {
/// All data, required to initialize the pallet.
init_data: InitializationData<Header>,
},
} }
/// The `BridgeGrandpaCall` used by a chain. /// The `BridgeGrandpaCall` used by a chain.
@@ -325,12 +334,15 @@ pub fn max_expected_submit_finality_proof_arguments_size<C: ChainWithGrandpa>(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use bp_runtime::ChainId;
use frame_support::weights::Weight; use frame_support::weights::Weight;
use sp_runtime::{testing::H256, traits::BlakeTwo256, MultiSignature}; use sp_runtime::{testing::H256, traits::BlakeTwo256, MultiSignature};
struct TestChain; struct TestChain;
impl Chain for TestChain { impl Chain for TestChain {
const ID: ChainId = *b"test";
type BlockNumber = u32; type BlockNumber = u32;
type Hash = H256; type Hash = H256;
type Hasher = BlakeTwo256; type Hasher = BlakeTwo256;
+42 -5
View File
@@ -16,14 +16,13 @@
//! Primitives of messages module. //! Primitives of messages module.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// RuntimeApi generated functions
#![allow(clippy::too_many_arguments)]
use bp_header_chain::HeaderChainError; use bp_header_chain::HeaderChainError;
use bp_runtime::{ use bp_runtime::{
messages::MessageDispatchResult, BasicOperatingMode, OperatingMode, RangeInclusiveExt, messages::MessageDispatchResult, BasicOperatingMode, Chain, OperatingMode, RangeInclusiveExt,
StorageProofError, StorageProofError, UnderlyingChainOf, UnderlyingChainProvider,
}; };
use codec::{Decode, Encode, MaxEncodedLen}; use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::PalletError; use frame_support::PalletError;
@@ -39,6 +38,36 @@ pub mod source_chain;
pub mod storage_keys; pub mod storage_keys;
pub mod target_chain; pub mod target_chain;
/// Substrate-based chain with messaging support.
pub trait ChainWithMessages: Chain {
/// Name of the bridge messages pallet (used in `construct_runtime` macro call) that is
/// deployed at some other chain to bridge with this `ChainWithMessages`.
///
/// We assume that all chains that are bridging with this `ChainWithMessages` are using
/// the same name.
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str;
/// Maximal number of unrewarded relayers in a single confirmation transaction at this
/// `ChainWithMessages`.
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce;
/// Maximal number of unconfirmed messages in a single confirmation transaction at this
/// `ChainWithMessages`.
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce;
}
impl<T> ChainWithMessages for T
where
T: Chain + UnderlyingChainProvider,
UnderlyingChainOf<T>: ChainWithMessages,
{
const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str =
UnderlyingChainOf::<T>::WITH_CHAIN_MESSAGES_PALLET_NAME;
const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce =
UnderlyingChainOf::<T>::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce =
UnderlyingChainOf::<T>::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
}
/// Messages pallet operating mode. /// Messages pallet operating mode.
#[derive( #[derive(
Encode, Encode,
@@ -264,6 +293,7 @@ pub struct ReceivedMessages<DispatchLevelResult> {
} }
impl<DispatchLevelResult> ReceivedMessages<DispatchLevelResult> { impl<DispatchLevelResult> ReceivedMessages<DispatchLevelResult> {
/// Creates new `ReceivedMessages` structure from given results.
pub fn new( pub fn new(
lane: LaneId, lane: LaneId,
receive_results: Vec<(MessageNonce, ReceivalResult<DispatchLevelResult>)>, receive_results: Vec<(MessageNonce, ReceivalResult<DispatchLevelResult>)>,
@@ -271,6 +301,7 @@ impl<DispatchLevelResult> ReceivedMessages<DispatchLevelResult> {
ReceivedMessages { lane, receive_results } ReceivedMessages { lane, receive_results }
} }
/// Push `result` of the `message` delivery onto `receive_results` vector.
pub fn push(&mut self, message: MessageNonce, result: ReceivalResult<DispatchLevelResult>) { pub fn push(&mut self, message: MessageNonce, result: ReceivalResult<DispatchLevelResult>) {
self.receive_results.push((message, result)); self.receive_results.push((message, result));
} }
@@ -342,7 +373,7 @@ pub struct UnrewardedRelayersState {
} }
impl UnrewardedRelayersState { impl UnrewardedRelayersState {
// Verify that the relayers state corresponds with the `InboundLaneData`. /// Verify that the relayers state corresponds with the `InboundLaneData`.
pub fn is_valid<RelayerId>(&self, lane_data: &InboundLaneData<RelayerId>) -> bool { pub fn is_valid<RelayerId>(&self, lane_data: &InboundLaneData<RelayerId>) -> bool {
self == &lane_data.into() self == &lane_data.into()
} }
@@ -423,15 +454,21 @@ pub enum BridgeMessagesCall<AccountId, MessagesProof, MessagesDeliveryProof> {
/// `pallet-bridge-messages::Call::receive_messages_proof` /// `pallet-bridge-messages::Call::receive_messages_proof`
#[codec(index = 2)] #[codec(index = 2)]
receive_messages_proof { receive_messages_proof {
/// Account id of relayer at the **bridged** chain.
relayer_id_at_bridged_chain: AccountId, relayer_id_at_bridged_chain: AccountId,
/// Messages proof.
proof: MessagesProof, proof: MessagesProof,
/// A number of messages in the proof.
messages_count: u32, messages_count: u32,
/// Total dispatch weight of messages in the proof.
dispatch_weight: Weight, dispatch_weight: Weight,
}, },
/// `pallet-bridge-messages::Call::receive_messages_delivery_proof` /// `pallet-bridge-messages::Call::receive_messages_delivery_proof`
#[codec(index = 3)] #[codec(index = 3)]
receive_messages_delivery_proof { receive_messages_delivery_proof {
/// Messages delivery proof.
proof: MessagesDeliveryProof, proof: MessagesDeliveryProof,
/// "Digest" of unrewarded relayers state at the bridged chain.
relayers_state: UnrewardedRelayersState, relayers_state: UnrewardedRelayersState,
}, },
} }
+15 -43
View File
@@ -16,7 +16,7 @@
//! Primitives of messages module, that are used on the source chain. //! Primitives of messages module, that are used on the source chain.
use crate::{InboundLaneData, LaneId, MessageNonce, OutboundLaneData, VerificationError}; use crate::{InboundLaneData, LaneId, MessageNonce, VerificationError};
use crate::UnrewardedRelayer; use crate::UnrewardedRelayer;
use bp_runtime::Size; use bp_runtime::Size;
@@ -64,24 +64,6 @@ pub trait TargetHeaderChain<Payload, AccountId> {
) -> Result<(LaneId, InboundLaneData<AccountId>), VerificationError>; ) -> Result<(LaneId, InboundLaneData<AccountId>), VerificationError>;
} }
/// Lane message verifier.
///
/// Runtime developer may implement any additional validation logic over message-lane mechanism.
/// E.g. if lanes should have some security (e.g. you can only accept Lane1 messages from
/// Submitter1, Lane2 messages for those who has submitted first message to this lane, disable
/// Lane3 until some block, ...), then it may be built using this verifier.
///
/// Any fee requirements should also be enforced here.
pub trait LaneMessageVerifier<Payload> {
/// Verify message payload and return Ok(()) if message is valid and allowed to be sent over the
/// lane.
fn verify_message(
lane: &LaneId,
outbound_data: &OutboundLaneData,
payload: &Payload,
) -> Result<(), VerificationError>;
}
/// Manages payments that are happening at the source chain during delivery confirmation /// Manages payments that are happening at the source chain during delivery confirmation
/// transaction. /// transaction.
pub trait DeliveryConfirmationPayments<AccountId> { pub trait DeliveryConfirmationPayments<AccountId> {
@@ -143,25 +125,25 @@ pub trait MessagesBridge<Payload> {
/// Error type. /// Error type.
type Error: Debug; type Error: Debug;
/// Intermediary structure returned by `validate_message()`.
///
/// It can than be passed to `send_message()` in order to actually send the message
/// on the bridge.
type SendMessageArgs;
/// Check if the message can be sent over the bridge.
fn validate_message(
lane: LaneId,
message: &Payload,
) -> Result<Self::SendMessageArgs, Self::Error>;
/// Send message over the bridge. /// Send message over the bridge.
/// ///
/// Returns unique message nonce or error if send has failed. /// Returns unique message nonce or error if send has failed.
fn send_message(lane: LaneId, message: Payload) -> Result<SendMessageArtifacts, Self::Error>; fn send_message(message: Self::SendMessageArgs) -> SendMessageArtifacts;
} }
/// Bridge that does nothing when message is being sent. /// Structure that may be used in place of `TargetHeaderChain` and
#[derive(Eq, RuntimeDebug, PartialEq)]
pub struct NoopMessagesBridge;
impl<Payload> MessagesBridge<Payload> for NoopMessagesBridge {
type Error = &'static str;
fn send_message(_lane: LaneId, _message: Payload) -> Result<SendMessageArtifacts, Self::Error> {
Ok(SendMessageArtifacts { nonce: 0, enqueued_messages: 0 })
}
}
/// Structure that may be used in place of `TargetHeaderChain`, `LaneMessageVerifier` and
/// `MessageDeliveryAndDispatchPayment` on chains, where outbound messages are forbidden. /// `MessageDeliveryAndDispatchPayment` on chains, where outbound messages are forbidden.
pub struct ForbidOutboundMessages; pub struct ForbidOutboundMessages;
@@ -183,16 +165,6 @@ impl<Payload, AccountId> TargetHeaderChain<Payload, AccountId> for ForbidOutboun
} }
} }
impl<Payload> LaneMessageVerifier<Payload> for ForbidOutboundMessages {
fn verify_message(
_lane: &LaneId,
_outbound_data: &OutboundLaneData,
_payload: &Payload,
) -> Result<(), VerificationError> {
Err(VerificationError::Other(ALL_OUTBOUND_MESSAGES_REJECTED))
}
}
impl<AccountId> DeliveryConfirmationPayments<AccountId> for ForbidOutboundMessages { impl<AccountId> DeliveryConfirmationPayments<AccountId> for ForbidOutboundMessages {
type Error = &'static str; type Error = &'static str;
+4
View File
@@ -16,6 +16,7 @@
//! Primitives of parachains module. //! Primitives of parachains module.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
pub use bp_header_chain::StoredHeaderData; pub use bp_header_chain::StoredHeaderData;
@@ -173,8 +174,11 @@ pub enum BridgeParachainCall {
/// `pallet-bridge-parachains::Call::submit_parachain_heads` /// `pallet-bridge-parachains::Call::submit_parachain_heads`
#[codec(index = 0)] #[codec(index = 0)]
submit_parachain_heads { submit_parachain_heads {
/// Relay chain block, for which we have submitted the `parachain_heads_proof`.
at_relay_block: (RelayBlockNumber, RelayBlockHash), at_relay_block: (RelayBlockNumber, RelayBlockHash),
/// Parachain identifiers and their head hashes.
parachains: Vec<(ParaId, ParaHash)>, parachains: Vec<(ParaId, ParaHash)>,
/// Parachain heads proof.
parachain_heads_proof: ParaHeadsProof, parachain_heads_proof: ParaHeadsProof,
}, },
} }
+22 -26
View File
@@ -14,6 +14,9 @@
// 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/>.
//! Primitives of the Polkadot-like chains.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
@@ -24,7 +27,7 @@ use bp_runtime::{
CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension, CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension,
SignedExtensionSchema, SignedExtensionSchema,
}, },
Chain, EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra, EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra,
}; };
use frame_support::{ use frame_support::{
dispatch::DispatchClass, dispatch::DispatchClass,
@@ -40,7 +43,7 @@ use sp_core::{storage::StorageKey, Hasher as HasherT};
use sp_runtime::{ use sp_runtime::{
generic, generic,
traits::{BlakeTwo256, IdentifyAccount, Verify}, traits::{BlakeTwo256, IdentifyAccount, Verify},
MultiAddress, MultiSignature, OpaqueExtrinsic, RuntimeDebug, MultiAddress, MultiSignature, OpaqueExtrinsic,
}; };
use sp_std::prelude::Vec; use sp_std::prelude::Vec;
@@ -173,11 +176,16 @@ pub use time_units::*;
pub mod time_units { pub mod time_units {
use super::BlockNumber; use super::BlockNumber;
/// Milliseconds between Polkadot-like chain blocks.
pub const MILLISECS_PER_BLOCK: u64 = 6000; pub const MILLISECS_PER_BLOCK: u64 = 6000;
/// Slot duration in Polkadot-like chain consensus algorithms.
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
/// A minute, expressed in Polkadot-like chain blocks.
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
/// A hour, expressed in Polkadot-like chain blocks.
pub const HOURS: BlockNumber = MINUTES * 60; pub const HOURS: BlockNumber = MINUTES * 60;
/// A day, expressed in Polkadot-like chain blocks.
pub const DAYS: BlockNumber = HOURS * 24; pub const DAYS: BlockNumber = HOURS * 24;
} }
@@ -227,31 +235,17 @@ pub type UncheckedExtrinsic<Call, SignedExt> =
/// Account address, used by the Polkadot-like chain. /// Account address, used by the Polkadot-like chain.
pub type Address = MultiAddress<AccountId, ()>; pub type Address = MultiAddress<AccountId, ()>;
/// Polkadot-like chain. /// Returns maximal extrinsic size on all Polkadot-like chains.
#[derive(RuntimeDebug)] pub fn max_extrinsic_size() -> u32 {
pub struct PolkadotLike; *BlockLength::get().max.get(DispatchClass::Normal)
}
impl Chain for PolkadotLike { /// Returns maximal extrinsic weight on all Polkadot-like chains.
type BlockNumber = BlockNumber; pub fn max_extrinsic_weight() -> Weight {
type Hash = Hash; BlockWeights::get()
type Hasher = Hasher; .get(DispatchClass::Normal)
type Header = Header; .max_extrinsic
.unwrap_or(Weight::MAX)
type AccountId = AccountId;
type Balance = Balance;
type Nonce = Nonce;
type Signature = Signature;
fn max_extrinsic_size() -> u32 {
*BlockLength::get().max.get(DispatchClass::Normal)
}
fn max_extrinsic_weight() -> Weight {
BlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic
.unwrap_or(Weight::MAX)
}
} }
/// Provides a storage key for account data. /// Provides a storage key for account data.
@@ -271,8 +265,10 @@ impl StorageMapKeyProvider for AccountInfoStorageMapKeyProvider {
} }
impl AccountInfoStorageMapKeyProvider { impl AccountInfoStorageMapKeyProvider {
/// Name of the system pallet.
const PALLET_NAME: &'static str = "System"; const PALLET_NAME: &'static str = "System";
/// Return storage key for given account data.
pub fn final_key(id: &AccountId) -> StorageKey { pub fn final_key(id: &AccountId) -> StorageKey {
<Self as StorageMapKeyProvider>::final_key(Self::PALLET_NAME, id) <Self as StorageMapKeyProvider>::final_key(Self::PALLET_NAME, id)
} }
@@ -89,11 +89,18 @@ pub type ParaHasher = crate::Hasher;
/// Raw storage proof of parachain heads, stored in polkadot-like chain runtime. /// Raw storage proof of parachain heads, stored in polkadot-like chain runtime.
#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)]
pub struct ParaHeadsProof(pub RawStorageProof); pub struct ParaHeadsProof {
/// Unverified storage proof of finalized parachain heads.
pub storage_proof: RawStorageProof,
}
impl Size for ParaHeadsProof { impl Size for ParaHeadsProof {
fn size(&self) -> u32 { fn size(&self) -> u32 {
u32::try_from(self.0.iter().fold(0usize, |sum, node| sum.saturating_add(node.len()))) u32::try_from(
.unwrap_or(u32::MAX) self.storage_proof
.iter()
.fold(0usize, |sum, node| sum.saturating_add(node.len())),
)
.unwrap_or(u32::MAX)
} }
} }
+7 -1
View File
@@ -14,7 +14,8 @@
// 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::HeaderIdProvider; use crate::{ChainId, HeaderIdProvider};
use codec::{Codec, Decode, Encode, MaxEncodedLen}; use codec::{Codec, Decode, Encode, MaxEncodedLen};
use frame_support::{weights::Weight, Parameter}; use frame_support::{weights::Weight, Parameter};
use num_traits::{AsPrimitive, Bounded, CheckedSub, Saturating, SaturatingAdd, Zero}; use num_traits::{AsPrimitive, Bounded, CheckedSub, Saturating, SaturatingAdd, Zero};
@@ -99,6 +100,9 @@ impl<ChainCall: Encode> Encode for EncodedOrDecodedCall<ChainCall> {
/// Minimal Substrate-based chain representation that may be used from no_std environment. /// Minimal Substrate-based chain representation that may be used from no_std environment.
pub trait Chain: Send + Sync + 'static { pub trait Chain: Send + Sync + 'static {
/// Chain id.
const ID: ChainId;
/// A type that fulfills the abstract idea of what a Substrate block number is. /// A type that fulfills the abstract idea of what a Substrate block number is.
// Constraits come from the associated Number type of `sp_runtime::traits::Header` // Constraits come from the associated Number type of `sp_runtime::traits::Header`
// See here for more info: // See here for more info:
@@ -208,6 +212,8 @@ impl<T> Chain for T
where where
T: Send + Sync + 'static + UnderlyingChainProvider, T: Send + Sync + 'static + UnderlyingChainProvider,
{ {
const ID: ChainId = <T::Chain as Chain>::ID;
type BlockNumber = <T::Chain as Chain>::BlockNumber; type BlockNumber = <T::Chain as Chain>::BlockNumber;
type Hash = <T::Chain as Chain>::Hash; type Hash = <T::Chain as Chain>::Hash;
type Hasher = <T::Chain as Chain>::Hasher; type Hasher = <T::Chain as Chain>::Hasher;
@@ -102,6 +102,7 @@ impl SignedExtensionSchema for Tuple {
/// and signed payloads in the client code. /// and signed payloads in the client code.
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
pub struct GenericSignedExtension<S: SignedExtensionSchema> { pub struct GenericSignedExtension<S: SignedExtensionSchema> {
/// A payload that is included in the transaction.
pub payload: S::Payload, pub payload: S::Payload,
#[codec(skip)] #[codec(skip)]
// It may be set to `None` if extensions are decoded. We are never reconstructing transactions // It may be set to `None` if extensions are decoded. We are never reconstructing transactions
@@ -112,6 +113,7 @@ pub struct GenericSignedExtension<S: SignedExtensionSchema> {
} }
impl<S: SignedExtensionSchema> GenericSignedExtension<S> { impl<S: SignedExtensionSchema> GenericSignedExtension<S> {
/// Create new `GenericSignedExtension` object.
pub fn new(payload: S::Payload, additional_signed: Option<S::AdditionalSigned>) -> Self { pub fn new(payload: S::Payload, additional_signed: Option<S::AdditionalSigned>) -> Self {
Self { payload, additional_signed } Self { payload, additional_signed }
} }
+11 -34
View File
@@ -16,6 +16,7 @@
//! Primitives that may be used at (bridges) runtime level. //! Primitives that may be used at (bridges) runtime level.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use codec::{Decode, Encode, FullCodec, MaxEncodedLen}; use codec::{Decode, Encode, FullCodec, MaxEncodedLen};
@@ -61,36 +62,6 @@ pub use sp_runtime::paste;
/// Use this when something must be shared among all instances. /// Use this when something must be shared among all instances.
pub const NO_INSTANCE_ID: ChainId = [0, 0, 0, 0]; pub const NO_INSTANCE_ID: ChainId = [0, 0, 0, 0];
/// Polkadot chain id.
pub const POLKADOT_CHAIN_ID: ChainId = *b"pdot";
/// Polkadot Bulletin chain id.
pub const POLKADOT_BULLETIN_CHAIN_ID: ChainId = *b"pdbc";
/// Kusama chain id.
pub const KUSAMA_CHAIN_ID: ChainId = *b"ksma";
/// Westend chain id.
pub const WESTEND_CHAIN_ID: ChainId = *b"wend";
/// `AssetHubWestmint` chain id.
pub const ASSET_HUB_WESTEND_CHAIN_ID: ChainId = *b"ahwe";
/// Rococo chain id.
pub const ROCOCO_CHAIN_ID: ChainId = *b"roco";
/// BridgeHubRococo chain id.
pub const BRIDGE_HUB_ROCOCO_CHAIN_ID: ChainId = *b"bhro";
/// BridgeHubWestend chain id.
pub const BRIDGE_HUB_WESTEND_CHAIN_ID: ChainId = *b"bhwd";
/// BridgeHubKusama chain id.
pub const BRIDGE_HUB_KUSAMA_CHAIN_ID: ChainId = *b"bhks";
/// BridgeHubPolkadot chain id.
pub const BRIDGE_HUB_POLKADOT_CHAIN_ID: ChainId = *b"bhpd";
/// Generic header Id. /// Generic header Id.
#[derive( #[derive(
RuntimeDebug, RuntimeDebug,
@@ -126,10 +97,10 @@ pub type HeaderIdOf<C> = HeaderId<HashOf<C>, BlockNumberOf<C>>;
/// Generic header id provider. /// Generic header id provider.
pub trait HeaderIdProvider<Header: HeaderT> { pub trait HeaderIdProvider<Header: HeaderT> {
// Get the header id. /// Get the header id.
fn id(&self) -> HeaderId<Header::Hash, Header::Number>; fn id(&self) -> HeaderId<Header::Hash, Header::Number>;
// Get the header id for the parent block. /// Get the header id for the parent block.
fn parent_id(&self) -> Option<HeaderId<Header::Hash, Header::Number>>; fn parent_id(&self) -> Option<HeaderId<Header::Hash, Header::Number>>;
} }
@@ -342,7 +313,7 @@ pub trait StorageDoubleMapKeyProvider {
} }
/// Error generated by the `OwnedBridgeModule` trait. /// Error generated by the `OwnedBridgeModule` trait.
#[derive(Encode, Decode, TypeInfo, PalletError)] #[derive(Encode, Decode, PartialEq, Eq, TypeInfo, PalletError)]
pub enum OwnedBridgeModuleError { pub enum OwnedBridgeModuleError {
/// All pallet operations are halted. /// All pallet operations are halted.
Halted, Halted,
@@ -350,7 +321,7 @@ pub enum OwnedBridgeModuleError {
/// Operating mode for a bridge module. /// Operating mode for a bridge module.
pub trait OperatingMode: Send + Copy + Debug + FullCodec { pub trait OperatingMode: Send + Copy + Debug + FullCodec {
// Returns true if the bridge module is halted. /// Returns true if the bridge module is halted.
fn is_halted(&self) -> bool; fn is_halted(&self) -> bool;
} }
@@ -392,8 +363,11 @@ pub trait OwnedBridgeModule<T: frame_system::Config> {
/// The target that will be used when publishing logs related to this module. /// The target that will be used when publishing logs related to this module.
const LOG_TARGET: &'static str; const LOG_TARGET: &'static str;
/// A storage entry that holds the module `Owner` account.
type OwnerStorage: StorageValue<T::AccountId, Query = Option<T::AccountId>>; type OwnerStorage: StorageValue<T::AccountId, Query = Option<T::AccountId>>;
/// Operating mode type of the pallet.
type OperatingMode: OperatingMode; type OperatingMode: OperatingMode;
/// A storage value that holds the pallet operating mode.
type OperatingModeStorage: StorageValue<Self::OperatingMode, Query = Self::OperatingMode>; type OperatingModeStorage: StorageValue<Self::OperatingMode, Query = Self::OperatingMode>;
/// Check if the module is halted. /// Check if the module is halted.
@@ -469,9 +443,11 @@ impl WeightExtraOps for Weight {
/// Trait that provides a static `str`. /// Trait that provides a static `str`.
pub trait StaticStrProvider { pub trait StaticStrProvider {
/// Static string.
const STR: &'static str; const STR: &'static str;
} }
/// A macro that generates `StaticStrProvider` with the string set to its stringified argument.
#[macro_export] #[macro_export]
macro_rules! generate_static_str_provider { macro_rules! generate_static_str_provider {
($str:expr) => { ($str:expr) => {
@@ -485,6 +461,7 @@ macro_rules! generate_static_str_provider {
}; };
} }
/// Error message that is only dispayable in `std` environment.
#[derive(Encode, Decode, Clone, Eq, PartialEq, PalletError, TypeInfo)] #[derive(Encode, Decode, Clone, Eq, PartialEq, PalletError, TypeInfo)]
#[scale_info(skip_type_params(T))] #[scale_info(skip_type_params(T))]
pub struct StrippableError<T> { pub struct StrippableError<T> {
+9 -1
View File
@@ -24,12 +24,17 @@ use sp_consensus_grandpa::{AuthorityId, AuthorityList, AuthorityWeight, SetId};
use sp_runtime::RuntimeDebug; use sp_runtime::RuntimeDebug;
use sp_std::prelude::*; use sp_std::prelude::*;
/// Set of test accounts with friendly names. /// Set of test accounts with friendly names: Alice.
pub const ALICE: Account = Account(0); pub const ALICE: Account = Account(0);
/// Set of test accounts with friendly names: Bob.
pub const BOB: Account = Account(1); pub const BOB: Account = Account(1);
/// Set of test accounts with friendly names: Charlie.
pub const CHARLIE: Account = Account(2); pub const CHARLIE: Account = Account(2);
/// Set of test accounts with friendly names: Dave.
pub const DAVE: Account = Account(3); pub const DAVE: Account = Account(3);
/// Set of test accounts with friendly names: Eve.
pub const EVE: Account = Account(4); pub const EVE: Account = Account(4);
/// Set of test accounts with friendly names: Ferdie.
pub const FERDIE: Account = Account(5); pub const FERDIE: Account = Account(5);
/// A test account which can be used to sign messages. /// A test account which can be used to sign messages.
@@ -37,10 +42,12 @@ pub const FERDIE: Account = Account(5);
pub struct Account(pub u16); pub struct Account(pub u16);
impl Account { impl Account {
/// Returns public key of this account.
pub fn public(&self) -> VerifyingKey { pub fn public(&self) -> VerifyingKey {
self.pair().verifying_key() self.pair().verifying_key()
} }
/// Returns key pair, used to sign data on behalf of this account.
pub fn pair(&self) -> SigningKey { pub fn pair(&self) -> SigningKey {
let data = self.0.encode(); let data = self.0.encode();
let mut bytes = [0_u8; 32]; let mut bytes = [0_u8; 32];
@@ -48,6 +55,7 @@ impl Account {
SigningKey::from_bytes(&bytes) SigningKey::from_bytes(&bytes)
} }
/// Generate a signature of given message.
pub fn sign(&self, msg: &[u8]) -> Signature { pub fn sign(&self, msg: &[u8]) -> Signature {
use ed25519_dalek::Signer; use ed25519_dalek::Signer;
self.pair().sign(msg) self.pair().sign(msg)
+5 -1
View File
@@ -16,6 +16,7 @@
//! Utilities for testing runtime code. //! Utilities for testing runtime code.
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use bp_header_chain::justification::{required_justification_precommits, GrandpaJustification}; use bp_header_chain::justification::{required_justification_precommits, GrandpaJustification};
@@ -33,8 +34,11 @@ pub use keyring::*;
mod keyring; mod keyring;
/// GRANDPA round number used across tests.
pub const TEST_GRANDPA_ROUND: u64 = 1; pub const TEST_GRANDPA_ROUND: u64 = 1;
/// GRANDPA validators set id used across tests.
pub const TEST_GRANDPA_SET_ID: SetId = 1; pub const TEST_GRANDPA_SET_ID: SetId = 1;
/// Name of the `Paras` pallet used across tests.
pub const PARAS_PALLET_NAME: &str = "Paras"; pub const PARAS_PALLET_NAME: &str = "Paras";
/// Configuration parameters when generating test GRANDPA justifications. /// Configuration parameters when generating test GRANDPA justifications.
@@ -190,7 +194,7 @@ pub fn prepare_parachain_heads_proof<H: HeaderT>(
.map_err(|_| "record_all_trie_keys has failed") .map_err(|_| "record_all_trie_keys has failed")
.expect("record_all_trie_keys should not fail in benchmarks"); .expect("record_all_trie_keys should not fail in benchmarks");
(root, ParaHeadsProof(storage_proof), parachains) (root, ParaHeadsProof { storage_proof }, parachains)
} }
/// Create signed precommit with given target. /// Create signed precommit with given target.
@@ -38,7 +38,7 @@ snowbridge-core = { path = "../../primitives/core", default-features = false }
snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false }
primitives = { package = "snowbridge-beacon-primitives", path = "../../primitives/beacon", default-features = false } primitives = { package = "snowbridge-beacon-primitives", path = "../../primitives/beacon", default-features = false }
static_assertions = { version = "1.1.0", default-features = false } static_assertions = { version = "1.1.0", default-features = false }
bp-runtime = { path = "../../../../../bridges/primitives/runtime", default-features = false } bp-runtime = { path = "../../../../primitives/runtime", default-features = false }
pallet-timestamp = { path = "../../../../../substrate/frame/timestamp", default-features = false, optional = true } pallet-timestamp = { path = "../../../../../substrate/frame/timestamp", default-features = false, optional = true }
[dev-dependencies] [dev-dependencies]
@@ -47,7 +47,7 @@ snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-featu
frame-benchmarking = { path = "../../../../../substrate/frame/benchmarking" } frame-benchmarking = { path = "../../../../../substrate/frame/benchmarking" }
sp-keyring = { path = "../../../../../substrate/primitives/keyring" } sp-keyring = { path = "../../../../../substrate/primitives/keyring" }
snowbridge-beacon-primitives = { path = "../../primitives/beacon" } snowbridge-beacon-primitives = { path = "../../primitives/beacon" }
snowbridge-pallet-ethereum-client = { path = "../../pallets/ethereum-client" } snowbridge-pallet-ethereum-client = { path = "../ethereum-client" }
hex-literal = { version = "0.4.1" } hex-literal = { version = "0.4.1" }
[features] [features]
@@ -31,7 +31,7 @@ sp-arithmetic = { path = "../../../../../substrate/primitives/arithmetic", defau
bridge-hub-common = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/common", default-features = false } bridge-hub-common = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/common", default-features = false }
snowbridge-core = { path = "../../primitives/core", features = ["serde"], default-features = false } snowbridge-core = { path = "../../primitives/core", default-features = false, features = ["serde"] }
snowbridge-outbound-queue-merkle-tree = { path = "merkle-tree", default-features = false } snowbridge-outbound-queue-merkle-tree = { path = "merkle-tree", default-features = false }
ethabi = { git = "https://github.com/snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } ethabi = { git = "https://github.com/snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false }
@@ -29,7 +29,7 @@ ssz_rs = { version = "0.9.0", default-features = false }
ssz_rs_derive = { version = "0.9.0", default-features = false } ssz_rs_derive = { version = "0.9.0", default-features = false }
byte-slice-cast = { version = "1.2.1", default-features = false } byte-slice-cast = { version = "1.2.1", default-features = false }
snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } snowbridge-ethereum = { path = "../ethereum", default-features = false }
static_assertions = { version = "1.1.0" } static_assertions = { version = "1.1.0" }
milagro_bls = { git = "https://github.com/snowfork/milagro_bls", default-features = false, rev = "a6d66e4eb89015e352fb1c9f7b661ecdbb5b2176" } milagro_bls = { git = "https://github.com/snowfork/milagro_bls", default-features = false, rev = "a6d66e4eb89015e352fb1c9f7b661ecdbb5b2176" }
@@ -29,7 +29,7 @@ sp-io = { path = "../../../../../substrate/primitives/io", default-features = fa
sp-core = { path = "../../../../../substrate/primitives/core", default-features = false } sp-core = { path = "../../../../../substrate/primitives/core", default-features = false }
sp-arithmetic = { path = "../../../../../substrate/primitives/arithmetic", default-features = false } sp-arithmetic = { path = "../../../../../substrate/primitives/arithmetic", default-features = false }
snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-features = false } snowbridge-beacon-primitives = { path = "../beacon", default-features = false }
ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false }
@@ -28,7 +28,7 @@ xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-f
xcm-builder = { package = "staging-xcm-builder", path = "../../../../../polkadot/xcm/xcm-builder", default-features = false } xcm-builder = { package = "staging-xcm-builder", path = "../../../../../polkadot/xcm/xcm-builder", default-features = false }
xcm-executor = { package = "staging-xcm-executor", path = "../../../../../polkadot/xcm/xcm-executor", default-features = false } xcm-executor = { package = "staging-xcm-executor", path = "../../../../../polkadot/xcm/xcm-executor", default-features = false }
snowbridge-core = { path = "../../primitives/core", default-features = false } snowbridge-core = { path = "../core", default-features = false }
ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false }
@@ -90,7 +90,7 @@ snowbridge-system-runtime-api = { path = "../../pallets/system/runtime-api", def
[dev-dependencies] [dev-dependencies]
static_assertions = "1.1" static_assertions = "1.1"
bridge-hub-test-utils = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/test-utils" } bridge-hub-test-utils = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/test-utils" }
bridge-runtime-common = { path = "../../../../../bridges/bin/runtime-common", features = ["integrity-test"] } bridge-runtime-common = { path = "../../../../bin/runtime-common", features = ["integrity-test"] }
sp-keyring = { path = "../../../../../substrate/primitives/keyring" } sp-keyring = { path = "../../../../../substrate/primitives/keyring" }
[features] [features]
@@ -27,6 +27,7 @@ use crate::{
RuntimeEvent, XcmOverRococoBulletin, XcmRouter, RuntimeEvent, XcmOverRococoBulletin, XcmRouter,
}; };
use bp_messages::LaneId; use bp_messages::LaneId;
use bp_runtime::Chain;
use bridge_runtime_common::{ use bridge_runtime_common::{
messages, messages,
messages::{ messages::{
@@ -63,7 +64,7 @@ parameter_types! {
pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce =
bp_polkadot_bulletin::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; bp_polkadot_bulletin::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
/// Bridge specific chain (network) identifier of the Rococo Bulletin Chain. /// Bridge specific chain (network) identifier of the Rococo Bulletin Chain.
pub const RococoBulletinChainId: bp_runtime::ChainId = bp_runtime::POLKADOT_BULLETIN_CHAIN_ID; pub const RococoBulletinChainId: bp_runtime::ChainId = bp_polkadot_bulletin::PolkadotBulletin::ID;
/// Interior location (relative to this runtime) of the with-RococoBulletin messages pallet. /// Interior location (relative to this runtime) of the with-RococoBulletin messages pallet.
pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorLocation = [ pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorLocation = [
PalletInstance(<BridgeRococoBulletinMessages as PalletInfoAccess>::index() as u8) PalletInstance(<BridgeRococoBulletinMessages as PalletInfoAccess>::index() as u8)
@@ -151,10 +152,6 @@ impl MessageBridge for WithRococoBulletinMessageBridge {
type BridgedHeaderChain = BridgeRococoBulletinGrandpa; type BridgedHeaderChain = BridgeRococoBulletinGrandpa;
} }
/// Message verifier for RococoBulletin messages sent from BridgeHubRococo.
pub type ToRococoBulletinMessageVerifier =
messages::source::FromThisChainMessageVerifier<WithRococoBulletinMessageBridge>;
/// Maximal outbound payload size of BridgeHubRococo -> RococoBulletin messages. /// Maximal outbound payload size of BridgeHubRococo -> RococoBulletin messages.
pub type ToRococoBulletinMaximalOutboundPayloadSize = pub type ToRococoBulletinMaximalOutboundPayloadSize =
messages::source::FromThisChainMaximalOutboundPayloadSize<WithRococoBulletinMessageBridge>; messages::source::FromThisChainMaximalOutboundPayloadSize<WithRococoBulletinMessageBridge>;
@@ -205,7 +202,6 @@ impl pallet_bridge_messages::Config<WithRococoBulletinMessagesInstance> for Runt
type DeliveryPayments = (); type DeliveryPayments = ();
type TargetHeaderChain = TargetHeaderChainAdapter<WithRococoBulletinMessageBridge>; type TargetHeaderChain = TargetHeaderChainAdapter<WithRococoBulletinMessageBridge>;
type LaneMessageVerifier = ToRococoBulletinMessageVerifier;
type DeliveryConfirmationPayments = (); type DeliveryConfirmationPayments = ();
type SourceHeaderChain = SourceHeaderChainAdapter<WithRococoBulletinMessageBridge>; type SourceHeaderChain = SourceHeaderChainAdapter<WithRococoBulletinMessageBridge>;
@@ -26,6 +26,7 @@ use crate::{
XcmRouter, XcmRouter,
}; };
use bp_messages::LaneId; use bp_messages::LaneId;
use bp_runtime::Chain;
use bridge_runtime_common::{ use bridge_runtime_common::{
messages, messages,
messages::{ messages::{
@@ -57,7 +58,7 @@ parameter_types! {
bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce =
bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
pub const BridgeHubWestendChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; pub const BridgeHubWestendChainId: bp_runtime::ChainId = BridgeHubWestend::ID;
pub BridgeRococoToWestendMessagesPalletInstance: InteriorLocation = [PalletInstance(<BridgeWestendMessages as PalletInfoAccess>::index() as u8)].into(); pub BridgeRococoToWestendMessagesPalletInstance: InteriorLocation = [PalletInstance(<BridgeWestendMessages as PalletInfoAccess>::index() as u8)].into();
pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend; pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend;
pub WestendGlobalConsensusNetworkLocation: Location = Location::new( pub WestendGlobalConsensusNetworkLocation: Location = Location::new(
@@ -157,10 +158,6 @@ impl MessageBridge for WithBridgeHubWestendMessageBridge {
>; >;
} }
/// Message verifier for BridgeHubWestend messages sent from BridgeHubRococo
pub type ToBridgeHubWestendMessageVerifier =
messages::source::FromThisChainMessageVerifier<WithBridgeHubWestendMessageBridge>;
/// Maximal outbound payload size of BridgeHubRococo -> BridgeHubWestend messages. /// Maximal outbound payload size of BridgeHubRococo -> BridgeHubWestend messages.
pub type ToBridgeHubWestendMaximalOutboundPayloadSize = pub type ToBridgeHubWestendMaximalOutboundPayloadSize =
messages::source::FromThisChainMaximalOutboundPayloadSize<WithBridgeHubWestendMessageBridge>; messages::source::FromThisChainMaximalOutboundPayloadSize<WithBridgeHubWestendMessageBridge>;
@@ -212,7 +209,6 @@ impl pallet_bridge_messages::Config<WithBridgeHubWestendMessagesInstance> for Ru
type DeliveryPayments = (); type DeliveryPayments = ();
type TargetHeaderChain = TargetHeaderChainAdapter<WithBridgeHubWestendMessageBridge>; type TargetHeaderChain = TargetHeaderChainAdapter<WithBridgeHubWestendMessageBridge>;
type LaneMessageVerifier = ToBridgeHubWestendMessageVerifier;
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
Runtime, Runtime,
WithBridgeHubWestendMessagesInstance, WithBridgeHubWestendMessagesInstance,
@@ -309,7 +305,7 @@ mod tests {
bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
max_unconfirmed_messages_in_bridged_confirmation_tx: max_unconfirmed_messages_in_bridged_confirmation_tx:
bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
bridged_chain_id: bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID, bridged_chain_id: BridgeHubWestend::ID,
}, },
pallet_names: AssertBridgePalletNames { pallet_names: AssertBridgePalletNames {
with_this_chain_messages_pallet_name: with_this_chain_messages_pallet_name:
@@ -70,6 +70,8 @@ use frame_system::{
EnsureRoot, EnsureRoot,
}; };
#[cfg(feature = "runtime-benchmarks")]
use bp_runtime::Chain;
use bp_runtime::HeaderId; use bp_runtime::HeaderId;
use bridge_hub_common::{ use bridge_hub_common::{
message_queue::{NarrowOriginToSibling, ParaIdToSibling}, message_queue::{NarrowOriginToSibling, ParaIdToSibling},
@@ -1275,7 +1277,7 @@ impl_runtime_apis! {
impl BridgeMessagesConfig<bridge_to_westend_config::WithBridgeHubWestendMessagesInstance> for Runtime { impl BridgeMessagesConfig<bridge_to_westend_config::WithBridgeHubWestendMessagesInstance> for Runtime {
fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool {
let bench_lane_id = <Self as BridgeMessagesConfig<bridge_to_westend_config::WithBridgeHubWestendMessagesInstance>>::bench_lane_id(); let bench_lane_id = <Self as BridgeMessagesConfig<bridge_to_westend_config::WithBridgeHubWestendMessagesInstance>>::bench_lane_id();
let bridged_chain_id = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; let bridged_chain_id = bp_bridge_hub_westend::BridgeHubWestend::ID;
pallet_bridge_relayers::Pallet::<Runtime>::relayer_reward( pallet_bridge_relayers::Pallet::<Runtime>::relayer_reward(
relayer, relayer,
bp_relayers::RewardsAccountParams::new( bp_relayers::RewardsAccountParams::new(
@@ -23,6 +23,7 @@ use crate::{
}; };
use bp_messages::LaneId; use bp_messages::LaneId;
use bp_parachains::SingleParaStoredHeaderDataBuilder; use bp_parachains::SingleParaStoredHeaderDataBuilder;
use bp_runtime::Chain;
use bridge_runtime_common::{ use bridge_runtime_common::{
messages, messages,
messages::{ messages::{
@@ -62,7 +63,7 @@ parameter_types! {
bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX;
pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce =
bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX;
pub const BridgeHubRococoChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; pub const BridgeHubRococoChainId: bp_runtime::ChainId = BridgeHubRococo::ID;
pub BridgeWestendToRococoMessagesPalletInstance: InteriorLocation = [PalletInstance(<BridgeRococoMessages as PalletInfoAccess>::index() as u8)].into(); pub BridgeWestendToRococoMessagesPalletInstance: InteriorLocation = [PalletInstance(<BridgeRococoMessages as PalletInfoAccess>::index() as u8)].into();
pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo; pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo;
pub RococoGlobalConsensusNetworkLocation: Location = Location::new( pub RococoGlobalConsensusNetworkLocation: Location = Location::new(
@@ -162,10 +163,6 @@ impl MessageBridge for WithBridgeHubRococoMessageBridge {
>; >;
} }
/// Message verifier for BridgeHubRococo messages sent from BridgeHubWestend
type ToBridgeHubRococoMessageVerifier =
messages::source::FromThisChainMessageVerifier<WithBridgeHubRococoMessageBridge>;
/// Maximal outbound payload size of BridgeHubWestend -> BridgeHubRococo messages. /// Maximal outbound payload size of BridgeHubWestend -> BridgeHubRococo messages.
type ToBridgeHubRococoMaximalOutboundPayloadSize = type ToBridgeHubRococoMaximalOutboundPayloadSize =
messages::source::FromThisChainMaximalOutboundPayloadSize<WithBridgeHubRococoMessageBridge>; messages::source::FromThisChainMaximalOutboundPayloadSize<WithBridgeHubRococoMessageBridge>;
@@ -249,7 +246,6 @@ impl pallet_bridge_messages::Config<WithBridgeHubRococoMessagesInstance> for Run
type DeliveryPayments = (); type DeliveryPayments = ();
type TargetHeaderChain = TargetHeaderChainAdapter<WithBridgeHubRococoMessageBridge>; type TargetHeaderChain = TargetHeaderChainAdapter<WithBridgeHubRococoMessageBridge>;
type LaneMessageVerifier = ToBridgeHubRococoMessageVerifier;
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
Runtime, Runtime,
WithBridgeHubRococoMessagesInstance, WithBridgeHubRococoMessagesInstance,
@@ -344,7 +340,7 @@ mod tests {
bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX,
max_unconfirmed_messages_in_bridged_confirmation_tx: max_unconfirmed_messages_in_bridged_confirmation_tx:
bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX,
bridged_chain_id: bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID, bridged_chain_id: BridgeHubRococo::ID,
}, },
pallet_names: AssertBridgePalletNames { pallet_names: AssertBridgePalletNames {
with_this_chain_messages_pallet_name: with_this_chain_messages_pallet_name:
@@ -69,6 +69,8 @@ pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
pub use sp_runtime::{MultiAddress, Perbill, Permill}; pub use sp_runtime::{MultiAddress, Perbill, Permill};
use xcm_config::{XcmOriginToTransactDispatchOrigin, XcmRouter}; use xcm_config::{XcmOriginToTransactDispatchOrigin, XcmRouter};
#[cfg(feature = "runtime-benchmarks")]
use bp_runtime::Chain;
use bp_runtime::HeaderId; use bp_runtime::HeaderId;
#[cfg(any(feature = "std", test))] #[cfg(any(feature = "std", test))]
@@ -974,7 +976,7 @@ impl_runtime_apis! {
impl BridgeMessagesConfig<bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance> for Runtime { impl BridgeMessagesConfig<bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance> for Runtime {
fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool {
let bench_lane_id = <Self as BridgeMessagesConfig<bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance>>::bench_lane_id(); let bench_lane_id = <Self as BridgeMessagesConfig<bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance>>::bench_lane_id();
let bridged_chain_id = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; let bridged_chain_id = bp_bridge_hub_rococo::BridgeHubRococo::ID;
pallet_bridge_relayers::Pallet::<Runtime>::relayer_reward( pallet_bridge_relayers::Pallet::<Runtime>::relayer_reward(
relayer, relayer,
bp_relayers::RewardsAccountParams::new( bp_relayers::RewardsAccountParams::new(