@@ -50,7 +50,7 @@ use bp_messages::{
5050 source_chain:: { LaneMessageVerifier , MessageDeliveryAndDispatchPayment , RelayersRewards , TargetHeaderChain } ,
5151 target_chain:: { DispatchMessage , MessageDispatch , ProvedLaneMessages , ProvedMessages , SourceHeaderChain } ,
5252 total_unrewarded_messages, InboundLaneData , LaneId , MessageData , MessageKey , MessageNonce , MessagePayload ,
53- OutboundLaneData , Parameter as MessagesParameter , UnrewardedRelayersState ,
53+ OperatingMode , OutboundLaneData , Parameter as MessagesParameter , UnrewardedRelayersState ,
5454} ;
5555use bp_runtime:: Size ;
5656use codec:: { Decode , Encode } ;
@@ -198,8 +198,10 @@ decl_storage! {
198198 /// runtime methods may still be used to do that (i.e. democracy::referendum to update halt
199199 /// flag directly or call the `halt_operations`).
200200 pub PalletOwner get( fn module_owner) : Option <T :: AccountId >;
201- /// If true, all pallet transactions are failed immediately.
202- pub IsHalted get( fn is_halted) config( ) : bool ;
201+ /// The current operating mode of the pallet.
202+ ///
203+ /// Depending on the mode either all, some, or no transactions will be allowed.
204+ pub PalletOperatingMode get( fn operating_mode) config( ) : OperatingMode ;
203205 /// Map of lane id => inbound lane data.
204206 pub InboundLanes : map hasher( blake2_128_concat) LaneId => InboundLaneData <T :: InboundRelayer >;
205207 /// Map of lane id => outbound lane data.
@@ -266,19 +268,18 @@ decl_module! {
266268 }
267269 }
268270
269- /// Halt or resume all pallet operations.
271+ /// Halt or resume all/some pallet operations.
270272 ///
271273 /// May only be called either by root, or by `PalletOwner`.
272274 #[ weight = ( T :: DbWeight :: get( ) . reads_writes( 1 , 1 ) , DispatchClass :: Operational ) ]
273- pub fn set_operational ( origin, operational : bool ) {
275+ pub fn set_operating_mode ( origin, operating_mode : OperatingMode ) {
274276 ensure_owner_or_root:: <T , I >( origin) ?;
275- <IsHalted <I >>:: put( operational) ;
276-
277- if operational {
278- log:: info!( target: "runtime::bridge-messages" , "Resuming pallet operations." ) ;
279- } else {
280- log:: warn!( target: "runtime::bridge-messages" , "Stopping pallet operations." ) ;
281- }
277+ <PalletOperatingMode <I >>:: put( operating_mode) ;
278+ log:: info!(
279+ target: "runtime::bridge-messages" ,
280+ "Setting messages pallet operating mode to {:?}." ,
281+ operating_mode,
282+ ) ;
282283 }
283284
284285 /// Update pallet parameter.
@@ -301,7 +302,7 @@ decl_module! {
301302 payload: T :: OutboundPayload ,
302303 delivery_and_dispatch_fee: T :: OutboundMessageFee ,
303304 ) -> DispatchResult {
304- ensure_operational :: <T , I >( ) ?;
305+ ensure_normal_operating_mode :: <T , I >( ) ?;
305306 let submitter = origin. into( ) . map_err( |_| BadOrigin ) ?;
306307
307308 // let's first check if message can be delivered to target chain
@@ -384,6 +385,7 @@ decl_module! {
384385 nonce: MessageNonce ,
385386 additional_fee: T :: OutboundMessageFee ,
386387 ) -> DispatchResult {
388+ ensure_not_halted:: <T , I >( ) ?;
387389 // if someone tries to pay for already-delivered message, we're rejecting this intention
388390 // (otherwise this additional fee will be locked forever in relayers fund)
389391 //
@@ -441,7 +443,7 @@ decl_module! {
441443 messages_count: u32 ,
442444 dispatch_weight: Weight ,
443445 ) -> DispatchResult {
444- ensure_operational :: <T , I >( ) ?;
446+ ensure_not_halted :: <T , I >( ) ?;
445447 let _ = ensure_signed( origin) ?;
446448
447449 // reject transactions that are declaring too many messages
@@ -532,7 +534,7 @@ decl_module! {
532534 proof: MessagesDeliveryProofOf <T , I >,
533535 relayers_state: UnrewardedRelayersState ,
534536 ) -> DispatchResult {
535- ensure_operational :: <T , I >( ) ?;
537+ ensure_not_halted :: <T , I >( ) ?;
536538
537539 let confirmation_relayer = ensure_signed( origin) ?;
538540 let ( lane_id, lane_data) = T :: TargetHeaderChain :: verify_messages_delivery_proof( proof) . map_err( |err| {
@@ -697,9 +699,18 @@ fn ensure_owner_or_root<T: Config<I>, I: Instance>(origin: T::Origin) -> Result<
697699 }
698700}
699701
700- /// Ensure that the pallet is in operational mode (not halted).
701- fn ensure_operational < T : Config < I > , I : Instance > ( ) -> Result < ( ) , Error < T , I > > {
702- if IsHalted :: < I > :: get ( ) {
702+ /// Ensure that the pallet is in normal operational mode.
703+ fn ensure_normal_operating_mode < T : Config < I > , I : Instance > ( ) -> Result < ( ) , Error < T , I > > {
704+ if PalletOperatingMode :: < I > :: get ( ) != OperatingMode :: Normal {
705+ Err ( Error :: < T , I > :: Halted )
706+ } else {
707+ Ok ( ( ) )
708+ }
709+ }
710+
711+ /// Ensure that the pallet is not halted.
712+ fn ensure_not_halted < T : Config < I > , I : Instance > ( ) -> Result < ( ) , Error < T , I > > {
713+ if PalletOperatingMode :: < I > :: get ( ) == OperatingMode :: Halted {
703714 Err ( Error :: < T , I > :: Halted )
704715 } else {
705716 Ok ( ( ) )
@@ -922,29 +933,41 @@ mod tests {
922933
923934 assert_ok ! ( Pallet :: <TestRuntime >:: set_owner( Origin :: root( ) , Some ( 1 ) ) ) ;
924935 assert_noop ! (
925- Pallet :: <TestRuntime >:: set_operational ( Origin :: signed( 2 ) , false ) ,
936+ Pallet :: <TestRuntime >:: set_operating_mode ( Origin :: signed( 2 ) , OperatingMode :: Halted ) ,
926937 DispatchError :: BadOrigin ,
927938 ) ;
928- assert_ok ! ( Pallet :: <TestRuntime >:: set_operational( Origin :: root( ) , false ) ) ;
939+ assert_ok ! ( Pallet :: <TestRuntime >:: set_operating_mode(
940+ Origin :: root( ) ,
941+ OperatingMode :: Halted
942+ ) ) ;
929943
930944 assert_ok ! ( Pallet :: <TestRuntime >:: set_owner( Origin :: signed( 1 ) , None ) ) ;
931945 assert_noop ! (
932- Pallet :: <TestRuntime >:: set_operational ( Origin :: signed( 1 ) , true ) ,
946+ Pallet :: <TestRuntime >:: set_operating_mode ( Origin :: signed( 1 ) , OperatingMode :: Normal ) ,
933947 DispatchError :: BadOrigin ,
934948 ) ;
935949 assert_noop ! (
936- Pallet :: <TestRuntime >:: set_operational ( Origin :: signed( 2 ) , true ) ,
950+ Pallet :: <TestRuntime >:: set_operating_mode ( Origin :: signed( 2 ) , OperatingMode :: Normal ) ,
937951 DispatchError :: BadOrigin ,
938952 ) ;
939- assert_ok ! ( Pallet :: <TestRuntime >:: set_operational( Origin :: root( ) , true ) ) ;
953+ assert_ok ! ( Pallet :: <TestRuntime >:: set_operating_mode(
954+ Origin :: root( ) ,
955+ OperatingMode :: Normal
956+ ) ) ;
940957 } ) ;
941958 }
942959
943960 #[ test]
944961 fn pallet_may_be_halted_by_root ( ) {
945962 run_test ( || {
946- assert_ok ! ( Pallet :: <TestRuntime >:: set_operational( Origin :: root( ) , false ) ) ;
947- assert_ok ! ( Pallet :: <TestRuntime >:: set_operational( Origin :: root( ) , true ) ) ;
963+ assert_ok ! ( Pallet :: <TestRuntime >:: set_operating_mode(
964+ Origin :: root( ) ,
965+ OperatingMode :: Halted
966+ ) ) ;
967+ assert_ok ! ( Pallet :: <TestRuntime >:: set_operating_mode(
968+ Origin :: root( ) ,
969+ OperatingMode :: Normal
970+ ) ) ;
948971 } ) ;
949972 }
950973
@@ -953,21 +976,30 @@ mod tests {
953976 run_test ( || {
954977 PalletOwner :: < TestRuntime > :: put ( 2 ) ;
955978
956- assert_ok ! ( Pallet :: <TestRuntime >:: set_operational( Origin :: signed( 2 ) , false ) ) ;
957- assert_ok ! ( Pallet :: <TestRuntime >:: set_operational( Origin :: signed( 2 ) , true ) ) ;
979+ assert_ok ! ( Pallet :: <TestRuntime >:: set_operating_mode(
980+ Origin :: signed( 2 ) ,
981+ OperatingMode :: Halted
982+ ) ) ;
983+ assert_ok ! ( Pallet :: <TestRuntime >:: set_operating_mode(
984+ Origin :: signed( 2 ) ,
985+ OperatingMode :: Normal
986+ ) ) ;
958987
959988 assert_noop ! (
960- Pallet :: <TestRuntime >:: set_operational ( Origin :: signed( 1 ) , false ) ,
989+ Pallet :: <TestRuntime >:: set_operating_mode ( Origin :: signed( 1 ) , OperatingMode :: Halted ) ,
961990 DispatchError :: BadOrigin ,
962991 ) ;
963992 assert_noop ! (
964- Pallet :: <TestRuntime >:: set_operational ( Origin :: signed( 1 ) , true ) ,
993+ Pallet :: <TestRuntime >:: set_operating_mode ( Origin :: signed( 1 ) , OperatingMode :: Normal ) ,
965994 DispatchError :: BadOrigin ,
966995 ) ;
967996
968- assert_ok ! ( Pallet :: <TestRuntime >:: set_operational( Origin :: signed( 2 ) , false ) ) ;
997+ assert_ok ! ( Pallet :: <TestRuntime >:: set_operating_mode(
998+ Origin :: signed( 2 ) ,
999+ OperatingMode :: Halted
1000+ ) ) ;
9691001 assert_noop ! (
970- Pallet :: <TestRuntime >:: set_operational ( Origin :: signed( 1 ) , true ) ,
1002+ Pallet :: <TestRuntime >:: set_operating_mode ( Origin :: signed( 1 ) , OperatingMode :: Normal ) ,
9711003 DispatchError :: BadOrigin ,
9721004 ) ;
9731005 } ) ;
@@ -1074,7 +1106,7 @@ mod tests {
10741106 // send message first to be able to check that delivery_proof fails later
10751107 send_regular_message ( ) ;
10761108
1077- IsHalted :: < DefaultInstance > :: put ( true ) ;
1109+ PalletOperatingMode :: < DefaultInstance > :: put ( OperatingMode :: Halted ) ;
10781110
10791111 assert_noop ! (
10801112 Pallet :: <TestRuntime >:: send_message(
@@ -1086,6 +1118,11 @@ mod tests {
10861118 Error :: <TestRuntime , DefaultInstance >:: Halted ,
10871119 ) ;
10881120
1121+ assert_noop ! (
1122+ Pallet :: <TestRuntime >:: increase_message_fee( Origin :: signed( 1 ) , TEST_LANE_ID , 1 , 1 , ) ,
1123+ Error :: <TestRuntime , DefaultInstance >:: Halted ,
1124+ ) ;
1125+
10891126 assert_noop ! (
10901127 Pallet :: <TestRuntime >:: receive_messages_proof(
10911128 Origin :: signed( 1 ) ,
@@ -1114,6 +1151,53 @@ mod tests {
11141151 } ) ;
11151152 }
11161153
1154+ #[ test]
1155+ fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode ( ) {
1156+ run_test ( || {
1157+ // send message first to be able to check that delivery_proof fails later
1158+ send_regular_message ( ) ;
1159+
1160+ PalletOperatingMode :: < DefaultInstance > :: put ( OperatingMode :: RejectingOutboundMessages ) ;
1161+
1162+ assert_noop ! (
1163+ Pallet :: <TestRuntime >:: send_message(
1164+ Origin :: signed( 1 ) ,
1165+ TEST_LANE_ID ,
1166+ REGULAR_PAYLOAD ,
1167+ REGULAR_PAYLOAD . 1 ,
1168+ ) ,
1169+ Error :: <TestRuntime , DefaultInstance >:: Halted ,
1170+ ) ;
1171+
1172+ assert_ok ! ( Pallet :: <TestRuntime >:: increase_message_fee(
1173+ Origin :: signed( 1 ) ,
1174+ TEST_LANE_ID ,
1175+ 1 ,
1176+ 1 ,
1177+ ) ) ;
1178+
1179+ assert_ok ! ( Pallet :: <TestRuntime >:: receive_messages_proof(
1180+ Origin :: signed( 1 ) ,
1181+ TEST_RELAYER_A ,
1182+ Ok ( vec![ message( 1 , REGULAR_PAYLOAD ) ] ) . into( ) ,
1183+ 1 ,
1184+ REGULAR_PAYLOAD . 1 ,
1185+ ) , ) ;
1186+
1187+ assert_ok ! ( Pallet :: <TestRuntime >:: receive_messages_delivery_proof(
1188+ Origin :: signed( 1 ) ,
1189+ TestMessagesDeliveryProof ( Ok ( (
1190+ TEST_LANE_ID ,
1191+ InboundLaneData {
1192+ last_confirmed_nonce: 1 ,
1193+ ..Default :: default ( )
1194+ } ,
1195+ ) ) ) ,
1196+ Default :: default ( ) ,
1197+ ) ) ;
1198+ } ) ;
1199+ }
1200+
11171201 #[ test]
11181202 fn send_message_works ( ) {
11191203 run_test ( || {
0 commit comments