From 01139ebbc47ce46937a525135f330ee86944c5aa Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Thu, 13 Apr 2023 10:38:34 +0300 Subject: [PATCH] Define `RangeInclusiveExt` (#2037) * Define RangeInclusiveExt * Use RangeInclusiveExt * Add docs --- bin/runtime-common/src/messages_call_ext.rs | 16 -------------- .../src/refund_relayer_extension.rs | 6 +++--- modules/messages/src/lib.rs | 7 ++----- primitives/messages/src/lib.rs | 8 ++----- primitives/runtime/src/lib.rs | 21 +++++++++++++++++-- 5 files changed, 26 insertions(+), 32 deletions(-) diff --git a/bin/runtime-common/src/messages_call_ext.rs b/bin/runtime-common/src/messages_call_ext.rs index b208a9d02b4..1ca1bab6a35 100644 --- a/bin/runtime-common/src/messages_call_ext.rs +++ b/bin/runtime-common/src/messages_call_ext.rs @@ -115,22 +115,6 @@ pub enum CallInfo { ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo), } -impl CallInfo { - /// Returns number of messages, bundled with this transaction. - pub fn bundled_messages(&self) -> MessageNonce { - let bundled_range = match *self { - Self::ReceiveMessagesProof(ref info) => &info.base.bundled_range, - Self::ReceiveMessagesDeliveryProof(ref info) => &info.0.bundled_range, - }; - - bundled_range - .end() - .checked_sub(*bundled_range.start()) - .map(|d| d.saturating_add(1)) - .unwrap_or(0) - } -} - /// Helper struct that provides methods for working with a call supported by `CallInfo`. pub struct CallHelper, I: 'static> { pub _phantom_data: sp_std::marker::PhantomData<(T, I)>, diff --git a/bin/runtime-common/src/refund_relayer_extension.rs b/bin/runtime-common/src/refund_relayer_extension.rs index 1aae6a16a3c..925fea2a743 100644 --- a/bin/runtime-common/src/refund_relayer_extension.rs +++ b/bin/runtime-common/src/refund_relayer_extension.rs @@ -24,7 +24,7 @@ use crate::messages_call_ext::{ }; use bp_messages::LaneId; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; -use bp_runtime::StaticStrProvider; +use bp_runtime::{RangeInclusiveExt, StaticStrProvider}; use codec::{Decode, Encode}; use frame_support::{ dispatch::{CallableCallFor, DispatchInfo, Dispatchable, PostDispatchInfo}, @@ -319,9 +319,9 @@ where if let Some(parsed_call) = parsed_call { // we give delivery transactions some boost, that depends on number of messages inside let messages_call_info = parsed_call.messages_call_info(); - if let MessagesCallInfo::ReceiveMessagesProof(_) = messages_call_info { + if let MessagesCallInfo::ReceiveMessagesProof(info) = messages_call_info { // compute total number of messages in transaction - let bundled_messages = messages_call_info.bundled_messages(); + let bundled_messages = info.base.bundled_range.checked_len().unwrap_or(0); // a quick check to avoid invalid high-priority transactions if bundled_messages <= Runtime::MaxUnconfirmedMessagesAtInboundLane::get() { diff --git a/modules/messages/src/lib.rs b/modules/messages/src/lib.rs index 3404ba0b219..5b1b98ea7a1 100644 --- a/modules/messages/src/lib.rs +++ b/modules/messages/src/lib.rs @@ -90,6 +90,7 @@ pub const LOG_TARGET: &str = "runtime::bridge-messages"; pub mod pallet { use super::*; use bp_messages::{ReceivalResult, ReceivedMessages}; + use bp_runtime::RangeInclusiveExt; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -514,11 +515,7 @@ pub mod pallet { ); relayers_state.total_messages = sp_std::cmp::min( relayers_state.total_messages, - received_range - .end() - .checked_sub(*received_range.start()) - .and_then(|x| x.checked_add(1)) - .unwrap_or(MessageNonce::MAX), + received_range.checked_len().unwrap_or(MessageNonce::MAX), ); }; diff --git a/primitives/messages/src/lib.rs b/primitives/messages/src/lib.rs index c877c9cdf2c..9481a4b9bb8 100644 --- a/primitives/messages/src/lib.rs +++ b/primitives/messages/src/lib.rs @@ -21,7 +21,7 @@ #![allow(clippy::too_many_arguments)] use bitvec::prelude::*; -use bp_runtime::{BasicOperatingMode, OperatingMode}; +use bp_runtime::{BasicOperatingMode, OperatingMode, RangeInclusiveExt}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::RuntimeDebug; use scale_info::TypeInfo; @@ -347,11 +347,7 @@ impl DeliveredMessages { /// Return total count of delivered messages. pub fn total_messages(&self) -> MessageNonce { - if self.end >= self.begin { - self.end - self.begin + 1 - } else { - 0 - } + (self.begin..=self.end).checked_len().unwrap_or(0) } /// Note new dispatched message. diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index d4f551ce57a..df77745bc02 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -27,7 +27,7 @@ use frame_system::RawOrigin; use scale_info::TypeInfo; use sp_core::storage::StorageKey; use sp_runtime::traits::{BadOrigin, Header as HeaderT, UniqueSaturatedInto}; -use sp_std::{convert::TryFrom, fmt::Debug, vec, vec::Vec}; +use sp_std::{convert::TryFrom, fmt::Debug, ops::RangeInclusive, vec, vec::Vec}; pub use chain::{ AccountIdOf, AccountPublicOf, BalanceOf, BlockNumberOf, Chain, EncodedOrDecodedCall, HashOf, @@ -35,7 +35,7 @@ pub use chain::{ UnderlyingChainProvider, }; pub use frame_support::storage::storage_prefix as storage_value_final_key; -use num_traits::{CheckedSub, One}; +use num_traits::{CheckedAdd, CheckedSub, One}; pub use storage_proof::{ record_all_keys as record_all_trie_keys, Error as StorageProofError, ProofSize as StorageProofSize, RawStorageProof, StorageProofChecker, @@ -523,6 +523,23 @@ impl Debug for StrippableError { } } +/// A trait defining helper methods for `RangeInclusive` (start..=end) +pub trait RangeInclusiveExt { + /// Computes the length of the `RangeInclusive`, checking for underflow and overflow. + fn checked_len(&self) -> Option; +} + +impl RangeInclusiveExt for RangeInclusive +where + Idx: CheckedSub + CheckedAdd + One, +{ + fn checked_len(&self) -> Option { + self.end() + .checked_sub(self.start()) + .and_then(|len| len.checked_add(&Idx::one())) + } +} + #[cfg(test)] mod tests { use super::*;