1919//! <BridgedName> chain.
2020
2121use crate :: messages_lane:: SubstrateMessageLane ;
22+ use crate :: messages_target:: SubstrateMessagesReceivingProof ;
2223use crate :: on_demand_headers:: OnDemandHeadersRelay ;
2324
2425use async_trait:: async_trait;
25- use bp_messages:: { LaneId , MessageNonce } ;
26+ use bp_messages:: { LaneId , MessageNonce , UnrewardedRelayersState } ;
2627use bp_runtime:: { messages:: DispatchFeePayment , ChainId } ;
27- use bridge_runtime_common:: messages:: target:: FromBridgedChainMessagesProof ;
28+ use bridge_runtime_common:: messages:: {
29+ source:: FromBridgedChainMessagesDeliveryProof , target:: FromBridgedChainMessagesProof ,
30+ } ;
2831use codec:: { Decode , Encode } ;
2932use frame_support:: { traits:: Instance , weights:: Weight } ;
3033use messages_relay:: {
@@ -33,6 +36,7 @@ use messages_relay::{
3336 ClientState , MessageDetails , MessageDetailsMap , MessageProofParameters , SourceClient , SourceClientState ,
3437 } ,
3538} ;
39+ use num_traits:: { Bounded , Zero } ;
3640use relay_substrate_client:: { Chain , Client , Error as SubstrateError , HashOf , HeaderIdOf } ;
3741use relay_utils:: { relay_loop:: Client as RelayClient , BlockNumberBase , HeaderId } ;
3842use sp_core:: Bytes ;
@@ -45,23 +49,23 @@ use std::{marker::PhantomData, ops::RangeInclusive};
4549pub type SubstrateMessagesProof < C > = ( Weight , FromBridgedChainMessagesProof < HashOf < C > > ) ;
4650
4751/// Substrate client as Substrate messages source.
48- pub struct SubstrateMessagesSource < C : Chain , P : SubstrateMessageLane , I > {
49- client : Client < C > ,
52+ pub struct SubstrateMessagesSource < SC : Chain , TC : Chain , P : SubstrateMessageLane , I > {
53+ client : Client < SC > ,
5054 lane : P ,
5155 lane_id : LaneId ,
5256 instance : ChainId ,
53- target_to_source_headers_relay : Option < OnDemandHeadersRelay < P :: TargetChain > > ,
57+ target_to_source_headers_relay : Option < OnDemandHeadersRelay < TC > > ,
5458 _phantom : PhantomData < I > ,
5559}
5660
57- impl < C : Chain , P : SubstrateMessageLane , I > SubstrateMessagesSource < C , P , I > {
61+ impl < SC : Chain , TC : Chain , P : SubstrateMessageLane , I > SubstrateMessagesSource < SC , TC , P , I > {
5862 /// Create new Substrate headers source.
5963 pub fn new (
60- client : Client < C > ,
64+ client : Client < SC > ,
6165 lane : P ,
6266 lane_id : LaneId ,
6367 instance : ChainId ,
64- target_to_source_headers_relay : Option < OnDemandHeadersRelay < P :: TargetChain > > ,
68+ target_to_source_headers_relay : Option < OnDemandHeadersRelay < TC > > ,
6569 ) -> Self {
6670 SubstrateMessagesSource {
6771 client,
@@ -74,7 +78,7 @@ impl<C: Chain, P: SubstrateMessageLane, I> SubstrateMessagesSource<C, P, I> {
7478 }
7579}
7680
77- impl < C : Chain , P : SubstrateMessageLane , I > Clone for SubstrateMessagesSource < C , P , I > {
81+ impl < SC : Chain , TC : Chain , P : SubstrateMessageLane , I > Clone for SubstrateMessagesSource < SC , TC , P , I > {
7882 fn clone ( & self ) -> Self {
7983 Self {
8084 client : self . client . clone ( ) ,
@@ -88,9 +92,10 @@ impl<C: Chain, P: SubstrateMessageLane, I> Clone for SubstrateMessagesSource<C,
8892}
8993
9094#[ async_trait]
91- impl < C , P , I > RelayClient for SubstrateMessagesSource < C , P , I >
95+ impl < SC , TC , P , I > RelayClient for SubstrateMessagesSource < SC , TC , P , I >
9296where
93- C : Chain ,
97+ SC : Chain ,
98+ TC : Chain ,
9499 P : SubstrateMessageLane ,
95100 I : Send + Sync + Instance ,
96101{
@@ -102,20 +107,22 @@ where
102107}
103108
104109#[ async_trait]
105- impl < C , P , I > SourceClient < P > for SubstrateMessagesSource < C , P , I >
110+ impl < SC , TC , P , I > SourceClient < P > for SubstrateMessagesSource < SC , TC , P , I >
106111where
107- C : Chain ,
108- C :: Header : DeserializeOwned ,
109- C :: Index : DeserializeOwned ,
110- C :: BlockNumber : BlockNumberBase ,
112+ SC : Chain < Hash = P :: SourceHeaderHash , BlockNumber = P :: SourceHeaderNumber , Balance = P :: SourceChainBalance > ,
113+ SC :: Hash : Copy ,
114+ SC :: BlockNumber : Copy ,
115+ SC :: Balance : Decode + Bounded ,
116+ SC :: Header : DeserializeOwned ,
117+ SC :: Index : DeserializeOwned ,
118+ SC :: BlockNumber : BlockNumberBase ,
119+ TC : Chain < Hash = P :: TargetHeaderHash , BlockNumber = P :: TargetHeaderNumber > ,
111120 P : SubstrateMessageLane <
112- MessagesProof = SubstrateMessagesProof < C > ,
113- SourceChainBalance = C :: Balance ,
114- SourceHeaderNumber = <C :: Header as HeaderT >:: Number ,
115- SourceHeaderHash = <C :: Header as HeaderT >:: Hash ,
116- SourceChain = C ,
121+ MessagesProof = SubstrateMessagesProof < SC > ,
122+ MessagesReceivingProof = SubstrateMessagesReceivingProof < TC > ,
123+ SourceChain = SC ,
124+ TargetChain = TC ,
117125 > ,
118- P :: TargetChain : Chain < Hash = P :: TargetHeaderHash , BlockNumber = P :: TargetHeaderNumber > ,
119126 P :: TargetHeaderNumber : Decode ,
120127 P :: TargetHeaderHash : Decode ,
121128 I : Send + Sync + Instance ,
@@ -180,7 +187,7 @@ where
180187 )
181188 . await ?;
182189
183- make_message_details_map :: < C > (
190+ make_message_details_map :: < SC > (
184191 Decode :: decode ( & mut & encoded_response. 0 [ ..] ) . map_err ( SubstrateError :: ResponseParseFailed ) ?,
185192 nonces,
186193 )
@@ -242,10 +249,40 @@ where
242249 }
243250
244251 async fn estimate_confirmation_transaction ( & self ) -> P :: SourceChainBalance {
245- num_traits:: Zero :: zero ( ) // TODO: https://github.com/paritytech/parity-bridges-common/issues/997
252+ self . client
253+ . estimate_extrinsic_fee ( self . lane . make_messages_receiving_proof_transaction (
254+ Zero :: zero ( ) ,
255+ HeaderId ( Default :: default ( ) , Default :: default ( ) ) ,
256+ prepare_dummy_messages_delivery_proof :: < SC , TC > ( ) ,
257+ ) )
258+ . await
259+ . unwrap_or_else ( |_| SC :: Balance :: max_value ( ) )
246260 }
247261}
248262
263+ /// Prepare 'dummy' messages delivery proof that will compose the delivery confirmation transaction.
264+ ///
265+ /// We don't care about proof actually being the valid proof, because its validity doesn't
266+ /// affect the call weight - we only care about its size.
267+ fn prepare_dummy_messages_delivery_proof < SC : Chain , TC : Chain > ( ) -> SubstrateMessagesReceivingProof < TC > {
268+ let single_message_confirmation_size =
269+ bp_messages:: InboundLaneData :: < ( ) > :: encoded_size_hint ( SC :: MAXIMAL_ENCODED_ACCOUNT_ID_SIZE , 1 , 1 )
270+ . unwrap_or ( u32:: MAX ) ;
271+ let proof_size = TC :: STORAGE_PROOF_OVERHEAD . saturating_add ( single_message_confirmation_size) ;
272+ (
273+ UnrewardedRelayersState {
274+ unrewarded_relayer_entries : 1 ,
275+ messages_in_oldest_entry : 1 ,
276+ total_messages : 1 ,
277+ } ,
278+ FromBridgedChainMessagesDeliveryProof {
279+ bridged_header_hash : Default :: default ( ) ,
280+ storage_proof : vec ! [ vec![ 0 ; proof_size as usize ] ] ,
281+ lane : Default :: default ( ) ,
282+ } ,
283+ )
284+ }
285+
249286pub async fn read_client_state < SelfChain , BridgedHeaderHash , BridgedHeaderNumber > (
250287 self_client : & Client < SelfChain > ,
251288 best_finalized_header_id_method_name : & str ,
@@ -295,7 +332,7 @@ fn make_message_details_map<C: Chain>(
295332) -> Result < MessageDetailsMap < C :: Balance > , SubstrateError > {
296333 let make_missing_nonce_error = |expected_nonce| {
297334 Err ( SubstrateError :: Custom ( format ! (
298- "Missing nonce {} in messages_dispatch_weight call result. Expected all nonces from {:?}" ,
335+ "Missing nonce {} in message_details call result. Expected all nonces from {:?}" ,
299336 expected_nonce, nonces,
300337 ) ) )
301338 } ;
@@ -346,8 +383,7 @@ fn make_message_details_map<C: Chain>(
346383 MessageDetails {
347384 dispatch_weight : details. dispatch_weight ,
348385 size : details. size as _ ,
349- // TODO: https://github.com/paritytech/parity-bridges-common/issues/997
350- reward : num_traits:: Zero :: zero ( ) ,
386+ reward : details. delivery_and_dispatch_fee ,
351387 dispatch_fee_payment : DispatchFeePayment :: AtSourceChain ,
352388 } ,
353389 ) ;
@@ -361,6 +397,9 @@ fn make_message_details_map<C: Chain>(
361397#[ cfg( test) ]
362398mod tests {
363399 use super :: * ;
400+ use bp_runtime:: messages:: DispatchFeePayment ;
401+ use relay_millau_client:: Millau ;
402+ use relay_rialto_client:: Rialto ;
364403
365404 fn message_details_from_rpc (
366405 nonces : RangeInclusive < MessageNonce > ,
@@ -469,4 +508,16 @@ mod tests {
469508 Err ( SubstrateError :: Custom ( _) )
470509 ) ) ;
471510 }
511+
512+ #[ test]
513+ fn prepare_dummy_messages_delivery_proof_works ( ) {
514+ let expected_minimal_size = Rialto :: MAXIMAL_ENCODED_ACCOUNT_ID_SIZE + Millau :: STORAGE_PROOF_OVERHEAD ;
515+ let dummy_proof = prepare_dummy_messages_delivery_proof :: < Rialto , Millau > ( ) ;
516+ assert ! (
517+ dummy_proof. 1 . encode( ) . len( ) as u32 > expected_minimal_size,
518+ "Expected proof size at least {}. Got: {}" ,
519+ expected_minimal_size,
520+ dummy_proof. 1 . encode( ) . len( ) ,
521+ ) ;
522+ }
472523}
0 commit comments