b6d35f6faf
Updated 4763 files with dual copyright: - Parity Technologies (UK) Ltd. - Dijital Kurdistan Tech Institute
165 lines
6.3 KiB
Rust
165 lines
6.3 KiB
Rust
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
|
|
// This file is part of Parity Bridges Common.
|
|
|
|
// Parity Bridges Common is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// Parity Bridges Common is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
//! Defines structures related to calls of the `pezpallet-bridge-messages` pezpallet.
|
|
|
|
use crate::{MessageNonce, UnrewardedRelayersState};
|
|
|
|
use codec::{Decode, Encode};
|
|
use pezframe_support::weights::Weight;
|
|
use pezsp_core::RuntimeDebug;
|
|
use pezsp_std::ops::RangeInclusive;
|
|
use scale_info::TypeInfo;
|
|
|
|
/// A minimized version of `pezpallet-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<AccountId, MessagesProof, MessagesDeliveryProof> {
|
|
/// `pezpallet-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,
|
|
},
|
|
/// `pezpallet-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<LaneId> {
|
|
/// 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<MessageNonce>,
|
|
/// 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<LaneId> BaseMessagesProofInfo<LaneId> {
|
|
/// 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<LaneId> {
|
|
/// Base messages proof info
|
|
pub base: BaseMessagesProofInfo<LaneId>,
|
|
/// State of unrewarded relayers vector.
|
|
pub unrewarded_relayers: UnrewardedRelayerOccupation,
|
|
}
|
|
|
|
impl<LaneId> ReceiveMessagesProofInfo<LaneId> {
|
|
/// 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<LaneId>(pub BaseMessagesProofInfo<LaneId>);
|
|
|
|
impl<LaneId> ReceiveMessagesDeliveryProofInfo<LaneId> {
|
|
/// 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<LaneId: Clone + Copy> {
|
|
/// Messages delivery call info.
|
|
ReceiveMessagesProof(ReceiveMessagesProofInfo<LaneId>),
|
|
/// Messages delivery confirmation call info.
|
|
ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo<LaneId>),
|
|
}
|
|
|
|
impl<LaneId: Clone + Copy> MessagesCallInfo<LaneId> {
|
|
/// Returns lane, used by the call.
|
|
pub fn lane_id(&self) -> LaneId {
|
|
match *self {
|
|
Self::ReceiveMessagesProof(ref info) => info.base.lane_id,
|
|
Self::ReceiveMessagesDeliveryProof(ref info) => info.0.lane_id,
|
|
}
|
|
}
|
|
|
|
/// Returns range of messages, bundled with the call.
|
|
pub fn bundled_messages(&self) -> RangeInclusive<MessageNonce> {
|
|
match *self {
|
|
Self::ReceiveMessagesProof(ref info) => info.base.bundled_range.clone(),
|
|
Self::ReceiveMessagesDeliveryProof(ref info) => info.0.bundled_range.clone(),
|
|
}
|
|
}
|
|
}
|