Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Commit 3213a4d

Browse files
hackfisherboundless-forest
authored andcommitted
cherry pick #137 (#140)
* cherry pick #137 * pick #141 Co-authored-by: bear <[email protected]>
1 parent 8b13160 commit 3213a4d

8 files changed

Lines changed: 97 additions & 18 deletions

File tree

bin/runtime-common/src/messages.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ pub mod target {
523523
///
524524
/// Our Call is opaque (`Vec<u8>`) for Bridged chain. So it is encoded, prefixed with
525525
/// vector length. Custom decode implementation here is exactly to deal with this.
526-
#[derive(Decode, Encode, RuntimeDebug, PartialEq)]
526+
#[derive(Decode, Encode, Clone, RuntimeDebug, PartialEq)]
527527
pub struct FromBridgedChainEncodedMessageCall<DecodedCall> {
528528
encoded_call: Vec<u8>,
529529
_marker: PhantomData<DecodedCall>,
@@ -573,6 +573,16 @@ pub mod target {
573573
message.data.payload.as_ref().map(|payload| payload.weight).unwrap_or(0)
574574
}
575575

576+
fn pre_dispatch(
577+
relayer_account: &AccountIdOf<ThisChain<B>>,
578+
message: &DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,
579+
) -> Result<(), &'static str> {
580+
pallet_bridge_dispatch::Pallet::<ThisRuntime, ThisDispatchInstance>::pre_dispatch(
581+
relayer_account,
582+
message.data.payload.as_ref().map_err(drop),
583+
)
584+
}
585+
576586
fn dispatch(
577587
relayer_account: &AccountIdOf<ThisChain<B>>,
578588
message: DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,

modules/dispatch/src/lib.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ pub mod pallet {
9292
/// that all other stuff (like `spec_version`) is ok. If we would try to decode
9393
/// `Call` which has been encoded using previous `spec_version`, then we might end
9494
/// up with decoding error, instead of `MessageVersionSpecMismatch`.
95-
type EncodedCall: Decode + Encode + Into<Result<<Self as Config<I>>::Call, ()>>;
95+
type EncodedCall: Decode + Encode + Into<Result<<Self as Config<I>>::Call, ()>> + Clone;
9696
/// A type which can be turned into an AccountId from a 256-bit hash.
9797
///
9898
/// Used when deriving target chain AccountIds from source chain AccountIds.
@@ -160,6 +160,16 @@ impl<T: Config<I>, I: 'static> MessageDispatch<T::AccountId, T::BridgeMessageId>
160160
message.weight
161161
}
162162

163+
fn pre_dispatch(
164+
relayer_account: &T::AccountId,
165+
message: Result<&Self::Message, ()>,
166+
) -> Result<(), &'static str> {
167+
let raw_message = message.map_err(|_| "Invalid Message")?;
168+
let call = raw_message.clone().call.into().map_err(|_| "Invalid Call")?;
169+
170+
T::CallValidator::check_receiving_before_dispatch(relayer_account, &call)
171+
}
172+
163173
fn dispatch<P: FnOnce(&T::AccountId, bp_message_dispatch::Weight) -> Result<(), ()>>(
164174
source_chain: ChainId,
165175
target_chain: ChainId,
@@ -275,8 +285,8 @@ impl<T: Config<I>, I: 'static> MessageDispatch<T::AccountId, T::BridgeMessageId>
275285
let dispatch_origin =
276286
T::IntoDispatchOrigin::into_dispatch_origin(&origin_derived_account, &call);
277287

278-
// filter the call
279-
if let Err(_) = T::CallValidator::pre_dispatch(relayer_account, &dispatch_origin, &call) {
288+
// validate the call
289+
if let Err(_e) = T::CallValidator::call_validate(relayer_account, &dispatch_origin, &call) {
280290
log::trace!(
281291
target: "runtime::bridge-dispatch",
282292
"Message {:?}/{:?}: the call ({:?}) is rejected by filter",
@@ -560,7 +570,7 @@ mod tests {
560570
type TargetChainSignature = TestSignature;
561571
}
562572

563-
#[derive(Decode, Encode)]
573+
#[derive(Decode, Encode, Clone)]
564574
pub struct EncodedCall(Vec<u8>);
565575

566576
impl From<EncodedCall> for Result<Call, ()> {
@@ -571,7 +581,14 @@ mod tests {
571581

572582
pub struct CallValidator;
573583
impl CallValidate<AccountId, Origin, Call> for CallValidator {
574-
fn pre_dispatch(
584+
fn check_receiving_before_dispatch(
585+
_relayer_account: &AccountId,
586+
_call: &Call,
587+
) -> Result<(), &'static str> {
588+
Ok(())
589+
}
590+
591+
fn call_validate(
575592
_relayer_account: &AccountId,
576593
_origin: &Origin,
577594
call: &Call,

modules/fee-market/src/tests.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,13 @@ impl MessageDispatch<AccountId, TestMessageFee> for TestMessageDispatch {
344344
}
345345
}
346346

347+
fn pre_dispatch(
348+
_relayer_account: &AccountId,
349+
_message: &DispatchMessage<TestPayload, TestMessageFee>,
350+
) -> Result<(), &'static str> {
351+
Ok(())
352+
}
353+
347354
fn dispatch(
348355
_relayer_account: &AccountId,
349356
message: DispatchMessage<TestPayload, TestMessageFee>,

modules/messages/src/inbound_lane.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ pub enum ReceivalResult {
5858
TooManyUnrewardedRelayers,
5959
/// There are too many unconfirmed messages at the lane.
6060
TooManyUnconfirmedMessages,
61+
/// Pre-dispatch validation failed before message dispatch.
62+
PreDispatchValidateFailed,
6163
}
6264

6365
/// Inbound messages lane.
@@ -141,14 +143,17 @@ impl<S: InboundLaneStorage> InboundLane<S> {
141143
return ReceivalResult::TooManyUnconfirmedMessages;
142144
}
143145

146+
let dispatch_message = DispatchMessage {
147+
key: MessageKey { lane_id: self.storage.id(), nonce },
148+
data: message_data,
149+
};
150+
// if there are some extra pre-dispatch validation errors, reject this message.
151+
if P::pre_dispatch(relayer_at_this_chain, &dispatch_message).is_err() {
152+
return ReceivalResult::PreDispatchValidateFailed
153+
}
154+
144155
// then, dispatch message
145-
let dispatch_result = P::dispatch(
146-
relayer_at_this_chain,
147-
DispatchMessage {
148-
key: MessageKey { lane_id: self.storage.id(), nonce },
149-
data: message_data,
150-
},
151-
);
156+
let dispatch_result = P::dispatch(relayer_at_this_chain, dispatch_message);
152157

153158
// now let's update inbound lane storage
154159
let push_new = match data.relayers.back_mut() {

modules/messages/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,10 @@ pub mod pallet {
466466
!dispatch_result.dispatch_fee_paid_during_dispatch,
467467
)
468468
},
469-
ReceivalResult::InvalidNonce
470-
| ReceivalResult::TooManyUnrewardedRelayers
471-
| ReceivalResult::TooManyUnconfirmedMessages => (dispatch_weight, true),
469+
ReceivalResult::InvalidNonce |
470+
ReceivalResult::TooManyUnrewardedRelayers |
471+
ReceivalResult::PreDispatchValidateFailed |
472+
ReceivalResult::TooManyUnconfirmedMessages => (dispatch_weight, true),
472473
};
473474

474475
let unspent_weight = sp_std::cmp::min(unspent_weight, dispatch_weight);

modules/messages/src/mock.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,13 @@ impl MessageDispatch<AccountId, TestMessageFee> for TestMessageDispatch {
489489
}
490490
}
491491

492+
fn pre_dispatch(
493+
_relayer_account: &AccountId,
494+
_message: &DispatchMessage<TestPayload, TestMessageFee>,
495+
) -> Result<(), &'static str> {
496+
Ok(())
497+
}
498+
492499
fn dispatch(
493500
_relayer_account: &AccountId,
494501
message: DispatchMessage<TestPayload, TestMessageFee>,

primitives/message-dispatch/src/lib.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ pub trait MessageDispatch<AccountId, BridgeMessageId> {
4646
/// of dispatch weight.
4747
fn dispatch_weight(message: &Self::Message) -> Weight;
4848

49+
/// Checking in message receiving step before dispatch
50+
///
51+
/// This will be called before the call enter dispatch phase. If failed, the message(call) will
52+
/// be not be processed by this relayer, latter relayers can still continue process it.
53+
fn pre_dispatch(
54+
relayer_account: &AccountId,
55+
message: Result<&Self::Message, ()>,
56+
) -> Result<(), &'static str>;
57+
4958
/// Dispatches the message internally.
5059
///
5160
/// `source_chain` indicates the chain where the message came from.
@@ -154,8 +163,15 @@ pub trait IntoDispatchOrigin<AccountId, Call, Origin> {
154163

155164
/// A generic trait to validate message before dispatch.
156165
pub trait CallValidate<AccountId, Origin, Call> {
157-
/// call validation
158-
fn pre_dispatch(
166+
/// Checking in message receiving step before dispatch
167+
///
168+
/// This will be called before the call enter dispatch phase. If failed, the message(call) will
169+
/// be not be processed by this relayer, latter relayers can still continue process it.
170+
fn check_receiving_before_dispatch(relayer_account: &AccountId, call: &Call) -> Result<(), &'static str>;
171+
/// In-dispatch call validation
172+
///
173+
/// This will be called in the dispatch process, If failed, return message dispatch errors.
174+
fn call_validate(
159175
relayer_account: &AccountId,
160176
origin: &Origin,
161177
call: &Call,

primitives/messages/src/target_chain.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ pub trait MessageDispatch<AccountId, Fee> {
9797
/// of dispatch weight.
9898
fn dispatch_weight(message: &DispatchMessage<Self::DispatchPayload, Fee>) -> Weight;
9999

100+
/// Checking in message receiving step before dispatch
101+
///
102+
/// This will be called before the call enter dispatch phase. If failed, the message(call) will
103+
/// be not be processed by this relayer, latter relayers can still continue process it.
104+
fn pre_dispatch(
105+
relayer_account: &AccountId,
106+
message: &DispatchMessage<Self::DispatchPayload, Fee>,
107+
) -> Result<(), &'static str>;
108+
100109
/// Called when inbound message is received.
101110
///
102111
/// It is up to the implementers of this trait to determine whether the message
@@ -160,6 +169,13 @@ impl<AccountId, Fee> MessageDispatch<AccountId, Fee> for ForbidInboundMessages {
160169
Weight::MAX
161170
}
162171

172+
fn pre_dispatch(
173+
_: &AccountId,
174+
_message: &DispatchMessage<Self::DispatchPayload, Fee>,
175+
) -> Result<(), &'static str> {
176+
Ok(())
177+
}
178+
163179
fn dispatch(
164180
_: &AccountId,
165181
_: DispatchMessage<Self::DispatchPayload, Fee>,

0 commit comments

Comments
 (0)