@@ -22,25 +22,57 @@ use frame_support::{dispatch::CallableCallFor, traits::IsSubType, RuntimeDebug};
22
22
use pallet_bridge_messages:: { Config , Pallet } ;
23
23
use sp_runtime:: transaction_validity:: TransactionValidity ;
24
24
25
- /// Info about a `ReceiveMessagesProof` call which tries to update a single lane .
25
+ /// Generic info about a messages delivery/confirmation proof .
26
26
#[ derive( PartialEq , RuntimeDebug ) ]
27
- pub struct ReceiveMessagesProofInfo {
27
+ pub struct BaseMessagesProofInfo {
28
28
pub lane_id : LaneId ,
29
- pub best_proof_nonce : MessageNonce ,
29
+ pub best_bundled_nonce : MessageNonce ,
30
30
pub best_stored_nonce : MessageNonce ,
31
31
}
32
32
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 > {
35
57
pub _phantom_data : sp_std:: marker:: PhantomData < ( T , I ) > ,
36
58
}
37
59
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
+ }
44
76
}
45
77
}
46
78
@@ -51,17 +83,21 @@ pub trait MessagesCallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>:
51
83
/// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call.
52
84
fn receive_messages_proof_info ( & self ) -> Option < ReceiveMessagesProofInfo > ;
53
85
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 > ;
57
93
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 > ;
61
97
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 ;
65
101
}
66
102
67
103
impl <
@@ -88,59 +124,80 @@ impl<
88
124
{
89
125
let inbound_lane_data = pallet_bridge_messages:: InboundLanes :: < T , I > :: get ( proof. lane ) ;
90
126
91
- return Some ( ReceiveMessagesProofInfo {
127
+ return Some ( ReceiveMessagesProofInfo ( BaseMessagesProofInfo {
92
128
lane_id : proof. lane ,
93
- best_proof_nonce : proof. nonces_end ,
129
+ best_bundled_nonce : proof. nonces_end ,
94
130
best_stored_nonce : inbound_lane_data. last_delivered_nonce ( ) ,
95
- } )
131
+ } ) )
96
132
}
97
133
98
134
None
99
135
}
100
136
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 > {
125
138
if let Some ( pallet_bridge_messages:: Call :: < T , I > :: receive_messages_delivery_proof {
126
139
ref proof,
127
140
ref relayers_state,
128
141
..
129
142
} ) = self . is_sub_type ( )
130
143
{
131
144
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 ( ) => {
133
181
log:: trace!(
134
182
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
140
185
) ;
141
186
142
187
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
+ _ => { } ,
144
201
}
145
202
146
203
Ok ( sp_runtime:: transaction_validity:: ValidTransaction :: default ( ) )
@@ -153,8 +210,8 @@ mod tests {
153
210
messages:: {
154
211
source:: FromBridgedChainMessagesDeliveryProof , target:: FromBridgedChainMessagesProof ,
155
212
} ,
213
+ messages_call_ext:: MessagesCallSubType ,
156
214
mock:: { TestRuntime , ThisChainRuntimeCall } ,
157
- BridgeRuntimeFilterCall ,
158
215
} ;
159
216
use bp_messages:: UnrewardedRelayersState ;
160
217
@@ -169,22 +226,21 @@ mod tests {
169
226
nonces_start : bp_messages:: MessageNonce ,
170
227
nonces_end : bp_messages:: MessageNonce ,
171
228
) -> 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,
185
240
} ,
186
- ) ,
241
+ } ,
187
242
)
243
+ . check_obsolete_call ( )
188
244
. is_ok ( )
189
245
}
190
246
@@ -230,21 +286,20 @@ mod tests {
230
286
}
231
287
232
288
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 ( )
245
299
} ,
246
- ) ,
300
+ } ,
247
301
)
302
+ . check_obsolete_call ( )
248
303
. is_ok ( )
249
304
}
250
305
0 commit comments