Skip to content
Snippets Groups Projects
Unverified Commit ed2781ef authored by Branislav Kontur's avatar Branislav Kontur
Browse files

Added `do_try_state_for_outbound_lanes` which checks unpruned messages

parent d63d620e
No related merge requests found
......@@ -575,6 +575,14 @@ pub mod pallet {
}
}
#[pallet::hooks]
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
#[cfg(feature = "try-runtime")]
fn try_state(_n: BlockNumberFor<T>) -> Result<(), sp_runtime::TryRuntimeError> {
Self::do_try_state()
}
}
impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Get stored data of the outbound message with given nonce.
pub fn outbound_message_data(lane: LaneId, nonce: MessageNonce) -> Option<MessagePayload> {
......@@ -609,6 +617,60 @@ pub mod pallet {
}
}
#[cfg(any(feature = "try-runtime", test))]
impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Ensure the correctness of the state of this pallet.
pub fn do_try_state() -> Result<(), sp_runtime::TryRuntimeError> {
Self::do_try_state_for_outbound_lanes()
}
/// Ensure the correctness of the state of outbound lanes.
pub fn do_try_state_for_outbound_lanes() -> Result<(), sp_runtime::TryRuntimeError> {
use sp_runtime::traits::One;
use sp_std::vec::Vec;
// collect unpruned lanes
let mut unpruned_lanes = Vec::new();
for (lane_id, lane_data) in OutboundLanes::<T, I>::iter() {
let Some(expected_last_prunned_nonce) =
lane_data.oldest_unpruned_nonce.checked_sub(One::one())
else {
continue;
};
// collect message_nonces that were supposed to be pruned
let mut unpruned_message_nonces = Vec::new();
let mut nonce_to_check = expected_last_prunned_nonce;
loop {
if OutboundMessages::<T, I>::contains_key(MessageKey {
lane_id,
nonce: nonce_to_check,
}) {
unpruned_message_nonces.push(nonce_to_check);
}
if let Some(new_nonce_to_check) = nonce_to_check.checked_sub(One::one()) {
nonce_to_check = new_nonce_to_check;
} else {
break;
}
}
if !unpruned_message_nonces.is_empty() {
log::warn!(
target: LOG_TARGET,
"do_try_state_for_outbound_lanes for lane_id: {lane_id:?} with lane_data: {lane_data:?} found unpruned_message_nonces: {unpruned_message_nonces:?}",
);
unpruned_lanes.push((lane_id, lane_data, unpruned_message_nonces));
}
}
// ensure messages before `oldest_unpruned_nonce` are really pruned.
ensure!(unpruned_lanes.is_empty(), "Found unpruned lanes!");
Ok(())
}
}
/// Get-parameter that returns number of active outbound lanes that the pallet maintains.
pub struct MaybeOutboundLanesCount<T, I>(PhantomData<(T, I)>);
......
......@@ -98,6 +98,7 @@ fn receive_messages_delivery_proof() {
last_delivered_nonce: 1,
},
));
assert_ok!(Pallet::<TestRuntime>::do_try_state());
assert_eq!(
System::<TestRuntime>::events(),
......@@ -159,6 +160,7 @@ fn pallet_rejects_transactions_if_halted() {
),
Error::<TestRuntime, ()>::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted),
);
assert_ok!(Pallet::<TestRuntime>::do_try_state());
});
}
......@@ -219,6 +221,7 @@ fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() {
last_delivered_nonce: 1,
},
));
assert_ok!(Pallet::<TestRuntime>::do_try_state());
});
}
......@@ -394,10 +397,14 @@ fn receive_messages_proof_rejects_proof_with_too_many_messages() {
#[test]
fn receive_messages_delivery_proof_works() {
run_test(|| {
assert_eq!(OutboundLanes::<TestRuntime, ()>::get(TEST_LANE_ID).latest_received_nonce, 0);
assert_eq!(OutboundLanes::<TestRuntime, ()>::get(TEST_LANE_ID).oldest_unpruned_nonce, 1);
send_regular_message(TEST_LANE_ID);
receive_messages_delivery_proof();
assert_eq!(OutboundLanes::<TestRuntime, ()>::get(TEST_LANE_ID).latest_received_nonce, 1,);
assert_eq!(OutboundLanes::<TestRuntime, ()>::get(TEST_LANE_ID).latest_received_nonce, 1);
assert_eq!(OutboundLanes::<TestRuntime, ()>::get(TEST_LANE_ID).oldest_unpruned_nonce, 2);
});
}
......@@ -427,6 +434,7 @@ fn receive_messages_delivery_proof_rewards_relayers() {
},
);
assert_ok!(result);
assert_ok!(Pallet::<TestRuntime>::do_try_state());
assert_eq!(
result.unwrap().actual_weight.unwrap(),
TestWeightInfo::receive_messages_delivery_proof_weight(
......@@ -466,6 +474,7 @@ fn receive_messages_delivery_proof_rewards_relayers() {
},
);
assert_ok!(result);
assert_ok!(Pallet::<TestRuntime>::do_try_state());
// even though the pre-dispatch weight was for two messages, the actual weight is
// for single message only
assert_eq!(
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment