mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 14:01:02 +00:00
cargo +nightly fmt (#3540)
* cargo +nightly fmt * add cargo-fmt check to ci * update ci * fmt * fmt * skip macro * ignore bridges
This commit is contained in:
@@ -15,22 +15,20 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
ensure_parachain,
|
||||
configuration::{self, HostConfiguration},
|
||||
initializer, paras, dmp,
|
||||
dmp, ensure_parachain, initializer, paras,
|
||||
};
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_support::traits::ReservableCurrency;
|
||||
use frame_support::{pallet_prelude::*, traits::ReservableCurrency};
|
||||
use frame_system::pallet_prelude::*;
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
use primitives::v1::{
|
||||
Balance, Hash, HrmpChannelId, Id as ParaId, InboundHrmpMessage, OutboundHrmpMessage,
|
||||
SessionIndex,
|
||||
};
|
||||
use sp_runtime::traits::{UniqueSaturatedInto, AccountIdConversion, BlakeTwo256, Hash as HashT};
|
||||
use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash as HashT, UniqueSaturatedInto};
|
||||
use sp_std::{
|
||||
mem, fmt,
|
||||
collections::{btree_map::BTreeMap, btree_set::BTreeSet},
|
||||
fmt, mem,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
@@ -63,7 +61,6 @@ pub struct HrmpChannel {
|
||||
// A parachain requested this struct can only depend on the subset of this struct. Specifically,
|
||||
// only a first few fields can be depended upon (See `AbridgedHrmpChannel`). These fields cannot
|
||||
// be changed without corresponding migration of parachains.
|
||||
|
||||
/// The maximum number of messages that can be pending in the channel at once.
|
||||
pub max_capacity: u32,
|
||||
/// The maximum total size of the messages that can be pending in the channel at once.
|
||||
@@ -93,48 +90,20 @@ pub struct HrmpChannel {
|
||||
/// An error returned by [`check_hrmp_watermark`] that indicates an acceptance criteria check
|
||||
/// didn't pass.
|
||||
pub enum HrmpWatermarkAcceptanceErr<BlockNumber> {
|
||||
AdvancementRule {
|
||||
new_watermark: BlockNumber,
|
||||
last_watermark: BlockNumber,
|
||||
},
|
||||
AheadRelayParent {
|
||||
new_watermark: BlockNumber,
|
||||
relay_chain_parent_number: BlockNumber,
|
||||
},
|
||||
LandsOnBlockWithNoMessages {
|
||||
new_watermark: BlockNumber,
|
||||
},
|
||||
AdvancementRule { new_watermark: BlockNumber, last_watermark: BlockNumber },
|
||||
AheadRelayParent { new_watermark: BlockNumber, relay_chain_parent_number: BlockNumber },
|
||||
LandsOnBlockWithNoMessages { new_watermark: BlockNumber },
|
||||
}
|
||||
|
||||
/// An error returned by [`check_outbound_hrmp`] that indicates an acceptance criteria check
|
||||
/// didn't pass.
|
||||
pub enum OutboundHrmpAcceptanceErr {
|
||||
MoreMessagesThanPermitted {
|
||||
sent: u32,
|
||||
permitted: u32,
|
||||
},
|
||||
NotSorted {
|
||||
idx: u32,
|
||||
},
|
||||
NoSuchChannel {
|
||||
idx: u32,
|
||||
channel_id: HrmpChannelId,
|
||||
},
|
||||
MaxMessageSizeExceeded {
|
||||
idx: u32,
|
||||
msg_size: u32,
|
||||
max_size: u32,
|
||||
},
|
||||
TotalSizeExceeded {
|
||||
idx: u32,
|
||||
total_size: u32,
|
||||
limit: u32,
|
||||
},
|
||||
CapacityExceeded {
|
||||
idx: u32,
|
||||
count: u32,
|
||||
limit: u32,
|
||||
},
|
||||
MoreMessagesThanPermitted { sent: u32, permitted: u32 },
|
||||
NotSorted { idx: u32 },
|
||||
NoSuchChannel { idx: u32, channel_id: HrmpChannelId },
|
||||
MaxMessageSizeExceeded { idx: u32, msg_size: u32, max_size: u32 },
|
||||
TotalSizeExceeded { idx: u32, total_size: u32, limit: u32 },
|
||||
CapacityExceeded { idx: u32, count: u32, limit: u32 },
|
||||
}
|
||||
|
||||
impl<BlockNumber> fmt::Debug for HrmpWatermarkAcceptanceErr<BlockNumber>
|
||||
@@ -144,18 +113,12 @@ where
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
use HrmpWatermarkAcceptanceErr::*;
|
||||
match self {
|
||||
AdvancementRule {
|
||||
new_watermark,
|
||||
last_watermark,
|
||||
} => write!(
|
||||
AdvancementRule { new_watermark, last_watermark } => write!(
|
||||
fmt,
|
||||
"the HRMP watermark is not advanced relative to the last watermark ({:?} > {:?})",
|
||||
new_watermark, last_watermark,
|
||||
),
|
||||
AheadRelayParent {
|
||||
new_watermark,
|
||||
relay_chain_parent_number,
|
||||
} => write!(
|
||||
AheadRelayParent { new_watermark, relay_chain_parent_number } => write!(
|
||||
fmt,
|
||||
"the HRMP watermark is ahead the relay-parent ({:?} > {:?})",
|
||||
new_watermark, relay_chain_parent_number
|
||||
@@ -178,30 +141,19 @@ impl fmt::Debug for OutboundHrmpAcceptanceErr {
|
||||
"more HRMP messages than permitted by config ({} > {})",
|
||||
sent, permitted,
|
||||
),
|
||||
NotSorted { idx } => write!(
|
||||
fmt,
|
||||
"the HRMP messages are not sorted (first unsorted is at index {})",
|
||||
idx,
|
||||
),
|
||||
NotSorted { idx } =>
|
||||
write!(fmt, "the HRMP messages are not sorted (first unsorted is at index {})", idx,),
|
||||
NoSuchChannel { idx, channel_id } => write!(
|
||||
fmt,
|
||||
"the HRMP message at index {} is sent to a non existent channel {:?}->{:?}",
|
||||
idx, channel_id.sender, channel_id.recipient,
|
||||
),
|
||||
MaxMessageSizeExceeded {
|
||||
idx,
|
||||
msg_size,
|
||||
max_size,
|
||||
} => write!(
|
||||
MaxMessageSizeExceeded { idx, msg_size, max_size } => write!(
|
||||
fmt,
|
||||
"the HRMP message at index {} exceeds the negotiated channel maximum message size ({} > {})",
|
||||
idx, msg_size, max_size,
|
||||
),
|
||||
TotalSizeExceeded {
|
||||
idx,
|
||||
total_size,
|
||||
limit,
|
||||
} => write!(
|
||||
TotalSizeExceeded { idx, total_size, limit } => write!(
|
||||
fmt,
|
||||
"sending the HRMP message at index {} would exceed the neogitiated channel total size ({} > {})",
|
||||
idx, total_size, limit,
|
||||
@@ -219,13 +171,14 @@ impl fmt::Debug for OutboundHrmpAcceptanceErr {
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(super) trait Store)]
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config + configuration::Config + paras::Config + dmp::Config {
|
||||
pub trait Config:
|
||||
frame_system::Config + configuration::Config + paras::Config + dmp::Config
|
||||
{
|
||||
/// The outer event type.
|
||||
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
|
||||
|
||||
@@ -294,39 +247,26 @@ pub mod pallet {
|
||||
/// Invariant:
|
||||
/// - There are no channels that exists in list but not in the set and vice versa.
|
||||
#[pallet::storage]
|
||||
pub type HrmpOpenChannelRequests<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat,
|
||||
HrmpChannelId,
|
||||
HrmpOpenChannelRequest
|
||||
>;
|
||||
pub type HrmpOpenChannelRequests<T: Config> =
|
||||
StorageMap<_, Twox64Concat, HrmpChannelId, HrmpOpenChannelRequest>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub type HrmpOpenChannelRequestsList<T: Config> = StorageValue<_, Vec<HrmpChannelId>, ValueQuery>;
|
||||
pub type HrmpOpenChannelRequestsList<T: Config> =
|
||||
StorageValue<_, Vec<HrmpChannelId>, ValueQuery>;
|
||||
|
||||
/// This mapping tracks how many open channel requests are initiated by a given sender para.
|
||||
/// Invariant: `HrmpOpenChannelRequests` should contain the same number of items that has `(X, _)`
|
||||
/// as the number of `HrmpOpenChannelRequestCount` for `X`.
|
||||
#[pallet::storage]
|
||||
pub type HrmpOpenChannelRequestCount<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat,
|
||||
ParaId,
|
||||
u32,
|
||||
ValueQuery
|
||||
>;
|
||||
pub type HrmpOpenChannelRequestCount<T: Config> =
|
||||
StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>;
|
||||
|
||||
/// This mapping tracks how many open channel requests were accepted by a given recipient para.
|
||||
/// Invariant: `HrmpOpenChannelRequests` should contain the same number of items `(_, X)` with
|
||||
/// `confirmed` set to true, as the number of `HrmpAcceptedChannelRequestCount` for `X`.
|
||||
#[pallet::storage]
|
||||
pub type HrmpAcceptedChannelRequestCount<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat,
|
||||
ParaId,
|
||||
u32,
|
||||
ValueQuery
|
||||
>;
|
||||
pub type HrmpAcceptedChannelRequestCount<T: Config> =
|
||||
StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>;
|
||||
|
||||
/// A set of pending HRMP close channel requests that are going to be closed during the session change.
|
||||
/// Used for checking if a given channel is registered for closure.
|
||||
@@ -339,7 +279,8 @@ pub mod pallet {
|
||||
pub type HrmpCloseChannelRequests<T: Config> = StorageMap<_, Twox64Concat, HrmpChannelId, ()>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub type HrmpCloseChannelRequestsList<T: Config> = StorageValue<_, Vec<HrmpChannelId>, ValueQuery>;
|
||||
pub type HrmpCloseChannelRequestsList<T: Config> =
|
||||
StorageValue<_, Vec<HrmpChannelId>, ValueQuery>;
|
||||
|
||||
/// The HRMP watermark associated with each para.
|
||||
/// Invariant:
|
||||
@@ -367,24 +308,14 @@ pub mod pallet {
|
||||
/// - there should be no other dangling channels in `HrmpChannels`.
|
||||
/// - the vectors are sorted.
|
||||
#[pallet::storage]
|
||||
pub type HrmpIngressChannelsIndex<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat,
|
||||
ParaId,
|
||||
Vec<ParaId>,
|
||||
ValueQuery
|
||||
>;
|
||||
pub type HrmpIngressChannelsIndex<T: Config> =
|
||||
StorageMap<_, Twox64Concat, ParaId, Vec<ParaId>, ValueQuery>;
|
||||
|
||||
// NOTE that this field is used by parachains via merkle storage proofs, therefore changing
|
||||
// the format will require migration of parachains.
|
||||
#[pallet::storage]
|
||||
pub type HrmpEgressChannelsIndex<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat,
|
||||
ParaId,
|
||||
Vec<ParaId>,
|
||||
ValueQuery
|
||||
>;
|
||||
pub type HrmpEgressChannelsIndex<T: Config> =
|
||||
StorageMap<_, Twox64Concat, ParaId, Vec<ParaId>, ValueQuery>;
|
||||
|
||||
/// Storage for the messages for each channel.
|
||||
/// Invariant: cannot be non-empty if the corresponding channel in `HrmpChannels` is `None`.
|
||||
@@ -394,7 +325,7 @@ pub mod pallet {
|
||||
Twox64Concat,
|
||||
HrmpChannelId,
|
||||
Vec<InboundHrmpMessage<T::BlockNumber>>,
|
||||
ValueQuery
|
||||
ValueQuery,
|
||||
>;
|
||||
|
||||
/// Maintains a mapping that can be used to answer the question:
|
||||
@@ -405,13 +336,8 @@ pub mod pallet {
|
||||
/// - The outer vector is sorted ascending by block number and cannot store two items with the same
|
||||
/// block number.
|
||||
#[pallet::storage]
|
||||
pub type HrmpChannelDigests<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat,
|
||||
ParaId,
|
||||
Vec<(T::BlockNumber, Vec<ParaId>)>,
|
||||
ValueQuery
|
||||
>;
|
||||
pub type HrmpChannelDigests<T: Config> =
|
||||
StorageMap<_, Twox64Concat, ParaId, Vec<(T::BlockNumber, Vec<ParaId>)>, ValueQuery>;
|
||||
|
||||
/// Preopen the given HRMP channels.
|
||||
///
|
||||
@@ -432,9 +358,7 @@ pub mod pallet {
|
||||
#[cfg(feature = "std")]
|
||||
impl Default for GenesisConfig {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
preopen_hrmp_channels: Default::default(),
|
||||
}
|
||||
GenesisConfig { preopen_hrmp_channels: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,13 +393,13 @@ pub mod pallet {
|
||||
origin,
|
||||
recipient,
|
||||
proposed_max_capacity,
|
||||
proposed_max_message_size
|
||||
proposed_max_message_size,
|
||||
)?;
|
||||
Self::deposit_event(Event::OpenChannelRequested(
|
||||
origin,
|
||||
recipient,
|
||||
proposed_max_capacity,
|
||||
proposed_max_message_size
|
||||
proposed_max_message_size,
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -496,7 +420,10 @@ pub mod pallet {
|
||||
///
|
||||
/// The closure can only happen on a session change.
|
||||
#[pallet::weight(0)]
|
||||
pub fn hrmp_close_channel(origin: OriginFor<T>, channel_id: HrmpChannelId) -> DispatchResult {
|
||||
pub fn hrmp_close_channel(
|
||||
origin: OriginFor<T>,
|
||||
channel_id: HrmpChannelId,
|
||||
) -> DispatchResult {
|
||||
let origin = ensure_parachain(<T as Config>::Origin::from(origin))?;
|
||||
Self::close_channel(origin, channel_id.clone())?;
|
||||
Self::deposit_event(Event::ChannelClosed(origin, channel_id));
|
||||
@@ -544,7 +471,9 @@ pub mod pallet {
|
||||
fn initialize_storage<T: Config>(preopen_hrmp_channels: &[(ParaId, ParaId, u32, u32)]) {
|
||||
let host_config = configuration::Pallet::<T>::config();
|
||||
for &(sender, recipient, max_capacity, max_message_size) in preopen_hrmp_channels {
|
||||
if let Err(err) = preopen_hrmp_channel::<T>(sender, recipient, max_capacity, max_message_size) {
|
||||
if let Err(err) =
|
||||
preopen_hrmp_channel::<T>(sender, recipient, max_capacity, max_message_size)
|
||||
{
|
||||
panic!("failed to initialize the genesis storage: {:?}", err);
|
||||
}
|
||||
}
|
||||
@@ -556,14 +485,9 @@ fn preopen_hrmp_channel<T: Config>(
|
||||
sender: ParaId,
|
||||
recipient: ParaId,
|
||||
max_capacity: u32,
|
||||
max_message_size: u32
|
||||
max_message_size: u32,
|
||||
) -> DispatchResult {
|
||||
<Pallet<T>>::init_open_channel(
|
||||
sender,
|
||||
recipient,
|
||||
max_capacity,
|
||||
max_message_size,
|
||||
)?;
|
||||
<Pallet<T>>::init_open_channel(sender, recipient, max_capacity, max_message_size)?;
|
||||
<Pallet<T>>::accept_open_channel(recipient, sender)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -603,16 +527,10 @@ impl<T: Config> Pallet<T> {
|
||||
|
||||
let ingress = <Self as Store>::HrmpIngressChannelsIndex::take(outgoing_para)
|
||||
.into_iter()
|
||||
.map(|sender| HrmpChannelId {
|
||||
sender,
|
||||
recipient: outgoing_para.clone(),
|
||||
});
|
||||
.map(|sender| HrmpChannelId { sender, recipient: outgoing_para.clone() });
|
||||
let egress = <Self as Store>::HrmpEgressChannelsIndex::take(outgoing_para)
|
||||
.into_iter()
|
||||
.map(|recipient| HrmpChannelId {
|
||||
sender: outgoing_para.clone(),
|
||||
recipient,
|
||||
});
|
||||
.map(|recipient| HrmpChannelId { sender: outgoing_para.clone(), recipient });
|
||||
let mut to_close = ingress.chain(egress).collect::<Vec<_>>();
|
||||
to_close.sort();
|
||||
to_close.dedup();
|
||||
@@ -629,7 +547,7 @@ impl<T: Config> Pallet<T> {
|
||||
fn process_hrmp_open_channel_requests(config: &HostConfiguration<T::BlockNumber>) {
|
||||
let mut open_req_channels = <Self as Store>::HrmpOpenChannelRequestsList::get();
|
||||
if open_req_channels.is_empty() {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// iterate the vector starting from the end making our way to the beginning. This way we
|
||||
@@ -638,7 +556,7 @@ impl<T: Config> Pallet<T> {
|
||||
loop {
|
||||
// bail if we've iterated over all items.
|
||||
if idx == 0 {
|
||||
break;
|
||||
break
|
||||
}
|
||||
|
||||
idx -= 1;
|
||||
@@ -648,8 +566,8 @@ impl<T: Config> Pallet<T> {
|
||||
);
|
||||
|
||||
if request.confirmed {
|
||||
if <paras::Pallet<T>>::is_valid_para(channel_id.sender)
|
||||
&& <paras::Pallet<T>>::is_valid_para(channel_id.recipient)
|
||||
if <paras::Pallet<T>>::is_valid_para(channel_id.sender) &&
|
||||
<paras::Pallet<T>>::is_valid_para(channel_id.recipient)
|
||||
{
|
||||
<Self as Store>::HrmpChannels::insert(
|
||||
&channel_id,
|
||||
@@ -745,11 +663,8 @@ impl<T: Config> Pallet<T> {
|
||||
/// This function is idempotent, meaning that after the first application it should have no
|
||||
/// effect (i.e. it won't return the deposits twice).
|
||||
fn close_hrmp_channel(channel_id: &HrmpChannelId) {
|
||||
if let Some(HrmpChannel {
|
||||
sender_deposit,
|
||||
recipient_deposit,
|
||||
..
|
||||
}) = <Self as Store>::HrmpChannels::take(channel_id)
|
||||
if let Some(HrmpChannel { sender_deposit, recipient_deposit, .. }) =
|
||||
<Self as Store>::HrmpChannels::take(channel_id)
|
||||
{
|
||||
T::Currency::unreserve(
|
||||
&channel_id.sender.into_account(),
|
||||
@@ -793,14 +708,14 @@ impl<T: Config> Pallet<T> {
|
||||
return Err(HrmpWatermarkAcceptanceErr::AdvancementRule {
|
||||
new_watermark: new_hrmp_watermark,
|
||||
last_watermark,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
if new_hrmp_watermark > relay_chain_parent_number {
|
||||
return Err(HrmpWatermarkAcceptanceErr::AheadRelayParent {
|
||||
new_watermark: new_hrmp_watermark,
|
||||
relay_chain_parent_number,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Second, check where the watermark CAN land. It's one of the following:
|
||||
@@ -817,7 +732,7 @@ impl<T: Config> Pallet<T> {
|
||||
{
|
||||
return Err(HrmpWatermarkAcceptanceErr::LandsOnBlockWithNoMessages {
|
||||
new_watermark: new_hrmp_watermark,
|
||||
});
|
||||
})
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -832,36 +747,28 @@ impl<T: Config> Pallet<T> {
|
||||
return Err(OutboundHrmpAcceptanceErr::MoreMessagesThanPermitted {
|
||||
sent: out_hrmp_msgs.len() as u32,
|
||||
permitted: config.hrmp_max_message_num_per_candidate,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
let mut last_recipient = None::<ParaId>;
|
||||
|
||||
for (idx, out_msg) in out_hrmp_msgs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, out_msg)| (idx as u32, out_msg))
|
||||
for (idx, out_msg) in
|
||||
out_hrmp_msgs.iter().enumerate().map(|(idx, out_msg)| (idx as u32, out_msg))
|
||||
{
|
||||
match last_recipient {
|
||||
// the messages must be sorted in ascending order and there must be no two messages sent
|
||||
// to the same recipient. Thus we can check that every recipient is strictly greater than
|
||||
// the previous one.
|
||||
Some(last_recipient) if out_msg.recipient <= last_recipient => {
|
||||
return Err(OutboundHrmpAcceptanceErr::NotSorted { idx });
|
||||
}
|
||||
Some(last_recipient) if out_msg.recipient <= last_recipient =>
|
||||
return Err(OutboundHrmpAcceptanceErr::NotSorted { idx }),
|
||||
_ => last_recipient = Some(out_msg.recipient),
|
||||
}
|
||||
|
||||
let channel_id = HrmpChannelId {
|
||||
sender,
|
||||
recipient: out_msg.recipient,
|
||||
};
|
||||
let channel_id = HrmpChannelId { sender, recipient: out_msg.recipient };
|
||||
|
||||
let channel = match <Self as Store>::HrmpChannels::get(&channel_id) {
|
||||
Some(channel) => channel,
|
||||
None => {
|
||||
return Err(OutboundHrmpAcceptanceErr::NoSuchChannel { channel_id, idx });
|
||||
}
|
||||
None => return Err(OutboundHrmpAcceptanceErr::NoSuchChannel { channel_id, idx }),
|
||||
};
|
||||
|
||||
let msg_size = out_msg.data.len() as u32;
|
||||
@@ -870,7 +777,7 @@ impl<T: Config> Pallet<T> {
|
||||
idx,
|
||||
msg_size,
|
||||
max_size: channel.max_message_size,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
let new_total_size = channel.total_size + out_msg.data.len() as u32;
|
||||
@@ -879,7 +786,7 @@ impl<T: Config> Pallet<T> {
|
||||
idx,
|
||||
total_size: new_total_size,
|
||||
limit: channel.max_total_size,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
let new_msg_count = channel.msg_count + 1;
|
||||
@@ -888,7 +795,7 @@ impl<T: Config> Pallet<T> {
|
||||
idx,
|
||||
count: new_msg_count,
|
||||
limit: channel.max_capacity,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -916,9 +823,8 @@ impl<T: Config> Pallet<T> {
|
||||
weight += T::DbWeight::get().reads_writes(1, 1);
|
||||
|
||||
// having all senders we can trivially find out the channels which we need to prune.
|
||||
let channels_to_prune = senders
|
||||
.into_iter()
|
||||
.map(|sender| HrmpChannelId { sender, recipient });
|
||||
let channels_to_prune =
|
||||
senders.into_iter().map(|sender| HrmpChannelId { sender, recipient });
|
||||
for channel_id in channels_to_prune {
|
||||
// prune each channel up to the new watermark keeping track how many messages we removed
|
||||
// and what is the total byte size of them.
|
||||
@@ -968,24 +874,18 @@ impl<T: Config> Pallet<T> {
|
||||
let now = <frame_system::Pallet<T>>::block_number();
|
||||
|
||||
for out_msg in out_hrmp_msgs {
|
||||
let channel_id = HrmpChannelId {
|
||||
sender,
|
||||
recipient: out_msg.recipient,
|
||||
};
|
||||
let channel_id = HrmpChannelId { sender, recipient: out_msg.recipient };
|
||||
|
||||
let mut channel = match <Self as Store>::HrmpChannels::get(&channel_id) {
|
||||
Some(channel) => channel,
|
||||
None => {
|
||||
// apparently, that since acceptance of this candidate the recipient was
|
||||
// offboarded and the channel no longer exists.
|
||||
continue;
|
||||
}
|
||||
continue
|
||||
},
|
||||
};
|
||||
|
||||
let inbound = InboundHrmpMessage {
|
||||
sent_at: now,
|
||||
data: out_msg.data,
|
||||
};
|
||||
let inbound = InboundHrmpMessage { sent_at: now, data: out_msg.data };
|
||||
|
||||
// book keeping
|
||||
channel.msg_count += 1;
|
||||
@@ -1052,27 +952,18 @@ impl<T: Config> Pallet<T> {
|
||||
);
|
||||
|
||||
let config = <configuration::Pallet<T>>::config();
|
||||
ensure!(
|
||||
proposed_max_capacity > 0,
|
||||
Error::<T>::OpenHrmpChannelZeroCapacity,
|
||||
);
|
||||
ensure!(proposed_max_capacity > 0, Error::<T>::OpenHrmpChannelZeroCapacity,);
|
||||
ensure!(
|
||||
proposed_max_capacity <= config.hrmp_channel_max_capacity,
|
||||
Error::<T>::OpenHrmpChannelCapacityExceedsLimit,
|
||||
);
|
||||
ensure!(
|
||||
proposed_max_message_size > 0,
|
||||
Error::<T>::OpenHrmpChannelZeroMessageSize,
|
||||
);
|
||||
ensure!(proposed_max_message_size > 0, Error::<T>::OpenHrmpChannelZeroMessageSize,);
|
||||
ensure!(
|
||||
proposed_max_message_size <= config.hrmp_channel_max_message_size,
|
||||
Error::<T>::OpenHrmpChannelMessageSizeExceedsLimit,
|
||||
);
|
||||
|
||||
let channel_id = HrmpChannelId {
|
||||
sender: origin,
|
||||
recipient,
|
||||
};
|
||||
let channel_id = HrmpChannelId { sender: origin, recipient };
|
||||
ensure!(
|
||||
<Self as Store>::HrmpOpenChannelRequests::get(&channel_id).is_none(),
|
||||
Error::<T>::OpenHrmpChannelAlreadyExists,
|
||||
@@ -1115,8 +1006,8 @@ impl<T: Config> Pallet<T> {
|
||||
<Self as Store>::HrmpOpenChannelRequestsList::append(channel_id);
|
||||
|
||||
let notification_bytes = {
|
||||
use xcm::opaque::{v0::Xcm, VersionedXcm};
|
||||
use parity_scale_codec::Encode as _;
|
||||
use xcm::opaque::{v0::Xcm, VersionedXcm};
|
||||
|
||||
VersionedXcm::from(Xcm::HrmpNewChannelOpenRequest {
|
||||
sender: u32::from(origin),
|
||||
@@ -1141,16 +1032,10 @@ impl<T: Config> Pallet<T> {
|
||||
/// Basically the same as [`hrmp_accept_open_channel`](Pallet::hrmp_accept_open_channel) but
|
||||
/// intendend for calling directly from other pallets rather than dispatched.
|
||||
pub fn accept_open_channel(origin: ParaId, sender: ParaId) -> DispatchResult {
|
||||
let channel_id = HrmpChannelId {
|
||||
sender,
|
||||
recipient: origin,
|
||||
};
|
||||
let channel_id = HrmpChannelId { sender, recipient: origin };
|
||||
let mut channel_req = <Self as Store>::HrmpOpenChannelRequests::get(&channel_id)
|
||||
.ok_or(Error::<T>::AcceptHrmpChannelDoesntExist)?;
|
||||
ensure!(
|
||||
!channel_req.confirmed,
|
||||
Error::<T>::AcceptHrmpChannelAlreadyConfirmed,
|
||||
);
|
||||
ensure!(!channel_req.confirmed, Error::<T>::AcceptHrmpChannelAlreadyConfirmed,);
|
||||
|
||||
// check if by accepting this open channel request, this parachain would exceed the
|
||||
// number of inbound channels.
|
||||
@@ -1183,10 +1068,7 @@ impl<T: Config> Pallet<T> {
|
||||
use parity_scale_codec::Encode as _;
|
||||
use xcm::opaque::{v0::Xcm, VersionedXcm};
|
||||
|
||||
VersionedXcm::from(Xcm::HrmpChannelAccepted {
|
||||
recipient: u32::from(origin),
|
||||
})
|
||||
.encode()
|
||||
VersionedXcm::from(Xcm::HrmpChannelAccepted { recipient: u32::from(origin) }).encode()
|
||||
};
|
||||
if let Err(dmp::QueueDownwardMessageError::ExceedsMaxMessageSize) =
|
||||
<dmp::Pallet<T>>::queue_downward_message(&config, sender, notification_bytes)
|
||||
@@ -1233,11 +1115,8 @@ impl<T: Config> Pallet<T> {
|
||||
})
|
||||
.encode()
|
||||
};
|
||||
let opposite_party = if origin == channel_id.sender {
|
||||
channel_id.recipient
|
||||
} else {
|
||||
channel_id.sender
|
||||
};
|
||||
let opposite_party =
|
||||
if origin == channel_id.sender { channel_id.recipient } else { channel_id.sender };
|
||||
if let Err(dmp::QueueDownwardMessageError::ExceedsMaxMessageSize) =
|
||||
<dmp::Pallet<T>>::queue_downward_message(&config, opposite_party, notification_bytes)
|
||||
{
|
||||
@@ -1292,15 +1171,14 @@ impl<T: Config> Pallet<T> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::mock::{
|
||||
new_test_ext, Test, Configuration, Paras, ParasShared, Hrmp, System, MockGenesisConfig,
|
||||
Event as MockEvent,
|
||||
new_test_ext, Configuration, Event as MockEvent, Hrmp, MockGenesisConfig, Paras,
|
||||
ParasShared, System, Test,
|
||||
};
|
||||
use frame_support::{assert_noop, assert_ok, traits::Currency as _};
|
||||
use primitives::v1::BlockNumber;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
fn run_to_block(to: BlockNumber, new_session: Option<Vec<BlockNumber>>) {
|
||||
|
||||
let config = Configuration::config();
|
||||
while System::block_number() < to {
|
||||
let b = System::block_number();
|
||||
@@ -1500,9 +1378,7 @@ mod tests {
|
||||
// An entry in `HrmpChannels` indicates that the channel is open. Only open channels can
|
||||
// have contents.
|
||||
for (non_empty_channel, contents) in <Hrmp as Store>::HrmpChannelContents::iter() {
|
||||
assert!(<Hrmp as Store>::HrmpChannels::contains_key(
|
||||
&non_empty_channel
|
||||
));
|
||||
assert!(<Hrmp as Store>::HrmpChannels::contains_key(&non_empty_channel));
|
||||
|
||||
// pedantic check: there should be no empty vectors in storage, those should be modeled
|
||||
// by a removed kv pair.
|
||||
@@ -1544,10 +1420,7 @@ mod tests {
|
||||
let channel_set_ground_truth = <Hrmp as Store>::HrmpChannels::iter()
|
||||
.map(|(k, _)| (k.sender, k.recipient))
|
||||
.collect::<HashSet<_>>();
|
||||
assert_eq!(
|
||||
channel_set_derived_from_ingress,
|
||||
channel_set_derived_from_egress
|
||||
);
|
||||
assert_eq!(channel_set_derived_from_ingress, channel_set_derived_from_egress);
|
||||
assert_eq!(channel_set_derived_from_egress, channel_set_ground_truth);
|
||||
|
||||
<Hrmp as Store>::HrmpIngressChannelsIndex::iter()
|
||||
@@ -1583,22 +1456,13 @@ mod tests {
|
||||
|
||||
fn assert_contains_only_onboarded(iter: impl Iterator<Item = ParaId>, cause: &str) {
|
||||
for para in iter {
|
||||
assert!(
|
||||
Paras::is_valid_para(para),
|
||||
"{}: {} para is offboarded",
|
||||
cause,
|
||||
para
|
||||
);
|
||||
assert!(Paras::is_valid_para(para), "{}: {} para is offboarded", cause, para);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_is_sorted<T: Ord>(slice: &[T], id: &str) {
|
||||
assert!(
|
||||
slice.windows(2).all(|xs| xs[0] <= xs[1]),
|
||||
"{} supposed to be sorted",
|
||||
id
|
||||
);
|
||||
assert!(slice.windows(2).all(|xs| xs[0] <= xs[1]), "{} supposed to be sorted", id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1623,15 +1487,13 @@ mod tests {
|
||||
run_to_block(5, Some(vec![4, 5]));
|
||||
Hrmp::hrmp_init_open_channel(para_a_origin.into(), para_b, 2, 8).unwrap();
|
||||
assert_storage_consistency_exhaustive();
|
||||
assert!(System::events().iter().any(|record|
|
||||
record.event == MockEvent::Hrmp(Event::OpenChannelRequested(para_a, para_b, 2, 8))
|
||||
));
|
||||
assert!(System::events().iter().any(|record| record.event ==
|
||||
MockEvent::Hrmp(Event::OpenChannelRequested(para_a, para_b, 2, 8))));
|
||||
|
||||
Hrmp::hrmp_accept_open_channel(para_b_origin.into(), para_a).unwrap();
|
||||
assert_storage_consistency_exhaustive();
|
||||
assert!(System::events().iter().any(|record|
|
||||
record.event == MockEvent::Hrmp(Event::OpenChannelAccepted(para_a, para_b))
|
||||
));
|
||||
assert!(System::events().iter().any(|record| record.event ==
|
||||
MockEvent::Hrmp(Event::OpenChannelAccepted(para_a, para_b))));
|
||||
|
||||
// Advance to a block 6, but without session change. That means that the channel has
|
||||
// not been created yet.
|
||||
@@ -1664,10 +1526,7 @@ mod tests {
|
||||
|
||||
// Close the channel. The effect is not immediate, but rather deferred to the next
|
||||
// session change.
|
||||
let channel_id = HrmpChannelId {
|
||||
sender: para_a,
|
||||
recipient: para_b,
|
||||
};
|
||||
let channel_id = HrmpChannelId { sender: para_a, recipient: para_b };
|
||||
Hrmp::hrmp_close_channel(para_b_origin.into(), channel_id.clone()).unwrap();
|
||||
assert!(channel_exists(para_a, para_b));
|
||||
assert_storage_consistency_exhaustive();
|
||||
@@ -1676,9 +1535,8 @@ mod tests {
|
||||
run_to_block(8, Some(vec![8]));
|
||||
assert!(!channel_exists(para_a, para_b));
|
||||
assert_storage_consistency_exhaustive();
|
||||
assert!(System::events().iter().any(|record|
|
||||
record.event == MockEvent::Hrmp(Event::ChannelClosed(para_b, channel_id.clone()))
|
||||
));
|
||||
assert!(System::events().iter().any(|record| record.event ==
|
||||
MockEvent::Hrmp(Event::ChannelClosed(para_b, channel_id.clone()))));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1732,27 +1590,31 @@ mod tests {
|
||||
register_parachain(para_a);
|
||||
register_parachain(para_b);
|
||||
|
||||
run_to_block(2, Some(vec![1,2]));
|
||||
run_to_block(2, Some(vec![1, 2]));
|
||||
Hrmp::init_open_channel(para_a, para_b, 2, 20).unwrap();
|
||||
Hrmp::accept_open_channel(para_b, para_a).unwrap();
|
||||
|
||||
run_to_block(3, Some(vec![3]));
|
||||
let _ = Hrmp::queue_outbound_hrmp(para_a, vec![OutboundHrmpMessage {
|
||||
recipient: para_b,
|
||||
data: vec![1, 2, 3],
|
||||
}]);
|
||||
let _ = Hrmp::queue_outbound_hrmp(
|
||||
para_a,
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: vec![1, 2, 3] }],
|
||||
);
|
||||
|
||||
run_to_block(4, None);
|
||||
let _ = Hrmp::queue_outbound_hrmp(para_a, vec![OutboundHrmpMessage {
|
||||
recipient: para_b,
|
||||
data: vec![4, 5, 6],
|
||||
}]);
|
||||
let _ = Hrmp::queue_outbound_hrmp(
|
||||
para_a,
|
||||
vec![OutboundHrmpMessage { recipient: para_b, data: vec![4, 5, 6] }],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Hrmp::hrmp_mqc_heads(para_b),
|
||||
vec![
|
||||
(para_a, hex_literal::hex!["a964fd3b4f3d3ce92a0e25e576b87590d92bb5cb7031909c7f29050e1f04a375"].into()),
|
||||
],
|
||||
vec![(
|
||||
para_a,
|
||||
hex_literal::hex![
|
||||
"a964fd3b4f3d3ce92a0e25e576b87590d92bb5cb7031909c7f29050e1f04a375"
|
||||
]
|
||||
.into()
|
||||
),],
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -1803,10 +1665,7 @@ mod tests {
|
||||
run_to_block(6, Some(vec![6]));
|
||||
assert!(Paras::is_valid_para(para_a));
|
||||
|
||||
let msgs = vec![OutboundHrmpMessage {
|
||||
recipient: para_b,
|
||||
data: b"knock".to_vec(),
|
||||
}];
|
||||
let msgs = vec![OutboundHrmpMessage { recipient: para_b, data: b"knock".to_vec() }];
|
||||
let config = Configuration::config();
|
||||
assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok());
|
||||
let _ = Hrmp::queue_outbound_hrmp(para_a, msgs.clone());
|
||||
@@ -1817,13 +1676,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
contents,
|
||||
vec![
|
||||
(
|
||||
para_a,
|
||||
vec![InboundHrmpMessage {
|
||||
sent_at: 6,
|
||||
data: b"knock".to_vec(),
|
||||
}]
|
||||
),
|
||||
(para_a, vec![InboundHrmpMessage { sent_at: 6, data: b"knock".to_vec() }]),
|
||||
(para_c, vec![])
|
||||
]
|
||||
.into_iter()
|
||||
@@ -1891,29 +1744,19 @@ mod tests {
|
||||
);
|
||||
|
||||
let raw_ingress_index =
|
||||
sp_io::storage::get(
|
||||
&well_known_keys::hrmp_ingress_channel_index(para_b),
|
||||
)
|
||||
.expect("the ingress index must be present for para_b");
|
||||
sp_io::storage::get(&well_known_keys::hrmp_ingress_channel_index(para_b))
|
||||
.expect("the ingress index must be present for para_b");
|
||||
let ingress_index = <Vec<ParaId>>::decode(&mut &raw_ingress_index[..])
|
||||
.expect("ingress indexx should be decodable as a list of para ids");
|
||||
assert_eq!(
|
||||
ingress_index,
|
||||
vec![para_a],
|
||||
);
|
||||
assert_eq!(ingress_index, vec![para_a],);
|
||||
|
||||
// Now, verify that we can access and decode the egress index.
|
||||
let raw_egress_index =
|
||||
sp_io::storage::get(
|
||||
&well_known_keys::hrmp_egress_channel_index(para_a)
|
||||
)
|
||||
.expect("the egress index must be present for para_a");
|
||||
sp_io::storage::get(&well_known_keys::hrmp_egress_channel_index(para_a))
|
||||
.expect("the egress index must be present for para_a");
|
||||
let egress_index = <Vec<ParaId>>::decode(&mut &raw_egress_index[..])
|
||||
.expect("egress index should be decodable as a list of para ids");
|
||||
assert_eq!(
|
||||
egress_index,
|
||||
vec![para_b],
|
||||
);
|
||||
assert_eq!(egress_index, vec![para_b],);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1962,34 +1805,16 @@ mod tests {
|
||||
run_to_block(5, Some(vec![4, 5]));
|
||||
Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap();
|
||||
Hrmp::accept_open_channel(para_b, para_a).unwrap();
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_a.into_account()),
|
||||
80
|
||||
);
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_b.into_account()),
|
||||
95
|
||||
);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_a.into_account()), 80);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_b.into_account()), 95);
|
||||
run_to_block(8, Some(vec![8]));
|
||||
|
||||
// Now, we close the channel and wait until the next session.
|
||||
Hrmp::close_channel(
|
||||
para_b,
|
||||
HrmpChannelId {
|
||||
sender: para_a,
|
||||
recipient: para_b,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
Hrmp::close_channel(para_b, HrmpChannelId { sender: para_a, recipient: para_b })
|
||||
.unwrap();
|
||||
run_to_block(10, Some(vec![10]));
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_a.into_account()),
|
||||
100
|
||||
);
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_b.into_account()),
|
||||
110
|
||||
);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_a.into_account()), 100);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_b.into_account()), 110);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2009,28 +1834,16 @@ mod tests {
|
||||
register_parachain_with_balance(para_b, 110);
|
||||
run_to_block(5, Some(vec![4, 5]));
|
||||
Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap();
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_a.into_account()),
|
||||
80
|
||||
);
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_b.into_account()),
|
||||
110
|
||||
);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_a.into_account()), 80);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_b.into_account()), 110);
|
||||
|
||||
// Request age is 1 out of 2
|
||||
run_to_block(10, Some(vec![10]));
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_a.into_account()),
|
||||
80
|
||||
);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_a.into_account()), 80);
|
||||
|
||||
// Request age is 2 out of 2. The request should expire.
|
||||
run_to_block(20, Some(vec![20]));
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_a.into_account()),
|
||||
100
|
||||
);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_a.into_account()), 100);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2049,14 +1862,8 @@ mod tests {
|
||||
run_to_block(5, Some(vec![4, 5]));
|
||||
Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap();
|
||||
Hrmp::accept_open_channel(para_b, para_a).unwrap();
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_a.into_account()),
|
||||
80
|
||||
);
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_b.into_account()),
|
||||
95
|
||||
);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_a.into_account()), 80);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_b.into_account()), 95);
|
||||
run_to_block(8, Some(vec![8]));
|
||||
assert!(channel_exists(para_a, para_b));
|
||||
|
||||
@@ -2069,14 +1876,8 @@ mod tests {
|
||||
assert!(!channel_exists(para_a, para_b));
|
||||
assert_storage_consistency_exhaustive();
|
||||
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_a.into_account()),
|
||||
100
|
||||
);
|
||||
assert_eq!(
|
||||
<Test as Config>::Currency::free_balance(¶_b.into_account()),
|
||||
110
|
||||
);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_a.into_account()), 100);
|
||||
assert_eq!(<Test as Config>::Currency::free_balance(¶_b.into_account()), 110);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user