diff --git a/bin/runtime-common/src/refund_relayer_extension.rs b/bin/runtime-common/src/refund_relayer_extension.rs
index a1eec7b3870..901647f813e 100644
--- a/bin/runtime-common/src/refund_relayer_extension.rs
+++ b/bin/runtime-common/src/refund_relayer_extension.rs
@@ -19,7 +19,9 @@
//! with calls that are: delivering new messsage and all necessary underlying headers
//! (parachain or relay chain).
-use bp_messages::{ChainWithMessages, LaneId, MessageNonce};
+use bp_header_chain::SubmitFinalityProofInfo;
+use bp_messages::{ChainWithMessages, LaneId, MessageNonce, MessagesCallInfo};
+use bp_parachains::SubmitParachainHeadsInfo;
use bp_relayers::{RewardsAccountOwner, RewardsAccountParams};
use bp_runtime::{Chain, Parachain, ParachainIdOf, RangeInclusiveExt, StaticStrProvider};
use codec::{Codec, Decode, Encode};
@@ -31,15 +33,13 @@ use frame_support::{
};
use pallet_bridge_grandpa::{
CallSubType as GrandpaCallSubType, Config as GrandpaConfig, SubmitFinalityProofHelper,
- SubmitFinalityProofInfo,
};
use pallet_bridge_messages::{
- CallHelper as MessagesCallHelper, CallInfo as MessagesCallInfo,
- CallSubType as MessagesCallSubType, Config as MessagesConfig,
+ CallHelper as MessagesCallHelper, CallSubType as MessagesCallSubType, Config as MessagesConfig,
};
use pallet_bridge_parachains::{
BoundedBridgeGrandpaConfig, CallSubType as ParachainsCallSubType, Config as ParachainsConfig,
- RelayBlockNumber, SubmitParachainHeadsHelper, SubmitParachainHeadsInfo,
+ RelayBlockNumber, SubmitParachainHeadsHelper,
};
use pallet_bridge_relayers::{
Config as RelayersConfig, Pallet as RelayersPallet, WeightInfoExt as _,
@@ -830,8 +830,9 @@ mod tests {
use crate::mock::*;
use bp_messages::{
source_chain::FromBridgedChainMessagesDeliveryProof,
- target_chain::FromBridgedChainMessagesProof, InboundLaneData, MessageNonce,
- OutboundLaneData, UnrewardedRelayersState,
+ target_chain::FromBridgedChainMessagesProof, BaseMessagesProofInfo, InboundLaneData,
+ MessageNonce, OutboundLaneData, ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo,
+ UnrewardedRelayerOccupation, UnrewardedRelayersState,
};
use bp_parachains::{BestParaHeadHash, ParaInfo};
use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId};
@@ -843,10 +844,7 @@ mod tests {
weights::Weight,
};
use pallet_bridge_grandpa::{Call as GrandpaCall, StoredAuthoritySet};
- use pallet_bridge_messages::{
- BaseMessagesProofInfo, Call as MessagesCall, ReceiveMessagesDeliveryProofInfo,
- ReceiveMessagesProofInfo, UnrewardedRelayerOccupation,
- };
+ use pallet_bridge_messages::Call as MessagesCall;
use pallet_bridge_parachains::{Call as ParachainsCall, RelayBlockHash};
use sp_runtime::{
traits::{ConstU64, Header as HeaderT},
diff --git a/modules/grandpa/src/call_ext.rs b/modules/grandpa/src/call_ext.rs
index e0648d5dd0f..a4012fdc6aa 100644
--- a/modules/grandpa/src/call_ext.rs
+++ b/modules/grandpa/src/call_ext.rs
@@ -15,42 +15,18 @@
// along with Parity Bridges Common. If not, see .
use crate::{weights::WeightInfo, BridgedBlockNumber, BridgedHeader, Config, Error, Pallet};
-use bp_header_chain::{justification::GrandpaJustification, ChainWithGrandpa};
+use bp_header_chain::{
+ justification::GrandpaJustification, ChainWithGrandpa, SubmitFinalityProofInfo,
+};
use bp_runtime::BlockNumberOf;
use codec::Encode;
use frame_support::{dispatch::CallableCallFor, traits::IsSubType, weights::Weight};
use sp_runtime::{
- traits::{Header, Zero},
+ traits::Header,
transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
- RuntimeDebug, SaturatedConversion,
+ SaturatedConversion,
};
-/// Info about a `SubmitParachainHeads` call which tries to update a single parachain.
-#[derive(Copy, Clone, PartialEq, RuntimeDebug)]
-pub struct SubmitFinalityProofInfo {
- /// Number of the finality target.
- pub block_number: N,
- /// Extra weight that we assume is included in the call.
- ///
- /// We have some assumptions about headers and justifications of the bridged chain.
- /// We know that if our assumptions are correct, then the call must not have the
- /// weight above some limit. The fee paid for weight above that limit, is never refunded.
- pub extra_weight: Weight,
- /// Extra size (in bytes) that we assume are included in the call.
- ///
- /// We have some assumptions about headers and justifications of the bridged chain.
- /// We know that if our assumptions are correct, then the call must not have the
- /// weight above some limit. The fee paid for bytes above that limit, is never refunded.
- pub extra_size: u32,
-}
-
-impl SubmitFinalityProofInfo {
- /// Returns `true` if call size/weight is below our estimations for regular calls.
- pub fn fits_limits(&self) -> bool {
- self.extra_weight.is_zero() && self.extra_size.is_zero()
- }
-}
-
/// Helper struct that provides methods for working with the `SubmitFinalityProof` call.
pub struct SubmitFinalityProofHelper, I: 'static> {
_phantom_data: sp_std::marker::PhantomData<(T, I)>,
diff --git a/modules/messages/src/call_ext.rs b/modules/messages/src/call_ext.rs
index 11cb1f16ac7..9e3eb829b6a 100644
--- a/modules/messages/src/call_ext.rs
+++ b/modules/messages/src/call_ext.rs
@@ -20,119 +20,15 @@
use crate::{BridgedChainOf, Config, InboundLanes, OutboundLanes, Pallet, LOG_TARGET};
use bp_messages::{
- target_chain::MessageDispatch, ChainWithMessages, InboundLaneData, LaneId, MessageNonce,
+ target_chain::MessageDispatch, BaseMessagesProofInfo, ChainWithMessages, InboundLaneData,
+ LaneId, MessageNonce, MessagesCallInfo, ReceiveMessagesDeliveryProofInfo,
+ ReceiveMessagesProofInfo, UnrewardedRelayerOccupation,
};
use bp_runtime::AccountIdOf;
use frame_support::{dispatch::CallableCallFor, traits::IsSubType};
-use sp_runtime::{transaction_validity::TransactionValidity, RuntimeDebug};
-use sp_std::ops::RangeInclusive;
-
-/// Generic info about a messages delivery/confirmation proof.
-#[derive(PartialEq, RuntimeDebug)]
-pub struct BaseMessagesProofInfo {
- /// Message lane, used by the call.
- pub lane_id: LaneId,
- /// Nonces of messages, included in the call.
- ///
- /// For delivery transaction, it is nonces of bundled messages. For confirmation
- /// transaction, it is nonces that are to be confirmed during the call.
- pub bundled_range: RangeInclusive,
- /// Nonce of the best message, stored by this chain before the call is dispatched.
- ///
- /// For delivery transaction, it is the nonce of best delivered message before the call.
- /// For confirmation transaction, it is the nonce of best confirmed message before the call.
- pub best_stored_nonce: MessageNonce,
-}
-
-impl BaseMessagesProofInfo {
- /// Returns true if `bundled_range` continues the `0..=best_stored_nonce` range.
- fn appends_to_stored_nonce(&self) -> bool {
- Some(*self.bundled_range.start()) == self.best_stored_nonce.checked_add(1)
- }
-}
-
-/// Occupation state of the unrewarded relayers vector.
-#[derive(PartialEq, RuntimeDebug)]
-#[cfg_attr(test, derive(Default))]
-pub struct UnrewardedRelayerOccupation {
- /// The number of remaining unoccupied entries for new relayers.
- pub free_relayer_slots: MessageNonce,
- /// The number of messages that we are ready to accept.
- pub free_message_slots: MessageNonce,
-}
-
-/// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
-#[derive(PartialEq, RuntimeDebug)]
-pub struct ReceiveMessagesProofInfo {
- /// Base messages proof info
- pub base: BaseMessagesProofInfo,
- /// State of unrewarded relayers vector.
- pub unrewarded_relayers: UnrewardedRelayerOccupation,
-}
-
-impl ReceiveMessagesProofInfo {
- /// Returns true if:
- ///
- /// - either inbound lane is ready to accept bundled messages;
- ///
- /// - or there are no bundled messages, but the inbound lane is blocked by too many unconfirmed
- /// messages and/or unrewarded relayers.
- fn is_obsolete(&self, is_dispatcher_active: bool) -> bool {
- // if dispatcher is inactive, we don't accept any delivery transactions
- if !is_dispatcher_active {
- return true
- }
-
- // transactions with zero bundled nonces are not allowed, unless they're message
- // delivery transactions, which brings reward confirmations required to unblock
- // the lane
- if self.base.bundled_range.is_empty() {
- let empty_transactions_allowed =
- // we allow empty transactions when we can't accept delivery from new relayers
- self.unrewarded_relayers.free_relayer_slots == 0 ||
- // or if we can't accept new messages at all
- self.unrewarded_relayers.free_message_slots == 0;
-
- return !empty_transactions_allowed
- }
-
- // otherwise we require bundled messages to continue stored range
- !self.base.appends_to_stored_nonce()
- }
-}
-
-/// Info about a `ReceiveMessagesDeliveryProof` call which tries to update a single lane.
-#[derive(PartialEq, RuntimeDebug)]
-pub struct ReceiveMessagesDeliveryProofInfo(pub BaseMessagesProofInfo);
-
-impl ReceiveMessagesDeliveryProofInfo {
- /// Returns true if outbound lane is ready to accept confirmations of bundled messages.
- fn is_obsolete(&self) -> bool {
- self.0.bundled_range.is_empty() || !self.0.appends_to_stored_nonce()
- }
-}
-
-/// Info about a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call
-/// which tries to update a single lane.
-#[derive(PartialEq, RuntimeDebug)]
-pub enum CallInfo {
- /// Messages delivery call info.
- ReceiveMessagesProof(ReceiveMessagesProofInfo),
- /// Messages delivery confirmation call info.
- ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo),
-}
-
-impl CallInfo {
- /// Returns range of messages, bundled with the call.
- pub fn bundled_messages(&self) -> RangeInclusive {
- match *self {
- Self::ReceiveMessagesProof(ref info) => info.base.bundled_range.clone(),
- Self::ReceiveMessagesDeliveryProof(ref info) => info.0.bundled_range.clone(),
- }
- }
-}
+use sp_runtime::transaction_validity::TransactionValidity;
-/// 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 `MessagesCallInfo`.
pub struct CallHelper, I: 'static> {
_phantom_data: sp_std::marker::PhantomData<(T, I)>,
}
@@ -144,9 +40,9 @@ impl, I: 'static> CallHelper {
///
/// - call is `receive_messages_delivery_proof` and all messages confirmations have been
/// received.
- pub fn was_successful(info: &CallInfo) -> bool {
+ pub fn was_successful(info: &MessagesCallInfo) -> bool {
match info {
- CallInfo::ReceiveMessagesProof(info) => {
+ MessagesCallInfo::ReceiveMessagesProof(info) => {
let inbound_lane_data = match InboundLanes::::get(info.base.lane_id) {
Some(inbound_lane_data) => inbound_lane_data,
None => return false,
@@ -164,7 +60,7 @@ impl, I: 'static> CallHelper {
inbound_lane_data.last_delivered_nonce() == *info.base.bundled_range.end()
},
- CallInfo::ReceiveMessagesDeliveryProof(info) => {
+ MessagesCallInfo::ReceiveMessagesDeliveryProof(info) => {
let outbound_lane_data = match OutboundLanes::::get(info.0.lane_id) {
Some(outbound_lane_data) => outbound_lane_data,
None => return false,
@@ -186,13 +82,13 @@ pub trait CallSubType, I: 'static>:
/// a `ReceiveMessagesDeliveryProof` call.
fn receive_messages_delivery_proof_info(&self) -> Option;
- /// Create a new instance of `CallInfo` from a `ReceiveMessagesProof`
+ /// Create a new instance of `MessagesCallInfo` from a `ReceiveMessagesProof`
/// or a `ReceiveMessagesDeliveryProof` call.
- fn call_info(&self) -> Option;
+ fn call_info(&self) -> Option;
- /// Create a new instance of `CallInfo` from a `ReceiveMessagesProof`
+ /// Create a new instance of `MessagesCallInfo` from a `ReceiveMessagesProof`
/// or a `ReceiveMessagesDeliveryProof` call, if the call is for the provided lane.
- fn call_info_for(&self, lane_id: LaneId) -> Option;
+ fn call_info_for(&self, lane_id: LaneId) -> Option;
/// Check that a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call is trying
/// to deliver/confirm at least some messages that are better than the ones we know of.
@@ -250,23 +146,23 @@ impl<
None
}
- fn call_info(&self) -> Option {
+ fn call_info(&self) -> Option {
if let Some(info) = self.receive_messages_proof_info() {
- return Some(CallInfo::ReceiveMessagesProof(info))
+ return Some(MessagesCallInfo::ReceiveMessagesProof(info))
}
if let Some(info) = self.receive_messages_delivery_proof_info() {
- return Some(CallInfo::ReceiveMessagesDeliveryProof(info))
+ return Some(MessagesCallInfo::ReceiveMessagesDeliveryProof(info))
}
None
}
- fn call_info_for(&self, lane_id: LaneId) -> Option {
+ fn call_info_for(&self, lane_id: LaneId) -> Option {
self.call_info().filter(|info| {
let actual_lane_id = match info {
- CallInfo::ReceiveMessagesProof(info) => info.base.lane_id,
- CallInfo::ReceiveMessagesDeliveryProof(info) => info.0.lane_id,
+ MessagesCallInfo::ReceiveMessagesProof(info) => info.base.lane_id,
+ MessagesCallInfo::ReceiveMessagesDeliveryProof(info) => info.0.lane_id,
};
actual_lane_id == lane_id
})
@@ -274,7 +170,7 @@ impl<
fn check_obsolete_call(&self) -> TransactionValidity {
match self.call_info() {
- Some(CallInfo::ReceiveMessagesProof(proof_info))
+ Some(MessagesCallInfo::ReceiveMessagesProof(proof_info))
if proof_info
.is_obsolete(T::MessageDispatch::is_active(proof_info.base.lane_id)) =>
{
@@ -286,7 +182,7 @@ impl<
return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
},
- Some(CallInfo::ReceiveMessagesDeliveryProof(proof_info))
+ Some(MessagesCallInfo::ReceiveMessagesDeliveryProof(proof_info))
if proof_info.is_obsolete() =>
{
log::trace!(
@@ -559,7 +455,7 @@ mod tests {
bundled_range: RangeInclusive,
is_empty: bool,
) -> bool {
- CallHelper::::was_successful(&CallInfo::ReceiveMessagesProof(
+ CallHelper::::was_successful(&MessagesCallInfo::ReceiveMessagesProof(
ReceiveMessagesProofInfo {
base: BaseMessagesProofInfo {
lane_id: test_lane_id(),
@@ -620,13 +516,15 @@ mod tests {
}
fn was_message_confirmation_successful(bundled_range: RangeInclusive) -> bool {
- CallHelper::::was_successful(&CallInfo::ReceiveMessagesDeliveryProof(
- ReceiveMessagesDeliveryProofInfo(BaseMessagesProofInfo {
- lane_id: test_lane_id(),
- bundled_range,
- best_stored_nonce: 0, // doesn't matter for `was_successful`
- }),
- ))
+ CallHelper::::was_successful(
+ &MessagesCallInfo::ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo(
+ BaseMessagesProofInfo {
+ lane_id: test_lane_id(),
+ bundled_range,
+ best_stored_nonce: 0, // doesn't matter for `was_successful`
+ },
+ )),
+ )
}
#[test]
diff --git a/modules/parachains/src/call_ext.rs b/modules/parachains/src/call_ext.rs
index efd7dd2c44b..1264d8ebd2f 100644
--- a/modules/parachains/src/call_ext.rs
+++ b/modules/parachains/src/call_ext.rs
@@ -14,25 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
-use crate::{Config, Pallet, RelayBlockNumber};
-use bp_parachains::BestParaHeadHash;
-use bp_polkadot_core::parachains::{ParaHash, ParaId};
+use crate::{Config, Pallet};
+use bp_parachains::{BestParaHeadHash, SubmitParachainHeadsInfo};
use frame_support::{dispatch::CallableCallFor, traits::IsSubType};
-use sp_runtime::{
- transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
- RuntimeDebug,
-};
-
-/// Info about a `SubmitParachainHeads` call which tries to update a single parachain.
-#[derive(PartialEq, RuntimeDebug)]
-pub struct SubmitParachainHeadsInfo {
- /// Number of the finalized relay block that has been used to prove parachain finality.
- pub at_relay_block_number: RelayBlockNumber,
- /// Parachain identifier.
- pub para_id: ParaId,
- /// Hash of the bundled parachain head.
- pub para_head_hash: ParaHash,
-}
+use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction};
/// Helper struct that provides methods for working with the `SubmitParachainHeads` call.
pub struct SubmitParachainHeadsHelper, I: 'static> {
diff --git a/modules/parachains/src/lib.rs b/modules/parachains/src/lib.rs
index 5993ee5a1c8..017a488ef27 100644
--- a/modules/parachains/src/lib.rs
+++ b/modules/parachains/src/lib.rs
@@ -28,7 +28,9 @@ pub use weights::WeightInfo;
pub use weights_ext::WeightInfoExt;
use bp_header_chain::{HeaderChain, HeaderChainError};
-use bp_parachains::{parachain_head_storage_key_at_source, ParaInfo, ParaStoredHeaderData};
+use bp_parachains::{
+ parachain_head_storage_key_at_source, ParaInfo, ParaStoredHeaderData, SubmitParachainHeadsInfo,
+};
use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId};
use bp_runtime::{Chain, HashOf, HeaderId, HeaderIdOf, Parachain};
use frame_support::{dispatch::PostDispatchInfo, DefaultNoBound};
diff --git a/primitives/header-chain/src/call_info.rs b/primitives/header-chain/src/call_info.rs
new file mode 100644
index 00000000000..4a9ca2951d9
--- /dev/null
+++ b/primitives/header-chain/src/call_info.rs
@@ -0,0 +1,78 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Parity Bridges Common.
+
+// Parity Bridges Common is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity Bridges Common is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity Bridges Common. If not, see .
+
+//! Defines structures related to calls of the `pallet-bridge-grandpa` pallet.
+
+use crate::{justification, InitializationData};
+
+use bp_runtime::HeaderOf;
+use codec::{Decode, Encode};
+use frame_support::weights::Weight;
+use scale_info::TypeInfo;
+use sp_runtime::{
+ traits::{Header as HeaderT, Zero},
+ RuntimeDebug,
+};
+use sp_std::boxed::Box;
+
+/// A minimized version of `pallet-bridge-grandpa::Call` that can be used without a runtime.
+#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
+#[allow(non_camel_case_types)]
+pub enum BridgeGrandpaCall {
+ /// `pallet-bridge-grandpa::Call::submit_finality_proof`
+ #[codec(index = 0)]
+ submit_finality_proof {
+ /// The header that we are going to finalize.
+ finality_target: Box,
+ /// Finality justification for the `finality_target`.
+ justification: justification::GrandpaJustification,
+ },
+ /// `pallet-bridge-grandpa::Call::initialize`
+ #[codec(index = 1)]
+ initialize {
+ /// All data, required to initialize the pallet.
+ init_data: InitializationData,
+ },
+}
+
+/// The `BridgeGrandpaCall` for a pallet that bridges with given `C`;
+pub type BridgeGrandpaCallOf = BridgeGrandpaCall>;
+
+/// A digest information on the `BridgeGrandpaCall::submit_finality_proof` call.
+#[derive(Copy, Clone, PartialEq, RuntimeDebug)]
+pub struct SubmitFinalityProofInfo {
+ /// Number of the finality target.
+ pub block_number: N,
+ /// Extra weight that we assume is included in the call.
+ ///
+ /// We have some assumptions about headers and justifications of the bridged chain.
+ /// We know that if our assumptions are correct, then the call must not have the
+ /// weight above some limit. The fee paid for weight above that limit, is never refunded.
+ pub extra_weight: Weight,
+ /// Extra size (in bytes) that we assume are included in the call.
+ ///
+ /// We have some assumptions about headers and justifications of the bridged chain.
+ /// We know that if our assumptions are correct, then the call must not have the
+ /// weight above some limit. The fee paid for bytes above that limit, is never refunded.
+ pub extra_size: u32,
+}
+
+impl SubmitFinalityProofInfo {
+ /// Returns `true` if call size/weight is below our estimations for regular calls.
+ pub fn fits_limits(&self) -> bool {
+ self.extra_weight.is_zero() && self.extra_size.is_zero()
+ }
+}
diff --git a/primitives/header-chain/src/lib.rs b/primitives/header-chain/src/lib.rs
index 3072f9ffdf5..434e7d995dc 100644
--- a/primitives/header-chain/src/lib.rs
+++ b/primitives/header-chain/src/lib.rs
@@ -24,8 +24,8 @@ use crate::justification::{
GrandpaJustification, JustificationVerificationContext, JustificationVerificationError,
};
use bp_runtime::{
- BasicOperatingMode, Chain, HashOf, HasherOf, HeaderOf, StorageProofError,
- UnderlyingChainProvider, UnverifiedStorageProof, VerifiedStorageProof,
+ BasicOperatingMode, Chain, HashOf, HasherOf, StorageProofError, UnderlyingChainProvider,
+ UnverifiedStorageProof, VerifiedStorageProof,
};
use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen};
use core::{clone::Clone, cmp::Eq, default::Default, fmt::Debug};
@@ -36,6 +36,10 @@ use sp_consensus_grandpa::{AuthorityList, ConsensusLog, SetId, GRANDPA_ENGINE_ID
use sp_runtime::{traits::Header as HeaderT, Digest, RuntimeDebug};
use sp_std::{boxed::Box, vec::Vec};
+pub use call_info::{BridgeGrandpaCall, BridgeGrandpaCallOf, SubmitFinalityProofInfo};
+
+mod call_info;
+
pub mod justification;
pub mod storage_keys;
@@ -240,29 +244,6 @@ pub trait FindEquivocations Result, Self::Error>;
}
-/// A minimized version of `pallet-bridge-grandpa::Call` that can be used without a runtime.
-#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
-#[allow(non_camel_case_types)]
-pub enum BridgeGrandpaCall {
- /// `pallet-bridge-grandpa::Call::submit_finality_proof`
- #[codec(index = 0)]
- submit_finality_proof {
- /// The header that we are going to finalize.
- finality_target: Box,
- /// Finality justification for the `finality_target`.
- justification: justification::GrandpaJustification,
- },
- /// `pallet-bridge-grandpa::Call::initialize`
- #[codec(index = 1)]
- initialize {
- /// All data, required to initialize the pallet.
- init_data: InitializationData,
- },
-}
-
-/// The `BridgeGrandpaCall` used by a chain.
-pub type BridgeGrandpaCallOf = BridgeGrandpaCall>;
-
/// Substrate-based chain that is using direct GRANDPA finality.
///
/// Keep in mind that parachains are relying on relay chain GRANDPA, so they should not implement
diff --git a/primitives/messages/src/call_info.rs b/primitives/messages/src/call_info.rs
new file mode 100644
index 00000000000..4cc3b9d4afe
--- /dev/null
+++ b/primitives/messages/src/call_info.rs
@@ -0,0 +1,164 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Parity Bridges Common.
+
+// Parity Bridges Common is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity Bridges Common is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity Bridges Common. If not, see .
+
+//! Defines structures related to calls of the `pallet-bridge-messages` pallet.
+
+use crate::{source_chain, target_chain, LaneId, MessageNonce, UnrewardedRelayersState};
+
+use bp_runtime::{AccountIdOf, HashOf};
+use codec::{Decode, Encode};
+use frame_support::weights::Weight;
+use scale_info::TypeInfo;
+use sp_core::RuntimeDebug;
+use sp_std::ops::RangeInclusive;
+
+/// The `BridgeMessagesCall` used to bridge with a given chain.
+pub type BridgeMessagesCallOf = BridgeMessagesCall<
+ AccountIdOf,
+ target_chain::FromBridgedChainMessagesProof>,
+ source_chain::FromBridgedChainMessagesDeliveryProof>,
+>;
+
+/// A minimized version of `pallet-bridge-messages::Call` that can be used without a runtime.
+#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
+#[allow(non_camel_case_types)]
+pub enum BridgeMessagesCall {
+ /// `pallet-bridge-messages::Call::receive_messages_proof`
+ #[codec(index = 2)]
+ receive_messages_proof {
+ /// Account id of relayer at the **bridged** chain.
+ relayer_id_at_bridged_chain: AccountId,
+ /// Messages proof.
+ proof: MessagesProof,
+ /// A number of messages in the proof.
+ messages_count: u32,
+ /// Total dispatch weight of messages in the proof.
+ dispatch_weight: Weight,
+ },
+ /// `pallet-bridge-messages::Call::receive_messages_delivery_proof`
+ #[codec(index = 3)]
+ receive_messages_delivery_proof {
+ /// Messages delivery proof.
+ proof: MessagesDeliveryProof,
+ /// "Digest" of unrewarded relayers state at the bridged chain.
+ relayers_state: UnrewardedRelayersState,
+ },
+}
+
+/// Generic info about a messages delivery/confirmation proof.
+#[derive(PartialEq, RuntimeDebug)]
+pub struct BaseMessagesProofInfo {
+ /// Message lane, used by the call.
+ pub lane_id: LaneId,
+ /// Nonces of messages, included in the call.
+ ///
+ /// For delivery transaction, it is nonces of bundled messages. For confirmation
+ /// transaction, it is nonces that are to be confirmed during the call.
+ pub bundled_range: RangeInclusive,
+ /// Nonce of the best message, stored by this chain before the call is dispatched.
+ ///
+ /// For delivery transaction, it is the nonce of best delivered message before the call.
+ /// For confirmation transaction, it is the nonce of best confirmed message before the call.
+ pub best_stored_nonce: MessageNonce,
+}
+
+impl BaseMessagesProofInfo {
+ /// Returns true if `bundled_range` continues the `0..=best_stored_nonce` range.
+ pub fn appends_to_stored_nonce(&self) -> bool {
+ Some(*self.bundled_range.start()) == self.best_stored_nonce.checked_add(1)
+ }
+}
+
+/// Occupation state of the unrewarded relayers vector.
+#[derive(PartialEq, RuntimeDebug)]
+#[cfg_attr(test, derive(Default))]
+pub struct UnrewardedRelayerOccupation {
+ /// The number of remaining unoccupied entries for new relayers.
+ pub free_relayer_slots: MessageNonce,
+ /// The number of messages that we are ready to accept.
+ pub free_message_slots: MessageNonce,
+}
+
+/// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
+#[derive(PartialEq, RuntimeDebug)]
+pub struct ReceiveMessagesProofInfo {
+ /// Base messages proof info
+ pub base: BaseMessagesProofInfo,
+ /// State of unrewarded relayers vector.
+ pub unrewarded_relayers: UnrewardedRelayerOccupation,
+}
+
+impl ReceiveMessagesProofInfo {
+ /// Returns true if:
+ ///
+ /// - either inbound lane is ready to accept bundled messages;
+ ///
+ /// - or there are no bundled messages, but the inbound lane is blocked by too many unconfirmed
+ /// messages and/or unrewarded relayers.
+ pub fn is_obsolete(&self, is_dispatcher_active: bool) -> bool {
+ // if dispatcher is inactive, we don't accept any delivery transactions
+ if !is_dispatcher_active {
+ return true
+ }
+
+ // transactions with zero bundled nonces are not allowed, unless they're message
+ // delivery transactions, which brings reward confirmations required to unblock
+ // the lane
+ if self.base.bundled_range.is_empty() {
+ let empty_transactions_allowed =
+ // we allow empty transactions when we can't accept delivery from new relayers
+ self.unrewarded_relayers.free_relayer_slots == 0 ||
+ // or if we can't accept new messages at all
+ self.unrewarded_relayers.free_message_slots == 0;
+
+ return !empty_transactions_allowed
+ }
+
+ // otherwise we require bundled messages to continue stored range
+ !self.base.appends_to_stored_nonce()
+ }
+}
+
+/// Info about a `ReceiveMessagesDeliveryProof` call which tries to update a single lane.
+#[derive(PartialEq, RuntimeDebug)]
+pub struct ReceiveMessagesDeliveryProofInfo(pub BaseMessagesProofInfo);
+
+impl ReceiveMessagesDeliveryProofInfo {
+ /// Returns true if outbound lane is ready to accept confirmations of bundled messages.
+ pub fn is_obsolete(&self) -> bool {
+ self.0.bundled_range.is_empty() || !self.0.appends_to_stored_nonce()
+ }
+}
+
+/// Info about a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call
+/// which tries to update a single lane.
+#[derive(PartialEq, RuntimeDebug)]
+pub enum MessagesCallInfo {
+ /// Messages delivery call info.
+ ReceiveMessagesProof(ReceiveMessagesProofInfo),
+ /// Messages delivery confirmation call info.
+ ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo),
+}
+
+impl MessagesCallInfo {
+ /// Returns range of messages, bundled with the call.
+ pub fn bundled_messages(&self) -> RangeInclusive {
+ match *self {
+ Self::ReceiveMessagesProof(ref info) => info.base.bundled_range.clone(),
+ Self::ReceiveMessagesDeliveryProof(ref info) => info.0.bundled_range.clone(),
+ }
+ }
+}
diff --git a/primitives/messages/src/lib.rs b/primitives/messages/src/lib.rs
index 85ea378871e..dd2a0ea2339 100644
--- a/primitives/messages/src/lib.rs
+++ b/primitives/messages/src/lib.rs
@@ -21,8 +21,8 @@
use bp_header_chain::HeaderChainError;
use bp_runtime::{
- messages::MessageDispatchResult, AccountIdOf, BasicOperatingMode, Chain, HashOf, OperatingMode,
- RangeInclusiveExt, StorageProofError, UnderlyingChainOf, UnderlyingChainProvider,
+ messages::MessageDispatchResult, BasicOperatingMode, Chain, OperatingMode, RangeInclusiveExt,
+ StorageProofError, UnderlyingChainOf, UnderlyingChainProvider,
};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::PalletError;
@@ -35,6 +35,13 @@ use sp_core::{RuntimeDebug, TypeId, H256};
use sp_io::hashing::blake2_256;
use sp_std::{collections::vec_deque::VecDeque, ops::RangeInclusive, prelude::*};
+pub use call_info::{
+ BaseMessagesProofInfo, BridgeMessagesCall, BridgeMessagesCallOf, MessagesCallInfo,
+ ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, UnrewardedRelayerOccupation,
+};
+
+mod call_info;
+
pub mod source_chain;
pub mod storage_keys;
pub mod target_chain;
@@ -604,39 +611,6 @@ where
relayers_rewards
}
-/// The `BridgeMessagesCall` used by a chain.
-pub type BridgeMessagesCallOf = BridgeMessagesCall<
- AccountIdOf,
- target_chain::FromBridgedChainMessagesProof>,
- source_chain::FromBridgedChainMessagesDeliveryProof>,
->;
-
-/// A minimized version of `pallet-bridge-messages::Call` that can be used without a runtime.
-#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
-#[allow(non_camel_case_types)]
-pub enum BridgeMessagesCall {
- /// `pallet-bridge-messages::Call::receive_messages_proof`
- #[codec(index = 2)]
- receive_messages_proof {
- /// Account id of relayer at the **bridged** chain.
- relayer_id_at_bridged_chain: AccountId,
- /// Messages proof.
- proof: MessagesProof,
- /// A number of messages in the proof.
- messages_count: u32,
- /// Total dispatch weight of messages in the proof.
- dispatch_weight: Weight,
- },
- /// `pallet-bridge-messages::Call::receive_messages_delivery_proof`
- #[codec(index = 3)]
- receive_messages_delivery_proof {
- /// Messages delivery proof.
- proof: MessagesDeliveryProof,
- /// "Digest" of unrewarded relayers state at the bridged chain.
- relayers_state: UnrewardedRelayersState,
- },
-}
-
/// Error that happens during message verification.
#[derive(Encode, Decode, RuntimeDebug, PartialEq, Eq, PalletError, TypeInfo)]
pub enum VerificationError {
diff --git a/primitives/parachains/src/call_info.rs b/primitives/parachains/src/call_info.rs
new file mode 100644
index 00000000000..6664b6eb341
--- /dev/null
+++ b/primitives/parachains/src/call_info.rs
@@ -0,0 +1,54 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Parity Bridges Common.
+
+// Parity Bridges Common is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity Bridges Common is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity Bridges Common. If not, see .
+
+//! Defines structures related to calls of the `pallet-bridge-parachains` pallet.
+
+use crate::{ParaHash, ParaId, RelayBlockHash, RelayBlockNumber};
+
+use bp_polkadot_core::parachains::ParaHeadsProof;
+use codec::{Decode, Encode};
+use scale_info::TypeInfo;
+use sp_runtime::RuntimeDebug;
+use sp_std::vec::Vec;
+
+/// A minimized version of `pallet-bridge-parachains::Call` that can be used without a runtime.
+#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
+#[allow(non_camel_case_types)]
+pub enum BridgeParachainCall {
+ /// `pallet-bridge-parachains::Call::submit_parachain_heads`
+ #[codec(index = 0)]
+ submit_parachain_heads {
+ /// Relay chain block, for which we have submitted the `parachain_heads_proof`.
+ at_relay_block: (RelayBlockNumber, RelayBlockHash),
+ /// Parachain identifiers and their head hashes.
+ parachains: Vec<(ParaId, ParaHash)>,
+ /// Parachain heads proof.
+ parachain_heads_proof: ParaHeadsProof,
+ },
+}
+
+/// Info about a `SubmitParachainHeads` call which tries to update a single parachain.
+///
+/// The pallet supports updating multiple parachain heads at once,
+#[derive(PartialEq, RuntimeDebug)]
+pub struct SubmitParachainHeadsInfo {
+ /// Number of the finalized relay block that has been used to prove parachain finality.
+ pub at_relay_block_number: RelayBlockNumber,
+ /// Parachain identifier.
+ pub para_id: ParaId,
+ /// Hash of the bundled parachain head.
+ pub para_head_hash: ParaHash,
+}
diff --git a/primitives/parachains/src/lib.rs b/primitives/parachains/src/lib.rs
index 692bbd99ece..777e0f3915a 100644
--- a/primitives/parachains/src/lib.rs
+++ b/primitives/parachains/src/lib.rs
@@ -22,7 +22,7 @@
pub use bp_header_chain::StoredHeaderData;
use bp_polkadot_core::{
- parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId},
+ parachains::{ParaHash, ParaHead, ParaId},
BlockNumber as RelayBlockNumber, Hash as RelayBlockHash,
};
use bp_runtime::{
@@ -36,6 +36,10 @@ use sp_core::storage::StorageKey;
use sp_runtime::{traits::Header as HeaderT, RuntimeDebug};
use sp_std::{marker::PhantomData, prelude::*};
+pub use call_info::{BridgeParachainCall, SubmitParachainHeadsInfo};
+
+mod call_info;
+
/// Best known parachain head hash.
#[derive(Clone, Decode, Encode, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)]
pub struct BestParaHeadHash {
@@ -166,19 +170,3 @@ impl ParaStoredHeaderDataBuilder for C {
None
}
}
-
-/// A minimized version of `pallet-bridge-parachains::Call` that can be used without a runtime.
-#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
-#[allow(non_camel_case_types)]
-pub enum BridgeParachainCall {
- /// `pallet-bridge-parachains::Call::submit_parachain_heads`
- #[codec(index = 0)]
- submit_parachain_heads {
- /// Relay chain block, for which we have submitted the `parachain_heads_proof`.
- at_relay_block: (RelayBlockNumber, RelayBlockHash),
- /// Parachain identifiers and their head hashes.
- parachains: Vec<(ParaId, ParaHash)>,
- /// Parachain heads proof.
- parachain_heads_proof: ParaHeadsProof,
- },
-}