@@ -22,25 +22,57 @@ use frame_support::{dispatch::CallableCallFor, traits::IsSubType, RuntimeDebug};
2222use pallet_bridge_messages:: { Config , Pallet } ;
2323use sp_runtime:: transaction_validity:: TransactionValidity ;
2424
25- /// Info about a `ReceiveMessagesProof` call which tries to update a single lane .
25+ /// Generic info about a messages delivery/confirmation proof .
2626#[ derive( PartialEq , RuntimeDebug ) ]
27- pub struct ReceiveMessagesProofInfo {
27+ pub struct BaseMessagesProofInfo {
2828 pub lane_id : LaneId ,
29- pub best_proof_nonce : MessageNonce ,
29+ pub best_bundled_nonce : MessageNonce ,
3030 pub best_stored_nonce : MessageNonce ,
3131}
3232
33- /// Helper struct that provides methods for working with the `ReceiveMessagesProof` call.
34- pub struct ReceiveMessagesProofHelper < T : Config < I > , I : ' static > {
33+ impl BaseMessagesProofInfo {
34+ fn is_obsolete ( & self ) -> bool {
35+ self . best_bundled_nonce <= self . best_stored_nonce
36+ }
37+ }
38+
39+ /// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
40+ #[ derive( PartialEq , RuntimeDebug ) ]
41+ pub struct ReceiveMessagesProofInfo ( pub BaseMessagesProofInfo ) ;
42+
43+ /// Info about a `ReceiveMessagesDeliveryProof` call which tries to update a single lane.
44+ #[ derive( PartialEq , RuntimeDebug ) ]
45+ pub struct ReceiveMessagesDeliveryProofInfo ( pub BaseMessagesProofInfo ) ;
46+
47+ /// Info about a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call
48+ /// which tries to update a single lane.
49+ #[ derive( PartialEq , RuntimeDebug ) ]
50+ pub enum CallInfo {
51+ ReceiveMessagesProof ( ReceiveMessagesProofInfo ) ,
52+ ReceiveMessagesDeliveryProof ( ReceiveMessagesDeliveryProofInfo ) ,
53+ }
54+
55+ /// Helper struct that provides methods for working with a call supported by `CallInfo`.
56+ pub struct CallHelper < T : Config < I > , I : ' static > {
3557 pub _phantom_data : sp_std:: marker:: PhantomData < ( T , I ) > ,
3658}
3759
38- impl < T : Config < I > , I : ' static > ReceiveMessagesProofHelper < T , I > {
39- /// Check if the `ReceiveMessagesProof` call delivered at least some of the messages that
40- /// it contained.
41- pub fn was_partially_successful ( info : & ReceiveMessagesProofInfo ) -> bool {
42- let inbound_lane_data = pallet_bridge_messages:: InboundLanes :: < T , I > :: get ( info. lane_id ) ;
43- inbound_lane_data. last_delivered_nonce ( ) > info. best_stored_nonce
60+ impl < T : Config < I > , I : ' static > CallHelper < T , I > {
61+ /// Check if a call delivered proof/confirmation for at least some of the messages that it
62+ /// contained.
63+ pub fn was_partially_successful ( info : & CallInfo ) -> bool {
64+ match info {
65+ CallInfo :: ReceiveMessagesProof ( info) => {
66+ let inbound_lane_data =
67+ pallet_bridge_messages:: InboundLanes :: < T , I > :: get ( info. 0 . lane_id ) ;
68+ inbound_lane_data. last_delivered_nonce ( ) > info. 0 . best_stored_nonce
69+ } ,
70+ CallInfo :: ReceiveMessagesDeliveryProof ( info) => {
71+ let outbound_lane_data =
72+ pallet_bridge_messages:: OutboundLanes :: < T , I > :: get ( info. 0 . lane_id ) ;
73+ outbound_lane_data. latest_received_nonce > info. 0 . best_stored_nonce
74+ } ,
75+ }
4476 }
4577}
4678
@@ -51,17 +83,21 @@ pub trait MessagesCallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>:
5183 /// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call.
5284 fn receive_messages_proof_info ( & self ) -> Option < ReceiveMessagesProofInfo > ;
5385
54- /// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call,
55- /// if the call is for the provided lane.
56- fn receive_messages_proof_info_for ( & self , lane_id : LaneId ) -> Option < ReceiveMessagesProofInfo > ;
86+ /// Create a new instance of `ReceiveMessagesDeliveryProofInfo` from
87+ /// a `ReceiveMessagesDeliveryProof` call.
88+ fn receive_messages_delivery_proof_info ( & self ) -> Option < ReceiveMessagesDeliveryProofInfo > ;
89+
90+ /// Create a new instance of `CallInfo` from a `ReceiveMessagesProof`
91+ /// or a `ReceiveMessagesDeliveryProof` call.
92+ fn call_info ( & self ) -> Option < CallInfo > ;
5793
58- /// Check that a `ReceiveMessagesProof` call is trying to deliver at least some messages that
59- /// are better than the ones we know of .
60- fn check_obsolete_receive_messages_proof ( & self ) -> TransactionValidity ;
94+ /// Create a new instance of `CallInfo` from a `ReceiveMessagesProof`
95+ /// or a `ReceiveMessagesDeliveryProof` call, if the call is for the provided lane .
96+ fn call_info_for ( & self , lane_id : LaneId ) -> Option < CallInfo > ;
6197
62- /// Check that a `ReceiveMessagesDeliveryProof` call is trying to deliver at least some message
63- /// confirmations that are better than the ones we know of.
64- fn check_obsolete_receive_messages_delivery_proof ( & self ) -> TransactionValidity ;
98+ /// Check that a `ReceiveMessagesProof` or a ` ReceiveMessagesDeliveryProof` call is trying
99+ /// to deliver/confirm at least some messages that are better than the ones we know of.
100+ fn check_obsolete_call ( & self ) -> TransactionValidity ;
65101}
66102
67103impl <
@@ -88,59 +124,80 @@ impl<
88124 {
89125 let inbound_lane_data = pallet_bridge_messages:: InboundLanes :: < T , I > :: get ( proof. lane ) ;
90126
91- return Some ( ReceiveMessagesProofInfo {
127+ return Some ( ReceiveMessagesProofInfo ( BaseMessagesProofInfo {
92128 lane_id : proof. lane ,
93- best_proof_nonce : proof. nonces_end ,
129+ best_bundled_nonce : proof. nonces_end ,
94130 best_stored_nonce : inbound_lane_data. last_delivered_nonce ( ) ,
95- } )
131+ } ) )
96132 }
97133
98134 None
99135 }
100136
101- fn receive_messages_proof_info_for ( & self , lane_id : LaneId ) -> Option < ReceiveMessagesProofInfo > {
102- self . receive_messages_proof_info ( ) . filter ( |info| info. lane_id == lane_id)
103- }
104-
105- fn check_obsolete_receive_messages_proof ( & self ) -> TransactionValidity {
106- if let Some ( proof_info) = self . receive_messages_proof_info ( ) {
107- if proof_info. best_proof_nonce <= proof_info. best_stored_nonce {
108- log:: trace!(
109- target: pallet_bridge_messages:: LOG_TARGET ,
110- "Rejecting obsolete messages delivery transaction: \
111- lane {:?}, bundled {:?}, best {:?}",
112- proof_info. lane_id,
113- proof_info. best_proof_nonce,
114- proof_info. best_stored_nonce,
115- ) ;
116-
117- return sp_runtime:: transaction_validity:: InvalidTransaction :: Stale . into ( )
118- }
119- }
120-
121- Ok ( sp_runtime:: transaction_validity:: ValidTransaction :: default ( ) )
122- }
123-
124- fn check_obsolete_receive_messages_delivery_proof ( & self ) -> TransactionValidity {
137+ fn receive_messages_delivery_proof_info ( & self ) -> Option < ReceiveMessagesDeliveryProofInfo > {
125138 if let Some ( pallet_bridge_messages:: Call :: < T , I > :: receive_messages_delivery_proof {
126139 ref proof,
127140 ref relayers_state,
128141 ..
129142 } ) = self . is_sub_type ( )
130143 {
131144 let outbound_lane_data = pallet_bridge_messages:: OutboundLanes :: < T , I > :: get ( proof. lane ) ;
132- if relayers_state. last_delivered_nonce <= outbound_lane_data. latest_received_nonce {
145+
146+ return Some ( ReceiveMessagesDeliveryProofInfo ( BaseMessagesProofInfo {
147+ lane_id : proof. lane ,
148+ best_bundled_nonce : relayers_state. last_delivered_nonce ,
149+ best_stored_nonce : outbound_lane_data. latest_received_nonce ,
150+ } ) )
151+ }
152+
153+ None
154+ }
155+
156+ fn call_info ( & self ) -> Option < CallInfo > {
157+ if let Some ( info) = self . receive_messages_proof_info ( ) {
158+ return Some ( CallInfo :: ReceiveMessagesProof ( info) )
159+ }
160+
161+ if let Some ( info) = self . receive_messages_delivery_proof_info ( ) {
162+ return Some ( CallInfo :: ReceiveMessagesDeliveryProof ( info) )
163+ }
164+
165+ None
166+ }
167+
168+ fn call_info_for ( & self , lane_id : LaneId ) -> Option < CallInfo > {
169+ self . call_info ( ) . filter ( |info| {
170+ let actual_lane_id = match info {
171+ CallInfo :: ReceiveMessagesProof ( info) => info. 0 . lane_id ,
172+ CallInfo :: ReceiveMessagesDeliveryProof ( info) => info. 0 . lane_id ,
173+ } ;
174+ actual_lane_id == lane_id
175+ } )
176+ }
177+
178+ fn check_obsolete_call ( & self ) -> TransactionValidity {
179+ match self . call_info ( ) {
180+ Some ( CallInfo :: ReceiveMessagesProof ( proof_info) ) if proof_info. 0 . is_obsolete ( ) => {
133181 log:: trace!(
134182 target: pallet_bridge_messages:: LOG_TARGET ,
135- "Rejecting obsolete messages confirmation transaction: \
136- lane {:?}, bundled {:?}, best {:?}",
137- proof. lane,
138- relayers_state. last_delivered_nonce,
139- outbound_lane_data. latest_received_nonce,
183+ "Rejecting obsolete messages delivery transaction: {:?}" ,
184+ proof_info
140185 ) ;
141186
142187 return sp_runtime:: transaction_validity:: InvalidTransaction :: Stale . into ( )
143- }
188+ } ,
189+ Some ( CallInfo :: ReceiveMessagesDeliveryProof ( proof_info) )
190+ if proof_info. 0 . is_obsolete ( ) =>
191+ {
192+ log:: trace!(
193+ target: pallet_bridge_messages:: LOG_TARGET ,
194+ "Rejecting obsolete messages confirmation transaction: {:?}" ,
195+ proof_info,
196+ ) ;
197+
198+ return sp_runtime:: transaction_validity:: InvalidTransaction :: Stale . into ( )
199+ } ,
200+ _ => { } ,
144201 }
145202
146203 Ok ( sp_runtime:: transaction_validity:: ValidTransaction :: default ( ) )
@@ -153,8 +210,8 @@ mod tests {
153210 messages:: {
154211 source:: FromBridgedChainMessagesDeliveryProof , target:: FromBridgedChainMessagesProof ,
155212 } ,
213+ messages_call_ext:: MessagesCallSubType ,
156214 mock:: { TestRuntime , ThisChainRuntimeCall } ,
157- BridgeRuntimeFilterCall ,
158215 } ;
159216 use bp_messages:: UnrewardedRelayersState ;
160217
@@ -169,22 +226,21 @@ mod tests {
169226 nonces_start : bp_messages:: MessageNonce ,
170227 nonces_end : bp_messages:: MessageNonce ,
171228 ) -> bool {
172- pallet_bridge_messages:: Pallet :: < TestRuntime > :: validate (
173- & ThisChainRuntimeCall :: BridgeMessages (
174- pallet_bridge_messages:: Call :: < TestRuntime , ( ) > :: receive_messages_proof {
175- relayer_id_at_bridged_chain : 42 ,
176- messages_count : ( nonces_end - nonces_start + 1 ) as u32 ,
177- dispatch_weight : frame_support:: weights:: Weight :: zero ( ) ,
178- proof : FromBridgedChainMessagesProof {
179- bridged_header_hash : Default :: default ( ) ,
180- storage_proof : vec ! [ ] ,
181- lane : bp_messages:: LaneId ( [ 0 , 0 , 0 , 0 ] ) ,
182- nonces_start,
183- nonces_end,
184- } ,
229+ ThisChainRuntimeCall :: BridgeMessages (
230+ pallet_bridge_messages:: Call :: < TestRuntime , ( ) > :: receive_messages_proof {
231+ relayer_id_at_bridged_chain : 42 ,
232+ messages_count : ( nonces_end - nonces_start + 1 ) as u32 ,
233+ dispatch_weight : frame_support:: weights:: Weight :: zero ( ) ,
234+ proof : FromBridgedChainMessagesProof {
235+ bridged_header_hash : Default :: default ( ) ,
236+ storage_proof : vec ! [ ] ,
237+ lane : bp_messages:: LaneId ( [ 0 , 0 , 0 , 0 ] ) ,
238+ nonces_start,
239+ nonces_end,
185240 } ,
186- ) ,
241+ } ,
187242 )
243+ . check_obsolete_call ( )
188244 . is_ok ( )
189245 }
190246
@@ -230,21 +286,20 @@ mod tests {
230286 }
231287
232288 fn validate_message_confirmation ( last_delivered_nonce : bp_messages:: MessageNonce ) -> bool {
233- pallet_bridge_messages:: Pallet :: < TestRuntime > :: validate (
234- & ThisChainRuntimeCall :: BridgeMessages (
235- pallet_bridge_messages:: Call :: < TestRuntime > :: receive_messages_delivery_proof {
236- proof : FromBridgedChainMessagesDeliveryProof {
237- bridged_header_hash : Default :: default ( ) ,
238- storage_proof : Vec :: new ( ) ,
239- lane : bp_messages:: LaneId ( [ 0 , 0 , 0 , 0 ] ) ,
240- } ,
241- relayers_state : UnrewardedRelayersState {
242- last_delivered_nonce,
243- ..Default :: default ( )
244- } ,
289+ ThisChainRuntimeCall :: BridgeMessages (
290+ pallet_bridge_messages:: Call :: < TestRuntime > :: receive_messages_delivery_proof {
291+ proof : FromBridgedChainMessagesDeliveryProof {
292+ bridged_header_hash : Default :: default ( ) ,
293+ storage_proof : Vec :: new ( ) ,
294+ lane : bp_messages:: LaneId ( [ 0 , 0 , 0 , 0 ] ) ,
295+ } ,
296+ relayers_state : UnrewardedRelayersState {
297+ last_delivered_nonce,
298+ ..Default :: default ( )
245299 } ,
246- ) ,
300+ } ,
247301 )
302+ . check_obsolete_call ( )
248303 . is_ok ( )
249304 }
250305
0 commit comments