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

Commit

Permalink
Squashed 'bridges/' changes from 4c4a7eae1..dcaec27aa
Browse files Browse the repository at this point in the history
dcaec27aa RefundRelayerForMessagesFromParachain improvements (#1879)
5457f0672 clippy fixes (#1880)
29e8a305c MaxValues for OutboundLanes map (#1871)
5219b56f8 More tests for message pallet weights (#1870)
c4c0c7a1b Bump signal-hook from 0.3.14 to 0.3.15
0ff597b96 Bump serde_json from 1.0.92 to 1.0.93
1c5132eb1 Bump subxt from `20adb19` to `9e2acff`
adb07816b update parachains relay doc (#1874)
972ef3133 Update README.md (#1872)
94648061b MaxValues for maps in parachain maps (#1868)
662267a6f "refund" proof size in GRANDPa pallet (#1863)

git-subtree-dir: bridges
git-subtree-split: dcaec27aaa6f41070fbdfbfd4fde2029697eb85f
  • Loading branch information
bkontur committed Feb 15, 2023
1 parent 97f2ab2 commit be711f1
Show file tree
Hide file tree
Showing 31 changed files with 1,298 additions and 945 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion bin/millau/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
clap = { version = "4.1.4", features = ["derive"] }
jsonrpsee = { version = "0.16.2", features = ["server"] }
serde_json = "1.0.92"
serde_json = "1.0.93"

# Bridge dependencies

Expand Down
1 change: 0 additions & 1 deletion bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,6 @@ pub type BridgeRefundRialtoParachainRelayers =
RialtoGrandpaInstance,
WithRialtoParachainsInstance,
WithRialtoParachainMessagesInstance,
BridgeRejectObsoleteHeadersAndMessages,
RialtoParachainId,
RialtoParachainMessagesLane,
Runtime,
Expand Down
2 changes: 1 addition & 1 deletion bin/rialto/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"

[dependencies]
clap = { version = "4.1.4", features = ["derive"] }
serde_json = "1.0.92"
serde_json = "1.0.93"

# Bridge dependencies

Expand Down
40 changes: 30 additions & 10 deletions bin/runtime-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@

#![cfg_attr(not(feature = "std"), no_std)]

use bp_runtime::FilterCall;
use crate::messages_call_ext::MessagesCallSubType;
use pallet_bridge_grandpa::CallSubType as GrandpaCallSubType;
use pallet_bridge_parachains::CallSubType as ParachainsCallSubtype;
use sp_runtime::transaction_validity::TransactionValidity;
use xcm::v3::NetworkId;

pub mod messages;
pub mod messages_api;
pub mod messages_benchmarking;
pub mod messages_extension;
pub mod messages_call_ext;
pub mod parachains_benchmarking;
pub mod refund_relayer_extension;

Expand All @@ -44,21 +46,39 @@ pub trait BridgeRuntimeFilterCall<Call> {
fn validate(call: &Call) -> TransactionValidity;
}

impl<Call, T, I> BridgeRuntimeFilterCall<Call> for pallet_bridge_grandpa::Pallet<T, I>
impl<T, I: 'static> BridgeRuntimeFilterCall<T::RuntimeCall> for pallet_bridge_grandpa::Pallet<T, I>
where
pallet_bridge_grandpa::Pallet<T, I>: FilterCall<Call>,
T: pallet_bridge_grandpa::Config<I>,
T::RuntimeCall: GrandpaCallSubType<T, I>,
{
fn validate(call: &Call) -> TransactionValidity {
<pallet_bridge_grandpa::Pallet<T, I> as FilterCall<Call>>::validate(call)
fn validate(call: &T::RuntimeCall) -> TransactionValidity {
GrandpaCallSubType::<T, I>::check_obsolete_submit_finality_proof(call)
}
}

impl<Call, T, I> BridgeRuntimeFilterCall<Call> for pallet_bridge_parachains::Pallet<T, I>
impl<T, I: 'static> BridgeRuntimeFilterCall<T::RuntimeCall>
for pallet_bridge_parachains::Pallet<T, I>
where
pallet_bridge_parachains::Pallet<T, I>: FilterCall<Call>,
T: pallet_bridge_parachains::Config<I>,
T::RuntimeCall: ParachainsCallSubtype<T, I>,
{
fn validate(call: &Call) -> TransactionValidity {
<pallet_bridge_parachains::Pallet<T, I> as FilterCall<Call>>::validate(call)
fn validate(call: &T::RuntimeCall) -> TransactionValidity {
ParachainsCallSubtype::<T, I>::check_obsolete_submit_parachain_heads(call)
}
}

impl<T: pallet_bridge_messages::Config<I>, I: 'static> BridgeRuntimeFilterCall<T::RuntimeCall>
for pallet_bridge_messages::Pallet<T, I>
where
T::RuntimeCall: MessagesCallSubType<T, I>,
{
/// Validate messages in order to avoid "mining" messages delivery and delivery confirmation
/// transactions, that are delivering outdated messages/confirmations. Without this validation,
/// 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()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,56 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.

use crate::{
messages::{
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
},
BridgeRuntimeFilterCall,
use crate::messages::{
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
};
use bp_messages::{LaneId, MessageNonce};
use frame_support::{dispatch::CallableCallFor, traits::IsSubType};
use pallet_bridge_messages::{Config, Pallet};
use sp_runtime::transaction_validity::TransactionValidity;
use sp_runtime::{transaction_validity::TransactionValidity, RuntimeDebug};

/// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
#[derive(Copy, Clone, PartialEq, RuntimeDebug)]
pub struct ReceiveMessagesProofInfo {
pub lane_id: LaneId,
pub best_proof_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> {
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
}
}

/// Trait representing a call that is a sub type of `pallet_bridge_messages::Call`.
pub trait MessagesCallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>:
IsSubType<CallableCallFor<Pallet<T, I>, T>>
{
/// 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>;

/// 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;

/// 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;
}

/// Validate messages in order to avoid "mining" messages delivery and delivery confirmation
/// transactions, that are delivering outdated messages/confirmations. Without this validation,
/// even honest relayers may lose their funds if there are multiple relays running and submitting
/// the same messages/confirmations.
impl<
BridgedHeaderHash,
SourceHeaderChain: bp_messages::target_chain::SourceHeaderChain<
Expand All @@ -42,52 +78,69 @@ impl<
T: frame_system::Config<RuntimeCall = Call>
+ Config<I, SourceHeaderChain = SourceHeaderChain, TargetHeaderChain = TargetHeaderChain>,
I: 'static,
> BridgeRuntimeFilterCall<Call> for Pallet<T, I>
> MessagesCallSubType<T, I> for T::RuntimeCall
{
fn validate(call: &Call) -> TransactionValidity {
match call.is_sub_type() {
Some(pallet_bridge_messages::Call::<T, I>::receive_messages_proof {
ref proof,
..
}) => {
let inbound_lane_data =
pallet_bridge_messages::InboundLanes::<T, I>::get(proof.lane);
if proof.nonces_end <= inbound_lane_data.last_delivered_nonce() {
log::trace!(
target: pallet_bridge_messages::LOG_TARGET,
"Rejecting obsolete messages delivery transaction: \
fn receive_messages_proof_info(&self) -> Option<ReceiveMessagesProofInfo> {
if let Some(pallet_bridge_messages::Call::<T, I>::receive_messages_proof {
ref proof,
..
}) = self.is_sub_type()
{
let inbound_lane_data = pallet_bridge_messages::InboundLanes::<T, I>::get(proof.lane);

return Some(ReceiveMessagesProofInfo {
lane_id: proof.lane,
best_proof_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.lane,
proof.nonces_end,
inbound_lane_data.last_delivered_nonce(),
);
proof_info.lane_id,
proof_info.best_proof_nonce,
proof_info.best_stored_nonce,
);

return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
}
},
Some(pallet_bridge_messages::Call::<T, I>::receive_messages_delivery_proof {
ref proof,
ref relayers_state,
..
}) => {
let latest_delivered_nonce = relayers_state.last_delivered_nonce;

let outbound_lane_data =
pallet_bridge_messages::OutboundLanes::<T, I>::get(proof.lane);
if latest_delivered_nonce <= outbound_lane_data.latest_received_nonce {
log::trace!(
target: pallet_bridge_messages::LOG_TARGET,
"Rejecting obsolete messages confirmation transaction: \
return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
}
}

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

fn check_obsolete_receive_messages_delivery_proof(&self) -> TransactionValidity {
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 {
log::trace!(
target: pallet_bridge_messages::LOG_TARGET,
"Rejecting obsolete messages confirmation transaction: \
lane {:?}, bundled {:?}, best {:?}",
proof.lane,
latest_delivered_nonce,
outbound_lane_data.latest_received_nonce,
);
proof.lane,
relayers_state.last_delivered_nonce,
outbound_lane_data.latest_received_nonce,
);

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

Ok(sp_runtime::transaction_validity::ValidTransaction::default())
Expand Down
Loading

0 comments on commit be711f1

Please sign in to comment.