Skip to content

Commit ebf4423

Browse files
authored
Update bridges subtree (#1803)
1 parent 2b4b33d commit ebf4423

File tree

4 files changed

+164
-12
lines changed

4 files changed

+164
-12
lines changed

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::messages::{
1818
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
1919
};
2020
use bp_messages::{target_chain::MessageDispatch, InboundLaneData, LaneId, MessageNonce};
21+
use bp_runtime::OwnedBridgeModule;
2122
use frame_support::{
2223
dispatch::CallableCallFor,
2324
traits::{Get, IsSubType},
@@ -187,8 +188,22 @@ pub trait MessagesCallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>:
187188
/// or a `ReceiveMessagesDeliveryProof` call, if the call is for the provided lane.
188189
fn call_info_for(&self, lane_id: LaneId) -> Option<CallInfo>;
189190

190-
/// Check that a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call is trying
191-
/// to deliver/confirm at least some messages that are better than the ones we know of.
191+
/// Ensures that a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call:
192+
///
193+
/// - does not deliver already delivered messages. We require all messages in the
194+
/// `ReceiveMessagesProof` call to be undelivered;
195+
///
196+
/// - does not submit empty `ReceiveMessagesProof` call with zero messages, unless the lane
197+
/// needs to be unblocked by providing relayer rewards proof;
198+
///
199+
/// - brings no new delivery confirmations in a `ReceiveMessagesDeliveryProof` call. We require
200+
/// at least one new delivery confirmation in the unrewarded relayers set;
201+
///
202+
/// - does not violate some basic (easy verifiable) messages pallet rules obsolete (like
203+
/// submitting a call when a pallet is halted or delivering messages when a dispatcher is
204+
/// inactive).
205+
///
206+
/// If one of above rules is violated, the transaction is treated as invalid.
192207
fn check_obsolete_call(&self) -> TransactionValidity;
193208
}
194209

@@ -278,7 +293,17 @@ impl<
278293
}
279294

