mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 18:41:03 +00:00
Rococo <> Wococo relayer balance guard (#998)
* relayer balance guards in Rococo <> Wococo * removed printlns * update constant * update constant * start balance guard for Wococo -> Rococo * Update relays/bin-substrate/src/chains/wococo_headers_to_rococo.rs Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> * Update relays/bin-substrate/src/chains/wococo_headers_to_rococo.rs Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomasz@parity.io>
This commit is contained in:
committed by
Bastian Köcher
parent
ec8412b6d0
commit
f321b07606
@@ -8,6 +8,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
parity-scale-codec = { version = "2.0.0", default-features = false, features = ["derive"] }
|
parity-scale-codec = { version = "2.0.0", default-features = false, features = ["derive"] }
|
||||||
|
smallvec = "1.6"
|
||||||
|
|
||||||
# Bridge Dependencies
|
# Bridge Dependencies
|
||||||
bp-header-chain = { path = "../header-chain", default-features = false }
|
bp-header-chain = { path = "../header-chain", default-features = false }
|
||||||
@@ -16,6 +17,7 @@ bp-polkadot-core = { path = "../polkadot-core", default-features = false }
|
|||||||
bp-runtime = { path = "../runtime", default-features = false }
|
bp-runtime = { path = "../runtime", default-features = false }
|
||||||
|
|
||||||
# Substrate Based Dependencies
|
# 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-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-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 }
|
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
@@ -28,6 +30,7 @@ std = [
|
|||||||
"bp-messages/std",
|
"bp-messages/std",
|
||||||
"bp-polkadot-core/std",
|
"bp-polkadot-core/std",
|
||||||
"bp-runtime/std",
|
"bp-runtime/std",
|
||||||
|
"frame-support/std",
|
||||||
"parity-scale-codec/std",
|
"parity-scale-codec/std",
|
||||||
"sp-api/std",
|
"sp-api/std",
|
||||||
"sp-runtime/std",
|
"sp-runtime/std",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
||||||
use bp_runtime::Chain;
|
use bp_runtime::Chain;
|
||||||
|
use frame_support::weights::{WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial};
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
use sp_version::RuntimeVersion;
|
use sp_version::RuntimeVersion;
|
||||||
|
|
||||||
@@ -43,6 +44,23 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|||||||
transaction_version: 0,
|
transaction_version: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NOTE: This needs to be kept up to date with the Rococo runtime found in the Polkadot repo.
|
||||||
|
pub struct WeightToFee;
|
||||||
|
impl WeightToFeePolynomial for WeightToFee {
|
||||||
|
type Balance = Balance;
|
||||||
|
fn polynomial() -> WeightToFeeCoefficients<Balance> {
|
||||||
|
const CENTS: Balance = 1_000_000_000_000 / 100;
|
||||||
|
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,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Rococo Runtime `Call` enum.
|
/// Rococo Runtime `Call` enum.
|
||||||
///
|
///
|
||||||
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
|
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ parity-scale-codec = { version = "2.0.0", default-features = false, features = [
|
|||||||
bp-header-chain = { path = "../header-chain", default-features = false }
|
bp-header-chain = { path = "../header-chain", default-features = false }
|
||||||
bp-messages = { path = "../messages", default-features = false }
|
bp-messages = { path = "../messages", default-features = false }
|
||||||
bp-polkadot-core = { path = "../polkadot-core", default-features = false }
|
bp-polkadot-core = { path = "../polkadot-core", default-features = false }
|
||||||
|
bp-rococo = { path = "../chain-rococo", default-features = false }
|
||||||
bp-runtime = { path = "../runtime", default-features = false }
|
bp-runtime = { path = "../runtime", default-features = false }
|
||||||
|
|
||||||
# Substrate Based Dependencies
|
# Substrate Based Dependencies
|
||||||
sp-api = { 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-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 }
|
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
@@ -28,9 +28,9 @@ std = [
|
|||||||
"bp-messages/std",
|
"bp-messages/std",
|
||||||
"bp-polkadot-core/std",
|
"bp-polkadot-core/std",
|
||||||
"bp-runtime/std",
|
"bp-runtime/std",
|
||||||
|
"bp-rococo/std",
|
||||||
"parity-scale-codec/std",
|
"parity-scale-codec/std",
|
||||||
"sp-api/std",
|
"sp-api/std",
|
||||||
"sp-runtime/std",
|
"sp-runtime/std",
|
||||||
"sp-std/std",
|
"sp-std/std",
|
||||||
"sp-version/std",
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -23,26 +23,16 @@
|
|||||||
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
use bp_messages::{LaneId, MessageDetails, MessageNonce, UnrewardedRelayersState};
|
||||||
use bp_runtime::Chain;
|
use bp_runtime::Chain;
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
use sp_version::RuntimeVersion;
|
|
||||||
|
|
||||||
pub use bp_polkadot_core::*;
|
pub use bp_polkadot_core::*;
|
||||||
|
// Rococo runtime = Wococo runtime
|
||||||
|
pub use bp_rococo::{WeightToFee, VERSION};
|
||||||
|
|
||||||
/// Wococo Chain
|
/// Wococo Chain
|
||||||
pub type Wococo = PolkadotLike;
|
pub type Wococo = PolkadotLike;
|
||||||
|
|
||||||
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
|
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
|
||||||
|
|
||||||
// NOTE: This needs to be kept up to date with the Rococo runtime found in the Polkadot repo.
|
|
||||||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|
||||||
spec_name: sp_version::create_runtime_str!("rococo"),
|
|
||||||
impl_name: sp_version::create_runtime_str!("parity-rococo-v1.6"),
|
|
||||||
authoring_version: 0,
|
|
||||||
spec_version: 9004,
|
|
||||||
impl_version: 0,
|
|
||||||
apis: sp_version::create_apis_vec![[]],
|
|
||||||
transaction_version: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Wococo Runtime `Call` enum.
|
/// Wococo Runtime `Call` enum.
|
||||||
///
|
///
|
||||||
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
|
/// The enum represents a subset of possible `Call`s we can send to Rococo chain.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ use frame_support::{
|
|||||||
dispatch::Dispatchable,
|
dispatch::Dispatchable,
|
||||||
parameter_types,
|
parameter_types,
|
||||||
weights::{
|
weights::{
|
||||||
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_PER_SECOND},
|
constants::{BlockExecutionWeight, WEIGHT_PER_SECOND},
|
||||||
DispatchClass, Weight,
|
DispatchClass, Weight,
|
||||||
},
|
},
|
||||||
Blake2_128Concat, RuntimeDebug, StorageHasher, Twox128,
|
Blake2_128Concat, RuntimeDebug, StorageHasher, Twox128,
|
||||||
@@ -33,13 +33,13 @@ use sp_core::Hasher as HasherT;
|
|||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
generic,
|
generic,
|
||||||
traits::{BlakeTwo256, IdentifyAccount, Verify},
|
traits::{BlakeTwo256, IdentifyAccount, Verify},
|
||||||
MultiAddress, MultiSignature, OpaqueExtrinsic, Perbill,
|
MultiAddress, MultiSignature, OpaqueExtrinsic,
|
||||||
};
|
};
|
||||||
use sp_std::prelude::Vec;
|
use sp_std::prelude::Vec;
|
||||||
|
|
||||||
// Re-export's to avoid extra substrate dependencies in chain-specific crates.
|
// Re-export's to avoid extra substrate dependencies in chain-specific crates.
|
||||||
pub use frame_support::Parameter;
|
pub use frame_support::{weights::constants::ExtrinsicBaseWeight, Parameter};
|
||||||
pub use sp_runtime::traits::Convert;
|
pub use sp_runtime::{traits::Convert, Perbill};
|
||||||
|
|
||||||
/// Number of extra bytes (excluding size of storage value itself) of storage proof, built at
|
/// Number of extra bytes (excluding size of storage value itself) of storage proof, built at
|
||||||
/// Polkadot-like chain. This mostly depends on number of entries in the storage trie.
|
/// Polkadot-like chain. This mostly depends on number of entries in the storage trie.
|
||||||
|
|||||||
@@ -59,5 +59,6 @@ sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|||||||
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
hex-literal = "0.3"
|
hex-literal = "0.3"
|
||||||
|
pallet-bridge-grandpa = { path = "../../modules/grandpa" }
|
||||||
|
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
@@ -16,12 +16,13 @@
|
|||||||
|
|
||||||
//! Rococo-to-Wococo headers sync entrypoint.
|
//! Rococo-to-Wococo headers sync entrypoint.
|
||||||
|
|
||||||
|
use crate::chains::wococo_headers_to_rococo::MAXIMAL_BALANCE_DECREASE_PER_DAY;
|
||||||
use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate};
|
use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate};
|
||||||
|
|
||||||
use bp_header_chain::justification::GrandpaJustification;
|
use bp_header_chain::justification::GrandpaJustification;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use relay_rococo_client::{Rococo, SyncHeader as RococoSyncHeader};
|
use relay_rococo_client::{Rococo, SyncHeader as RococoSyncHeader};
|
||||||
use relay_substrate_client::{Chain, Client, TransactionSignScheme};
|
use relay_substrate_client::{Chain, TransactionSignScheme};
|
||||||
use relay_utils::metrics::MetricsParams;
|
use relay_utils::metrics::MetricsParams;
|
||||||
use relay_wococo_client::{SigningParams as WococoSigningParams, Wococo};
|
use relay_wococo_client::{SigningParams as WococoSigningParams, Wococo};
|
||||||
use sp_core::{Bytes, Pair};
|
use sp_core::{Bytes, Pair};
|
||||||
@@ -38,11 +39,16 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
|
|||||||
crate::chains::add_polkadot_kusama_price_metrics::<Self>(params)
|
crate::chains::add_polkadot_kusama_price_metrics::<Self>(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_relay_guards(target_client: &Client<Self::TargetChain>) {
|
fn start_relay_guards(&self) {
|
||||||
relay_substrate_client::guard::abort_on_spec_version_change(
|
relay_substrate_client::guard::abort_on_spec_version_change(
|
||||||
target_client.clone(),
|
self.target_client.clone(),
|
||||||
bp_wococo::VERSION.spec_version,
|
bp_wococo::VERSION.spec_version,
|
||||||
)
|
);
|
||||||
|
relay_substrate_client::guard::abort_when_account_balance_decreased(
|
||||||
|
self.target_client.clone(),
|
||||||
|
self.transactions_author(),
|
||||||
|
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_author(&self) -> bp_wococo::AccountId {
|
fn transactions_author(&self) -> bp_wococo::AccountId {
|
||||||
|
|||||||
@@ -21,11 +21,18 @@ use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityT
|
|||||||
use bp_header_chain::justification::GrandpaJustification;
|
use bp_header_chain::justification::GrandpaJustification;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use relay_rococo_client::{Rococo, SigningParams as RococoSigningParams};
|
use relay_rococo_client::{Rococo, SigningParams as RococoSigningParams};
|
||||||
use relay_substrate_client::{Chain, Client, TransactionSignScheme};
|
use relay_substrate_client::{Chain, TransactionSignScheme};
|
||||||
use relay_utils::metrics::MetricsParams;
|
use relay_utils::metrics::MetricsParams;
|
||||||
use relay_wococo_client::{SyncHeader as WococoSyncHeader, Wococo};
|
use relay_wococo_client::{SyncHeader as WococoSyncHeader, Wococo};
|
||||||
use sp_core::{Bytes, Pair};
|
use sp_core::{Bytes, Pair};
|
||||||
|
|
||||||
|
/// Maximal saturating difference between `balance(now)` and `balance(now-24h)` to treat
|
||||||
|
/// relay as gone wild.
|
||||||
|
///
|
||||||
|
/// See `maximal_balance_decrease_per_day_is_sane` test for details.
|
||||||
|
/// Note that this is in plancks, so this corresponds to `1500 UNITS`.
|
||||||
|
pub(crate) const MAXIMAL_BALANCE_DECREASE_PER_DAY: bp_rococo::Balance = 1_500_000_000_000_000;
|
||||||
|
|
||||||
/// Wococo-to-Rococo finality sync pipeline.
|
/// Wococo-to-Rococo finality sync pipeline.
|
||||||
pub(crate) type WococoFinalityToRococo = SubstrateFinalityToSubstrate<Wococo, Rococo, RococoSigningParams>;
|
pub(crate) type WococoFinalityToRococo = SubstrateFinalityToSubstrate<Wococo, Rococo, RococoSigningParams>;
|
||||||
|
|
||||||
@@ -38,11 +45,16 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
|
|||||||
crate::chains::add_polkadot_kusama_price_metrics::<Self>(params)
|
crate::chains::add_polkadot_kusama_price_metrics::<Self>(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_relay_guards(target_client: &Client<Self::TargetChain>) {
|
fn start_relay_guards(&self) {
|
||||||
relay_substrate_client::guard::abort_on_spec_version_change(
|
relay_substrate_client::guard::abort_on_spec_version_change(
|
||||||
target_client.clone(),
|
self.target_client.clone(),
|
||||||
bp_rococo::VERSION.spec_version,
|
bp_rococo::VERSION.spec_version,
|
||||||
)
|
);
|
||||||
|
relay_substrate_client::guard::abort_when_account_balance_decreased(
|
||||||
|
self.target_client.clone(),
|
||||||
|
self.transactions_author(),
|
||||||
|
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_author(&self) -> bp_rococo::AccountId {
|
fn transactions_author(&self) -> bp_rococo::AccountId {
|
||||||
@@ -65,3 +77,41 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
|
|||||||
Bytes(transaction.encode())
|
Bytes(transaction.encode())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use frame_support::weights::WeightToFeePolynomial;
|
||||||
|
use pallet_bridge_grandpa::weights::WeightInfo;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn maximal_balance_decrease_per_day_is_sane() {
|
||||||
|
// Rococo/Wococo GRANDPA pallet weights. They're now using Rialto weights => using `RialtoWeight` is justified.
|
||||||
|
//
|
||||||
|
// Using Rialto runtime this is slightly incorrect, because `DbWeight` of Rococo/Wococo runtime may differ
|
||||||
|
// from the `DbWeight` of Rialto runtime. But now (and most probably forever) it is the same.
|
||||||
|
type RococoGrandpaPalletWeights = pallet_bridge_grandpa::weights::RialtoWeight<rialto_runtime::Runtime>;
|
||||||
|
|
||||||
|
// The following formula shall not be treated as super-accurate - guard is to protect from mad relays,
|
||||||
|
// not to protect from over-average loses.
|
||||||
|
//
|
||||||
|
// Worst case: we're submitting proof for every source header. Since we submit every header, the number of
|
||||||
|
// headers in ancestry proof is near to 0 (let's round up to 2). And the number of authorities is 1024,
|
||||||
|
// which is (now) larger than on any existing chain => normally there'll be ~1024*2/3+1 commits.
|
||||||
|
const AVG_VOTES_ANCESTRIES_LEN: u32 = 2;
|
||||||
|
const AVG_PRECOMMITS_LEN: u32 = 1024 * 2 / 3 + 1;
|
||||||
|
let number_of_source_headers_per_day: bp_wococo::Balance = bp_wococo::DAYS as _;
|
||||||
|
let single_source_header_submit_call_weight =
|
||||||
|
RococoGrandpaPalletWeights::submit_finality_proof(AVG_VOTES_ANCESTRIES_LEN, AVG_PRECOMMITS_LEN);
|
||||||
|
// for simplicity - add extra weight for base tx fee + fee that is paid for the tx size + adjusted fee
|
||||||
|
let single_source_header_submit_tx_weight = single_source_header_submit_call_weight * 3 / 2;
|
||||||
|
let single_source_header_tx_cost = bp_rococo::WeightToFee::calc(&single_source_header_submit_tx_weight);
|
||||||
|
let maximal_expected_decrease = single_source_header_tx_cost * number_of_source_headers_per_day;
|
||||||
|
assert!(
|
||||||
|
MAXIMAL_BALANCE_DECREASE_PER_DAY >= maximal_expected_decrease,
|
||||||
|
"Maximal expected loss per day {} is larger than hardcoded {}",
|
||||||
|
maximal_expected_decrease,
|
||||||
|
MAXIMAL_BALANCE_DECREASE_PER_DAY,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -97,15 +97,10 @@ impl RelayHeaders {
|
|||||||
let target_client = self.target.to_client::<Target>().await?;
|
let target_client = self.target.to_client::<Target>().await?;
|
||||||
let target_sign = self.target_sign.to_keypair::<Target>()?;
|
let target_sign = self.target_sign.to_keypair::<Target>()?;
|
||||||
let metrics_params = Finality::customize_metrics(self.prometheus_params.into())?;
|
let metrics_params = Finality::customize_metrics(self.prometheus_params.into())?;
|
||||||
Finality::start_relay_guards(&target_client);
|
let finality = Finality::new(target_client.clone(), target_sign);
|
||||||
|
finality.start_relay_guards();
|
||||||
|
|
||||||
crate::finality_pipeline::run(
|
crate::finality_pipeline::run(finality, source_client, target_client, metrics_params).await
|
||||||
Finality::new(target_client.clone(), target_sign),
|
|
||||||
source_client,
|
|
||||||
target_client,
|
|
||||||
metrics_params,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub trait SubstrateFinalitySyncPipeline: FinalitySyncPipeline {
|
|||||||
/// Different finality bridges may have different set of guards - e.g. on ephemeral chains we
|
/// Different finality bridges may have different set of guards - e.g. on ephemeral chains we
|
||||||
/// don't need version guards, on test chains we don't care that much about relayer account
|
/// don't need version guards, on test chains we don't care that much about relayer account
|
||||||
/// balance, ... So the implementation is left to the specific bridges.
|
/// balance, ... So the implementation is left to the specific bridges.
|
||||||
fn start_relay_guards(_target_client: &Client<Self::TargetChain>) {}
|
fn start_relay_guards(&self) {}
|
||||||
|
|
||||||
/// Returns id of account that we're using to sign transactions at target chain.
|
/// Returns id of account that we're using to sign transactions at target chain.
|
||||||
fn transactions_author(&self) -> <Self::TargetChain as Chain>::AccountId;
|
fn transactions_author(&self) -> <Self::TargetChain as Chain>::AccountId;
|
||||||
|
|||||||
Reference in New Issue
Block a user