Skip to content

Commit ea1f46f

Browse files
svyatonikbkchr
authored andcommitted
Add another condition to the reject-obsolete-parachain-heads extension (#1505)
* add another condition to the reject-obsolete-parachain-heads extension * add tracing to obsolete-tx-extensions * fix tests * extension_rejects_header_from_new_relay_block_with_same_hash * fmt * fix benchmarks
1 parent e9d7adf commit ea1f46f

File tree

13 files changed

+225
-92
lines changed

13 files changed

+225
-92
lines changed

bridges/bin/millau/runtime/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,7 @@ impl_runtime_apis! {
10351035
pallet_bridge_parachains::RelayBlockNumber,
10361036
pallet_bridge_parachains::RelayBlockHash,
10371037
bp_polkadot_core::parachains::ParaHeadsProof,
1038+
Vec<(bp_polkadot_core::parachains::ParaId, bp_polkadot_core::parachains::ParaHash)>,
10381039
) {
10391040
bridge_runtime_common::parachains_benchmarking::prepare_parachain_heads_proof::<Runtime, WithRialtoParachainsInstance>(
10401041
parachains,

bridges/bin/runtime-common/src/messages_extension.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ macro_rules! declare_bridge_reject_obsolete_messages {
7070

7171
let inbound_lane_data = pallet_bridge_messages::InboundLanes::<$runtime, $instance>::get(&proof.lane);
7272
if proof.nonces_end <= inbound_lane_data.last_delivered_nonce() {
73+
log::trace!(
74+
target: pallet_bridge_messages::LOG_TARGET,
75+
"Rejecting obsolete messages delivery transaction: lane {:?}, bundled {:?}, best {:?}",
76+
proof.lane,
77+
proof.nonces_end,
78+
inbound_lane_data.last_delivered_nonce(),
79+
);
80+
7381
return sp_runtime::transaction_validity::InvalidTransaction::Stale.into();
7482
}
7583

@@ -84,6 +92,14 @@ macro_rules! declare_bridge_reject_obsolete_messages {
8492

8593
let outbound_lane_data = pallet_bridge_messages::OutboundLanes::<$runtime, $instance>::get(&proof.lane);
8694
if latest_delivered_nonce <= outbound_lane_data.latest_received_nonce {
95+
log::trace!(
96+
target: pallet_bridge_messages::LOG_TARGET,
97+
"Rejecting obsolete messages confirmation transaction: lane {:?}, bundled {:?}, best {:?}",
98+
proof.lane,
99+
latest_delivered_nonce,
100+
outbound_lane_data.latest_received_nonce,
101+
);
102+
87103
return sp_runtime::transaction_validity::InvalidTransaction::Stale.into();
88104
}
89105

bridges/bin/runtime-common/src/parachains_benchmarking.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
use crate::messages_benchmarking::{grow_trie, insert_header_to_grandpa_pallet};
2222

2323
use bp_parachains::parachain_head_storage_key_at_source;
24-
use bp_polkadot_core::parachains::{ParaHead, ParaHeadsProof, ParaId};
24+
use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId};
2525
use bp_runtime::StorageProofSize;
2626
use codec::Encode;
2727
use frame_support::traits::Get;
@@ -37,7 +37,7 @@ pub fn prepare_parachain_heads_proof<R, PI>(
3737
parachains: &[ParaId],
3838
parachain_head_size: u32,
3939
size: StorageProofSize,
40-
) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof)
40+
) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>)
4141
where
4242
R: pallet_bridge_parachains::Config<PI>
4343
+ pallet_bridge_grandpa::Config<R::BridgesGrandpaPalletInstance>,
@@ -48,6 +48,7 @@ where
4848
let parachain_head = ParaHead(vec![0u8; parachain_head_size as usize]);
4949

5050
// insert all heads to the trie
51+
let mut parachain_heads = Vec::with_capacity(parachains.len());
5152
let mut storage_keys = Vec::with_capacity(parachains.len());
5253
let mut state_root = Default::default();
5354
let mut mdb = MemoryDB::default();
@@ -62,6 +63,7 @@ where
6263
.map_err(|_| "TrieMut::insert has failed")
6364
.expect("TrieMut::insert should not fail in benchmarks");
6465
storage_keys.push(storage_key);
66+
parachain_heads.push((*parachain, parachain_head.hash()))
6567
}
6668
}
6769
state_root = grow_trie(state_root, &mut mdb, size);
@@ -76,5 +78,5 @@ where
7678
let (relay_block_number, relay_block_hash) =
7779
insert_header_to_grandpa_pallet::<R, R::BridgesGrandpaPalletInstance>(state_root);
7880

79-
(relay_block_number, relay_block_hash, ParaHeadsProof(proof))
81+
(relay_block_number, relay_block_hash, ParaHeadsProof(proof), parachain_heads)
8082
}

bridges/modules/grandpa/src/extension.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ macro_rules! declare_bridge_reject_obsolete_grandpa_header {
7575
if best_finalized_number < bundled_block_number {
7676
Ok(sp_runtime::transaction_validity::ValidTransaction::default())
7777
} else {
78+
log::trace!(
79+
target: $crate::LOG_TARGET,
80+
"Rejecting obsolete bridged header: bundled {:?}, best {:?}",
81+
bundled_block_number,
82+
best_finalized_number,
83+
);
84+
7885
sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
7986
}
8087
},

