Skip to content

Commit c34d7a5

Browse files
authored
estimate transaction fee (paritytech#1015)
1 parent 93404b1 commit c34d7a5

File tree

21 files changed

+299
-72
lines changed

21 files changed

+299
-72
lines changed

Cargo.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

relays/bin-substrate/src/chains/millau_messages_to_rialto.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,11 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
127127

128128
/// Millau node as messages source.
129129
type MillauSourceClient =
130-
SubstrateMessagesSource<Millau, MillauMessagesToRialto, millau_runtime::WithRialtoMessagesInstance>;
130+
SubstrateMessagesSource<Millau, Rialto, MillauMessagesToRialto, millau_runtime::WithRialtoMessagesInstance>;
131131

132132
/// Rialto node as messages target.
133133
type RialtoTargetClient =
134-
SubstrateMessagesTarget<Rialto, MillauMessagesToRialto, rialto_runtime::WithMillauMessagesInstance>;
134+
SubstrateMessagesTarget<Millau, Rialto, MillauMessagesToRialto, rialto_runtime::WithMillauMessagesInstance>;
135135

136136
/// Run Millau-to-Rialto messages sync.
137137
pub async fn run(

relays/bin-substrate/src/chains/rialto_messages_to_millau.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,11 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
127127

128128
/// Rialto node as messages source.
129129
type RialtoSourceClient =
130-
SubstrateMessagesSource<Rialto, RialtoMessagesToMillau, rialto_runtime::WithMillauMessagesInstance>;
130+
SubstrateMessagesSource<Rialto, Millau, RialtoMessagesToMillau, rialto_runtime::WithMillauMessagesInstance>;
131131

132132
/// Millau node as messages target.
133133
type MillauTargetClient =
134-
SubstrateMessagesTarget<Millau, RialtoMessagesToMillau, millau_runtime::WithRialtoMessagesInstance>;
134+
SubstrateMessagesTarget<Rialto, Millau, RialtoMessagesToMillau, millau_runtime::WithRialtoMessagesInstance>;
135135

136136
/// Run Rialto-to-Millau messages sync.
137137
pub async fn run(

relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,20 @@ impl SubstrateMessageLane for RococoMessagesToWococo {
124124
}
125125

126126
/// Rococo node as messages source.
127-
type RococoSourceClient =
128-
SubstrateMessagesSource<Rococo, RococoMessagesToWococo, relay_rococo_client::runtime::WithWococoMessagesInstance>;
127+
type RococoSourceClient = SubstrateMessagesSource<
128+
Rococo,
129+
Wococo,
130+
RococoMessagesToWococo,
131+
relay_rococo_client::runtime::WithWococoMessagesInstance,
132+
>;
129133

130134
/// Wococo node as messages target.
131-
type WococoTargetClient =
132-
SubstrateMessagesTarget<Wococo, RococoMessagesToWococo, relay_wococo_client::runtime::WithRococoMessagesInstance>;
135+
type WococoTargetClient = SubstrateMessagesTarget<
136+
Rococo,
137+
Wococo,
138+
RococoMessagesToWococo,
139+
relay_wococo_client::runtime::WithRococoMessagesInstance,
140+
>;
133141

134142
/// Run Rococo-to-Wococo messages sync.
135143
pub async fn run(

relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,20 @@ impl SubstrateMessageLane for WococoMessagesToRococo {
124124
}
125125

126126
/// Wococo node as messages source.
127-
type WococoSourceClient =
128-
SubstrateMessagesSource<Wococo, WococoMessagesToRococo, relay_wococo_client::runtime::WithRococoMessagesInstance>;
127+
type WococoSourceClient = SubstrateMessagesSource<
128+
Wococo,
129+
Rococo,
130+
WococoMessagesToRococo,
131+
relay_wococo_client::runtime::WithRococoMessagesInstance,
132+
>;
129133

130134
/// Rococo node as messages target.
131-
type RococoTargetClient =
132-
SubstrateMessagesTarget<Rococo, WococoMessagesToRococo, relay_rococo_client::runtime::WithWococoMessagesInstance>;
135+
type RococoTargetClient = SubstrateMessagesTarget<
136+
Wococo,
137+
Rococo,
138+
WococoMessagesToRococo,
139+
relay_rococo_client::runtime::WithWococoMessagesInstance,
140+
>;
133141

134142
/// Run Wococo-to-Rococo messages sync.
135143
pub async fn run(

relays/bin-substrate/src/messages_source.rs

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
//! <BridgedName> chain.
2020
2121
use crate::messages_lane::SubstrateMessageLane;
22+
use crate::messages_target::SubstrateMessagesReceivingProof;
2223
use crate::on_demand_headers::OnDemandHeadersRelay;
2324

2425
use async_trait::async_trait;
25-
use bp_messages::{LaneId, MessageNonce};
26+
use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState};
2627
use 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+
};
2831
use codec::{Decode, Encode};
2932
use frame_support::{traits::Instance, weights::Weight};
3033
use messages_relay::{
@@ -33,6 +36,7 @@ use messages_relay::{
3336
ClientState, MessageDetails, MessageDetailsMap, MessageProofParameters, SourceClient, SourceClientState,
3437
},
3538
};
39+
use num_traits::{Bounded, Zero};
3640
use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf, HeaderIdOf};
3741
use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase, HeaderId};
3842
use sp_core::Bytes;
@@ -45,23 +49,23 @@ use std::{marker::PhantomData, ops::RangeInclusive};
4549
pub 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>
9296
where
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>
106111
where
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+
249286
pub 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)]
362398
mod 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

Comments
 (0)