referrerpolicy=no-referrer-when-downgrade

bp_messages/
call_info.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Parity Bridges Common.
3
4// Parity Bridges Common is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Bridges Common is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Bridges Common.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Defines structures related to calls of the `pallet-bridge-messages` pallet.
18
19use crate::{MessageNonce, UnrewardedRelayersState};
20
21use codec::{Decode, Encode};
22use frame_support::weights::Weight;
23use scale_info::TypeInfo;
24use sp_core::RuntimeDebug;
25use sp_std::ops::RangeInclusive;
26
27/// A minimized version of `pallet-bridge-messages::Call` that can be used without a runtime.
28#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
29#[allow(non_camel_case_types)]
30pub enum BridgeMessagesCall<AccountId, MessagesProof, MessagesDeliveryProof> {
31	/// `pallet-bridge-messages::Call::receive_messages_proof`
32	#[codec(index = 2)]
33	receive_messages_proof {
34		/// Account id of relayer at the **bridged** chain.
35		relayer_id_at_bridged_chain: AccountId,
36		/// Messages proof.
37		proof: MessagesProof,
38		/// A number of messages in the proof.
39		messages_count: u32,
40		/// Total dispatch weight of messages in the proof.
41		dispatch_weight: Weight,
42	},
43	/// `pallet-bridge-messages::Call::receive_messages_delivery_proof`
44	#[codec(index = 3)]
45	receive_messages_delivery_proof {
46		/// Messages delivery proof.
47		proof: MessagesDeliveryProof,
48		/// "Digest" of unrewarded relayers state at the bridged chain.
49		relayers_state: UnrewardedRelayersState,
50	},
51}
52
53/// Generic info about a messages delivery/confirmation proof.
54#[derive(PartialEq, RuntimeDebug)]
55pub struct BaseMessagesProofInfo<LaneId> {
56	/// Message lane, used by the call.
57	pub lane_id: LaneId,
58	/// Nonces of messages, included in the call.
59	///
60	/// For delivery transaction, it is nonces of bundled messages. For confirmation
61	/// transaction, it is nonces that are to be confirmed during the call.
62	pub bundled_range: RangeInclusive<MessageNonce>,
63	/// Nonce of the best message, stored by this chain before the call is dispatched.
64	///
65	/// For delivery transaction, it is the nonce of best delivered message before the call.
66	/// For confirmation transaction, it is the nonce of best confirmed message before the call.
67	pub best_stored_nonce: MessageNonce,
68}
69
70impl<LaneId> BaseMessagesProofInfo<LaneId> {
71	/// Returns true if `bundled_range` continues the `0..=best_stored_nonce` range.
72	pub fn appends_to_stored_nonce(&self) -> bool {
73		Some(*self.bundled_range.start()) == self.best_stored_nonce.checked_add(1)
74	}
75}
76
77/// Occupation state of the unrewarded relayers vector.
78#[derive(PartialEq, RuntimeDebug)]
79#[cfg_attr(test, derive(Default))]
80pub struct UnrewardedRelayerOccupation {
81	/// The number of remaining unoccupied entries for new relayers.
82	pub free_relayer_slots: MessageNonce,
83	/// The number of messages that we are ready to accept.
84	pub free_message_slots: MessageNonce,
85}
86
87/// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
88#[derive(PartialEq, RuntimeDebug)]
89pub struct ReceiveMessagesProofInfo<LaneId> {
90	/// Base messages proof info
91	pub base: BaseMessagesProofInfo<LaneId>,
92	/// State of unrewarded relayers vector.
93	pub unrewarded_relayers: UnrewardedRelayerOccupation,
94}
95
96impl<LaneId> ReceiveMessagesProofInfo<LaneId> {
97	/// Returns true if:
98	///
99	/// - either inbound lane is ready to accept bundled messages;
100	///
101	/// - or there are no bundled messages, but the inbound lane is blocked by too many unconfirmed
102	///   messages and/or unrewarded relayers.
103	pub fn is_obsolete(&self, is_dispatcher_active: bool) -> bool {
104		// if dispatcher is inactive, we don't accept any delivery transactions
105		if !is_dispatcher_active {
106			return true
107		}
108
109		// transactions with zero bundled nonces are not allowed, unless they're message
110		// delivery transactions, which brings reward confirmations required to unblock
111		// the lane
112		if self.base.bundled_range.is_empty() {
113			let empty_transactions_allowed =
114				// we allow empty transactions when we can't accept delivery from new relayers
115				self.unrewarded_relayers.free_relayer_slots == 0 ||
116				// or if we can't accept new messages at all
117				self.unrewarded_relayers.free_message_slots == 0;
118
119			return !empty_transactions_allowed
120		}
121
122		// otherwise we require bundled messages to continue stored range
123		!self.base.appends_to_stored_nonce()
124	}
125}
126
127/// Info about a `ReceiveMessagesDeliveryProof` call which tries to update a single lane.
128#[derive(PartialEq, RuntimeDebug)]
129pub struct ReceiveMessagesDeliveryProofInfo<LaneId>(pub BaseMessagesProofInfo<LaneId>);
130
131impl<LaneId> ReceiveMessagesDeliveryProofInfo<LaneId> {
132	/// Returns true if outbound lane is ready to accept confirmations of bundled messages.
133	pub fn is_obsolete(&self) -> bool {
134		self.0.bundled_range.is_empty() || !self.0.appends_to_stored_nonce()
135	}
136}
137
138/// Info about a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call
139/// which tries to update a single lane.
140#[derive(PartialEq, RuntimeDebug)]
141pub enum MessagesCallInfo<LaneId: Clone + Copy> {
142	/// Messages delivery call info.
143	ReceiveMessagesProof(ReceiveMessagesProofInfo<LaneId>),
144	/// Messages delivery confirmation call info.
145	ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo<LaneId>),
146}
147
148impl<LaneId: Clone + Copy> MessagesCallInfo<LaneId> {
149	/// Returns lane, used by the call.
150	pub fn lane_id(&self) -> LaneId {
151		match *self {
152			Self::ReceiveMessagesProof(ref info) => info.base.lane_id,
153			Self::ReceiveMessagesDeliveryProof(ref info) => info.0.lane_id,
154		}
155	}
156
157	/// Returns range of messages, bundled with the call.
158	pub fn bundled_messages(&self) -> RangeInclusive<MessageNonce> {
159		match *self {
160			Self::ReceiveMessagesProof(ref info) => info.base.bundled_range.clone(),
161			Self::ReceiveMessagesDeliveryProof(ref info) => info.0.bundled_range.clone(),
162		}
163	}
164}