bridges/modules/grandpa/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub use pallet::*;
6060
pub use weights::WeightInfo;
6161

6262
/// The target that will be used when publishing logs related to this pallet.
63-
const LOG_TARGET: &str = "runtime::bridge-grandpa";
63+
pub const LOG_TARGET: &str = "runtime::bridge-grandpa";
6464

6565
/// Block number of the bridged chain.
6666
pub type BridgedBlockNumber<T, I> = BlockNumberOf<<T as Config<I>>::BridgedChain>;

bridges/modules/messages/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ mod mock;
9191
pub use pallet::*;
9292

9393
/// The target that will be used when publishing logs related to this pallet.
94-
const LOG_TARGET: &str = "runtime::bridge-messages";
94+
pub const LOG_TARGET: &str = "runtime::bridge-messages";
9595

9696
#[frame_support::pallet]
9797
pub mod pallet {

bridges/modules/parachains/src/benchmarking.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{
2121
RelayBlockNumber,
2222
};
2323

24-
use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId};
24+
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
2525
use bp_runtime::StorageProofSize;
2626
use frame_benchmarking::{account, benchmarks_instance_pallet};
2727
use frame_system::RawOrigin;
@@ -37,7 +37,7 @@ pub trait Config<I: 'static>: crate::Config<I> {
3737
parachains: &[ParaId],
3838
parachain_head_size: u32,
3939
proof_size: StorageProofSize,
40-
) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof);
40+
) -> (RelayBlockNumber, RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>);
4141
}
4242

