mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 16:08:08 +00:00
Fix delivery transaction estimation used by rational relayer (#1109)
* fix delivery transaction estimation in greedy relayer * fixed typo * improve logging * improve logging * fmt * fix compilation * fmt * Update relays/lib-substrate-relay/src/messages_target.rs Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * review Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
This commit is contained in:
committed by
Bastian Köcher
parent
2101ed9cc5
commit
03a54df398
@@ -282,7 +282,7 @@ parameter_types! {
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, ()>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = IdentityFee<Balance>;
|
||||
type WeightToFee = bp_millau::WeightToFee;
|
||||
type FeeMultiplierUpdate = pallet_transaction_payment::TargetedFeeAdjustment<
|
||||
Runtime,
|
||||
TargetBlockFullness,
|
||||
|
||||
@@ -414,7 +414,7 @@ parameter_types! {
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, ()>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = IdentityFee<Balance>;
|
||||
type WeightToFee = bp_rialto::WeightToFee;
|
||||
type FeeMultiplierUpdate = pallet_transaction_payment::TargetedFeeAdjustment<
|
||||
Runtime,
|
||||
TargetBlockFullness,
|
||||
|
||||
@@ -7,13 +7,17 @@ edition = "2018"
|
||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||
|
||||
[dependencies]
|
||||
smallvec = "1.6"
|
||||
|
||||
# Bridge Dependencies
|
||||
|
||||
bp-messages = { path = "../messages", default-features = false }
|
||||
bp-polkadot-core = { path = "../polkadot-core", default-features = false }
|
||||
bp-runtime = { path = "../runtime", default-features = false }
|
||||
|
||||
# Substrate Based Dependencies
|
||||
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
|
||||
@@ -23,6 +27,7 @@ std = [
|
||||
"bp-messages/std",
|
||||
"bp-polkadot-core/std",
|
||||
"bp-runtime/std",
|
||||
"frame-support/std",
|
||||
"sp-api/std",
|
||||
"sp-std/std",
|
||||
]
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#![allow(clippy::unnecessary_mut_passed)]
|
||||
|
||||
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
||||
use frame_support::weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial};
|
||||
use sp_std::prelude::*;
|
||||
|
||||
pub use bp_polkadot_core::*;
|
||||
@@ -28,6 +29,24 @@ pub use bp_polkadot_core::*;
|
||||
/// Kusama Chain
|
||||
pub type Kusama = PolkadotLike;
|
||||
|
||||
// NOTE: This needs to be kept up to date with the Kusama runtime found in the Polkadot repo.
|
||||
pub struct WeightToFee;
|
||||
impl WeightToFeePolynomial for WeightToFee {
|
||||
type Balance = Balance;
|
||||
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
||||
const CENTS: Balance = 1_000_000_000_000 / 30_000;
|
||||
// in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
|
||||
let p = CENTS;
|
||||
let q = 10 * Balance::from(ExtrinsicBaseWeight::get());
|
||||
smallvec::smallvec![WeightToFeeCoefficient {
|
||||
degree: 1,
|
||||
negative: false,
|
||||
coeff_frac: Perbill::from_rational(p % q, q),
|
||||
coeff_integer: p / q,
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
// We use this to get the account on Kusama (target) which is derived from Polkadot's (source)
|
||||
// account.
|
||||
pub fn derive_account_from_polkadot_id(id: bp_runtime::SourceAccount<AccountId>) -> AccountId {
|
||||
|
||||
@@ -25,7 +25,7 @@ mod millau_hash;
|
||||
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
||||
use bp_runtime::Chain;
|
||||
use frame_support::{
|
||||
weights::{constants::WEIGHT_PER_SECOND, DispatchClass, Weight},
|
||||
weights::{constants::WEIGHT_PER_SECOND, DispatchClass, IdentityFee, Weight},
|
||||
Parameter, RuntimeDebug,
|
||||
};
|
||||
use frame_system::limits;
|
||||
@@ -149,6 +149,9 @@ pub type AccountSigner = MultiSigner;
|
||||
/// Balance of an account.
|
||||
pub type Balance = u64;
|
||||
|
||||
/// Weight-to-Fee type used by Millau.
|
||||
pub type WeightToFee = IdentityFee<Balance>;
|
||||
|
||||
/// Millau chain.
|
||||
#[derive(RuntimeDebug)]
|
||||
pub struct Millau;
|
||||
|
||||
@@ -7,14 +7,17 @@ edition = "2018"
|
||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||
|
||||
[dependencies]
|
||||
smallvec = "1.6"
|
||||
|
||||
# Bridge Dependencies
|
||||
|
||||
bp-messages = { path = "../messages", default-features = false }
|
||||
bp-polkadot-core = { path = "../polkadot-core", default-features = false }
|
||||
bp-runtime = { path = "../runtime", default-features = false }
|
||||
|
||||
# Substrate Based Dependencies
|
||||
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
|
||||
@@ -24,6 +27,7 @@ std = [
|
||||
"bp-messages/std",
|
||||
"bp-polkadot-core/std",
|
||||
"bp-runtime/std",
|
||||
"frame-support/std",
|
||||
"sp-api/std",
|
||||
"sp-std/std",
|
||||
]
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#![allow(clippy::unnecessary_mut_passed)]
|
||||
|
||||
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
||||
use frame_support::weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial};
|
||||
use sp_std::prelude::*;
|
||||
|
||||
pub use bp_polkadot_core::*;
|
||||
@@ -28,6 +29,24 @@ pub use bp_polkadot_core::*;
|
||||
/// Polkadot Chain
|
||||
pub type Polkadot = PolkadotLike;
|
||||
|
||||
// NOTE: This needs to be kept up to date with the Polkadot runtime found in the Polkadot repo.
|
||||
pub struct WeightToFee;
|
||||
impl WeightToFeePolynomial for WeightToFee {
|
||||
type Balance = Balance;
|
||||
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
||||
const CENTS: Balance = 10_000_000_000 / 100;
|
||||
// in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
|
||||
let p = CENTS;
|
||||
let q = 10 * Balance::from(ExtrinsicBaseWeight::get());
|
||||
smallvec::smallvec![WeightToFeeCoefficient {
|
||||
degree: 1,
|
||||
negative: false,
|
||||
coeff_frac: Perbill::from_rational(p % q, q),
|
||||
coeff_integer: p / q,
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
// We use this to get the account on Polkadot (target) which is derived from Kusama's (source)
|
||||
// account.
|
||||
pub fn derive_account_from_kusama_id(id: bp_runtime::SourceAccount<AccountId>) -> AccountId {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
||||
use bp_runtime::Chain;
|
||||
use frame_support::{
|
||||
weights::{constants::WEIGHT_PER_SECOND, DispatchClass, Weight},
|
||||
weights::{constants::WEIGHT_PER_SECOND, DispatchClass, IdentityFee, Weight},
|
||||
Parameter, RuntimeDebug,
|
||||
};
|
||||
use frame_system::limits;
|
||||
@@ -148,6 +148,9 @@ pub type Balance = u128;
|
||||
/// An instant or duration in time.
|
||||
pub type Moment = u64;
|
||||
|
||||
/// Weight-to-Fee type used by Rialto.
|
||||
pub type WeightToFee = IdentityFee<Balance>;
|
||||
|
||||
/// Rialto chain.
|
||||
#[derive(RuntimeDebug)]
|
||||
pub struct Rialto;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#![allow(clippy::unnecessary_mut_passed)]
|
||||
|
||||
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
||||
use frame_support::weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial};
|
||||
use frame_support::weights::{Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial};
|
||||
use sp_std::prelude::*;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
@@ -97,6 +97,13 @@ pub const FROM_ROCOCO_LATEST_CONFIRMED_NONCE_METHOD: &str = "FromRococoInboundLa
|
||||
/// Name of the `FromRococoInboundLaneApi::unrewarded_relayers_state` runtime method.
|
||||
pub const FROM_ROCOCO_UNREWARDED_RELAYERS_STATE: &str = "FromRococoInboundLaneApi_unrewarded_relayers_state";
|
||||
|
||||
/// Weight of pay-dispatch-fee operation for inbound messages at Rococo chain.
|
||||
///
|
||||
/// This value corresponds to the result of `pallet_bridge_messages::WeightInfoExt::pay_inbound_dispatch_fee_overhead()`
|
||||
/// call for your chain. Don't put too much reserve there, because it is used to **decrease**
|
||||
/// `DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT` cost. So putting large reserve would make delivery transactions cheaper.
|
||||
pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = 600_000_000;
|
||||
|
||||
sp_api::decl_runtime_apis! {
|
||||
/// API for querying information about the finalized Rococo headers.
|
||||
///
|
||||
|
||||
@@ -8,14 +8,18 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||
|
||||
[dependencies]
|
||||
parity-scale-codec = { version = "2.2.0", default-features = false, features = ["derive"] }
|
||||
smallvec = "1.6"
|
||||
|
||||
# Bridge Dependencies
|
||||
|
||||
bp-header-chain = { path = "../header-chain", default-features = false }
|
||||
bp-messages = { path = "../messages", default-features = false }
|
||||
bp-polkadot-core = { path = "../polkadot-core", default-features = false }
|
||||
bp-runtime = { path = "../runtime", default-features = false }
|
||||
|
||||
# Substrate Based Dependencies
|
||||
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
@@ -28,6 +32,7 @@ std = [
|
||||
"bp-messages/std",
|
||||
"bp-polkadot-core/std",
|
||||
"bp-runtime/std",
|
||||
"frame-support/std",
|
||||
"parity-scale-codec/std",
|
||||
"sp-api/std",
|
||||
"sp-runtime/std",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
||||
use bp_runtime::Chain;
|
||||
use frame_support::weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial};
|
||||
use sp_std::prelude::*;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
@@ -30,6 +31,24 @@ pub use bp_polkadot_core::*;
|
||||
/// Westend Chain
|
||||
pub type Westend = PolkadotLike;
|
||||
|
||||
// NOTE: This needs to be kept up to date with the Westend runtime found in the Polkadot repo.
|
||||
pub struct WeightToFee;
|
||||
impl WeightToFeePolynomial for WeightToFee {
|
||||
type Balance = Balance;
|
||||
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
||||
const CENTS: Balance = 1_000_000_000_000 / 1_000;
|
||||
// in Westend, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
|
||||
let p = CENTS;
|
||||
let q = 10 * Balance::from(ExtrinsicBaseWeight::get());
|
||||
smallvec::smallvec![WeightToFeeCoefficient {
|
||||
degree: 1,
|
||||
negative: false,
|
||||
coeff_frac: Perbill::from_rational(p % q, q),
|
||||
coeff_integer: p / q,
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
|
||||
|
||||
// NOTE: This needs to be kept up to date with the Westend runtime found in the Polkadot repo.
|
||||
|
||||
@@ -25,7 +25,7 @@ use sp_std::prelude::*;
|
||||
|
||||
pub use bp_polkadot_core::*;
|
||||
// Rococo runtime = Wococo runtime
|
||||
pub use bp_rococo::{WeightToFee, SESSION_LENGTH, VERSION};
|
||||
pub use bp_rococo::{WeightToFee, PAY_INBOUND_DISPATCH_FEE_WEIGHT, SESSION_LENGTH, VERSION};
|
||||
|
||||
/// Wococo Chain
|
||||
pub type Wococo = PolkadotLike;
|
||||
|
||||
@@ -24,6 +24,7 @@ use sp_core::{Bytes, Pair};
|
||||
|
||||
use bp_messages::MessageNonce;
|
||||
use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof;
|
||||
use frame_support::weights::Weight;
|
||||
use messages_relay::message_lane::MessageLane;
|
||||
use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SigningParams as MillauSigningParams};
|
||||
use relay_rialto_client::{HeaderId as RialtoHeaderId, Rialto, SigningParams as RialtoSigningParams};
|
||||
@@ -64,6 +65,8 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
|
||||
const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = bp_millau::WITH_RIALTO_MESSAGES_PALLET_NAME;
|
||||
const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = bp_rialto::WITH_MILLAU_MESSAGES_PALLET_NAME;
|
||||
|
||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_TARGET_CHAIN: Weight = bp_rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT;
|
||||
|
||||
type SourceChain = Millau;
|
||||
type TargetChain = Rialto;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ use sp_core::{Bytes, Pair};
|
||||
|
||||
use bp_messages::MessageNonce;
|
||||
use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof;
|
||||
use frame_support::weights::Weight;
|
||||
use messages_relay::message_lane::MessageLane;
|
||||
use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SigningParams as MillauSigningParams};
|
||||
use relay_rialto_client::{HeaderId as RialtoHeaderId, Rialto, SigningParams as RialtoSigningParams};
|
||||
@@ -64,6 +65,8 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
|
||||
const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = bp_rialto::WITH_MILLAU_MESSAGES_PALLET_NAME;
|
||||
const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = bp_millau::WITH_RIALTO_MESSAGES_PALLET_NAME;
|
||||
|
||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_TARGET_CHAIN: Weight = bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT;
|
||||
|
||||
type SourceChain = Rialto;
|
||||
type TargetChain = Millau;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ use sp_core::{Bytes, Pair};
|
||||
|
||||
use bp_messages::MessageNonce;
|
||||
use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof;
|
||||
use frame_support::weights::Weight;
|
||||
use messages_relay::message_lane::MessageLane;
|
||||
use relay_rococo_client::{HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams};
|
||||
use relay_substrate_client::{Chain, Client, TransactionSignScheme};
|
||||
@@ -63,6 +64,8 @@ impl SubstrateMessageLane for RococoMessagesToWococo {
|
||||
const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = bp_rococo::WITH_WOCOCO_MESSAGES_PALLET_NAME;
|
||||
const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = bp_wococo::WITH_ROCOCO_MESSAGES_PALLET_NAME;
|
||||
|
||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_TARGET_CHAIN: Weight = bp_wococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT;
|
||||
|
||||
type SourceChain = Rococo;
|
||||
type TargetChain = Wococo;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ use sp_core::{Bytes, Pair};
|
||||
|
||||
use bp_messages::MessageNonce;
|
||||
use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof;
|
||||
use frame_support::weights::Weight;
|
||||
use messages_relay::message_lane::MessageLane;
|
||||
use relay_rococo_client::{HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams};
|
||||
use relay_substrate_client::{Chain, Client, TransactionSignScheme};
|
||||
@@ -62,6 +63,8 @@ impl SubstrateMessageLane for WococoMessagesToRococo {
|
||||
const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = bp_wococo::WITH_ROCOCO_MESSAGES_PALLET_NAME;
|
||||
const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = bp_rococo::WITH_WOCOCO_MESSAGES_PALLET_NAME;
|
||||
|
||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_TARGET_CHAIN: Weight = bp_rococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT;
|
||||
|
||||
type SourceChain = Wococo;
|
||||
type TargetChain = Rococo;
|
||||
|
||||
|
||||
@@ -190,8 +190,9 @@ impl SendMessage {
|
||||
|
||||
log::info!(
|
||||
target: "bridge",
|
||||
"Sending message to {}. Size: {}. Dispatch weight: {}. Fee: {}",
|
||||
"Sending message to {}. Lane: {:?}. Size: {}. Dispatch weight: {}. Fee: {}",
|
||||
Target::NAME,
|
||||
lane,
|
||||
signed_source_call.len(),
|
||||
dispatch_weight,
|
||||
fee,
|
||||
|
||||
@@ -44,6 +44,7 @@ impl Chain for Kusama {
|
||||
type SignedBlock = bp_kusama::SignedBlock;
|
||||
type Call = ();
|
||||
type Balance = bp_kusama::Balance;
|
||||
type WeightToFee = bp_kusama::WeightToFee;
|
||||
}
|
||||
|
||||
/// Kusama header type used in headers sync.
|
||||
|
||||
@@ -47,6 +47,7 @@ impl Chain for Millau {
|
||||
type SignedBlock = millau_runtime::SignedBlock;
|
||||
type Call = millau_runtime::Call;
|
||||
type Balance = millau_runtime::Balance;
|
||||
type WeightToFee = bp_millau::WeightToFee;
|
||||
}
|
||||
|
||||
impl ChainWithBalances for Millau {
|
||||
|
||||
@@ -44,6 +44,7 @@ impl Chain for Polkadot {
|
||||
type SignedBlock = bp_polkadot::SignedBlock;
|
||||
type Call = ();
|
||||
type Balance = bp_polkadot::Balance;
|
||||
type WeightToFee = bp_polkadot::WeightToFee;
|
||||
}
|
||||
|
||||
/// Polkadot header type used in headers sync.
|
||||
|
||||
@@ -47,6 +47,7 @@ impl Chain for Rialto {
|
||||
type SignedBlock = rialto_runtime::SignedBlock;
|
||||
type Call = rialto_runtime::Call;
|
||||
type Balance = rialto_runtime::Balance;
|
||||
type WeightToFee = bp_rialto::WeightToFee;
|
||||
}
|
||||
|
||||
impl ChainWithBalances for Rialto {
|
||||
|
||||
@@ -52,6 +52,7 @@ impl Chain for Rococo {
|
||||
type SignedBlock = bp_rococo::SignedBlock;
|
||||
type Call = crate::runtime::Call;
|
||||
type Balance = bp_rococo::Balance;
|
||||
type WeightToFee = bp_rococo::WeightToFee;
|
||||
}
|
||||
|
||||
impl ChainWithBalances for Rococo {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use bp_runtime::Chain as ChainBase;
|
||||
use frame_support::Parameter;
|
||||
use frame_support::{weights::WeightToFeePolynomial, Parameter};
|
||||
use jsonrpsee_ws_client::{DeserializeOwned, Serialize};
|
||||
use num_traits::{Bounded, CheckedSub, SaturatingAdd, Zero};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
@@ -77,12 +77,17 @@ pub trait Chain: ChainBase + Clone {
|
||||
+ SaturatingAdd
|
||||
+ Zero
|
||||
+ std::convert::TryFrom<sp_core::U256>;
|
||||
|
||||
/// Type that is used by the chain, to convert from weight to fee.
|
||||
type WeightToFee: WeightToFeePolynomial<Balance = Self::Balance>;
|
||||
}
|
||||
|
||||
/// Balance type used by the chain
|
||||
pub type BalanceOf<C> = <C as Chain>::Balance;
|
||||
/// Index type used by the chain
|
||||
pub type IndexOf<C> = <C as Chain>::Index;
|
||||
/// Weight-to-Fee type used by the chain
|
||||
pub type WeightToFeeOf<C> = <C as Chain>::WeightToFee;
|
||||
|
||||
/// Substrate-based chain with `frame_system::Config::AccountData` set to
|
||||
/// the `pallet_balances::AccountData<Balance>`.
|
||||
|
||||
@@ -310,23 +310,24 @@ impl<C: Chain> Client<C> {
|
||||
}
|
||||
|
||||
/// Estimate fee that will be spent on given extrinsic.
|
||||
pub async fn estimate_extrinsic_fee(&self, transaction: Bytes) -> Result<C::Balance> {
|
||||
pub async fn estimate_extrinsic_fee(&self, transaction: Bytes) -> Result<InclusionFee<C::Balance>> {
|
||||
self.jsonrpsee_execute(move |client| async move {
|
||||
let fee_details = Substrate::<C>::payment_query_fee_details(&*client, transaction, None).await?;
|
||||
let inclusion_fee = fee_details
|
||||
.inclusion_fee
|
||||
.map(|inclusion_fee| {
|
||||
InclusionFee {
|
||||
base_fee: C::Balance::try_from(inclusion_fee.base_fee.into_u256())
|
||||
.unwrap_or_else(|_| C::Balance::max_value()),
|
||||
len_fee: C::Balance::try_from(inclusion_fee.len_fee.into_u256())
|
||||
.unwrap_or_else(|_| C::Balance::max_value()),
|
||||
adjusted_weight_fee: C::Balance::try_from(inclusion_fee.adjusted_weight_fee.into_u256())
|
||||
.unwrap_or_else(|_| C::Balance::max_value()),
|
||||
}
|
||||
.inclusion_fee()
|
||||
.map(|inclusion_fee| InclusionFee {
|
||||
base_fee: C::Balance::try_from(inclusion_fee.base_fee.into_u256())
|
||||
.unwrap_or_else(|_| C::Balance::max_value()),
|
||||
len_fee: C::Balance::try_from(inclusion_fee.len_fee.into_u256())
|
||||
.unwrap_or_else(|_| C::Balance::max_value()),
|
||||
adjusted_weight_fee: C::Balance::try_from(inclusion_fee.adjusted_weight_fee.into_u256())
|
||||
.unwrap_or_else(|_| C::Balance::max_value()),
|
||||
})
|
||||
.unwrap_or_else(Zero::zero);
|
||||
.unwrap_or_else(|| InclusionFee {
|
||||
base_fee: Zero::zero(),
|
||||
len_fee: Zero::zero(),
|
||||
adjusted_weight_fee: Zero::zero(),
|
||||
});
|
||||
Ok(inclusion_fee)
|
||||
})
|
||||
.await
|
||||
|
||||
@@ -194,6 +194,7 @@ mod tests {
|
||||
sp_runtime::generic::SignedBlock<sp_runtime::generic::Block<Self::Header, sp_runtime::OpaqueExtrinsic>>;
|
||||
type Call = ();
|
||||
type Balance = u32;
|
||||
type WeightToFee = frame_support::weights::IdentityFee<u32>;
|
||||
}
|
||||
|
||||
impl ChainWithBalances for TestChain {
|
||||
|
||||
@@ -31,7 +31,9 @@ pub mod metrics;
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
pub use crate::chain::{BalanceOf, BlockWithJustification, Chain, ChainWithBalances, IndexOf, TransactionSignScheme};
|
||||
pub use crate::chain::{
|
||||
BalanceOf, BlockWithJustification, Chain, ChainWithBalances, IndexOf, TransactionSignScheme, WeightToFeeOf,
|
||||
};
|
||||
pub use crate::client::{Client, JustificationsSubscription, OpaqueGrandpaAuthoritiesSet};
|
||||
pub use crate::error::{Error, Result};
|
||||
pub use crate::sync_header::SyncHeader;
|
||||
|
||||
@@ -50,6 +50,7 @@ impl Chain for Westend {
|
||||
type SignedBlock = bp_westend::SignedBlock;
|
||||
type Call = bp_westend::Call;
|
||||
type Balance = bp_westend::Balance;
|
||||
type WeightToFee = bp_westend::WeightToFee;
|
||||
}
|
||||
|
||||
impl ChainWithBalances for Westend {
|
||||
|
||||
@@ -52,6 +52,7 @@ impl Chain for Wococo {
|
||||
type SignedBlock = bp_wococo::SignedBlock;
|
||||
type Call = crate::runtime::Call;
|
||||
type Balance = bp_wococo::Balance;
|
||||
type WeightToFee = bp_wococo::WeightToFee;
|
||||
}
|
||||
|
||||
impl ChainWithBalances for Wococo {
|
||||
|
||||
@@ -40,8 +40,9 @@ sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[dev-dependencies]
|
||||
relay-millau-client = { path = "../client-millau" }
|
||||
relay-rialto-client = { path = "../client-rialto" }
|
||||
bp-rialto = { path = "../../primitives/chain-rialto" }
|
||||
bp-millau = { path = "../../primitives/chain-millau" }
|
||||
bp-rococo = { path = "../../primitives/chain-rococo" }
|
||||
bp-wococo = { path = "../../primitives/chain-wococo" }
|
||||
relay-rococo-client = { path = "../client-rococo" }
|
||||
relay-wococo-client = { path = "../client-wococo" }
|
||||
rialto-runtime = { path = "../../bin/rialto/runtime" }
|
||||
|
||||
@@ -88,6 +88,13 @@ pub trait SubstrateMessageLane: 'static + Clone + Send + Sync {
|
||||
/// Name of the messages pallet as it is declared in the `construct_runtime!()` at target chain.
|
||||
const MESSAGE_PALLET_NAME_AT_TARGET: &'static str;
|
||||
|
||||
/// Extra weight of the delivery transaction at the target chain, that is paid to cover
|
||||
/// dispatch fee payment.
|
||||
///
|
||||
/// If dispatch fee is paid at the source chain, then this weight is refunded by the
|
||||
/// delivery transaction.
|
||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_TARGET_CHAIN: Weight;
|
||||
|
||||
/// Source chain.
|
||||
type SourceChain: Chain;
|
||||
/// Target chain.
|
||||
|
||||
@@ -24,7 +24,6 @@ use crate::on_demand_headers::OnDemandHeadersRelay;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState};
|
||||
use bp_runtime::messages::DispatchFeePayment;
|
||||
use bridge_runtime_common::messages::{
|
||||
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
||||
};
|
||||
@@ -43,7 +42,10 @@ use relay_substrate_client::{
|
||||
};
|
||||
use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase, HeaderId};
|
||||
use sp_core::Bytes;
|
||||
use sp_runtime::{traits::Header as HeaderT, DeserializeOwned};
|
||||
use sp_runtime::{
|
||||
traits::{AtLeast32BitUnsigned, Header as HeaderT},
|
||||
DeserializeOwned,
|
||||
};
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
/// Intermediate message proof returned by the source Substrate node. Includes everything
|
||||
@@ -121,6 +123,7 @@ where
|
||||
>,
|
||||
<P::MessageLane as MessageLane>::TargetHeaderNumber: Decode,
|
||||
<P::MessageLane as MessageLane>::TargetHeaderHash: Decode,
|
||||
<P::MessageLane as MessageLane>::SourceChainBalance: AtLeast32BitUnsigned,
|
||||
{
|
||||
async fn state(&self) -> Result<SourceClientState<P::MessageLane>, SubstrateError> {
|
||||
// we can't continue to deliver confirmations if source node is out of sync, because
|
||||
@@ -264,6 +267,7 @@ where
|
||||
prepare_dummy_messages_delivery_proof::<P::SourceChain, P::TargetChain>(),
|
||||
))
|
||||
.await
|
||||
.map(|fee| fee.inclusion_fee())
|
||||
.unwrap_or_else(|_| BalanceOf::<P::SourceChain>::max_value())
|
||||
}
|
||||
}
|
||||
@@ -397,7 +401,7 @@ fn make_message_details_map<C: Chain>(
|
||||
dispatch_weight: details.dispatch_weight,
|
||||
size: details.size as _,
|
||||
reward: details.delivery_and_dispatch_fee,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
dispatch_fee_payment: details.dispatch_fee_payment,
|
||||
},
|
||||
);
|
||||
expected_nonce = details.nonce + 1;
|
||||
@@ -411,12 +415,12 @@ fn make_message_details_map<C: Chain>(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use bp_runtime::messages::DispatchFeePayment;
|
||||
use relay_millau_client::Millau;
|
||||
use relay_rialto_client::Rialto;
|
||||
use relay_rococo_client::Rococo;
|
||||
use relay_wococo_client::Wococo;
|
||||
|
||||
fn message_details_from_rpc(
|
||||
nonces: RangeInclusive<MessageNonce>,
|
||||
) -> Vec<bp_messages::MessageDetails<bp_rialto::Balance>> {
|
||||
) -> Vec<bp_messages::MessageDetails<bp_wococo::Balance>> {
|
||||
nonces
|
||||
.into_iter()
|
||||
.map(|nonce| bp_messages::MessageDetails {
|
||||
@@ -432,7 +436,7 @@ mod tests {
|
||||
#[test]
|
||||
fn make_message_details_map_succeeds_if_no_messages_are_missing() {
|
||||
assert_eq!(
|
||||
make_message_details_map::<relay_rialto_client::Rialto>(message_details_from_rpc(1..=3), 1..=3,).unwrap(),
|
||||
make_message_details_map::<Wococo>(message_details_from_rpc(1..=3), 1..=3,).unwrap(),
|
||||
vec![
|
||||
(
|
||||
1,
|
||||
@@ -470,7 +474,7 @@ mod tests {
|
||||
#[test]
|
||||
fn make_message_details_map_succeeds_if_head_messages_are_missing() {
|
||||
assert_eq!(
|
||||
make_message_details_map::<relay_rialto_client::Rialto>(message_details_from_rpc(2..=3), 1..=3,).unwrap(),
|
||||
make_message_details_map::<Wococo>(message_details_from_rpc(2..=3), 1..=3,).unwrap(),
|
||||
vec![
|
||||
(
|
||||
2,
|
||||
@@ -501,7 +505,7 @@ mod tests {
|
||||
let mut message_details_from_rpc = message_details_from_rpc(1..=3);
|
||||
message_details_from_rpc.remove(1);
|
||||
assert!(matches!(
|
||||
make_message_details_map::<relay_rialto_client::Rialto>(message_details_from_rpc, 1..=3,),
|
||||
make_message_details_map::<Wococo>(message_details_from_rpc, 1..=3,),
|
||||
Err(SubstrateError::Custom(_))
|
||||
));
|
||||
}
|
||||
@@ -509,7 +513,7 @@ mod tests {
|
||||
#[test]
|
||||
fn make_message_details_map_fails_if_tail_messages_are_missing() {
|
||||
assert!(matches!(
|
||||
make_message_details_map::<relay_rialto_client::Rialto>(message_details_from_rpc(1..=2), 1..=3,),
|
||||
make_message_details_map::<Wococo>(message_details_from_rpc(1..=2), 1..=3,),
|
||||
Err(SubstrateError::Custom(_))
|
||||
));
|
||||
}
|
||||
@@ -517,15 +521,15 @@ mod tests {
|
||||
#[test]
|
||||
fn make_message_details_map_fails_if_all_messages_are_missing() {
|
||||
assert!(matches!(
|
||||
make_message_details_map::<relay_rialto_client::Rialto>(vec![], 1..=3),
|
||||
make_message_details_map::<Wococo>(vec![], 1..=3),
|
||||
Err(SubstrateError::Custom(_))
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prepare_dummy_messages_delivery_proof_works() {
|
||||
let expected_minimal_size = Rialto::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE + Millau::STORAGE_PROOF_OVERHEAD;
|
||||
let dummy_proof = prepare_dummy_messages_delivery_proof::<Rialto, Millau>();
|
||||
let expected_minimal_size = Wococo::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE + Rococo::STORAGE_PROOF_OVERHEAD;
|
||||
let dummy_proof = prepare_dummy_messages_delivery_proof::<Wococo, Rococo>();
|
||||
assert!(
|
||||
dummy_proof.1.encode().len() as u32 > expected_minimal_size,
|
||||
"Expected proof size at least {}. Got: {}",
|
||||
|
||||
@@ -29,7 +29,7 @@ use bridge_runtime_common::messages::{
|
||||
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::weights::Weight;
|
||||
use frame_support::weights::{Weight, WeightToFeePolynomial};
|
||||
use messages_relay::message_lane::MessageLane;
|
||||
use messages_relay::{
|
||||
message_lane::{SourceHeaderIdOf, TargetHeaderIdOf},
|
||||
@@ -37,11 +37,11 @@ use messages_relay::{
|
||||
};
|
||||
use num_traits::{Bounded, Zero};
|
||||
use relay_substrate_client::{
|
||||
BalanceOf, BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf, HeaderOf, IndexOf,
|
||||
BalanceOf, BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf, HeaderOf, IndexOf, WeightToFeeOf,
|
||||
};
|
||||
use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase, HeaderId};
|
||||
use sp_core::Bytes;
|
||||
use sp_runtime::{DeserializeOwned, FixedPointNumber, FixedU128};
|
||||
use sp_runtime::{traits::Saturating, DeserializeOwned, FixedPointNumber, FixedU128};
|
||||
use std::{convert::TryFrom, ops::RangeInclusive};
|
||||
|
||||
/// Message receiving proof returned by the target Substrate node.
|
||||
@@ -118,7 +118,6 @@ where
|
||||
BlockNumberOf<P::TargetChain>: Copy,
|
||||
HeaderOf<P::TargetChain>: DeserializeOwned,
|
||||
BlockNumberOf<P::TargetChain>: BlockNumberBase,
|
||||
|
||||
P::MessageLane: MessageLane<
|
||||
MessagesProof = SubstrateMessagesProof<P::SourceChain>,
|
||||
MessagesReceivingProof = SubstrateMessagesReceivingProof<P::TargetChain>,
|
||||
@@ -244,6 +243,7 @@ where
|
||||
async fn estimate_delivery_transaction_in_source_tokens(
|
||||
&self,
|
||||
nonces: RangeInclusive<MessageNonce>,
|
||||
total_prepaid_nonces: MessageNonce,
|
||||
total_dispatch_weight: Weight,
|
||||
total_size: u32,
|
||||
) -> Result<<P::MessageLane as MessageLane>::SourceChainBalance, SubstrateError> {
|
||||
@@ -258,27 +258,88 @@ where
|
||||
P::SourceChain::NAME,
|
||||
))
|
||||
})?;
|
||||
|
||||
// Prepare 'dummy' delivery transaction - we only care about its length and dispatch weight.
|
||||
let delivery_tx = self.lane.make_messages_delivery_transaction(
|
||||
Zero::zero(),
|
||||
HeaderId(Default::default(), Default::default()),
|
||||
nonces.clone(),
|
||||
prepare_dummy_messages_proof::<P::SourceChain>(nonces.clone(), total_dispatch_weight, total_size),
|
||||
);
|
||||
let delivery_tx_fee = self.client.estimate_extrinsic_fee(delivery_tx).await?;
|
||||
let inclusion_fee_in_target_tokens = delivery_tx_fee.inclusion_fee();
|
||||
|
||||
// The pre-dispatch cost of delivery transaction includes additional fee to cover dispatch fee payment
|
||||
// (Currency::transfer in regular deployment). But if message dispatch has already been paid
|
||||
// at the Source chain, the delivery transaction will refund relayer with this additional cost.
|
||||
// But `estimate_extrinsic_fee` obviously just returns pre-dispatch cost of the transaction. So
|
||||
// if transaction delivers prepaid message, then it may happen that pre-dispatch cost is larger
|
||||
// than reward and `Rational` relayer will refuse to deliver this message.
|
||||
//
|
||||
// The most obvious solution would be to deduct total weight of dispatch fee payments from the
|
||||
// `total_dispatch_weight` and use regular `estimate_extrinsic_fee` call. But what if
|
||||
// `total_dispatch_weight` is less than total dispatch fee payments weight? Weight is strictly
|
||||
// positive, so we can't use this option.
|
||||
//
|
||||
// Instead we'll be directly using `WeightToFee` and `NextFeeMultiplier` of the Target chain.
|
||||
// This requires more knowledge of the Target chain, but seems there's no better way to solve
|
||||
// this now.
|
||||
let expected_refund_in_target_tokens = if total_prepaid_nonces != 0 {
|
||||
const WEIGHT_DIFFERENCE: Weight = 100;
|
||||
|
||||
let larger_dispatch_weight = total_dispatch_weight.saturating_add(WEIGHT_DIFFERENCE);
|
||||
let larger_delivery_tx_fee = self
|
||||
.client
|
||||
.estimate_extrinsic_fee(self.lane.make_messages_delivery_transaction(
|
||||
Zero::zero(),
|
||||
HeaderId(Default::default(), Default::default()),
|
||||
nonces.clone(),
|
||||
prepare_dummy_messages_proof::<P::SourceChain>(nonces.clone(), larger_dispatch_weight, total_size),
|
||||
))
|
||||
.await?;
|
||||
|
||||
compute_prepaid_messages_refund::<P>(
|
||||
total_prepaid_nonces,
|
||||
compute_fee_multiplier::<P::TargetChain>(
|
||||
delivery_tx_fee.adjusted_weight_fee,
|
||||
total_dispatch_weight,
|
||||
larger_delivery_tx_fee.adjusted_weight_fee,
|
||||
larger_dispatch_weight,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
Zero::zero()
|
||||
};
|
||||
|
||||
let delivery_fee_in_source_tokens = convert_target_tokens_to_source_tokens::<P::SourceChain, P::TargetChain>(
|
||||
FixedU128::from_float(conversion_rate),
|
||||
inclusion_fee_in_target_tokens.saturating_sub(expected_refund_in_target_tokens),
|
||||
);
|
||||
|
||||
log::trace!(
|
||||
target: "bridge",
|
||||
"Using conversion rate {} when converting from {} tokens to {} tokens",
|
||||
conversion_rate,
|
||||
P::TargetChain::NAME,
|
||||
P::SourceChain::NAME,
|
||||
"Estimated {} -> {} messages delivery transaction.\n\t\
|
||||
Total nonces: {:?}\n\t\
|
||||
Prepaid messages: {}\n\t\
|
||||
Total messages size: {}\n\t\
|
||||
Total messages dispatch weight: {}\n\t\
|
||||
Inclusion fee (in {1} tokens): {:?}\n\t\
|
||||
Expected refund (in {1} tokens): {:?}\n\t\
|
||||
{1} -> {0} conversion rate: {:?}\n\t\
|
||||
Expected delivery tx fee (in {0} tokens): {:?}",
|
||||
P::SourceChain::NAME,
|
||||
P::TargetChain::NAME,
|
||||
nonces,
|
||||
total_prepaid_nonces,
|
||||
total_size,
|
||||
total_dispatch_weight,
|
||||
inclusion_fee_in_target_tokens,
|
||||
expected_refund_in_target_tokens,
|
||||
conversion_rate,
|
||||
delivery_fee_in_source_tokens,
|
||||
);
|
||||
Ok(
|
||||
convert_target_tokens_to_source_tokens::<P::SourceChain, P::TargetChain>(
|
||||
FixedU128::from_float(conversion_rate),
|
||||
self.client
|
||||
.estimate_extrinsic_fee(self.lane.make_messages_delivery_transaction(
|
||||
Zero::zero(),
|
||||
HeaderId(Default::default(), Default::default()),
|
||||
nonces.clone(),
|
||||
prepare_dummy_messages_proof::<P::SourceChain>(nonces, total_dispatch_weight, total_size),
|
||||
))
|
||||
.await
|
||||
.unwrap_or_else(|_| <P::TargetChain as Chain>::Balance::max_value()),
|
||||
),
|
||||
)
|
||||
|
||||
Ok(delivery_fee_in_source_tokens)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,17 +377,110 @@ where
|
||||
.unwrap_or_else(|_| SC::Balance::max_value())
|
||||
}
|
||||
|
||||
/// Compute fee multiplier that is used by the chain, given couple of fees for transactions
|
||||
/// that are only differ in dispatch weights.
|
||||
///
|
||||
/// This function assumes that standard transaction payment pallet is used by the chain.
|
||||
/// The only fee component that depends on dispatch weight is the `adjusted_weight_fee`.
|
||||
///
|
||||
/// **WARNING**: this functions will only be accurate if weight-to-fee conversion function
|
||||
/// is linear. For non-linear polynomials the error will grow with `weight_difference` growth.
|
||||
/// So better to use smaller differences.
|
||||
fn compute_fee_multiplier<C: Chain>(
|
||||
smaller_adjusted_weight_fee: BalanceOf<C>,
|
||||
smaller_tx_weight: Weight,
|
||||
larger_adjusted_weight_fee: BalanceOf<C>,
|
||||
larger_tx_weight: Weight,
|
||||
) -> FixedU128 {
|
||||
let adjusted_weight_fee_difference = larger_adjusted_weight_fee.saturating_sub(smaller_adjusted_weight_fee);
|
||||
let smaller_tx_unadjusted_weight_fee = WeightToFeeOf::<C>::calc(&smaller_tx_weight);
|
||||
let larger_tx_unadjusted_weight_fee = WeightToFeeOf::<C>::calc(&larger_tx_weight);
|
||||
FixedU128::saturating_from_rational(
|
||||
adjusted_weight_fee_difference,
|
||||
larger_tx_unadjusted_weight_fee.saturating_sub(smaller_tx_unadjusted_weight_fee),
|
||||
)
|
||||
}
|
||||
|
||||
/// Compute fee that will be refunded to the relayer because dispatch of `total_prepaid_nonces`
|
||||
/// messages has been paid at the source chain.
|
||||
fn compute_prepaid_messages_refund<P: SubstrateMessageLane>(
|
||||
total_prepaid_nonces: MessageNonce,
|
||||
fee_multiplier: FixedU128,
|
||||
) -> BalanceOf<P::TargetChain> {
|
||||
fee_multiplier.saturating_mul_int(WeightToFeeOf::<P::TargetChain>::calc(
|
||||
&P::PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_TARGET_CHAIN.saturating_mul(total_prepaid_nonces),
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use relay_millau_client::Millau;
|
||||
use relay_rialto_client::Rialto;
|
||||
use relay_rococo_client::{Rococo, SigningParams as RococoSigningParams};
|
||||
use relay_wococo_client::{SigningParams as WococoSigningParams, Wococo};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct TestSubstrateMessageLane;
|
||||
|
||||
impl SubstrateMessageLane for TestSubstrateMessageLane {
|
||||
type MessageLane = crate::messages_lane::SubstrateMessageLaneToSubstrate<
|
||||
Rococo,
|
||||
RococoSigningParams,
|
||||
Wococo,
|
||||
WococoSigningParams,
|
||||
>;
|
||||
|
||||
const OUTBOUND_LANE_MESSAGE_DETAILS_METHOD: &'static str = "";
|
||||
const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str = "";
|
||||
const OUTBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = "";
|
||||
|
||||
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = "";
|
||||
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str = "";
|
||||
const INBOUND_LANE_UNREWARDED_RELAYERS_STATE: &'static str = "";
|
||||
|
||||
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = "";
|
||||
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = "";
|
||||
|
||||
const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = "";
|
||||
const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = "";
|
||||
|
||||
const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_TARGET_CHAIN: Weight = 100_000;
|
||||
|
||||
type SourceChain = Rococo;
|
||||
type TargetChain = Wococo;
|
||||
|
||||
fn source_transactions_author(&self) -> bp_rococo::AccountId {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn make_messages_receiving_proof_transaction(
|
||||
&self,
|
||||
_transaction_nonce: <Rococo as Chain>::Index,
|
||||
_generated_at_block: TargetHeaderIdOf<Self::MessageLane>,
|
||||
_proof: <Self::MessageLane as MessageLane>::MessagesReceivingProof,
|
||||
) -> Bytes {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn target_transactions_author(&self) -> bp_wococo::AccountId {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn make_messages_delivery_transaction(
|
||||
&self,
|
||||
_transaction_nonce: <Wococo as Chain>::Index,
|
||||
_generated_at_header: SourceHeaderIdOf<Self::MessageLane>,
|
||||
_nonces: RangeInclusive<MessageNonce>,
|
||||
_proof: <Self::MessageLane as MessageLane>::MessagesProof,
|
||||
) -> Bytes {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prepare_dummy_messages_proof_works() {
|
||||
const DISPATCH_WEIGHT: Weight = 1_000_000;
|
||||
const SIZE: u32 = 1_000;
|
||||
let dummy_proof = prepare_dummy_messages_proof::<Rialto>(1..=10, DISPATCH_WEIGHT, SIZE);
|
||||
let dummy_proof = prepare_dummy_messages_proof::<Rococo>(1..=10, DISPATCH_WEIGHT, SIZE);
|
||||
assert_eq!(dummy_proof.0, DISPATCH_WEIGHT);
|
||||
assert!(
|
||||
dummy_proof.1.encode().len() as u32 > SIZE,
|
||||
@@ -339,16 +493,47 @@ mod tests {
|
||||
#[test]
|
||||
fn convert_target_tokens_to_source_tokens_works() {
|
||||
assert_eq!(
|
||||
convert_target_tokens_to_source_tokens::<Rialto, Millau>((150, 100).into(), 1_000),
|
||||
convert_target_tokens_to_source_tokens::<Rococo, Wococo>((150, 100).into(), 1_000),
|
||||
1_500
|
||||
);
|
||||
assert_eq!(
|
||||
convert_target_tokens_to_source_tokens::<Rialto, Millau>((50, 100).into(), 1_000),
|
||||
convert_target_tokens_to_source_tokens::<Rococo, Wococo>((50, 100).into(), 1_000),
|
||||
500
|
||||
);
|
||||
assert_eq!(
|
||||
convert_target_tokens_to_source_tokens::<Rialto, Millau>((100, 100).into(), 1_000),
|
||||
convert_target_tokens_to_source_tokens::<Rococo, Wococo>((100, 100).into(), 1_000),
|
||||
1_000
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_fee_multiplier_returns_sane_results() {
|
||||
let multiplier = FixedU128::saturating_from_rational(1, 1000);
|
||||
|
||||
let smaller_weight = 1_000_000;
|
||||
let smaller_adjusted_weight_fee = multiplier.saturating_mul_int(WeightToFeeOf::<Rococo>::calc(&smaller_weight));
|
||||
|
||||
let larger_weight = smaller_weight + 200_000;
|
||||
let larger_adjusted_weight_fee = multiplier.saturating_mul_int(WeightToFeeOf::<Rococo>::calc(&larger_weight));
|
||||
|
||||
assert_eq!(
|
||||
compute_fee_multiplier::<Rococo>(
|
||||
smaller_adjusted_weight_fee,
|
||||
smaller_weight,
|
||||
larger_adjusted_weight_fee,
|
||||
larger_weight,
|
||||
),
|
||||
multiplier,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_prepaid_messages_refund_returns_sane_results() {
|
||||
assert!(
|
||||
compute_prepaid_messages_refund::<TestSubstrateMessageLane>(
|
||||
10,
|
||||
FixedU128::saturating_from_rational(110, 100),
|
||||
) > (10 * TestSubstrateMessageLane::PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_TARGET_CHAIN).into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,10 +420,10 @@ fn on_demand_headers_relay_name<SourceChain: Chain, TargetChain: Chain>() -> Str
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
type TestChain = relay_millau_client::Millau;
|
||||
type TestChain = relay_rococo_client::Rococo;
|
||||
|
||||
const AT_SOURCE: Option<bp_millau::BlockNumber> = Some(10);
|
||||
const AT_TARGET: Option<bp_millau::BlockNumber> = Some(1);
|
||||
const AT_SOURCE: Option<bp_rococo::BlockNumber> = Some(10);
|
||||
const AT_TARGET: Option<bp_rococo::BlockNumber> = Some(1);
|
||||
|
||||
#[async_std::test]
|
||||
async fn mandatory_headers_scan_range_selects_range_if_too_many_headers_are_missing() {
|
||||
|
||||
@@ -210,6 +210,7 @@ pub trait TargetClient<P: MessageLane>: RelayClient {
|
||||
async fn estimate_delivery_transaction_in_source_tokens(
|
||||
&self,
|
||||
nonces: RangeInclusive<MessageNonce>,
|
||||
total_prepaid_nonces: MessageNonce,
|
||||
total_dispatch_weight: Weight,
|
||||
total_size: u32,
|
||||
) -> Result<P::SourceChainBalance, Self::Error>;
|
||||
@@ -773,6 +774,7 @@ pub(crate) mod tests {
|
||||
async fn estimate_delivery_transaction_in_source_tokens(
|
||||
&self,
|
||||
nonces: RangeInclusive<MessageNonce>,
|
||||
_total_prepaid_nonces: MessageNonce,
|
||||
total_dispatch_weight: Weight,
|
||||
total_size: u32,
|
||||
) -> Result<TestSourceChainBalance, TestError> {
|
||||
|
||||
@@ -561,6 +561,7 @@ async fn select_nonces_for_delivery_transaction<P: MessageLane>(
|
||||
|
||||
let mut selected_weight: Weight = 0;
|
||||
let mut selected_unpaid_weight: Weight = 0;
|
||||
let mut selected_prepaid_nonces = 0;
|
||||
let mut selected_size: u32 = 0;
|
||||
let mut selected_count: MessageNonce = 0;
|
||||
let mut selected_reward = P::SourceChainBalance::zero();
|
||||
@@ -570,6 +571,8 @@ async fn select_nonces_for_delivery_transaction<P: MessageLane>(
|
||||
let mut total_confirmations_cost = P::SourceChainBalance::zero();
|
||||
let mut total_cost = P::SourceChainBalance::zero();
|
||||
|
||||
let hard_selected_begin_nonce = nonces_queue[nonces_queue_range.start].1.begin();
|
||||
|
||||
// technically, multiple confirmations will be delivered in a single transaction,
|
||||
// meaning less loses for relayer. But here we don't know the final relayer yet, so
|
||||
// we're adding a separate transaction for every message. Normally, this cost is covered
|
||||
@@ -637,8 +640,12 @@ async fn select_nonces_for_delivery_transaction<P: MessageLane>(
|
||||
// dispatch origin account AND reward is not covering this fee.
|
||||
//
|
||||
// So in the latter case we're not adding the dispatch weight to the delivery transaction weight.
|
||||
let mut new_selected_prepaid_nonces = selected_prepaid_nonces;
|
||||
let new_selected_unpaid_weight = match details.dispatch_fee_payment {
|
||||
DispatchFeePayment::AtSourceChain => selected_unpaid_weight.saturating_add(details.dispatch_weight),
|
||||
DispatchFeePayment::AtSourceChain => {
|
||||
new_selected_prepaid_nonces += 1;
|
||||
selected_unpaid_weight.saturating_add(details.dispatch_weight)
|
||||
}
|
||||
DispatchFeePayment::AtTargetChain => selected_unpaid_weight,
|
||||
};
|
||||
|
||||
@@ -651,7 +658,8 @@ async fn select_nonces_for_delivery_transaction<P: MessageLane>(
|
||||
RelayerMode::Rational => {
|
||||
let delivery_transaction_cost = lane_target_client
|
||||
.estimate_delivery_transaction_in_source_tokens(
|
||||
0..=(new_selected_count as MessageNonce - 1),
|
||||
hard_selected_begin_nonce..=(hard_selected_begin_nonce + index as MessageNonce),
|
||||
new_selected_prepaid_nonces,
|
||||
new_selected_unpaid_weight,
|
||||
new_selected_size as u32,
|
||||
)
|
||||
@@ -711,11 +719,11 @@ async fn select_nonces_for_delivery_transaction<P: MessageLane>(
|
||||
hard_selected_count = index + 1;
|
||||
selected_weight = new_selected_weight;
|
||||
selected_unpaid_weight = new_selected_unpaid_weight;
|
||||
selected_prepaid_nonces = new_selected_prepaid_nonces;
|
||||
selected_size = new_selected_size;
|
||||
selected_count = new_selected_count;
|
||||
}
|
||||
|
||||
let hard_selected_begin_nonce = nonces_queue[nonces_queue_range.start].1.begin();
|
||||
if hard_selected_count != soft_selected_count {
|
||||
let hard_selected_end_nonce = hard_selected_begin_nonce + hard_selected_count as MessageNonce - 1;
|
||||
let soft_selected_begin_nonce = hard_selected_begin_nonce;
|
||||
|
||||
Reference in New Issue
Block a user