280295
fn check_obsolete_call(&self) -> TransactionValidity {
296+
let is_pallet_halted = Pallet::<T, I>::ensure_not_halted().is_err();
281297
match self.call_info() {
298+
Some(proof_info) if is_pallet_halted => {
299+
log::trace!(
300+
target: pallet_bridge_messages::LOG_TARGET,
301+
"Rejecting messages transaction on halted pallet: {:?}",
302+
proof_info
303+
);
304+
305+
return sp_runtime::transaction_validity::InvalidTransaction::Call.into()
306+
},
282307
Some(CallInfo::ReceiveMessagesProof(proof_info))
283308
if proof_info.is_obsolete(T::MessageDispatch::is_active()) =>
284309
{

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

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -838,21 +838,23 @@ mod tests {
838838
mock::*,
839839
};
840840
use bp_messages::{
841-
DeliveredMessages, InboundLaneData, MessageNonce, OutboundLaneData, UnrewardedRelayer,
842-
UnrewardedRelayersState,
841+
DeliveredMessages, InboundLaneData, MessageNonce, MessagesOperatingMode, OutboundLaneData,
842+
UnrewardedRelayer, UnrewardedRelayersState,
843843
};
844844
use bp_parachains::{BestParaHeadHash, ParaInfo};
845845
use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId};
846-
use bp_runtime::HeaderId;
846+
use bp_runtime::{BasicOperatingMode, HeaderId};
847847
use bp_test_utils::{make_default_justification, test_keyring};
848848
use frame_support::{
849849
assert_storage_noop, parameter_types,
850850
traits::{fungible::Mutate, ReservableCurrency},
851851
weights::Weight,
852852
};
853-
use pallet_bridge_grandpa::{Call as GrandpaCall, StoredAuthoritySet};
854-
use pallet_bridge_messages::Call as MessagesCall;
855-
use pallet_bridge_parachains::{Call as ParachainsCall, RelayBlockHash};
853+
use pallet_bridge_grandpa::{Call as GrandpaCall, Pallet as GrandpaPallet, StoredAuthoritySet};
854+
use pallet_bridge_messages::{Call as MessagesCall, Pallet as MessagesPallet};
855+
use pallet_bridge_parachains::{
856+
Call as ParachainsCall, Pallet as ParachainsPallet, RelayBlockHash,
857+
};
856858
use sp_runtime::{
857859
traits::{ConstU64, Header as HeaderT},
858860
transaction_validity::{InvalidTransaction, ValidTransaction},
@@ -1592,6 +1594,99 @@ mod tests {
15921594
});
15931595
}
15941596

1597+
#[test]
1598+
fn ext_rejects_batch_with_grandpa_finality_proof_when_grandpa_pallet_is_halted() {
1599+
run_test(|| {
1600+
initialize_environment(100, 100, 100);
1601+
1602+
GrandpaPallet::<TestRuntime, ()>::set_operating_mode(
1603+
RuntimeOrigin::root(),
1604+
BasicOperatingMode::Halted,
1605+
)
1606+
.unwrap();
1607+
1608+
assert_eq!(
1609+
run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
1610+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1611+
);
1612+
assert_eq!(
1613+
run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 200)),
1614+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1615+
);
1616+
});
1617+
}
1618+
1619+
#[test]
1620+
fn ext_rejects_batch_with_parachain_finality_proof_when_parachains_pallet_is_halted() {
1621+
run_test(|| {
1622+
initialize_environment(100, 100, 100);
1623+
1624+
ParachainsPallet::<TestRuntime, ()>::set_operating_mode(
1625+
RuntimeOrigin::root(),
1626+
BasicOperatingMode::Halted,
1627+
)
1628+
.unwrap();
1629+
1630+
assert_eq!(
1631+
run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
1632+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1633+
);
1634+
assert_eq!(
1635+
run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 200)),
1636+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1637+
);
1638+
1639+
assert_eq!(
1640+
run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 200)),
1641+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1642+
);
1643+
assert_eq!(
1644+
run_pre_dispatch(parachain_finality_and_confirmation_batch_call(200, 200)),
1645+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1646+
);
1647+
});
1648+
}
1649+
1650+
#[test]
1651+
fn ext_rejects_transaction_when_messages_pallet_is_halted() {
1652+
run_test(|| {
1653+
initialize_environment(100, 100, 100);
1654+
1655+
MessagesPallet::<TestRuntime, ()>::set_operating_mode(
1656+
RuntimeOrigin::root(),
1657+
MessagesOperatingMode::Basic(BasicOperatingMode::Halted),
1658+
)
1659+
.unwrap();
1660+
1661+
assert_eq!(
1662+
run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
1663+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1664+
);
1665+
assert_eq!(
1666+
run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 200)),
1667+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1668+
);
1669+
1670+
assert_eq!(
1671+
run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 200)),
1672+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1673+
);
1674+
assert_eq!(
1675+
run_pre_dispatch(parachain_finality_and_confirmation_batch_call(200, 200)),
1676+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1677+
);
1678+
1679+
assert_eq!(
1680+
run_pre_dispatch(message_delivery_call(200)),
1681+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1682+
);
1683+
assert_eq!(
1684+
run_pre_dispatch(message_confirmation_call(200)),
1685+
Err(TransactionValidityError::Invalid(InvalidTransaction::Call)),
1686+
);
1687+
});
1688+
}
1689+
15951690
#[test]
15961691
fn pre_dispatch_parses_batch_with_relay_chain_and_parachain_headers() {
15971692
run_test(|| {

bridges/modules/grandpa/src/call_ext.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
use crate::{weights::WeightInfo, BridgedBlockNumber, BridgedHeader, Config, Error, Pallet};
1818
use bp_header_chain::{justification::GrandpaJustification, ChainWithGrandpa};
19-
use bp_runtime::BlockNumberOf;
19+
use bp_runtime::{BlockNumberOf, OwnedBridgeModule};
2020
use codec::Encode;
2121
use frame_support::{dispatch::CallableCallFor, traits::IsSubType, weights::Weight};
2222
use sp_runtime::{
@@ -126,6 +126,10 @@ pub trait CallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>:
126126
_ => return Ok(ValidTransaction::default()),
127127
};
128128

129+
if Pallet::<T, I>::ensure_not_halted().is_err() {
130+
return InvalidTransaction::Call.into()
131+
}
132+
129133
match SubmitFinalityProofHelper::<T, I>::check_obsolete(finality_target.block_number) {
130134
Ok(_) => Ok(ValidTransaction::default()),
131135
Err(Error::<T, I>::OldHeader) => InvalidTransaction::Stale.into(),
@@ -192,10 +196,10 @@ mod tests {
192196
use crate::{
193197
call_ext::CallSubType,
194198
mock::{run_test, test_header, RuntimeCall, TestBridgedChain, TestNumber, TestRuntime},
195-
BestFinalized, Config, WeightInfo,
199+
BestFinalized, Config, PalletOperatingMode, WeightInfo,
196200
};
197201
use bp_header_chain::ChainWithGrandpa;
198-
use bp_runtime::HeaderId;
202+
use bp_runtime::{BasicOperatingMode, HeaderId};
199203
use bp_test_utils::{
200204
make_default_justification, make_justification_for_header, JustificationGeneratorParams,
201205
};
@@ -238,6 +242,17 @@ mod tests {
238242
});
239243
}
240244

245+
#[test]
246+
fn extension_rejects_new_header_if_pallet_is_halted() {
247+
run_test(|| {
248+
// when pallet is halted => tx is rejected
249+
sync_to_header_10();
250+
PalletOperatingMode::<TestRuntime, ()>::put(BasicOperatingMode::Halted);
251+
252+
assert!(!validate_block_submit(15));
253+
});
254+
}
255+
241256
#[test]
242257
fn extension_accepts_new_header() {
243258
run_test(|| {

bridges/modules/parachains/src/call_ext.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use crate::{Config, Pallet, RelayBlockNumber};
1818
use bp_parachains::BestParaHeadHash;
1919
use bp_polkadot_core::parachains::{ParaHash, ParaId};
20+
use bp_runtime::OwnedBridgeModule;
2021
use frame_support::{dispatch::CallableCallFor, traits::IsSubType};
2122
use sp_runtime::{
2223
transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
@@ -141,6 +142,10 @@ pub trait CallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>:
141142
None => return Ok(ValidTransaction::default()),
142143
};
143144

145+
if Pallet::<T, I>::ensure_not_halted().is_err() {
146+
return InvalidTransaction::Call.into()
147+
}
148+
144149
if SubmitParachainHeadsHelper::<T, I>::is_obsolete(&update) {
145150
return InvalidTransaction::Stale.into()
146151
}
@@ -160,10 +165,11 @@ where
160165
mod tests {
161166
use crate::{
162167
mock::{run_test, RuntimeCall, TestRuntime},
163-
CallSubType, ParaInfo, ParasInfo, RelayBlockNumber,
168+
CallSubType, PalletOperatingMode, ParaInfo, ParasInfo, RelayBlockNumber,
164169
};
165170
use bp_parachains::BestParaHeadHash;
166171
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
172+
use bp_runtime::BasicOperatingMode;
167173

168174
fn validate_submit_parachain_heads(
169175
num: RelayBlockNumber,
@@ -221,6 +227,17 @@ mod tests {
221227
});
222228
}
223229

230+
#[test]
231+
fn extension_rejects_header_if_pallet_is_halted() {
232+
run_test(|| {
233+
// when pallet is halted => tx is rejected
234+
sync_to_relay_header_10();
235+
PalletOperatingMode::<TestRuntime, ()>::put(BasicOperatingMode::Halted);
236+
237+
assert!(!validate_submit_parachain_heads(15, vec![(ParaId(1), [2u8; 32].into())]));
238+
});
239+
}
240+
224241
#[test]
225242
fn extension_accepts_new_header() {
226243
run_test(|| {

0 commit comments

Comments
 (0)