Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Update bridges subtree (#2254)
Browse files Browse the repository at this point in the history
* Squashed 'bridges/' changes from 3c15c3645..d05a98473

d05a98473 Refund messages confirmation tx (#1904)
e2e8a7198 Relayers pallet: extend payment source id (#1907)
cccf73b3f fix nightly clippy issues (#1915)
a33a91e79 Bump tempfile from 3.3.0 to 3.4.0
1df768a2e Bump time from 0.3.17 to 0.3.20
cf17b424f Bump sysinfo from 0.28.0 to 0.28.1
0b6276b41 Bump jsonrpsee from 0.15.1 to 0.16.2
328dde02b Bump rand from 0.7.3 to 0.8.5
2f302a4b6 Bump trie-db from 0.25.1 to 0.26.0
b5d5d03ab CI add jobs to publish Docker images description to hub.docker.com (#1906)
db5168f18 Do not stall on lost transaction (#1903)
2d83d6389 Fix init-bridge (#1900)

git-subtree-dir: bridges
git-subtree-split: d05a98473dc933cfed9e5f59023efa2ec811f03c

* Rewards adjustments
  • Loading branch information
serban300 committed Mar 1, 2023
1 parent b0d56a5 commit bded8f4
Show file tree
Hide file tree
Showing 25 changed files with 717 additions and 315 deletions.
23 changes: 20 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bridges/bin/runtime-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ bp-header-chain = { path = "../../primitives/header-chain", default-features = f
bp-messages = { path = "../../primitives/messages", default-features = false }
bp-parachains = { path = "../../primitives/parachains", default-features = false }
bp-polkadot-core = { path = "../../primitives/polkadot-core", default-features = false }
bp-relayers = { path = "../../primitives/relayers", default-features = false }
bp-runtime = { path = "../../primitives/runtime", default-features = false }
pallet-bridge-grandpa = { path = "../../modules/grandpa", default-features = false }
pallet-bridge-messages = { path = "../../modules/messages", default-features = false }
Expand Down
3 changes: 1 addition & 2 deletions bridges/bin/runtime-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ where
/// even honest relayers may lose their funds if there are multiple relays running and
/// submitting the same messages/confirmations.
fn validate(call: &T::RuntimeCall) -> TransactionValidity {
call.check_obsolete_receive_messages_proof()?;
call.check_obsolete_receive_messages_delivery_proof()
call.check_obsolete_call()
}
}

Expand Down
219 changes: 137 additions & 82 deletions bridges/bin/runtime-common/src/messages_call_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,57 @@ use frame_support::{dispatch::CallableCallFor, traits::IsSubType, RuntimeDebug};
use pallet_bridge_messages::{Config, Pallet};
use sp_runtime::transaction_validity::TransactionValidity;

/// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
/// Generic info about a messages delivery/confirmation proof.
#[derive(PartialEq, RuntimeDebug)]
pub struct ReceiveMessagesProofInfo {
pub struct BaseMessagesProofInfo {
pub lane_id: LaneId,
pub best_proof_nonce: MessageNonce,
pub best_bundled_nonce: MessageNonce,
pub best_stored_nonce: MessageNonce,
}

/// Helper struct that provides methods for working with the `ReceiveMessagesProof` call.
pub struct ReceiveMessagesProofHelper<T: Config<I>, I: 'static> {
impl BaseMessagesProofInfo {
fn is_obsolete(&self) -> bool {
self.best_bundled_nonce <= self.best_stored_nonce
}
}

/// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
#[derive(PartialEq, RuntimeDebug)]
pub struct ReceiveMessagesProofInfo(pub BaseMessagesProofInfo);

/// Info about a `ReceiveMessagesDeliveryProof` call which tries to update a single lane.
#[derive(PartialEq, RuntimeDebug)]
pub struct ReceiveMessagesDeliveryProofInfo(pub BaseMessagesProofInfo);

/// Info about a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call
/// which tries to update a single lane.
#[derive(PartialEq, RuntimeDebug)]
pub enum CallInfo {
ReceiveMessagesProof(ReceiveMessagesProofInfo),
ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo),
}

/// Helper struct that provides methods for working with a call supported by `CallInfo`.
pub struct CallHelper<T: Config<I>, I: 'static> {
pub _phantom_data: sp_std::marker::PhantomData<(T, I)>,
}

impl<T: Config<I>, I: 'static> ReceiveMessagesProofHelper<T, I> {
/// Check if the `ReceiveMessagesProof` call delivered at least some of the messages that
/// it contained.
pub fn was_partially_successful(info: &ReceiveMessagesProofInfo) -> bool {
let inbound_lane_data = pallet_bridge_messages::InboundLanes::<T, I>::get(info.lane_id);
inbound_lane_data.last_delivered_nonce() > info.best_stored_nonce
impl<T: Config<I>, I: 'static> CallHelper<T, I> {
/// Check if a call delivered proof/confirmation for at least some of the messages that it
/// contained.
pub fn was_partially_successful(info: &CallInfo) -> bool {
match info {
CallInfo::ReceiveMessagesProof(info) => {
let inbound_lane_data =
pallet_bridge_messages::InboundLanes::<T, I>::get(info.0.lane_id);
inbound_lane_data.last_delivered_nonce() > info.0.best_stored_nonce
},
CallInfo::ReceiveMessagesDeliveryProof(info) => {
let outbound_lane_data =
pallet_bridge_messages::OutboundLanes::<T, I>::get(info.0.lane_id);
outbound_lane_data.latest_received_nonce > info.0.best_stored_nonce
},
}
}
}

Expand All @@ -51,17 +83,21 @@ pub trait MessagesCallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>:
/// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call.
fn receive_messages_proof_info(&self) -> Option<ReceiveMessagesProofInfo>;

/// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call,
/// if the call is for the provided lane.
fn receive_messages_proof_info_for(&self, lane_id: LaneId) -> Option<ReceiveMessagesProofInfo>;
/// Create a new instance of `ReceiveMessagesDeliveryProofInfo` from
/// a `ReceiveMessagesDeliveryProof` call.
fn receive_messages_delivery_proof_info(&self) -> Option<ReceiveMessagesDeliveryProofInfo>;

/// Create a new instance of `CallInfo` from a `ReceiveMessagesProof`
/// or a `ReceiveMessagesDeliveryProof` call.
fn call_info(&self) -> Option<CallInfo>;

/// Check that a `ReceiveMessagesProof` call is trying to deliver at least some messages that
/// are better than the ones we know of.
fn check_obsolete_receive_messages_proof(&self) -> TransactionValidity;
/// Create a new instance of `CallInfo` from a `ReceiveMessagesProof`
/// or a `ReceiveMessagesDeliveryProof` call, if the call is for the provided lane.
fn call_info_for(&self, lane_id: LaneId) -> Option<CallInfo>;

/// Check that a `ReceiveMessagesDeliveryProof` call is trying to deliver at least some message
/// confirmations that are better than the ones we know of.
fn check_obsolete_receive_messages_delivery_proof(&self) -> TransactionValidity;
/// Check that a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call is trying
/// to deliver/confirm at least some messages that are better than the ones we know of.
fn check_obsolete_call(&self) -> TransactionValidity;
}

impl<
Expand All @@ -88,59 +124,80 @@ impl<
{
let inbound_lane_data = pallet_bridge_messages::InboundLanes::<T, I>::get(proof.lane);

return Some(ReceiveMessagesProofInfo {
return Some(ReceiveMessagesProofInfo(BaseMessagesProofInfo {
lane_id: proof.lane,
best_proof_nonce: proof.nonces_end,
best_bundled_nonce: proof.nonces_end,
best_stored_nonce: inbound_lane_data.last_delivered_nonce(),
})
}))
}

None
}

fn receive_messages_proof_info_for(&self, lane_id: LaneId) -> Option<ReceiveMessagesProofInfo> {
self.receive_messages_proof_info().filter(|info| info.lane_id == lane_id)
}

fn check_obsolete_receive_messages_proof(&self) -> TransactionValidity {
if let Some(proof_info) = self.receive_messages_proof_info() {
if proof_info.best_proof_nonce <= proof_info.best_stored_nonce {
log::trace!(
target: pallet_bridge_messages::LOG_TARGET,
"Rejecting obsolete messages delivery transaction: \
lane {:?}, bundled {:?}, best {:?}",
proof_info.lane_id,
proof_info.best_proof_nonce,
proof_info.best_stored_nonce,
);

return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
}
}

Ok(sp_runtime::transaction_validity::ValidTransaction::default())
}

fn check_obsolete_receive_messages_delivery_proof(&self) -> TransactionValidity {
fn receive_messages_delivery_proof_info(&self) -> Option<ReceiveMessagesDeliveryProofInfo> {
if let Some(pallet_bridge_messages::Call::<T, I>::receive_messages_delivery_proof {
ref proof,
ref relayers_state,
..
}) = self.is_sub_type()
{
let outbound_lane_data = pallet_bridge_messages::OutboundLanes::<T, I>::get(proof.lane);
if relayers_state.last_delivered_nonce <= outbound_lane_data.latest_received_nonce {

return Some(ReceiveMessagesDeliveryProofInfo(BaseMessagesProofInfo {
lane_id: proof.lane,
best_bundled_nonce: relayers_state.last_delivered_nonce,
best_stored_nonce: outbound_lane_data.latest_received_nonce,
}))
}

None
}

fn call_info(&self) -> Option<CallInfo> {
if let Some(info) = self.receive_messages_proof_info() {
return Some(CallInfo::ReceiveMessagesProof(info))
}

if let Some(info) = self.receive_messages_delivery_proof_info() {
return Some(CallInfo::ReceiveMessagesDeliveryProof(info))
}

None
}

fn call_info_for(&self, lane_id: LaneId) -> Option<CallInfo> {
self.call_info().filter(|info| {
let actual_lane_id = match info {
CallInfo::ReceiveMessagesProof(info) => info.0.lane_id,
CallInfo::ReceiveMessagesDeliveryProof(info) => info.0.lane_id,
};
actual_lane_id == lane_id
})
}

fn check_obsolete_call(&self) -> TransactionValidity {
match self.call_info() {
Some(CallInfo::ReceiveMessagesProof(proof_info)) if proof_info.0.is_obsolete() => {
log::trace!(
target: pallet_bridge_messages::LOG_TARGET,
"Rejecting obsolete messages confirmation transaction: \
lane {:?}, bundled {:?}, best {:?}",
proof.lane,
relayers_state.last_delivered_nonce,
outbound_lane_data.latest_received_nonce,
"Rejecting obsolete messages delivery transaction: {:?}",
proof_info
);

return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
}
},
Some(CallInfo::ReceiveMessagesDeliveryProof(proof_info))
if proof_info.0.is_obsolete() =>
{
log::trace!(
target: pallet_bridge_messages::LOG_TARGET,
"Rejecting obsolete messages confirmation transaction: {:?}",
proof_info,
);

return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
},
_ => {},
}

Ok(sp_runtime::transaction_validity::ValidTransaction::default())
Expand All @@ -153,8 +210,8 @@ mod tests {
messages::{
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
},
messages_call_ext::MessagesCallSubType,
mock::{TestRuntime, ThisChainRuntimeCall},
BridgeRuntimeFilterCall,
};
use bp_messages::UnrewardedRelayersState;

Expand All @@ -169,22 +226,21 @@ mod tests {
nonces_start: bp_messages::MessageNonce,
nonces_end: bp_messages::MessageNonce,
) -> bool {
pallet_bridge_messages::Pallet::<TestRuntime>::validate(
&ThisChainRuntimeCall::BridgeMessages(
pallet_bridge_messages::Call::<TestRuntime, ()>::receive_messages_proof {
relayer_id_at_bridged_chain: 42,
messages_count: (nonces_end - nonces_start + 1) as u32,
dispatch_weight: frame_support::weights::Weight::zero(),
proof: FromBridgedChainMessagesProof {
bridged_header_hash: Default::default(),
storage_proof: vec![],
lane: bp_messages::LaneId([0, 0, 0, 0]),
nonces_start,
nonces_end,
},
ThisChainRuntimeCall::BridgeMessages(
pallet_bridge_messages::Call::<TestRuntime, ()>::receive_messages_proof {
relayer_id_at_bridged_chain: 42,
messages_count: (nonces_end - nonces_start + 1) as u32,
dispatch_weight: frame_support::weights::Weight::zero(),
proof: FromBridgedChainMessagesProof {
bridged_header_hash: Default::default(),
storage_proof: vec![],
lane: bp_messages::LaneId([0, 0, 0, 0]),
nonces_start,
nonces_end,
},
),
},
)
.check_obsolete_call()
.is_ok()
}

Expand Down Expand Up @@ -230,21 +286,20 @@ mod tests {
}

fn validate_message_confirmation(last_delivered_nonce: bp_messages::MessageNonce) -> bool {
pallet_bridge_messages::Pallet::<TestRuntime>::validate(
&ThisChainRuntimeCall::BridgeMessages(
pallet_bridge_messages::Call::<TestRuntime>::receive_messages_delivery_proof {
proof: FromBridgedChainMessagesDeliveryProof {
bridged_header_hash: Default::default(),
storage_proof: Vec::new(),
lane: bp_messages::LaneId([0, 0, 0, 0]),
},
relayers_state: UnrewardedRelayersState {
last_delivered_nonce,
..Default::default()
},
ThisChainRuntimeCall::BridgeMessages(
pallet_bridge_messages::Call::<TestRuntime>::receive_messages_delivery_proof {
proof: FromBridgedChainMessagesDeliveryProof {
bridged_header_hash: Default::default(),
storage_proof: Vec::new(),
lane: bp_messages::LaneId([0, 0, 0, 0]),
},
relayers_state: UnrewardedRelayersState {
last_delivered_nonce,
..Default::default()
},
),
},
)
.check_obsolete_call()
.is_ok()
}

Expand Down
Loading

0 comments on commit bded8f4

Please sign in to comment.