mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-23 16:35:46 +00:00
Update bridges subtree (#5165)
* Squashed 'bridges/' changes from 1602249f0a..f220d2fcca f220d2fcca Polkadot staging update (#1356) 02fd3d497c fix parse_transaction on Rialto+Millau (#1360) bc191fd9a2 update parity-scale-codec to 3.1.2 (#1359) a37226e79c update chain versions (#1358) ff5d539fcb Update Substrate/Polkadot/Cumulus references (#1353) 1581f60cd5 Support dedicated lanes for pallets (#962) 0a7ccf5c57 ignore more "increase" alerts that are sometimes signalling NoData at startup (#1351) 31165127cc added no_stack_overflow_when_decoding_nested_call_during_dispatch test (#1349) 7000619eb8 replace From<>InboundLaneApi with direct storage reads (#1348) 515df10ccc added alerts for relay balances (#1347) b56f6a87de Mortal conversion rate updater transactions (#1257) 20f2f331ec edition = "2021" (#1346) 99147d4f75 update regex to 1.5.5 (#1345) 686191f379 use DecodeLimit when decoding incoming calls (#1344) a70c276006 get rid of '[No Data] Messages from Millau to Rialto are not being delivered' warnings (#1342) 01f29b8ac1 fix conversion rate metric in dashboards (#1341) 51c3bf351f Increase rate from metric when estimating fee (#1340) 3bb9c4f68f fix generator scripts to be consistent with updatedrelay output (#1339) 0475a1667b fixed mess with conversion rates (#1338) d8fdd7d716 synchronize relay cli changes and token swap generator script (#1337) 6e928137a5 fix conversion rate override in token swap (#1336) 62d4a4811d override conversion rate in tokens swap generator (#1335) ed9e1c839c fi typo in generator script (#1334) 3254b5af7a Override conversion rate when computing message fee (#1261) 66df68b5b8 Revert "Revert "override conversion rate in estimate-message-fee RPC (#1189)" (#1275)" (#1333) 0ca6fc6ef8 fix clippy issues (#1332) 5414b2fffb Reinitialize bridge relay subcommand (#1331) a63d95ba7d removed extra *_RUNTIME_VERSION consts from relay code (#1330) 59fb18a310 fix typo in alert expression (#1329) a6267a47ee Using-same-fork metric for finality and complex relay (#1327) 88d684d37e use mortal transactions in transaction resubmitter (#1326) 8ff88b6844 impl Decode for SignedExtensions (otherwise transaction resubmitter panicks) (#1325) 1ed09854f0 Encode and estimate Rococo/Wococo/Kusama/Polkadot messages (#1322) ddb4517e13 Add some tests to check integrity of chain constants + bridge configuration (#1316) bdeedb7ab9 Fix issues from cargo deny (#1311) d3d79d01e0 expose fee multiplier metrics in messages relay (#1312) c8b3f0ea16 Endow relayer account at target chain in message benchmarks (#1310) f51ecd92b6 fix benchmarks before using it in Polkadot/Kusama/Rococo runtimes (#1309) 6935c619ad increase relay balance guard limits for Polkadot<>Kusama bridge (#1308) 7e31834c66 Fix mandatory headers scanning in on-demand relay (#1306) 92ddc3ea7a Polkadot-staging update (#1305) 3787193a31 fix session length of Rococo and Wococo (#1304) eb468d29c0 Revert nightly docker pin (#1301) e2d4c073e1 Use raw balance value if tokenDecimals property is missing (#1299) 108f4b29d1 Fix ss58 prefixes of Polkadot, Kusama and Westend used by relay (#1298) 64fbd2705e bump chain spec versions (#1297) 5707777b86 Bump Substrate/Polkadot/Cumulus refs (#1295) 29eecdf1fa Merge pull request #1294 from paritytech/polkadot-staging-update 1f0c05368e Relay balance metrics (#1291) 6356bb90b3 when messages pallet is halted, relay shall not submit messages delivery/confirmation transactions (#1289) 800dc2df8d when GRANDPA pallet is halted, relay shall not submit finality transactions (#1288) 3dd8e4f936 disable BEEFY allerts for Rialto (#1285) f58fed7380 support version mode cli options in send-message subcommand (#1284) 3aac448da3 reuse polkadot-service code (#1273) 2bdbb651e1 replace latest_confirmed_nonce runtime APIs with direct storage reads (#1282) 5f9c6d241f move "common" code of messages pallet benchmarks helpers to the common library (#1281) 173d2d8229 Merge pull request #1280 from paritytech/polkadot-staging-update 8b9c4ec16d do not start spec_version guard when version mode is set to auto (#1278) e98d682de2 removed extra messages benchmarks (#1279) c730e25b61 Move benchmarks from Rialto to Millau (#1277) 54146416e7 Merge pull request #1276 from paritytech/polkadot-staging-update df70118174 Merge branch 'master' into polkadot-staging-update ed7def64c4 Revert "override conversion rate in estimate-message-fee RPC (#1189)" (#1275) 38c6c3a49f Use "production" floating tag when uilding docker image from version git tags (#1272) ded9ff6dbb Replace InboundLaneApi::latest_received_nonce with direct storage read (#1269) f704a741ee Polkadot staging update (#1270) 8c65f0d7ab verify that GRANDPA pallet is not initialized before submitting initialization transaction (#1267) e7e83d8944 remove OutboundLaneApi::latest_received_nonce (#1262) 9f4b34acf1 bump rococo version (#1263) 82c08c5a87 read latest_generated_nonce directly from storage (#1260) 50ffb5dd08 override conversion rate in estimate-message-fee RPC (#1189) 467ca5ef59 move storage keys computation to primitivs (#1254) 4f9884066b remporary use pinned bridges-ci image in Dockerfile (#1258) edfcb74e00 Change submit transaction spec_version and transaction_version query from chain (#1248) 4009d970d0 pin bridges-ci image (#1256) 65e51b5e1c decrease startup sleep to 5s for relays and to 120s for generators + remove curl (#1251) 3bc74355d9 Add missing RPC APIs to rialto parachain node (#1250) 80c9429284 Bump relay version to 1.0.0 (#1249) 9ead06af2a runtimes: fix call_size() test (#1245) 4fc8a29357 Use same endowed accounts set on dev/local chains (#1244) fed54371c2 Refactor message relay helpers (#1234) a15b4faae7 post-merge build fix (#1243) 52232d8d54 Fix transactions mortality (#1196) c07bba931f Expose prometheus BEEFY metrics and add them to grafana dashboard (#1242) f927775bd5 Refactor finality relay helpers (#1220) 7bf76f14a8 Update Rococo/Wococo version + prepare relay for Rococo<>Wococo bridge (#1241) e860fecd04 Enable offchain indexing for Rialto/Millau nodes (#1239) 04d4d1c6b4 Enable Beefy debug logs in test deployment (#1237) cd771f1089 Fix storage parameter name computation (#1238) 816ddd2dd2 Integrate BEEFY with Rialto & Millau runtimes (#1227) d94b62b1ac update dependencies (#1229) 98eb9ee13d Add mut support (#1232) ffef6f89f9 fixed set_operational in GRANDPA pallet (#1226) bd2f8bfbd7 Add CODEOWNERS file (#1219) 6b5cf2b591 Unify metric names (#1209) d1541e797e remove abandoned exchange relay (#1217) 39140d0b34 Remove unused `relays/headers` (#1216) 9bc071d42b Remove unused PoA<>Substrate bridge (#1210) 877e8d01e3 Fix UI deployment. (#1211) 6cd5775ebe Add `AtLeast32BitUnsigned` for MessageLance::SourceChainBalance (#1207) git-subtree-dir: bridges git-subtree-split: f220d2fccabbf141101d19456ecb4e3576a1d797 * fix compilation warnings
This commit is contained in:
committed by
GitHub
parent
20da356434
commit
8e01ba9c03
@@ -0,0 +1,331 @@
|
||||
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity Bridges Common.
|
||||
|
||||
// Parity Bridges Common is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity Bridges Common is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Integrity tests for chain constants and pallets configuration.
|
||||
//!
|
||||
//! Most of the tests in this module assume that the bridge is using standard (see `crate::messages`
|
||||
//! module for details) configuration.
|
||||
|
||||
use crate::messages::MessageBridge;
|
||||
|
||||
use bp_messages::MessageNonce;
|
||||
use bp_runtime::{Chain, ChainId};
|
||||
use codec::Encode;
|
||||
use frame_support::{storage::generator::StorageValue, traits::Get};
|
||||
use frame_system::limits;
|
||||
|
||||
/// Macro that ensures that the runtime configuration and chain primitives crate are sharing
|
||||
/// the same types (index, block number, hash, hasher, account id and header).
|
||||
#[macro_export]
|
||||
macro_rules! assert_chain_types(
|
||||
( runtime: $r:path, this_chain: $this:path ) => {
|
||||
{
|
||||
// if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard
|
||||
// configuration is used), or something has broke existing configuration (meaning that all bridged chains
|
||||
// and relays will stop functioning)
|
||||
use frame_system::Config as SystemConfig;
|
||||
use static_assertions::assert_type_eq_all;
|
||||
|
||||
assert_type_eq_all!(<$r as SystemConfig>::Index, bp_runtime::IndexOf<$this>);
|
||||
assert_type_eq_all!(<$r as SystemConfig>::BlockNumber, bp_runtime::BlockNumberOf<$this>);
|
||||
assert_type_eq_all!(<$r as SystemConfig>::Hash, bp_runtime::HashOf<$this>);
|
||||
assert_type_eq_all!(<$r as SystemConfig>::Hashing, bp_runtime::HasherOf<$this>);
|
||||
assert_type_eq_all!(<$r as SystemConfig>::AccountId, bp_runtime::AccountIdOf<$this>);
|
||||
assert_type_eq_all!(<$r as SystemConfig>::Header, bp_runtime::HeaderOf<$this>);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/// Macro that ensures that the bridge configuration and chain primitives crates are sharing
|
||||
/// the same types (hash, account id, ...).
|
||||
#[macro_export]
|
||||
macro_rules! assert_bridge_types(
|
||||
( bridge: $bridge:path, this_chain: $this:path, bridged_chain: $bridged:path ) => {
|
||||
{
|
||||
// if one of this asserts fail, then all chains, bridged with this chain and bridge relays are now broken
|
||||
//
|
||||
// `frame_support::weights::Weight` is used here directly, because all chains we know are using this
|
||||
// primitive (may be changed in the future)
|
||||
use $crate::messages::{
|
||||
AccountIdOf, BalanceOf, BridgedChain, HashOf, SignatureOf, SignerOf, ThisChain, WeightOf,
|
||||
};
|
||||
use static_assertions::assert_type_eq_all;
|
||||
|
||||
assert_type_eq_all!(HashOf<ThisChain<$bridge>>, bp_runtime::HashOf<$this>);
|
||||
assert_type_eq_all!(AccountIdOf<ThisChain<$bridge>>, bp_runtime::AccountIdOf<$this>);
|
||||
assert_type_eq_all!(SignerOf<ThisChain<$bridge>>, bp_runtime::AccountPublicOf<$this>);
|
||||
assert_type_eq_all!(SignatureOf<ThisChain<$bridge>>, bp_runtime::SignatureOf<$this>);
|
||||
assert_type_eq_all!(WeightOf<ThisChain<$bridge>>, frame_support::weights::Weight);
|
||||
assert_type_eq_all!(BalanceOf<ThisChain<$bridge>>, bp_runtime::BalanceOf<$this>);
|
||||
|
||||
assert_type_eq_all!(HashOf<BridgedChain<$bridge>>, bp_runtime::HashOf<$bridged>);
|
||||
assert_type_eq_all!(AccountIdOf<BridgedChain<$bridge>>, bp_runtime::AccountIdOf<$bridged>);
|
||||
assert_type_eq_all!(SignerOf<BridgedChain<$bridge>>, bp_runtime::AccountPublicOf<$bridged>);
|
||||
assert_type_eq_all!(SignatureOf<BridgedChain<$bridge>>, bp_runtime::SignatureOf<$bridged>);
|
||||
assert_type_eq_all!(WeightOf<BridgedChain<$bridge>>, frame_support::weights::Weight);
|
||||
assert_type_eq_all!(BalanceOf<BridgedChain<$bridge>>, bp_runtime::BalanceOf<$bridged>);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/// Macro that ensures that the bridge GRANDPA pallet is configured properly to bridge with given
|
||||
/// chain.
|
||||
#[macro_export]
|
||||
macro_rules! assert_bridge_grandpa_pallet_types(
|
||||
( runtime: $r:path, with_bridged_chain_grandpa_instance: $i:path, bridged_chain: $bridged:path ) => {
|
||||
{
|
||||
// if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard
|
||||
// configuration is used), or something has broke existing configuration (meaning that all bridged chains
|
||||
// and relays will stop functioning)
|
||||
use pallet_bridge_grandpa::Config as GrandpaConfig;
|
||||
use static_assertions::assert_type_eq_all;
|
||||
|
||||
assert_type_eq_all!(<$r as GrandpaConfig<$i>>::BridgedChain, $bridged);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/// Macro that ensures that the bridge messages pallet is configured properly to bridge using given
|
||||
/// configuration.
|
||||
#[macro_export]
|
||||
macro_rules! assert_bridge_messages_pallet_types(
|
||||
(
|
||||
runtime: $r:path,
|
||||
with_bridged_chain_messages_instance: $i:path,
|
||||
bridge: $bridge:path,
|
||||
this_chain_account_id_converter: $this_converter:path
|
||||
) => {
|
||||
{
|
||||
// if one of asserts fail, then either bridge isn't configured properly (or alternatively - non-standard
|
||||
// configuration is used), or something has broke existing configuration (meaning that all bridged chains
|
||||
// and relays will stop functioning)
|
||||
use $crate::messages::{
|
||||
source::FromThisChainMessagePayload,
|
||||
target::FromBridgedChainMessagePayload,
|
||||
AccountIdOf, BalanceOf, BridgedChain, ThisChain, WeightOf,
|
||||
};
|
||||
use pallet_bridge_messages::Config as MessagesConfig;
|
||||
use static_assertions::assert_type_eq_all;
|
||||
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundPayload, FromThisChainMessagePayload<$bridge>);
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::OutboundMessageFee, BalanceOf<ThisChain<$bridge>>);
|
||||
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundPayload, FromBridgedChainMessagePayload<$bridge>);
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundMessageFee, BalanceOf<BridgedChain<$bridge>>);
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::InboundRelayer, AccountIdOf<BridgedChain<$bridge>>);
|
||||
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::AccountIdConverter, $this_converter);
|
||||
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::TargetHeaderChain, BridgedChain<$bridge>);
|
||||
assert_type_eq_all!(<$r as MessagesConfig<$i>>::SourceHeaderChain, BridgedChain<$bridge>);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/// Macro that combines four other macro calls - `assert_chain_types`, `assert_bridge_types`,
|
||||
/// `assert_bridge_grandpa_pallet_types` and `assert_bridge_messages_pallet_types`. It may be used
|
||||
/// at the chain that is implemeting complete standard messages bridge (i.e. with bridge GRANDPA and
|
||||
/// messages pallets deployed).
|
||||
#[macro_export]
|
||||
macro_rules! assert_complete_bridge_types(
|
||||
(
|
||||
runtime: $r:path,
|
||||
with_bridged_chain_grandpa_instance: $gi:path,
|
||||
with_bridged_chain_messages_instance: $mi:path,
|
||||
bridge: $bridge:path,
|
||||
this_chain: $this:path,
|
||||
bridged_chain: $bridged:path,
|
||||
this_chain_account_id_converter: $this_converter:path
|
||||
) => {
|
||||
$crate::assert_chain_types!(runtime: $r, this_chain: $this);
|
||||
$crate::assert_bridge_types!(bridge: $bridge, this_chain: $this, bridged_chain: $bridged);
|
||||
$crate::assert_bridge_grandpa_pallet_types!(
|
||||
runtime: $r,
|
||||
with_bridged_chain_grandpa_instance: $gi,
|
||||
bridged_chain: $bridged
|
||||
);
|
||||
$crate::assert_bridge_messages_pallet_types!(
|
||||
runtime: $r,
|
||||
with_bridged_chain_messages_instance: $mi,
|
||||
bridge: $bridge,
|
||||
this_chain_account_id_converter: $this_converter
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/// Parameters for asserting chain-related constants.
|
||||
#[derive(Debug)]
|
||||
pub struct AssertChainConstants {
|
||||
/// Block length limits of the chain.
|
||||
pub block_length: limits::BlockLength,
|
||||
/// Block weight limits of the chain.
|
||||
pub block_weights: limits::BlockWeights,
|
||||
}
|
||||
|
||||
/// Test that our hardcoded, chain-related constants, are matching chain runtime configuration.
|
||||
///
|
||||
/// In particular, this test ensures that:
|
||||
///
|
||||
/// 1) block weight limits are matching;
|
||||
/// 2) block size limits are matching.
|
||||
pub fn assert_chain_constants<R, C>(params: AssertChainConstants)
|
||||
where
|
||||
R: frame_system::Config,
|
||||
C: Chain,
|
||||
{
|
||||
// we don't check runtime version here, because in our case we'll be building relay from one
|
||||
// repo and runtime will live in another repo, along with outdated relay version. To avoid
|
||||
// unneeded commits, let's not raise an error in case of version mismatch.
|
||||
|
||||
// if one of following assert fails, it means that we may need to upgrade bridged chain and
|
||||
// relay to use updated constants. If constants are now smaller than before, it may lead to
|
||||
// undeliverable messages.
|
||||
|
||||
// `BlockLength` struct is not implementing `PartialEq`, so we compare encoded values here.
|
||||
assert_eq!(
|
||||
R::BlockLength::get().encode(),
|
||||
params.block_length.encode(),
|
||||
"BlockLength from runtime ({:?}) differ from hardcoded: {:?}",
|
||||
R::BlockLength::get(),
|
||||
params.block_length,
|
||||
);
|
||||
// `BlockWeights` struct is not implementing `PartialEq`, so we compare encoded values here
|
||||
assert_eq!(
|
||||
R::BlockWeights::get().encode(),
|
||||
params.block_weights.encode(),
|
||||
"BlockWeights from runtime ({:?}) differ from hardcoded: {:?}",
|
||||
R::BlockWeights::get(),
|
||||
params.block_weights,
|
||||
);
|
||||
}
|
||||
|
||||
/// Test that the constants, used in GRANDPA pallet configuration are valid.
|
||||
pub fn assert_bridge_grandpa_pallet_constants<R, GI>()
|
||||
where
|
||||
R: pallet_bridge_grandpa::Config<GI>,
|
||||
GI: 'static,
|
||||
{
|
||||
assert!(
|
||||
R::MaxRequests::get() > 0,
|
||||
"MaxRequests ({}) must be larger than zero",
|
||||
R::MaxRequests::get(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters for asserting messages pallet constants.
|
||||
#[derive(Debug)]
|
||||
pub struct AssertBridgeMessagesPalletConstants {
|
||||
/// Maximal number of unrewarded relayer entries in a confirmation transaction at the bridged
|
||||
/// chain.
|
||||
pub max_unrewarded_relayers_in_bridged_confirmation_tx: MessageNonce,
|
||||
/// Maximal number of unconfirmed messages in a confirmation transaction at the bridged chain.
|
||||
pub max_unconfirmed_messages_in_bridged_confirmation_tx: MessageNonce,
|
||||
/// Identifier of the bridged chain.
|
||||
pub bridged_chain_id: ChainId,
|
||||
}
|
||||
|
||||
/// Test that the constants, used in messages pallet configuration are valid.
|
||||
pub fn assert_bridge_messages_pallet_constants<R, MI>(params: AssertBridgeMessagesPalletConstants)
|
||||
where
|
||||
R: pallet_bridge_messages::Config<MI>,
|
||||
MI: 'static,
|
||||
{
|
||||
assert!(
|
||||
R::MaxMessagesToPruneAtOnce::get() > 0,
|
||||
"MaxMessagesToPruneAtOnce ({}) must be larger than zero",
|
||||
R::MaxMessagesToPruneAtOnce::get(),
|
||||
);
|
||||
assert!(
|
||||
R::MaxUnrewardedRelayerEntriesAtInboundLane::get() <= params.max_unrewarded_relayers_in_bridged_confirmation_tx,
|
||||
"MaxUnrewardedRelayerEntriesAtInboundLane ({}) must be <= than the hardcoded value for bridged chain: {}",
|
||||
R::MaxUnrewardedRelayerEntriesAtInboundLane::get(),
|
||||
params.max_unrewarded_relayers_in_bridged_confirmation_tx,
|
||||
);
|
||||
assert!(
|
||||
R::MaxUnconfirmedMessagesAtInboundLane::get() <= params.max_unconfirmed_messages_in_bridged_confirmation_tx,
|
||||
"MaxUnrewardedRelayerEntriesAtInboundLane ({}) must be <= than the hardcoded value for bridged chain: {}",
|
||||
R::MaxUnconfirmedMessagesAtInboundLane::get(),
|
||||
params.max_unconfirmed_messages_in_bridged_confirmation_tx,
|
||||
);
|
||||
assert_eq!(R::BridgedChainId::get(), params.bridged_chain_id);
|
||||
}
|
||||
|
||||
/// Parameters for asserting bridge pallet names.
|
||||
#[derive(Debug)]
|
||||
pub struct AssertBridgePalletNames<'a> {
|
||||
/// Name of the messages pallet, deployed at the bridged chain and used to bridge with this
|
||||
/// chain.
|
||||
pub with_this_chain_messages_pallet_name: &'a str,
|
||||
/// Name of the GRANDPA pallet, deployed at this chain and used to bridge with the bridged
|
||||
/// chain.
|
||||
pub with_bridged_chain_grandpa_pallet_name: &'a str,
|
||||
/// Name of the messages pallet, deployed at this chain and used to bridge with the bridged
|
||||
/// chain.
|
||||
pub with_bridged_chain_messages_pallet_name: &'a str,
|
||||
}
|
||||
|
||||
/// Tests that bridge pallet names used in `construct_runtime!()` macro call are matching constants
|
||||
/// from chain primitives crates.
|
||||
pub fn assert_bridge_pallet_names<B, R, GI, MI>(params: AssertBridgePalletNames)
|
||||
where
|
||||
B: MessageBridge,
|
||||
R: pallet_bridge_grandpa::Config<GI> + pallet_bridge_messages::Config<MI>,
|
||||
GI: 'static,
|
||||
MI: 'static,
|
||||
{
|
||||
assert_eq!(B::BRIDGED_MESSAGES_PALLET_NAME, params.with_this_chain_messages_pallet_name);
|
||||
assert_eq!(
|
||||
pallet_bridge_grandpa::PalletOwner::<R, GI>::storage_value_final_key().to_vec(),
|
||||
bp_runtime::storage_value_key(params.with_bridged_chain_grandpa_pallet_name, "PalletOwner",).0,
|
||||
);
|
||||
assert_eq!(
|
||||
pallet_bridge_messages::PalletOwner::<R, MI>::storage_value_final_key().to_vec(),
|
||||
bp_runtime::storage_value_key(
|
||||
params.with_bridged_chain_messages_pallet_name,
|
||||
"PalletOwner",
|
||||
)
|
||||
.0,
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters for asserting complete standard messages bridge.
|
||||
#[derive(Debug)]
|
||||
pub struct AssertCompleteBridgeConstants<'a> {
|
||||
/// Parameters to assert this chain constants.
|
||||
pub this_chain_constants: AssertChainConstants,
|
||||
/// Parameters to assert messages pallet constants.
|
||||
pub messages_pallet_constants: AssertBridgeMessagesPalletConstants,
|
||||
/// Parameters to assert pallet names constants.
|
||||
pub pallet_names: AssertBridgePalletNames<'a>,
|
||||
}
|
||||
|
||||
/// All bridge-related constants tests for the complete standard messages bridge (i.e. with bridge
|
||||
/// GRANDPA and messages pallets deployed).
|
||||
pub fn assert_complete_bridge_constants<R, GI, MI, B, This>(params: AssertCompleteBridgeConstants)
|
||||
where
|
||||
R: frame_system::Config
|
||||
+ pallet_bridge_grandpa::Config<GI>
|
||||
+ pallet_bridge_messages::Config<MI>,
|
||||
GI: 'static,
|
||||
MI: 'static,
|
||||
B: MessageBridge,
|
||||
This: Chain,
|
||||
{
|
||||
assert_chain_constants::<R, This>(params.this_chain_constants);
|
||||
assert_bridge_grandpa_pallet_constants::<R, GI>();
|
||||
assert_bridge_messages_pallet_constants::<R, MI>(params.messages_pallet_constants);
|
||||
assert_bridge_pallet_names::<B, R, GI, MI>(params.pallet_names);
|
||||
}
|
||||
@@ -21,3 +21,6 @@
|
||||
pub mod messages;
|
||||
pub mod messages_api;
|
||||
pub mod messages_benchmarking;
|
||||
|
||||
#[cfg(feature = "integrity-test")]
|
||||
pub mod integrity;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
use bp_message_dispatch::MessageDispatch as _;
|
||||
use bp_messages::{
|
||||
source_chain::{LaneMessageVerifier, Sender},
|
||||
source_chain::LaneMessageVerifier,
|
||||
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages},
|
||||
InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, OutboundLaneData,
|
||||
};
|
||||
@@ -30,7 +30,7 @@ use bp_runtime::{
|
||||
messages::{DispatchFeePayment, MessageDispatchResult},
|
||||
ChainId, Size, StorageProofChecker,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use codec::{Decode, DecodeLimit, Encode};
|
||||
use frame_support::{
|
||||
traits::{Currency, ExistenceRequirement},
|
||||
weights::{Weight, WeightToFeePolynomial},
|
||||
@@ -70,6 +70,7 @@ pub trait MessageBridge {
|
||||
/// Convert Bridged chain balance into This chain balance.
|
||||
fn bridged_balance_to_this_balance(
|
||||
bridged_balance: BalanceOf<BridgedChain<Self>>,
|
||||
bridged_to_this_conversion_rate_override: Option<FixedU128>,
|
||||
) -> BalanceOf<ThisChain<Self>>;
|
||||
}
|
||||
|
||||
@@ -110,11 +111,13 @@ pub struct MessageTransaction<Weight> {
|
||||
|
||||
/// This chain that has `pallet-bridge-messages` and `dispatch` modules.
|
||||
pub trait ThisChainWithMessages: ChainWithMessages {
|
||||
/// Call origin on the chain.
|
||||
type Origin;
|
||||
/// Call type on the chain.
|
||||
type Call: Encode + Decode;
|
||||
|
||||
/// Are we accepting any messages to the given lane?
|
||||
fn is_outbound_lane_enabled(lane: &LaneId) -> bool;
|
||||
/// Do we accept message sent by given origin to given lane?
|
||||
fn is_message_accepted(origin: &Self::Origin, lane: &LaneId) -> bool;
|
||||
|
||||
/// Maximal number of pending (not yet delivered) messages at This chain.
|
||||
///
|
||||
@@ -172,11 +175,13 @@ pub type SignatureOf<C> = <C as ChainWithMessages>::Signature;
|
||||
pub type WeightOf<C> = <C as ChainWithMessages>::Weight;
|
||||
/// Type of balances that is used on the chain.
|
||||
pub type BalanceOf<C> = <C as ChainWithMessages>::Balance;
|
||||
/// Type of origin that is used on the chain.
|
||||
pub type OriginOf<C> = <C as ThisChainWithMessages>::Origin;
|
||||
/// Type of call that is used on this chain.
|
||||
pub type CallOf<C> = <C as ThisChainWithMessages>::Call;
|
||||
|
||||
/// Raw storage proof type (just raw trie nodes).
|
||||
type RawStorageProof = Vec<Vec<u8>>;
|
||||
pub type RawStorageProof = Vec<Vec<u8>>;
|
||||
|
||||
/// Compute fee of transaction at runtime where regular transaction payment pallet is being used.
|
||||
///
|
||||
@@ -269,7 +274,8 @@ pub mod source {
|
||||
pub struct FromThisChainMessageVerifier<B>(PhantomData<B>);
|
||||
|
||||
/// The error message returned from LaneMessageVerifier when outbound lane is disabled.
|
||||
pub const OUTBOUND_LANE_DISABLED: &str = "The outbound message lane is disabled.";
|
||||
pub const MESSAGE_REJECTED_BY_OUTBOUND_LANE: &str =
|
||||
"The outbound message lane has rejected the message.";
|
||||
/// The error message returned from LaneMessageVerifier when too many pending messages at the
|
||||
/// lane.
|
||||
pub const TOO_MANY_PENDING_MESSAGES: &str = "Too many pending messages at the lane.";
|
||||
@@ -280,26 +286,30 @@ pub mod source {
|
||||
|
||||
impl<B>
|
||||
LaneMessageVerifier<
|
||||
OriginOf<ThisChain<B>>,
|
||||
AccountIdOf<ThisChain<B>>,
|
||||
FromThisChainMessagePayload<B>,
|
||||
BalanceOf<ThisChain<B>>,
|
||||
> for FromThisChainMessageVerifier<B>
|
||||
where
|
||||
B: MessageBridge,
|
||||
// matches requirements from the `frame_system::Config::Origin`
|
||||
OriginOf<ThisChain<B>>: Clone
|
||||
+ Into<Result<frame_system::RawOrigin<AccountIdOf<ThisChain<B>>>, OriginOf<ThisChain<B>>>>,
|
||||
AccountIdOf<ThisChain<B>>: PartialEq + Clone,
|
||||
{
|
||||
type Error = &'static str;
|
||||
|
||||
fn verify_message(
|
||||
submitter: &Sender<AccountIdOf<ThisChain<B>>>,
|
||||
submitter: &OriginOf<ThisChain<B>>,
|
||||
delivery_and_dispatch_fee: &BalanceOf<ThisChain<B>>,
|
||||
lane: &LaneId,
|
||||
lane_outbound_data: &OutboundLaneData,
|
||||
payload: &FromThisChainMessagePayload<B>,
|
||||
) -> Result<(), Self::Error> {
|
||||
// reject message if lane is blocked
|
||||
if !ThisChain::<B>::is_outbound_lane_enabled(lane) {
|
||||
return Err(OUTBOUND_LANE_DISABLED)
|
||||
if !ThisChain::<B>::is_message_accepted(submitter, lane) {
|
||||
return Err(MESSAGE_REJECTED_BY_OUTBOUND_LANE)
|
||||
}
|
||||
|
||||
// reject message if there are too many pending messages at this lane
|
||||
@@ -313,11 +323,29 @@ pub mod source {
|
||||
|
||||
// Do the dispatch-specific check. We assume that the target chain uses
|
||||
// `Dispatch`, so we verify the message accordingly.
|
||||
pallet_bridge_dispatch::verify_message_origin(submitter, payload)
|
||||
.map_err(|_| BAD_ORIGIN)?;
|
||||
let raw_origin_or_err: Result<
|
||||
frame_system::RawOrigin<AccountIdOf<ThisChain<B>>>,
|
||||
OriginOf<ThisChain<B>>,
|
||||
> = submitter.clone().into();
|
||||
match raw_origin_or_err {
|
||||
Ok(raw_origin) =>
|
||||
pallet_bridge_dispatch::verify_message_origin(&raw_origin, payload)
|
||||
.map(drop)
|
||||
.map_err(|_| BAD_ORIGIN)?,
|
||||
Err(_) => {
|
||||
// so what it means that we've failed to convert origin to the
|
||||
// `frame_system::RawOrigin`? now it means that the custom pallet origin has
|
||||
// been used to send the message. Do we need to verify it? The answer is no,
|
||||
// because pallet may craft any origin (e.g. root) && we can't verify whether it
|
||||
// is valid, or not.
|
||||
},
|
||||
};
|
||||
|
||||
let minimal_fee_in_this_tokens =
|
||||
estimate_message_dispatch_and_delivery_fee::<B>(payload, B::RELAYER_FEE_PERCENT)?;
|
||||
let minimal_fee_in_this_tokens = estimate_message_dispatch_and_delivery_fee::<B>(
|
||||
payload,
|
||||
B::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
)?;
|
||||
|
||||
// compare with actual fee paid
|
||||
if *delivery_and_dispatch_fee < minimal_fee_in_this_tokens {
|
||||
@@ -371,6 +399,7 @@ pub mod source {
|
||||
pub fn estimate_message_dispatch_and_delivery_fee<B: MessageBridge>(
|
||||
payload: &FromThisChainMessagePayload<B>,
|
||||
relayer_fee_percent: u32,
|
||||
bridged_to_this_conversion_rate: Option<FixedU128>,
|
||||
) -> Result<BalanceOf<ThisChain<B>>, &'static str> {
|
||||
// the fee (in Bridged tokens) of all transactions that are made on the Bridged chain
|
||||
//
|
||||
@@ -391,8 +420,11 @@ pub mod source {
|
||||
ThisChain::<B>::transaction_payment(confirmation_transaction);
|
||||
|
||||
// minimal fee (in This tokens) is a sum of all required fees
|
||||
let minimal_fee = B::bridged_balance_to_this_balance(delivery_transaction_fee)
|
||||
.checked_add(&confirmation_transaction_fee);
|
||||
let minimal_fee = B::bridged_balance_to_this_balance(
|
||||
delivery_transaction_fee,
|
||||
bridged_to_this_conversion_rate,
|
||||
)
|
||||
.checked_add(&confirmation_transaction_fee);
|
||||
|
||||
// before returning, add extra fee that is paid to the relayer (relayer interest)
|
||||
minimal_fee
|
||||
@@ -428,7 +460,7 @@ pub mod source {
|
||||
// Messages delivery proof is just proof of single storage key read => any error
|
||||
// is fatal.
|
||||
let storage_inbound_lane_data_key =
|
||||
pallet_bridge_messages::storage_keys::inbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, &lane);
|
||||
bp_messages::storage_keys::inbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, &lane);
|
||||
let raw_inbound_lane_data = storage
|
||||
.read_value(storage_inbound_lane_data_key.0.as_ref())
|
||||
.map_err(|_| "Failed to read inbound lane state from storage proof")?
|
||||
@@ -513,7 +545,11 @@ pub mod target {
|
||||
for Result<DecodedCall, ()>
|
||||
{
|
||||
fn from(encoded_call: FromBridgedChainEncodedMessageCall<DecodedCall>) -> Self {
|
||||
DecodedCall::decode(&mut &encoded_call.encoded_call[..]).map_err(drop)
|
||||
DecodedCall::decode_with_depth_limit(
|
||||
sp_api::MAX_EXTRINSIC_DEPTH,
|
||||
&mut &encoded_call.encoded_call[..],
|
||||
)
|
||||
.map_err(drop)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,16 +710,15 @@ pub mod target {
|
||||
B: MessageBridge,
|
||||
{
|
||||
fn read_raw_outbound_lane_data(&self, lane_id: &LaneId) -> Option<Vec<u8>> {
|
||||
let storage_outbound_lane_data_key =
|
||||
pallet_bridge_messages::storage_keys::outbound_lane_data_key(
|
||||
B::BRIDGED_MESSAGES_PALLET_NAME,
|
||||
lane_id,
|
||||
);
|
||||
let storage_outbound_lane_data_key = bp_messages::storage_keys::outbound_lane_data_key(
|
||||
B::BRIDGED_MESSAGES_PALLET_NAME,
|
||||
lane_id,
|
||||
);
|
||||
self.storage.read_value(storage_outbound_lane_data_key.0.as_ref()).ok()?
|
||||
}
|
||||
|
||||
fn read_raw_message(&self, message_key: &MessageKey) -> Option<Vec<u8>> {
|
||||
let storage_message_key = pallet_bridge_messages::storage_keys::message_key(
|
||||
let storage_message_key = bp_messages::storage_keys::message_key(
|
||||
B::BRIDGED_MESSAGES_PALLET_NAME,
|
||||
&message_key.lane_id,
|
||||
message_key.nonce,
|
||||
@@ -799,8 +834,12 @@ mod tests {
|
||||
|
||||
fn bridged_balance_to_this_balance(
|
||||
bridged_balance: BridgedChainBalance,
|
||||
bridged_to_this_conversion_rate_override: Option<FixedU128>,
|
||||
) -> ThisChainBalance {
|
||||
ThisChainBalance(bridged_balance.0 * BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE as u32)
|
||||
let conversion_rate = bridged_to_this_conversion_rate_override
|
||||
.map(|r| r.to_float() as u32)
|
||||
.unwrap_or(BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE);
|
||||
ThisChainBalance(bridged_balance.0 * conversion_rate)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,7 +857,10 @@ mod tests {
|
||||
type ThisChain = BridgedChain;
|
||||
type BridgedChain = ThisChain;
|
||||
|
||||
fn bridged_balance_to_this_balance(_this_balance: ThisChainBalance) -> BridgedChainBalance {
|
||||
fn bridged_balance_to_this_balance(
|
||||
_this_balance: ThisChainBalance,
|
||||
_bridged_to_this_conversion_rate_override: Option<FixedU128>,
|
||||
) -> BridgedChainBalance {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
@@ -836,6 +878,18 @@ mod tests {
|
||||
#[codec(index = 84)]
|
||||
Mint,
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
struct ThisChainOrigin(Result<frame_system::RawOrigin<ThisChainAccountId>, ()>);
|
||||
|
||||
impl From<ThisChainOrigin>
|
||||
for Result<frame_system::RawOrigin<ThisChainAccountId>, ThisChainOrigin>
|
||||
{
|
||||
fn from(
|
||||
origin: ThisChainOrigin,
|
||||
) -> Result<frame_system::RawOrigin<ThisChainAccountId>, ThisChainOrigin> {
|
||||
origin.clone().0.map_err(|_| origin)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Decode, Encode)]
|
||||
struct BridgedChainAccountId(u32);
|
||||
@@ -845,6 +899,18 @@ mod tests {
|
||||
struct BridgedChainSignature(u32);
|
||||
#[derive(Debug, PartialEq, Decode, Encode)]
|
||||
enum BridgedChainCall {}
|
||||
#[derive(Clone, Debug)]
|
||||
struct BridgedChainOrigin;
|
||||
|
||||
impl From<BridgedChainOrigin>
|
||||
for Result<frame_system::RawOrigin<BridgedChainAccountId>, BridgedChainOrigin>
|
||||
{
|
||||
fn from(
|
||||
_origin: BridgedChainOrigin,
|
||||
) -> Result<frame_system::RawOrigin<BridgedChainAccountId>, BridgedChainOrigin> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_wrapped_balance {
|
||||
($name:ident) => {
|
||||
@@ -922,9 +988,10 @@ mod tests {
|
||||
}
|
||||
|
||||
impl ThisChainWithMessages for ThisChain {
|
||||
type Origin = ThisChainOrigin;
|
||||
type Call = ThisChainCall;
|
||||
|
||||
fn is_outbound_lane_enabled(lane: &LaneId) -> bool {
|
||||
fn is_message_accepted(_send_origin: &Self::Origin, lane: &LaneId) -> bool {
|
||||
lane == TEST_LANE_ID
|
||||
}
|
||||
|
||||
@@ -982,9 +1049,10 @@ mod tests {
|
||||
}
|
||||
|
||||
impl ThisChainWithMessages for BridgedChain {
|
||||
type Origin = BridgedChainOrigin;
|
||||
type Call = BridgedChainCall;
|
||||
|
||||
fn is_outbound_lane_enabled(_lane: &LaneId) -> bool {
|
||||
fn is_message_accepted(_send_origin: &Self::Origin, _lane: &LaneId) -> bool {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
@@ -1096,6 +1164,7 @@ mod tests {
|
||||
source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
|
||||
&payload,
|
||||
OnThisChainBridge::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
),
|
||||
Ok(ThisChainBalance(EXPECTED_MINIMAL_FEE)),
|
||||
);
|
||||
@@ -1107,6 +1176,7 @@ mod tests {
|
||||
source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
|
||||
&payload_with_pay_on_target,
|
||||
OnThisChainBridge::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
)
|
||||
.expect(
|
||||
"estimate_message_dispatch_and_delivery_fee failed for pay-at-target-chain message",
|
||||
@@ -1121,7 +1191,7 @@ mod tests {
|
||||
// and now check that the verifier checks the fee
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&ThisChainBalance(1),
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
@@ -1130,7 +1200,7 @@ mod tests {
|
||||
Err(source::TOO_LOW_FEE)
|
||||
);
|
||||
assert!(source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&ThisChainBalance(1_000_000),
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
@@ -1153,7 +1223,7 @@ mod tests {
|
||||
// and now check that the verifier checks the fee
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Signed(ThisChainAccountId(0)),
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Signed(ThisChainAccountId(0)))),
|
||||
&ThisChainBalance(1_000_000),
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
@@ -1163,7 +1233,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::None,
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::None)),
|
||||
&ThisChainBalance(1_000_000),
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
@@ -1172,7 +1242,7 @@ mod tests {
|
||||
Err(source::BAD_ORIGIN)
|
||||
);
|
||||
assert!(source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&ThisChainBalance(1_000_000),
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
@@ -1195,7 +1265,7 @@ mod tests {
|
||||
// and now check that the verifier checks the fee
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Signed(ThisChainAccountId(0)),
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Signed(ThisChainAccountId(0)))),
|
||||
&ThisChainBalance(1_000_000),
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
@@ -1204,7 +1274,7 @@ mod tests {
|
||||
Err(source::BAD_ORIGIN)
|
||||
);
|
||||
assert!(source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Signed(ThisChainAccountId(1)),
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Signed(ThisChainAccountId(1)))),
|
||||
&ThisChainBalance(1_000_000),
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
@@ -1217,13 +1287,13 @@ mod tests {
|
||||
fn message_is_rejected_when_sent_using_disabled_lane() {
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&ThisChainBalance(1_000_000),
|
||||
b"dsbl",
|
||||
&test_lane_outbound_data(),
|
||||
®ular_outbound_message_payload(),
|
||||
),
|
||||
Err(source::OUTBOUND_LANE_DISABLED)
|
||||
Err(source::MESSAGE_REJECTED_BY_OUTBOUND_LANE)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1231,7 +1301,7 @@ mod tests {
|
||||
fn message_is_rejected_when_there_are_too_many_pending_messages_at_outbound_lane() {
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainOrigin(Ok(frame_system::RawOrigin::Root)),
|
||||
&ThisChainBalance(1_000_000),
|
||||
TEST_LANE_ID,
|
||||
&OutboundLaneData {
|
||||
@@ -1573,4 +1643,21 @@ mod tests {
|
||||
100 + 50 * 10 + 777,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conversion_rate_override_works() {
|
||||
let payload = regular_outbound_message_payload();
|
||||
let regular_fee = source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
|
||||
&payload,
|
||||
OnThisChainBridge::RELAYER_FEE_PERCENT,
|
||||
None,
|
||||
);
|
||||
let overrided_fee = source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
|
||||
&payload,
|
||||
OnThisChainBridge::RELAYER_FEE_PERCENT,
|
||||
Some(FixedU128::from_float((BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE * 2) as f64)),
|
||||
);
|
||||
|
||||
assert!(regular_fee < overrided_fee);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,40 +20,310 @@
|
||||
#![cfg(feature = "runtime-benchmarks")]
|
||||
|
||||
use crate::messages::{
|
||||
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
||||
AccountIdOf, BalanceOf, BridgedChain, HashOf, MessageBridge, ThisChain,
|
||||
source::{FromBridgedChainMessagesDeliveryProof, FromThisChainMessagePayload},
|
||||
target::FromBridgedChainMessagesProof,
|
||||
AccountIdOf, BalanceOf, BridgedChain, CallOf, HashOf, MessageBridge, RawStorageProof,
|
||||
SignatureOf, SignerOf, ThisChain,
|
||||
};
|
||||
|
||||
use bp_messages::{LaneId, MessageData, MessageKey, MessagePayload};
|
||||
use bp_runtime::ChainId;
|
||||
use bp_messages::{storage_keys, MessageData, MessageKey, MessagePayload};
|
||||
use bp_runtime::{messages::DispatchFeePayment, ChainId};
|
||||
use codec::Encode;
|
||||
use ed25519_dalek::{PublicKey, SecretKey, Signer, KEYPAIR_LENGTH, SECRET_KEY_LENGTH};
|
||||
use frame_support::weights::Weight;
|
||||
use frame_support::{
|
||||
traits::Currency,
|
||||
weights::{GetDispatchInfo, Weight},
|
||||
};
|
||||
use pallet_bridge_messages::benchmarking::{
|
||||
MessageDeliveryProofParams, MessageProofParams, ProofSize,
|
||||
MessageDeliveryProofParams, MessageParams, MessageProofParams, ProofSize,
|
||||
};
|
||||
use sp_core::Hasher;
|
||||
use sp_runtime::traits::Header;
|
||||
use sp_std::prelude::*;
|
||||
use sp_runtime::traits::{Header, IdentifyAccount, MaybeSerializeDeserialize, Zero};
|
||||
use sp_std::{fmt::Debug, prelude::*};
|
||||
use sp_trie::{record_all_keys, trie_types::TrieDBMutV1, LayoutV1, MemoryDB, Recorder, TrieMut};
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
/// Return this chain account, used to dispatch message.
|
||||
pub fn dispatch_account<B>() -> AccountIdOf<ThisChain<B>>
|
||||
where
|
||||
B: MessageBridge,
|
||||
SignerOf<ThisChain<B>>:
|
||||
From<sp_core::ed25519::Public> + IdentifyAccount<AccountId = AccountIdOf<ThisChain<B>>>,
|
||||
{
|
||||
let this_raw_public = PublicKey::from(&dispatch_account_secret());
|
||||
let this_public: SignerOf<ThisChain<B>> =
|
||||
sp_core::ed25519::Public::from_raw(this_raw_public.to_bytes()).into();
|
||||
this_public.into_account()
|
||||
}
|
||||
|
||||
/// Return public key of this chain account, used to dispatch message.
|
||||
pub fn dispatch_account_secret() -> SecretKey {
|
||||
// key from the repo example (https://docs.rs/ed25519-dalek/1.0.1/ed25519_dalek/struct.SecretKey.html)
|
||||
SecretKey::from_bytes(&[
|
||||
157, 097, 177, 157, 239, 253, 090, 096, 186, 132, 074, 244, 146, 236, 044, 196, 068, 073,
|
||||
197, 105, 123, 050, 105, 025, 112, 059, 172, 003, 028, 174, 127, 096,
|
||||
])
|
||||
.expect("harcoded key is valid")
|
||||
}
|
||||
|
||||
/// Prepare outbound message for the `send_message` call.
|
||||
pub fn prepare_outbound_message<B>(
|
||||
params: MessageParams<AccountIdOf<ThisChain<B>>>,
|
||||
) -> FromThisChainMessagePayload<B>
|
||||
where
|
||||
B: MessageBridge,
|
||||
BalanceOf<ThisChain<B>>: From<u64>,
|
||||
{
|
||||
let message_payload = vec![0; params.size as usize];
|
||||
let dispatch_origin = bp_message_dispatch::CallOrigin::SourceAccount(params.sender_account);
|
||||
|
||||
FromThisChainMessagePayload::<B> {
|
||||
spec_version: 0,
|
||||
weight: params.size as _,
|
||||
origin: dispatch_origin,
|
||||
call: message_payload,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepare proof of messages for the `receive_messages_proof` call.
|
||||
///
|
||||
/// In addition to returning valid messages proof, environment is prepared to verify this message
|
||||
/// proof.
|
||||
pub fn prepare_message_proof<R, BI, FI, B, BH, BHH>(
|
||||
params: MessageProofParams,
|
||||
version: &RuntimeVersion,
|
||||
endow_amount: BalanceOf<ThisChain<B>>,
|
||||
) -> (FromBridgedChainMessagesProof<HashOf<BridgedChain<B>>>, Weight)
|
||||
where
|
||||
R: frame_system::Config<AccountId = AccountIdOf<ThisChain<B>>>
|
||||
+ pallet_balances::Config<BI, Balance = BalanceOf<ThisChain<B>>>
|
||||
+ pallet_bridge_grandpa::Config<FI>,
|
||||
R::BridgedChain: bp_runtime::Chain<Header = BH>,
|
||||
B: MessageBridge,
|
||||
BI: 'static,
|
||||
FI: 'static,
|
||||
BH: Header<Hash = HashOf<BridgedChain<B>>>,
|
||||
BHH: Hasher<Out = HashOf<BridgedChain<B>>>,
|
||||
AccountIdOf<ThisChain<B>>: PartialEq + sp_std::fmt::Debug,
|
||||
AccountIdOf<BridgedChain<B>>: From<[u8; 32]>,
|
||||
BalanceOf<ThisChain<B>>: Debug + MaybeSerializeDeserialize,
|
||||
CallOf<ThisChain<B>>: From<frame_system::Call<R>> + GetDispatchInfo,
|
||||
HashOf<BridgedChain<B>>: Copy + Default,
|
||||
SignatureOf<ThisChain<B>>: From<sp_core::ed25519::Signature>,
|
||||
SignerOf<ThisChain<B>>: Clone
|
||||
+ From<sp_core::ed25519::Public>
|
||||
+ IdentifyAccount<AccountId = AccountIdOf<ThisChain<B>>>,
|
||||
{
|
||||
// we'll be dispatching the same call at This chain
|
||||
let remark = match params.size {
|
||||
ProofSize::Minimal(ref size) => vec![0u8; *size as _],
|
||||
_ => vec![],
|
||||
};
|
||||
let call: CallOf<ThisChain<B>> = frame_system::Call::remark { remark }.into();
|
||||
let call_weight = call.get_dispatch_info().weight;
|
||||
|
||||
// message payload needs to be signed, because we use `TargetAccount` call origin
|
||||
// (which is 'heaviest' to verify)
|
||||
let bridged_account_id: AccountIdOf<BridgedChain<B>> = [0u8; 32].into();
|
||||
let (this_raw_public, this_raw_signature) = ed25519_sign(
|
||||
&call,
|
||||
&bridged_account_id,
|
||||
version.spec_version,
|
||||
B::BRIDGED_CHAIN_ID,
|
||||
B::THIS_CHAIN_ID,
|
||||
);
|
||||
let this_public: SignerOf<ThisChain<B>> =
|
||||
sp_core::ed25519::Public::from_raw(this_raw_public).into();
|
||||
let this_signature: SignatureOf<ThisChain<B>> =
|
||||
sp_core::ed25519::Signature::from_raw(this_raw_signature).into();
|
||||
|
||||
// if dispatch fee is paid at this chain, endow relayer account
|
||||
if params.dispatch_fee_payment == DispatchFeePayment::AtTargetChain {
|
||||
assert_eq!(this_public.clone().into_account(), dispatch_account::<B>());
|
||||
pallet_balances::Pallet::<R, BI>::make_free_balance_be(
|
||||
&this_public.clone().into_account(),
|
||||
endow_amount,
|
||||
);
|
||||
}
|
||||
|
||||
// prepare message payload that is stored in the Bridged chain storage
|
||||
let message_payload = bp_message_dispatch::MessagePayload {
|
||||
spec_version: version.spec_version,
|
||||
weight: call_weight,
|
||||
origin: bp_message_dispatch::CallOrigin::<
|
||||
AccountIdOf<BridgedChain<B>>,
|
||||
SignerOf<ThisChain<B>>,
|
||||
SignatureOf<ThisChain<B>>,
|
||||
>::TargetAccount(bridged_account_id, this_public, this_signature),
|
||||
dispatch_fee_payment: params.dispatch_fee_payment.clone(),
|
||||
call: call.encode(),
|
||||
}
|
||||
.encode();
|
||||
|
||||
// finally - prepare storage proof and update environment
|
||||
let (state_root, storage_proof) =
|
||||
prepare_messages_storage_proof::<B, BHH>(¶ms, message_payload);
|
||||
let bridged_header_hash = insert_bridged_chain_header::<R, FI, B, BH>(state_root);
|
||||
|
||||
(
|
||||
FromBridgedChainMessagesProof {
|
||||
bridged_header_hash,
|
||||
storage_proof,
|
||||
lane: params.lane,
|
||||
nonces_start: *params.message_nonces.start(),
|
||||
nonces_end: *params.message_nonces.end(),
|
||||
},
|
||||
call_weight
|
||||
.checked_mul(
|
||||
params.message_nonces.end().saturating_sub(*params.message_nonces.start()) + 1,
|
||||
)
|
||||
.expect("too many messages requested by benchmark"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Prepare proof of messages delivery for the `receive_messages_delivery_proof` call.
|
||||
pub fn prepare_message_delivery_proof<R, FI, B, BH, BHH>(
|
||||
params: MessageDeliveryProofParams<AccountIdOf<ThisChain<B>>>,
|
||||
) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChain<B>>>
|
||||
where
|
||||
R: pallet_bridge_grandpa::Config<FI>,
|
||||
R::BridgedChain: bp_runtime::Chain<Header = BH>,
|
||||
FI: 'static,
|
||||
B: MessageBridge,
|
||||
BH: Header<Hash = HashOf<BridgedChain<B>>>,
|
||||
BHH: Hasher<Out = HashOf<BridgedChain<B>>>,
|
||||
HashOf<BridgedChain<B>>: Copy + Default,
|
||||
{
|
||||
// prepare Bridged chain storage with inbound lane state
|
||||
let storage_key =
|
||||
storage_keys::inbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, ¶ms.lane).0;
|
||||
let mut root = Default::default();
|
||||
let mut mdb = MemoryDB::default();
|
||||
{
|
||||
let mut trie = TrieDBMutV1::<BHH>::new(&mut mdb, &mut root);
|
||||
trie.insert(&storage_key, ¶ms.inbound_lane_data.encode())
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
.expect("TrieMut::insert should not fail in benchmarks");
|
||||
}
|
||||
root = grow_trie(root, &mut mdb, params.size);
|
||||
|
||||
// generate storage proof to be delivered to This chain
|
||||
let mut proof_recorder = Recorder::<BHH::Out>::new();
|
||||
record_all_keys::<LayoutV1<BHH>, _>(&mdb, &root, &mut proof_recorder)
|
||||
.map_err(|_| "record_all_keys has failed")
|
||||
.expect("record_all_keys should not fail in benchmarks");
|
||||
let storage_proof = proof_recorder.drain().into_iter().map(|n| n.data.to_vec()).collect();
|
||||
|
||||
// finally insert header with given state root to our storage
|
||||
let bridged_header_hash = insert_bridged_chain_header::<R, FI, B, BH>(root);
|
||||
|
||||
FromBridgedChainMessagesDeliveryProof {
|
||||
bridged_header_hash: bridged_header_hash.into(),
|
||||
storage_proof,
|
||||
lane: params.lane,
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepare storage proof of given messages.
|
||||
///
|
||||
/// Returns state trie root and nodes with prepared messages.
|
||||
fn prepare_messages_storage_proof<B, BHH>(
|
||||
params: &MessageProofParams,
|
||||
message_payload: MessagePayload,
|
||||
) -> (HashOf<BridgedChain<B>>, RawStorageProof)
|
||||
where
|
||||
B: MessageBridge,
|
||||
BHH: Hasher<Out = HashOf<BridgedChain<B>>>,
|
||||
HashOf<BridgedChain<B>>: Copy + Default,
|
||||
{
|
||||
// prepare Bridged chain storage with messages and (optionally) outbound lane state
|
||||
let message_count =
|
||||
params.message_nonces.end().saturating_sub(*params.message_nonces.start()) + 1;
|
||||
let mut storage_keys = Vec::with_capacity(message_count as usize + 1);
|
||||
let mut root = Default::default();
|
||||
let mut mdb = MemoryDB::default();
|
||||
{
|
||||
let mut trie = TrieDBMutV1::<BHH>::new(&mut mdb, &mut root);
|
||||
|
||||
// insert messages
|
||||
for nonce in params.message_nonces.clone() {
|
||||
let message_key = MessageKey { lane_id: params.lane, nonce };
|
||||
let message_data = MessageData {
|
||||
fee: BalanceOf::<BridgedChain<B>>::from(0),
|
||||
payload: message_payload.clone(),
|
||||
};
|
||||
let storage_key = storage_keys::message_key(
|
||||
B::BRIDGED_MESSAGES_PALLET_NAME,
|
||||
&message_key.lane_id,
|
||||
message_key.nonce,
|
||||
)
|
||||
.0;
|
||||
trie.insert(&storage_key, &message_data.encode())
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
.expect("TrieMut::insert should not fail in benchmarks");
|
||||
storage_keys.push(storage_key);
|
||||
}
|
||||
|
||||
// insert outbound lane state
|
||||
if let Some(ref outbound_lane_data) = params.outbound_lane_data {
|
||||
let storage_key =
|
||||
storage_keys::outbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, ¶ms.lane)
|
||||
.0;
|
||||
trie.insert(&storage_key, &outbound_lane_data.encode())
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
.expect("TrieMut::insert should not fail in benchmarks");
|
||||
storage_keys.push(storage_key);
|
||||
}
|
||||
}
|
||||
root = grow_trie(root, &mut mdb, params.size);
|
||||
|
||||
// generate storage proof to be delivered to This chain
|
||||
let mut proof_recorder = Recorder::<BHH::Out>::new();
|
||||
record_all_keys::<LayoutV1<BHH>, _>(&mdb, &root, &mut proof_recorder)
|
||||
.map_err(|_| "record_all_keys has failed")
|
||||
.expect("record_all_keys should not fail in benchmarks");
|
||||
let storage_proof = proof_recorder.drain().into_iter().map(|n| n.data.to_vec()).collect();
|
||||
|
||||
(root, storage_proof)
|
||||
}
|
||||
|
||||
/// Insert Bridged chain header with given state root into storage of GRANDPA pallet at This chain.
|
||||
fn insert_bridged_chain_header<R, FI, B, BH>(
|
||||
state_root: HashOf<BridgedChain<B>>,
|
||||
) -> HashOf<BridgedChain<B>>
|
||||
where
|
||||
R: pallet_bridge_grandpa::Config<FI>,
|
||||
R::BridgedChain: bp_runtime::Chain<Header = BH>,
|
||||
FI: 'static,
|
||||
B: MessageBridge,
|
||||
BH: Header<Hash = HashOf<BridgedChain<B>>>,
|
||||
HashOf<BridgedChain<B>>: Default,
|
||||
{
|
||||
let bridged_header = BH::new(
|
||||
Zero::zero(),
|
||||
Default::default(),
|
||||
state_root,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
);
|
||||
let bridged_header_hash = bridged_header.hash();
|
||||
pallet_bridge_grandpa::initialize_for_benchmarks::<R, FI>(bridged_header);
|
||||
bridged_header_hash
|
||||
}
|
||||
|
||||
/// Generate ed25519 signature to be used in
|
||||
/// `pallet_brdige_call_dispatch::CallOrigin::TargetAccount`.
|
||||
///
|
||||
/// Returns public key of the signer and the signature itself.
|
||||
pub fn ed25519_sign(
|
||||
fn ed25519_sign(
|
||||
target_call: &impl Encode,
|
||||
source_account_id: &impl Encode,
|
||||
target_spec_version: u32,
|
||||
source_chain_id: ChainId,
|
||||
target_chain_id: ChainId,
|
||||
) -> ([u8; 32], [u8; 64]) {
|
||||
// key from the repo example (https://docs.rs/ed25519-dalek/1.0.1/ed25519_dalek/struct.SecretKey.html)
|
||||
let target_secret = SecretKey::from_bytes(&[
|
||||
157, 097, 177, 157, 239, 253, 090, 096, 186, 132, 074, 244, 146, 236, 044, 196, 068, 073,
|
||||
197, 105, 123, 050, 105, 025, 112, 059, 172, 003, 028, 174, 127, 096,
|
||||
])
|
||||
.expect("harcoded key is valid");
|
||||
let target_secret = dispatch_account_secret();
|
||||
let target_public: PublicKey = (&target_secret).into();
|
||||
|
||||
let mut target_pair_bytes = [0u8; KEYPAIR_LENGTH];
|
||||
@@ -76,131 +346,6 @@ pub fn ed25519_sign(
|
||||
(target_public.to_bytes(), target_origin_signature.to_bytes())
|
||||
}
|
||||
|
||||
/// Prepare proof of messages for the `receive_messages_proof` call.
|
||||
pub fn prepare_message_proof<B, H, R, FI, MM, ML, MH>(
|
||||
params: MessageProofParams,
|
||||
make_bridged_message_storage_key: MM,
|
||||
make_bridged_outbound_lane_data_key: ML,
|
||||
make_bridged_header: MH,
|
||||
message_dispatch_weight: Weight,
|
||||
message_payload: MessagePayload,
|
||||
) -> (FromBridgedChainMessagesProof<HashOf<BridgedChain<B>>>, Weight)
|
||||
where
|
||||
B: MessageBridge,
|
||||
H: Hasher,
|
||||
R: pallet_bridge_grandpa::Config<FI>,
|
||||
FI: 'static,
|
||||
<R::BridgedChain as bp_runtime::Chain>::Hash: Into<HashOf<BridgedChain<B>>>,
|
||||
MM: Fn(MessageKey) -> Vec<u8>,
|
||||
ML: Fn(LaneId) -> Vec<u8>,
|
||||
MH: Fn(H::Out) -> <R::BridgedChain as bp_runtime::Chain>::Header,
|
||||
{
|
||||
// prepare Bridged chain storage with messages and (optionally) outbound lane state
|
||||
let message_count =
|
||||
params.message_nonces.end().saturating_sub(*params.message_nonces.start()) + 1;
|
||||
let mut storage_keys = Vec::with_capacity(message_count as usize + 1);
|
||||
let mut root = Default::default();
|
||||
let mut mdb = MemoryDB::default();
|
||||
{
|
||||
let mut trie = TrieDBMutV1::<H>::new(&mut mdb, &mut root);
|
||||
|
||||
// insert messages
|
||||
for nonce in params.message_nonces.clone() {
|
||||
let message_key = MessageKey { lane_id: params.lane, nonce };
|
||||
let message_data = MessageData {
|
||||
fee: BalanceOf::<BridgedChain<B>>::from(0),
|
||||
payload: message_payload.clone(),
|
||||
};
|
||||
let storage_key = make_bridged_message_storage_key(message_key);
|
||||
trie.insert(&storage_key, &message_data.encode())
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
.expect("TrieMut::insert should not fail in benchmarks");
|
||||
storage_keys.push(storage_key);
|
||||
}
|
||||
|
||||
// insert outbound lane state
|
||||
if let Some(outbound_lane_data) = params.outbound_lane_data {
|
||||
let storage_key = make_bridged_outbound_lane_data_key(params.lane);
|
||||
trie.insert(&storage_key, &outbound_lane_data.encode())
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
.expect("TrieMut::insert should not fail in benchmarks");
|
||||
storage_keys.push(storage_key);
|
||||
}
|
||||
}
|
||||
root = grow_trie(root, &mut mdb, params.size);
|
||||
|
||||
// generate storage proof to be delivered to This chain
|
||||
let mut proof_recorder = Recorder::<H::Out>::new();
|
||||
record_all_keys::<LayoutV1<H>, _>(&mdb, &root, &mut proof_recorder)
|
||||
.map_err(|_| "record_all_keys has failed")
|
||||
.expect("record_all_keys should not fail in benchmarks");
|
||||
let storage_proof = proof_recorder.drain().into_iter().map(|n| n.data.to_vec()).collect();
|
||||
|
||||
// prepare Bridged chain header and insert it into the Substrate pallet
|
||||
let bridged_header = make_bridged_header(root);
|
||||
let bridged_header_hash = bridged_header.hash();
|
||||
pallet_bridge_grandpa::initialize_for_benchmarks::<R, FI>(bridged_header);
|
||||
|
||||
(
|
||||
FromBridgedChainMessagesProof {
|
||||
bridged_header_hash: bridged_header_hash.into(),
|
||||
storage_proof,
|
||||
lane: params.lane,
|
||||
nonces_start: *params.message_nonces.start(),
|
||||
nonces_end: *params.message_nonces.end(),
|
||||
},
|
||||
message_dispatch_weight
|
||||
.checked_mul(message_count)
|
||||
.expect("too many messages requested by benchmark"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Prepare proof of messages delivery for the `receive_messages_delivery_proof` call.
|
||||
pub fn prepare_message_delivery_proof<B, H, R, FI, ML, MH>(
|
||||
params: MessageDeliveryProofParams<AccountIdOf<ThisChain<B>>>,
|
||||
make_bridged_inbound_lane_data_key: ML,
|
||||
make_bridged_header: MH,
|
||||
) -> FromBridgedChainMessagesDeliveryProof<HashOf<BridgedChain<B>>>
|
||||
where
|
||||
B: MessageBridge,
|
||||
H: Hasher,
|
||||
R: pallet_bridge_grandpa::Config<FI>,
|
||||
FI: 'static,
|
||||
<R::BridgedChain as bp_runtime::Chain>::Hash: Into<HashOf<BridgedChain<B>>>,
|
||||
ML: Fn(LaneId) -> Vec<u8>,
|
||||
MH: Fn(H::Out) -> <R::BridgedChain as bp_runtime::Chain>::Header,
|
||||
{
|
||||
// prepare Bridged chain storage with inbound lane state
|
||||
let storage_key = make_bridged_inbound_lane_data_key(params.lane);
|
||||
let mut root = Default::default();
|
||||
let mut mdb = MemoryDB::default();
|
||||
{
|
||||
let mut trie = TrieDBMutV1::<H>::new(&mut mdb, &mut root);
|
||||
trie.insert(&storage_key, ¶ms.inbound_lane_data.encode())
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
.expect("TrieMut::insert should not fail in benchmarks");
|
||||
}
|
||||
root = grow_trie(root, &mut mdb, params.size);
|
||||
|
||||
// generate storage proof to be delivered to This chain
|
||||
let mut proof_recorder = Recorder::<H::Out>::new();
|
||||
record_all_keys::<LayoutV1<H>, _>(&mdb, &root, &mut proof_recorder)
|
||||
.map_err(|_| "record_all_keys has failed")
|
||||
.expect("record_all_keys should not fail in benchmarks");
|
||||
let storage_proof = proof_recorder.drain().into_iter().map(|n| n.data.to_vec()).collect();
|
||||
|
||||
// prepare Bridged chain header and insert it into the Substrate pallet
|
||||
let bridged_header = make_bridged_header(root);
|
||||
let bridged_header_hash = bridged_header.hash();
|
||||
pallet_bridge_grandpa::initialize_for_benchmarks::<R, FI>(bridged_header);
|
||||
|
||||
FromBridgedChainMessagesDeliveryProof {
|
||||
bridged_header_hash: bridged_header_hash.into(),
|
||||
storage_proof,
|
||||
lane: params.lane,
|
||||
}
|
||||
}
|
||||
|
||||
/// Populate trie with dummy keys+values until trie has at least given size.
|
||||
fn grow_trie<H: Hasher>(mut root: H::Out, mdb: &mut MemoryDB<H>, trie_size: ProofSize) -> H::Out {
|
||||
let (iterations, leaf_size, minimal_trie_size) = match trie_size {
|
||||
@@ -222,8 +367,8 @@ fn grow_trie<H: Hasher>(mut root: H::Out, mdb: &mut MemoryDB<H>, trie_size: Proo
|
||||
}
|
||||
|
||||
let mut trie = TrieDBMutV1::<H>::from_existing(mdb, &mut root)
|
||||
.map_err(|_| "TrieDBMut::from_existing has failed")
|
||||
.expect("TrieDBMut::from_existing should not fail in benchmarks");
|
||||
.map_err(|_| "TrieDBMutV1::from_existing has failed")
|
||||
.expect("TrieDBMutV1::from_existing should not fail in benchmarks");
|
||||
for _ in 0..iterations {
|
||||
trie.insert(&key_index.encode(), &vec![42u8; leaf_size as _])
|
||||
.map_err(|_| "TrieMut::insert has failed")
|
||||
|
||||
Reference in New Issue
Block a user