4343
benchmarks_instance_pallet! {
@@ -57,13 +57,13 @@ benchmarks_instance_pallet! {
5757

5858
let sender = account("sender", 0, 0);
5959
let parachains = (1..=p).map(ParaId).collect::<Vec<_>>();
60-
let (relay_block_number, relay_block_hash, parachain_heads_proof) = T::prepare_parachain_heads_proof(
60+
let (relay_block_number, relay_block_hash, parachain_heads_proof, parachains_heads) = T::prepare_parachain_heads_proof(
6161
&parachains,
6262
DEFAULT_PARACHAIN_HEAD_SIZE,
6363
StorageProofSize::Minimal(0),
6464
);
6565
let at_relay_block = (relay_block_number, relay_block_hash);
66-
}: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains.clone(), parachain_heads_proof)
66+
}: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains_heads, parachain_heads_proof)
6767
verify {
6868
for parachain in parachains {
6969
assert!(crate::Pallet::<T, I>::best_parachain_head(parachain).is_some());
@@ -74,13 +74,13 @@ benchmarks_instance_pallet! {
7474
submit_parachain_heads_with_1kb_proof {
7575
let sender = account("sender", 0, 0);
7676
let parachains = vec![ParaId(1)];
77-
let (relay_block_number, relay_block_hash, parachain_heads_proof) = T::prepare_parachain_heads_proof(
77+
let (relay_block_number, relay_block_hash, parachain_heads_proof, parachains_heads) = T::prepare_parachain_heads_proof(
7878
&parachains,
7979
DEFAULT_PARACHAIN_HEAD_SIZE,
8080
StorageProofSize::HasExtraNodes(1024),
8181
);
8282
let at_relay_block = (relay_block_number, relay_block_hash);
83-
}: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains.clone(), parachain_heads_proof)
83+
}: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains_heads, parachain_heads_proof)
8484
verify {
8585
for parachain in parachains {
8686
assert!(crate::Pallet::<T, I>::best_parachain_head(parachain).is_some());
@@ -91,13 +91,13 @@ benchmarks_instance_pallet! {
9191
submit_parachain_heads_with_16kb_proof {
9292
let sender = account("sender", 0, 0);
9393
let parachains = vec![ParaId(1)];
94-
let (relay_block_number, relay_block_hash, parachain_heads_proof) = T::prepare_parachain_heads_proof(
94+
let (relay_block_number, relay_block_hash, parachain_heads_proof, parachains_heads) = T::prepare_parachain_heads_proof(
9595
&parachains,
9696
DEFAULT_PARACHAIN_HEAD_SIZE,
9797
StorageProofSize::HasExtraNodes(16 * 1024),
9898
);
9999
let at_relay_block = (relay_block_number, relay_block_hash);
100-
}: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains.clone(), parachain_heads_proof)
100+
}: submit_parachain_heads(RawOrigin::Signed(sender), at_relay_block, parachains_heads, parachain_heads_proof)
101101
verify {
102102
for parachain in parachains {
103103
assert!(crate::Pallet::<T, I>::best_parachain_head(parachain).is_some());

bridges/modules/parachains/src/extension.rs

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,34 @@ macro_rules! declare_bridge_reject_obsolete_parachain_header {
7272
ref parachains,
7373
..
7474
}) if parachains.len() == 1 => {
75-
let parachain = parachains.get(0).expect("verified by match condition; qed");
75+
let (parachain, parachain_head_hash) = parachains.get(0).expect("verified by match condition; qed");
7676

7777
let bundled_relay_block_number = at_relay_block.0;
7878

7979
let best_parachain_head = $crate::BestParaHeads::<$runtime, $instance>::get(parachain);
80+
8081
match best_parachain_head {
8182
Some(best_parachain_head) if best_parachain_head.at_relay_block_number
82-
>= bundled_relay_block_number =>
83-
sp_runtime::transaction_validity::InvalidTransaction::Stale.into(),
83+
>= bundled_relay_block_number => {
84+
log::trace!(
85+
target: $crate::LOG_TARGET,
86+
"Rejecting obsolete parachain-head {:?} transaction: bundled relay block number: \
87+
{:?} best relay block number: {:?}",
88+
parachain,
89+
bundled_relay_block_number,
90+
best_parachain_head.at_relay_block_number,
91+
);
92+
sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
93+
}
94+
Some(best_parachain_head) if best_parachain_head.head_hash == *parachain_head_hash => {
95+
log::trace!(
96+
target: $crate::LOG_TARGET,
97+
"Rejecting obsolete parachain-head {:?} transaction: head hash {:?}",
98+
parachain,
99+
best_parachain_head.head_hash,
100+
);
101+
sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
102+
}
84103
_ => Ok(sp_runtime::transaction_validity::ValidTransaction::default()),
85104
}
86105
},
@@ -118,7 +137,7 @@ mod tests {
118137
mock::{run_test, Call, TestRuntime},
119138
BestParaHead, BestParaHeads, RelayBlockNumber,
120139
};
121-
use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId};
140+
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
122141
use frame_support::weights::{DispatchClass, DispatchInfo, Pays};
123142
use sp_runtime::traits::SignedExtension;
124143

@@ -127,7 +146,10 @@ mod tests {
127146
Call::Parachains => ()
128147
}
129148

130-
fn validate_submit_parachain_heads(num: RelayBlockNumber, parachains: Vec<ParaId>) -> bool {
149+
fn validate_submit_parachain_heads(
150+
num: RelayBlockNumber,
151+
parachains: Vec<(ParaId, ParaHash)>,
152+
) -> bool {
131153
BridgeRejectObsoleteParachainHeader
132154
.validate(
133155
&42,
@@ -147,29 +169,39 @@ mod tests {
147169
ParaId(1),
148170
BestParaHead {
149171
at_relay_block_number: 10,
150-
head_hash: Default::default(),
172+
head_hash: [1u8; 32].into(),
151173
next_imported_hash_position: 0,
152174
},
153175
);
154176
}
155177

156178
#[test]
157-
fn extension_rejects_obsolete_header() {
179+
fn extension_rejects_header_from_the_obsolete_relay_block() {
158180
run_test(|| {
159181
// when current best finalized is #10 and we're trying to import header#5 => tx is
160182
// rejected
161183
sync_to_relay_header_10();
162-
assert!(!validate_submit_parachain_heads(5, vec![ParaId(1)]));
184+
assert!(!validate_submit_parachain_heads(5, vec![(ParaId(1), [1u8; 32].into())]));
185+
});
186+
}
187+
188+
#[test]
189+
fn extension_rejects_header_from_the_same_relay_block() {
190+
run_test(|| {
191+
// when current best finalized is #10 and we're trying to import header#10 => tx is
192+
// rejected
193+
sync_to_relay_header_10();
194+
assert!(!validate_submit_parachain_heads(10, vec![(ParaId(1), [1u8; 32].into())]));
163195
});
164196
}
165197

166198
#[test]
167-
fn extension_rejects_same_header() {
199+
fn extension_rejects_header_from_new_relay_block_with_same_hash() {
168200
run_test(|| {
169201
// when current best finalized is #10 and we're trying to import header#10 => tx is
170202
// rejected
171203
sync_to_relay_header_10();
172-
assert!(!validate_submit_parachain_heads(10, vec![ParaId(1)]));
204+
assert!(!validate_submit_parachain_heads(20, vec![(ParaId(1), [1u8; 32].into())]));
173205
});
174206
}
175207

@@ -179,7 +211,7 @@ mod tests {
179211
// when current best finalized is #10 and we're trying to import header#15 => tx is
180212
// accepted
181213
sync_to_relay_header_10();
182-
assert!(validate_submit_parachain_heads(15, vec![ParaId(1)]));
214+
assert!(validate_submit_parachain_heads(15, vec![(ParaId(1), [2u8; 32].into())]));
183215
});
184216
}
185217

@@ -189,7 +221,10 @@ mod tests {
189221
// when current best finalized is #10 and we're trying to import header#5, but another
190222
// parachain head is also supplied => tx is accepted
191223
sync_to_relay_header_10();
192-
assert!(validate_submit_parachain_heads(5, vec![ParaId(1), ParaId(2)]));
224+
assert!(validate_submit_parachain_heads(
225+
5,
226+
vec![(ParaId(1), [1u8; 32].into()), (ParaId(2), [1u8; 32].into())]
227+
));
193228
});
194229
}
195230
}

0 commit comments

Comments
 (0)