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

Commit

Permalink
cherry pick #137 (#140)
Browse files Browse the repository at this point in the history
* cherry pick #137

* pick #141

Co-authored-by: bear <[email protected]>
  • Loading branch information
2 people authored and jiguantong committed Sep 29, 2022
1 parent d2c2f11 commit 9eca261
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 48 deletions.
12 changes: 11 additions & 1 deletion bin/runtime-common/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ pub mod target {
///
/// Our Call is opaque (`Vec<u8>`) for Bridged chain. So it is encoded, prefixed with
/// vector length. Custom decode implementation here is exactly to deal with this.
#[derive(Decode, Encode, RuntimeDebug, PartialEq)]
#[derive(Decode, Encode, Clone, RuntimeDebug, PartialEq)]
pub struct FromBridgedChainEncodedMessageCall<DecodedCall> {
encoded_call: Vec<u8>,
_marker: PhantomData<DecodedCall>,
Expand Down Expand Up @@ -573,6 +573,16 @@ pub mod target {
message.data.payload.as_ref().map(|payload| payload.weight).unwrap_or(0)
}

fn pre_dispatch(
relayer_account: &AccountIdOf<ThisChain<B>>,
message: &DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,
) -> Result<(), &'static str> {
pallet_bridge_dispatch::Pallet::<ThisRuntime, ThisDispatchInstance>::pre_dispatch(
relayer_account,
message.data.payload.as_ref().map_err(drop),
)
}

fn dispatch(
relayer_account: &AccountIdOf<ThisChain<B>>,
message: DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,
Expand Down
27 changes: 22 additions & 5 deletions modules/dispatch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub mod pallet {
/// that all other stuff (like `spec_version`) is ok. If we would try to decode
/// `Call` which has been encoded using previous `spec_version`, then we might end
/// up with decoding error, instead of `MessageVersionSpecMismatch`.
type EncodedCall: Decode + Encode + Into<Result<<Self as Config<I>>::Call, ()>>;
type EncodedCall: Decode + Encode + Into<Result<<Self as Config<I>>::Call, ()>> + Clone;
/// A type which can be turned into an AccountId from a 256-bit hash.
///
/// Used when deriving target chain AccountIds from source chain AccountIds.
Expand Down Expand Up @@ -160,6 +160,16 @@ impl<T: Config<I>, I: 'static> MessageDispatch<T::AccountId, T::BridgeMessageId>
message.weight
}

fn pre_dispatch(
relayer_account: &T::AccountId,
message: Result<&Self::Message, ()>,
) -> Result<(), &'static str> {
let raw_message = message.map_err(|_| "Invalid Message")?;
let call = raw_message.clone().call.into().map_err(|_| "Invalid Call")?;

T::CallValidator::check_receiving_before_dispatch(relayer_account, &call)
}

fn dispatch<P: FnOnce(&T::AccountId, bp_message_dispatch::Weight) -> Result<(), ()>>(
source_chain: ChainId,
target_chain: ChainId,
Expand Down Expand Up @@ -275,8 +285,8 @@ impl<T: Config<I>, I: 'static> MessageDispatch<T::AccountId, T::BridgeMessageId>
let dispatch_origin =
T::IntoDispatchOrigin::into_dispatch_origin(&origin_derived_account, &call);

// filter the call
if let Err(_) = T::CallValidator::pre_dispatch(relayer_account, &dispatch_origin, &call) {
// validate the call
if let Err(_e) = T::CallValidator::call_validate(relayer_account, &dispatch_origin, &call) {
log::trace!(
target: "runtime::bridge-dispatch",
"Message {:?}/{:?}: the call ({:?}) is rejected by filter",
Expand Down Expand Up @@ -560,7 +570,7 @@ mod tests {
type TargetChainSignature = TestSignature;
}

#[derive(Decode, Encode)]
#[derive(Decode, Encode, Clone)]
pub struct EncodedCall(Vec<u8>);

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

pub struct CallValidator;
impl CallValidate<AccountId, Origin, Call> for CallValidator {
fn pre_dispatch(
fn check_receiving_before_dispatch(
_relayer_account: &AccountId,
_call: &Call,
) -> Result<(), &'static str> {
Ok(())
}

fn call_validate(
_relayer_account: &AccountId,
_origin: &Origin,
call: &Call,
Expand Down
7 changes: 7 additions & 0 deletions modules/fee-market/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,13 @@ impl MessageDispatch<AccountId, TestMessageFee> for TestMessageDispatch {
}
}

fn pre_dispatch(
_relayer_account: &AccountId,
_message: &DispatchMessage<TestPayload, TestMessageFee>,
) -> Result<(), &'static str> {
Ok(())
}

fn dispatch(
_relayer_account: &AccountId,
message: DispatchMessage<TestPayload, TestMessageFee>,
Expand Down
2 changes: 1 addition & 1 deletion modules/messages/src/inbound_lane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl<S: InboundLaneStorage> InboundLane<S> {
};
// if there are some extra pre-dispatch validation errors, reject this message.
if P::pre_dispatch(relayer_at_this_chain, &dispatch_message).is_err() {
return ReceivalResult::PreDispatchValidateFailed;
return ReceivalResult::PreDispatchValidateFailed
}

// then, dispatch message
Expand Down
43 changes: 4 additions & 39 deletions modules/messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,10 @@ pub mod pallet {
!dispatch_result.dispatch_fee_paid_during_dispatch,
)
},
ReceivalResult::InvalidNonce
| ReceivalResult::TooManyUnrewardedRelayers
| ReceivalResult::PreDispatchValidateFailed
| ReceivalResult::TooManyUnconfirmedMessages => (dispatch_weight, true),
ReceivalResult::InvalidNonce |
ReceivalResult::TooManyUnrewardedRelayers |
ReceivalResult::PreDispatchValidateFailed |
ReceivalResult::TooManyUnconfirmedMessages => (dispatch_weight, true),
};

let unspent_weight = sp_std::cmp::min(unspent_weight, dispatch_weight);
Expand Down Expand Up @@ -761,41 +761,6 @@ pub mod pallet {
) -> Option<MessageData<T::OutboundMessageFee>> {
OutboundMessages::<T, I>::get(MessageKey { lane_id: lane, nonce })
}

/// Get nonce of the latest generated message at given outbound lane.
pub fn outbound_latest_generated_nonce(lane: LaneId) -> MessageNonce {
OutboundLanes::<T, I>::get(&lane).latest_generated_nonce
}

/// Get nonce of the latest confirmed message at given outbound lane.
pub fn outbound_latest_received_nonce(lane: LaneId) -> MessageNonce {
OutboundLanes::<T, I>::get(&lane).latest_received_nonce
}

/// Get nonce of the latest received message at given inbound lane.
pub fn inbound_latest_received_nonce(lane: LaneId) -> MessageNonce {
InboundLanes::<T, I>::get(&lane).last_delivered_nonce()
}

/// Get nonce of the latest confirmed message at given inbound lane.
pub fn inbound_latest_confirmed_nonce(lane: LaneId) -> MessageNonce {
InboundLanes::<T, I>::get(&lane).last_confirmed_nonce
}

/// Get state of unrewarded relayers set.
pub fn inbound_unrewarded_relayers_state(
lane: bp_messages::LaneId,
) -> bp_messages::UnrewardedRelayersState {
let relayers = InboundLanes::<T, I>::get(&lane).relayers;
bp_messages::UnrewardedRelayersState {
unrewarded_relayer_entries: relayers.len() as _,
messages_in_oldest_entry: relayers
.front()
.map(|entry| 1 + entry.messages.end - entry.messages.begin)
.unwrap_or(0),
total_messages: total_unrewarded_messages(&relayers).unwrap_or(MessageNonce::MAX),
}
}
}
}

Expand Down
20 changes: 18 additions & 2 deletions primitives/message-dispatch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ pub trait MessageDispatch<AccountId, BridgeMessageId> {
/// of dispatch weight.
fn dispatch_weight(message: &Self::Message) -> Weight;

/// Checking in message receiving step before dispatch
///
/// This will be called before the call enter dispatch phase. If failed, the message(call) will
/// be not be processed by this relayer, latter relayers can still continue process it.
fn pre_dispatch(
relayer_account: &AccountId,
message: Result<&Self::Message, ()>,
) -> Result<(), &'static str>;

/// Dispatches the message internally.
///
/// `source_chain` indicates the chain where the message came from.
Expand Down Expand Up @@ -154,8 +163,15 @@ pub trait IntoDispatchOrigin<AccountId, Call, Origin> {

/// A generic trait to validate message before dispatch.
pub trait CallValidate<AccountId, Origin, Call> {
/// call validation
fn pre_dispatch(
/// Checking in message receiving step before dispatch
///
/// This will be called before the call enter dispatch phase. If failed, the message(call) will
/// be not be processed by this relayer, latter relayers can still continue process it.
fn check_receiving_before_dispatch(relayer_account: &AccountId, call: &Call) -> Result<(), &'static str>;
/// In-dispatch call validation
///
/// This will be called in the dispatch process, If failed, return message dispatch errors.
fn call_validate(
relayer_account: &AccountId,
origin: &Origin,
call: &Call,
Expand Down

0 comments on commit 9eca261

Please sign in to comment.