mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 22:11:02 +00:00
Pre-dispatch call filter (#687)
* pre-dispatch call filter * swap filter <-> weight * clippy * fmt
This commit is contained in:
committed by
Bastian Köcher
parent
a9e607c9a2
commit
8ee90afae6
@@ -215,6 +215,7 @@ impl pallet_bridge_call_dispatch::Config for Runtime {
|
|||||||
type Event = Event;
|
type Event = Event;
|
||||||
type MessageId = (bp_message_lane::LaneId, bp_message_lane::MessageNonce);
|
type MessageId = (bp_message_lane::LaneId, bp_message_lane::MessageNonce);
|
||||||
type Call = Call;
|
type Call = Call;
|
||||||
|
type CallFilter = ();
|
||||||
type EncodedCall = crate::rialto_messages::FromRialtoEncodedCall;
|
type EncodedCall = crate::rialto_messages::FromRialtoEncodedCall;
|
||||||
type SourceChainAccountId = bp_rialto::AccountId;
|
type SourceChainAccountId = bp_rialto::AccountId;
|
||||||
type TargetChainAccountPublic = MultiSigner;
|
type TargetChainAccountPublic = MultiSigner;
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ impl pallet_bridge_call_dispatch::Config for Runtime {
|
|||||||
type Event = Event;
|
type Event = Event;
|
||||||
type MessageId = (bp_message_lane::LaneId, bp_message_lane::MessageNonce);
|
type MessageId = (bp_message_lane::LaneId, bp_message_lane::MessageNonce);
|
||||||
type Call = Call;
|
type Call = Call;
|
||||||
|
type CallFilter = ();
|
||||||
type EncodedCall = crate::millau_messages::FromMillauEncodedCall;
|
type EncodedCall = crate::millau_messages::FromMillauEncodedCall;
|
||||||
type SourceChainAccountId = bp_millau::AccountId;
|
type SourceChainAccountId = bp_millau::AccountId;
|
||||||
type TargetChainAccountPublic = MultiSigner;
|
type TargetChainAccountPublic = MultiSigner;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ use frame_support::{
|
|||||||
decl_event, decl_module, decl_storage,
|
decl_event, decl_module, decl_storage,
|
||||||
dispatch::{Dispatchable, Parameter},
|
dispatch::{Dispatchable, Parameter},
|
||||||
ensure,
|
ensure,
|
||||||
traits::Get,
|
traits::{Filter, Get},
|
||||||
weights::{extract_actual_weight, GetDispatchInfo},
|
weights::{extract_actual_weight, GetDispatchInfo},
|
||||||
RuntimeDebug,
|
RuntimeDebug,
|
||||||
};
|
};
|
||||||
@@ -134,6 +134,11 @@ pub trait Config<I = DefaultInstance>: frame_system::Config {
|
|||||||
Origin = <Self as frame_system::Config>::Origin,
|
Origin = <Self as frame_system::Config>::Origin,
|
||||||
PostInfo = frame_support::dispatch::PostDispatchInfo,
|
PostInfo = frame_support::dispatch::PostDispatchInfo,
|
||||||
>;
|
>;
|
||||||
|
/// Pre-dispatch filter for incoming calls.
|
||||||
|
///
|
||||||
|
/// The pallet will filter all incoming calls right before they're dispatched. If this filter
|
||||||
|
/// rejects the call, special event (`Event::MessageCallRejected`) is emitted.
|
||||||
|
type CallFilter: Filter<<Self as Config<I>>::Call>;
|
||||||
/// The type that is used to wrap the `Self::Call` when it is moved over bridge.
|
/// The type that is used to wrap the `Self::Call` when it is moved over bridge.
|
||||||
///
|
///
|
||||||
/// The idea behind this is to avoid `Call` conversion/decoding until we'll be sure
|
/// The idea behind this is to avoid `Call` conversion/decoding until we'll be sure
|
||||||
@@ -172,6 +177,8 @@ decl_event!(
|
|||||||
MessageDispatched(InstanceId, MessageId, DispatchResult),
|
MessageDispatched(InstanceId, MessageId, DispatchResult),
|
||||||
/// We have failed to decode Call from the message.
|
/// We have failed to decode Call from the message.
|
||||||
MessageCallDecodeFailed(InstanceId, MessageId),
|
MessageCallDecodeFailed(InstanceId, MessageId),
|
||||||
|
/// The call from the message has been rejected by the call filter.
|
||||||
|
MessageCallRejected(InstanceId, MessageId),
|
||||||
/// Phantom member, never used. Needed to handle multiple pallet instances.
|
/// Phantom member, never used. Needed to handle multiple pallet instances.
|
||||||
_Dummy(PhantomData<I>),
|
_Dummy(PhantomData<I>),
|
||||||
}
|
}
|
||||||
@@ -269,6 +276,18 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::MessageId> for Module<T, I> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// filter the call
|
||||||
|
if !T::CallFilter::filter(&call) {
|
||||||
|
frame_support::debug::trace!(
|
||||||
|
"Message {:?}/{:?}: the call ({:?}) is rejected by filter",
|
||||||
|
bridge,
|
||||||
|
id,
|
||||||
|
call,
|
||||||
|
);
|
||||||
|
Self::deposit_event(RawEvent::MessageCallRejected(bridge, id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// verify weight
|
// verify weight
|
||||||
// (we want passed weight to be at least equal to pre-dispatch weight of the call
|
// (we want passed weight to be at least equal to pre-dispatch weight of the call
|
||||||
// because otherwise Calls may be dispatched at lower price)
|
// because otherwise Calls may be dispatched at lower price)
|
||||||
@@ -488,6 +507,7 @@ mod tests {
|
|||||||
type TargetChainAccountPublic = TestAccountPublic;
|
type TargetChainAccountPublic = TestAccountPublic;
|
||||||
type TargetChainSignature = TestSignature;
|
type TargetChainSignature = TestSignature;
|
||||||
type Call = Call;
|
type Call = Call;
|
||||||
|
type CallFilter = TestCallFilter;
|
||||||
type EncodedCall = EncodedCall;
|
type EncodedCall = EncodedCall;
|
||||||
type AccountIdConverter = AccountIdConverter;
|
type AccountIdConverter = AccountIdConverter;
|
||||||
}
|
}
|
||||||
@@ -501,6 +521,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct TestCallFilter;
|
||||||
|
|
||||||
|
impl Filter<Call> for TestCallFilter {
|
||||||
|
fn filter(call: &Call) -> bool {
|
||||||
|
!matches!(*call, Call::System(frame_system::Call::fill_block(_)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const TEST_SPEC_VERSION: SpecVersion = 0;
|
const TEST_SPEC_VERSION: SpecVersion = 0;
|
||||||
const TEST_WEIGHT: Weight = 1_000_000_000;
|
const TEST_WEIGHT: Weight = 1_000_000_000;
|
||||||
|
|
||||||
@@ -668,6 +696,31 @@ mod tests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_emit_event_for_rejected_calls() {
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
let bridge = b"ethb".to_owned();
|
||||||
|
let id = [0; 4];
|
||||||
|
|
||||||
|
let call = Call::System(<frame_system::Call<TestRuntime>>::fill_block(Perbill::from_percent(75)));
|
||||||
|
let weight = call.get_dispatch_info().weight;
|
||||||
|
let mut message = prepare_root_message(call);
|
||||||
|
message.weight = weight;
|
||||||
|
|
||||||
|
System::set_block_number(1);
|
||||||
|
CallDispatch::dispatch(bridge, id, Ok(message));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
System::events(),
|
||||||
|
vec![EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::call_dispatch(Event::<TestRuntime>::MessageCallRejected(bridge, id)),
|
||||||
|
topics: vec![],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_dispatch_bridge_message_from_root_origin() {
|
fn should_dispatch_bridge_message_from_root_origin() {
|
||||||
new_test_ext().execute_with(|| {
|
new_test_ext().execute_with(|| {
|
||||||
|
|||||||
Reference in New Issue
Block a user