diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index 1e6f97bdb8944..4da6c38c6cc12 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -412,6 +412,7 @@ dependencies = [ "artemis-core", "artemis-ethereum", "ethabi-decode", + "frame-benchmarking", "frame-support", "frame-system", "hex-literal", diff --git a/parachain/pallets/basic-channel/src/inbound/benchmarking.rs b/parachain/pallets/basic-channel/src/inbound/benchmarking.rs index 1773e53fdbc42..3a606a061e8fd 100644 --- a/parachain/pallets/basic-channel/src/inbound/benchmarking.rs +++ b/parachain/pallets/basic-channel/src/inbound/benchmarking.rs @@ -22,20 +22,6 @@ fn assert_last_event(system_event: ::Event assert_eq!(event, &system_event); } -fn make_header_chain(parent: Header, length: u32) -> Vec
{ - let mut chain = vec![parent.clone()]; - (0..length).fold(parent, |ancestor, _| { - let mut header: Header = Default::default(); - header.parent_hash = ancestor.compute_hash(); - header.number = ancestor.number.saturating_add(1); - header.difficulty = 1.into(); - chain.push(header.clone()); - header - }); - - chain -} - // This collection of benchmarks should include a benchmark for each // call dispatched by the channel, i.e. each "app" pallet function // that can be invoked by MessageDispatch. The most expensive call @@ -48,8 +34,6 @@ benchmarks! { // * `submit` dispatches the DotApp::unlock call // * `unlock` call successfully unlocks DOT submit { - let h in 0 .. 20; - let caller: T::AccountId = whitelisted_caller(); let (header, message) = dot_unlock_data(); let envelope: envelope::Envelope = rlp::decode::(&message.data) @@ -59,7 +43,7 @@ benchmarks! { SourceChannel::put(envelope.channel); T::Verifier::initialize_storage( - make_header_chain(header, h), + vec![header], 0.into(), 0, // forces all headers to be finalized )?; @@ -76,8 +60,6 @@ benchmarks! { #[extra] submit_eth_mint { - let h in 0 .. 20; - let caller: T::AccountId = whitelisted_caller(); let (header, message) = eth_mint_data(); let envelope: envelope::Envelope = rlp::decode::(&message.data) @@ -87,7 +69,7 @@ benchmarks! { SourceChannel::put(envelope.channel); T::Verifier::initialize_storage( - make_header_chain(header, h), + vec![header], 0.into(), 0, // forces all headers to be finalized )?; @@ -104,8 +86,6 @@ benchmarks! { #[extra] submit_erc20_mint { - let h in 0 .. 20; - let caller: T::AccountId = whitelisted_caller(); let (header, message) = erc20_mint_data(); let envelope: envelope::Envelope = rlp::decode::(&message.data) @@ -115,7 +95,7 @@ benchmarks! { SourceChannel::put(envelope.channel); T::Verifier::initialize_storage( - make_header_chain(header, h), + vec![header], 0.into(), 0, // forces all headers to be finalized )?; diff --git a/parachain/pallets/basic-channel/src/inbound/mod.rs b/parachain/pallets/basic-channel/src/inbound/mod.rs index 3e995a5bac67a..7fec5afbbc4d4 100644 --- a/parachain/pallets/basic-channel/src/inbound/mod.rs +++ b/parachain/pallets/basic-channel/src/inbound/mod.rs @@ -1,6 +1,7 @@ use frame_support::{ decl_error, decl_event, decl_module, decl_storage, dispatch::DispatchResult, + weights::Weight, }; use frame_system::{self as system, ensure_signed}; use sp_core::H160; @@ -20,6 +21,15 @@ mod test; mod envelope; +/// Weight functions needed for this pallet. +pub trait WeightInfo { + fn submit() -> Weight; +} + +impl WeightInfo for () { + fn submit() -> Weight { 0 } +} + pub trait Config: system::Config { type Event: From + Into<::Event>; @@ -28,6 +38,9 @@ pub trait Config: system::Config { /// Verifier module for message verification. type MessageDispatch: MessageDispatch; + + /// Weight information for extrinsics in this pallet + type WeightInfo: WeightInfo; } decl_storage! { @@ -61,7 +74,7 @@ decl_module! { fn deposit_event() = default; - #[weight = 0] + #[weight = T::WeightInfo::submit()] pub fn submit(origin, message: Message) -> DispatchResult { ensure_signed(origin)?; // submit message to verifier for verification diff --git a/parachain/pallets/basic-channel/src/inbound/test.rs b/parachain/pallets/basic-channel/src/inbound/test.rs index a1f04d9e5a89f..d06ffe9ae944b 100644 --- a/parachain/pallets/basic-channel/src/inbound/test.rs +++ b/parachain/pallets/basic-channel/src/inbound/test.rs @@ -98,6 +98,7 @@ impl basic_inbound_channel::Config for Test { type Event = Event; type Verifier = MockVerifier; type MessageDispatch = MockMessageDispatch; + type WeightInfo = (); } pub fn new_tester(source_channel: H160) -> sp_io::TestExternalities { diff --git a/parachain/pallets/incentivized-channel/Cargo.toml b/parachain/pallets/incentivized-channel/Cargo.toml index 0be6c291f74bb..94eabeea83c8f 100644 --- a/parachain/pallets/incentivized-channel/Cargo.toml +++ b/parachain/pallets/incentivized-channel/Cargo.toml @@ -12,7 +12,10 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { version = "2.0.0", package = "parity-scale-codec", default-features = false, features = ["derive"] } +hex-literal = { version = "0.3.1", optional = true } +rlp = { version = "0.5", default-features = false, optional = true } +frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "rococo-v1", default-features = false, optional = true } frame-support = { git = "https://github.com/paritytech/substrate.git", branch = "rococo-v1", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate.git", branch = "rococo-v1", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "rococo-v1", default-features = false } @@ -47,4 +50,9 @@ std = [ ] runtime-benchmarks = [ "artemis-core/runtime-benchmarks", + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "hex-literal", + "rlp", ] diff --git a/parachain/pallets/incentivized-channel/src/inbound/benchmarking.rs b/parachain/pallets/incentivized-channel/src/inbound/benchmarking.rs new file mode 100644 index 0000000000000..ee7d12be76703 --- /dev/null +++ b/parachain/pallets/incentivized-channel/src/inbound/benchmarking.rs @@ -0,0 +1,172 @@ +//! IncentivizedInboundChannel pallet benchmarking + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_system::{RawOrigin, self, EventRecord}; +use frame_benchmarking::{benchmarks, whitelisted_caller, impl_benchmark_test_suite}; +use hex_literal::hex; +use sp_std::convert::TryInto; + +use artemis_core::{ChannelId, Message, MessageId, Proof}; +use artemis_ethereum::{Log, Header}; + +#[allow(unused_imports)] +use crate::inbound::Module as IncentivizedInboundChannel; + +fn assert_last_event(system_event: ::Event) { + let events = frame_system::Pallet::::events(); + // compare to the last event record + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +// This collection of benchmarks should include a benchmark for each +// call dispatched by the channel, i.e. each "app" pallet function +// that can be invoked by MessageDispatch. The most expensive call +// should be used in the `submit` benchmark. +// +// We rely on configuration via chain spec of the app pallets because +// we don't have access to their storage here. +benchmarks! { + // Benchmark `submit` extrinsic under worst case conditions: + // * `submit` dispatches the DotApp::unlock call + // * `unlock` call successfully unlocks DOT + submit { + let caller: T::AccountId = whitelisted_caller(); + let (header, message) = dot_unlock_data(); + let envelope: envelope::Envelope = rlp::decode::(&message.data) + .map(|log| log.try_into().unwrap()) + .unwrap(); + Nonce::put(envelope.nonce - 1); + SourceChannel::put(envelope.channel); + + T::Verifier::initialize_storage( + vec![header], + 0.into(), + 0, // forces all headers to be finalized + )?; + + }: _(RawOrigin::Signed(caller.clone()), message) + verify { + assert_eq!(envelope.nonce, Nonce::get()); + + let message_id = MessageId::new(ChannelId::Incentivized, envelope.nonce); + if let Some(event) = T::MessageDispatch::successful_dispatch_event(message_id) { + assert_last_event::(event); + } + } + + #[extra] + submit_eth_mint { + let caller: T::AccountId = whitelisted_caller(); + let (header, message) = eth_mint_data(); + let envelope: envelope::Envelope = rlp::decode::(&message.data) + .map(|log| log.try_into().unwrap()) + .unwrap(); + Nonce::put(envelope.nonce - 1); + SourceChannel::put(envelope.channel); + + T::Verifier::initialize_storage( + vec![header], + 0.into(), + 0, // forces all headers to be finalized + )?; + + }: submit(RawOrigin::Signed(caller.clone()), message) + verify { + assert_eq!(envelope.nonce, Nonce::get()); + + let message_id = MessageId::new(ChannelId::Incentivized, envelope.nonce); + if let Some(event) = T::MessageDispatch::successful_dispatch_event(message_id) { + assert_last_event::(event); + } + } + + // TODO: add back ECR20 mint benchmark +} + +// ETH mint +// Channel = 0xeda338e4dc46038493b885327842fd3e301cab39 +// Nonce = 2 +// Source = 0x774667629726ec1fabebcec0d9139bd1c8f72a23 +fn eth_mint_data() -> (Header, Message) { + ( + Header { + parent_hash: hex!("3f136282153539e5b4006c05d0c6ab033786d5793c7cc3b784ca3b274918181e").into(), + timestamp: 1618295862u64.into(), + number: 3584u64.into(), + author: hex!("0000000000000000000000000000000000000000").into(), + transactions_root: hex!("84ed6b4ad707994d7095eff6f5458d2c6e351fcab00669b084705229faa63840").into(), + ommers_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + extra_data: hex!("").into(), + state_root: hex!("ab5ce23d0914c05c74504cb797349fa8fca1b9b286f2f1ab11f0adb7f8c2d12c").into(), + receipts_root: hex!("ac1dbc12173e495453bf5277fb1cc507a092218adcb795e7743308615ed62c89").into(), + logs_bloom: (&hex!("00000000000040000000000000000200000000000000400010000000010080000000000000000000000000001000000010000000000000000000000000000080000000000000000400000008000000000000000000008000000000000000000000000000020000000000000000000800000001000400000000000010000000000000020000000000000000000400000000000000000000000000040000000000000000000004000000000000000000000220000000000001000000000200080000000002000000000000000000000000000000000000000000000000000020402000000000000000000000000000000000000000000000000000000000000000")).into(), + gas_used: 97210u64.into(), + gas_limit: 6721975u64.into(), + difficulty: 0u64.into(), + seal: vec![ + hex!("a00000000000000000000000000000000000000000000000000000000000000000").to_vec(), + hex!("880000000000000000").to_vec(), + ], + }, + Message { + data: hex!("f9013a94eda338e4dc46038493b885327842fd3e301cab39e1a05e9ae1d7c484f74d554a503aa825e823725531d97e784dd9b1aacdb58d1f7076b90100000000000000000000000000774667629726ec1fabebcec0d9139bd1c8f72a2300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000570c0189b4ab1ef20763630df9743acf155865600daff200d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0000c16ff2862300000000000000000000000000000000000000000000000000000000000000000000").to_vec(), + proof: Proof { + block_hash: hex!("fbd6740f975d184468373c65c1278051403867361c03ab8c245c5ff42e53c9e2").into(), + tx_index: 0, + data: ( + vec![hex!("ac1dbc12173e495453bf5277fb1cc507a092218adcb795e7743308615ed62c89").to_vec()], + vec![hex!("f904a8822080b904a2f9049f0183017bbab9010000000000000040000000000000000200000000000000400010000000010080000000000000000000000000001000000010000000000000000000000000000080000000000000000400000008000000000000000000008000000000000000000000000000020000000000000000000800000001000400000000000010000000000000020000000000000000000400000000000000000000000000040000000000000000000004000000000000000000000220000000000001000000000200080000000002000000000000000000000000000000000000000000000000000020402000000000000000000000000000000000000000000000000000000000000000f90394f89994774667629726ec1fabebcec0d9139bd1c8f72a23e1a0caae0f5e72020d428da73a237d1f9bf162e158dda6d4908769b8b60c095b01f4b86000000000000000000000000089b4ab1ef20763630df9743acf155865600daff2d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000000000000000000000000000000000000000000000000002386f26fc10000f9011c94672a95c8928c8450b594186cf7954ec269626a2df863a0a78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098a0000000000000000000000000b1185ede04202fe62d38f5db72f71e38ff3e8305a000000000000000000000000089b4ab1ef20763630df9743acf155865600daff2b8a00000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f89b94672a95c8928c8450b594186cf7954ec269626a2df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000089b4ab1ef20763630df9743acf155865600daff2a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000de0b6b3a7640000f9013a94eda338e4dc46038493b885327842fd3e301cab39e1a05e9ae1d7c484f74d554a503aa825e823725531d97e784dd9b1aacdb58d1f7076b90100000000000000000000000000774667629726ec1fabebcec0d9139bd1c8f72a2300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000570c0189b4ab1ef20763630df9743acf155865600daff200d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0000c16ff2862300000000000000000000000000000000000000000000000000000000000000000000").to_vec()], + ), + }, + }, + ) +} + +// DOT unlock +// Channel = 0xeda338e4dc46038493b885327842fd3e301cab39 +// Nonce = 1 +// Source = 0xb1185ede04202fe62d38f5db72f71e38ff3e8305 +fn dot_unlock_data() -> (Header, Message) { + ( + Header { + parent_hash: hex!("6e54738f4e58949361383e11d06cfe5b72c87410881230fae3289f1de8487927").into(), + timestamp: 1618291501u64.into(), + number: 2496u64.into(), + author: hex!("0000000000000000000000000000000000000000").into(), + transactions_root: hex!("9c53bbde6f3dfe2afd272cfd64a8639db23588d3ec63406b5225b38fa79a0490").into(), + ommers_hash: hex!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").into(), + extra_data: hex!("").into(), + state_root: hex!("b262afa00f5d920137d59f2061cb2075a9cece1d53775ba6f1b38f88423f6ff7").into(), + receipts_root: hex!("f19e53a299860306c5ad8201b28f78d505ea4a46f08739f2f58def37652cd386").into(), + logs_bloom: (&hex!("00000000000040000000000000000200000000000000000010000000000080000000000000000000000000001000000010000000000000000000000000000000000000000000000400000008000000000000000000008000000000000000000000000000020000000000000000000800000001000400000000000010000000000000020000000000000000000400000000000000000000000000040000000000000000000004000000000000000000000200000000000001000000000200000000000002000000000000000000000000000000000000000000000000000020400000000000000000000000000000000000000000000000000000000000000000")).into(), + gas_used: 107966u64.into(), + gas_limit: 6721975u64.into(), + difficulty: 0u64.into(), + seal: vec![ + hex!("a00000000000000000000000000000000000000000000000000000000000000000").to_vec(), + hex!("880000000000000000").to_vec(), + ], + }, + Message { + data: hex!("f9013a94eda338e4dc46038493b885327842fd3e301cab39e1a05e9ae1d7c484f74d554a503aa825e823725531d97e784dd9b1aacdb58d1f7076b90100000000000000000000000000b1185ede04202fe62d38f5db72f71e38ff3e830500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000570e0189b4ab1ef20763630df9743acf155865600daff200d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000064a7b3b6e00d000000000000000000000000000000000000000000000000000000000000000000").to_vec(), + proof: Proof { + block_hash: hex!("2e2ac53ae0dcd35d23e004d105f21a07cfb841ee7f86b5edd957067684d61f85").into(), + tx_index: 0, + data: ( + vec![hex!("f19e53a299860306c5ad8201b28f78d505ea4a46f08739f2f58def37652cd386").to_vec()], + vec![hex!("f905e9822080b905e3f905e0018301a5beb9010000000000000040000000000000000200000000000000000010000000000080000000000000000000000000001000000010000000000000000000000000000000000000000000000400000008000000000000000000008000000000000000000000000000020000000000000000000800000001000400000000000010000000000000020000000000000000000400000000000000000000000000040000000000000000000004000000000000000000000200000000000001000000000200000000000002000000000000000000000000000000000000000000000000000020400000000000000000000000000000000000000000000000000000000000000000f904d5f9013c94672a95c8928c8450b594186cf7954ec269626a2df863a0a78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098a0000000000000000000000000b1185ede04202fe62d38f5db72f71e38ff3e8305a000000000000000000000000089b4ab1ef20763630df9743acf155865600daff2b8c00000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0000000000000000000000000000000000000000000000000000000000000000f89b94672a95c8928c8450b594186cf7954ec269626a2df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000089b4ab1ef20763630df9743acf155865600daff2a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000de0b6b3a7640000f9011c94672a95c8928c8450b594186cf7954ec269626a2df863a0a78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098a0000000000000000000000000b1185ede04202fe62d38f5db72f71e38ff3e8305a000000000000000000000000089b4ab1ef20763630df9743acf155865600daff2b8a00000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f89b94672a95c8928c8450b594186cf7954ec269626a2df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000089b4ab1ef20763630df9743acf155865600daff2a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000de0b6b3a7640000f9013a94eda338e4dc46038493b885327842fd3e301cab39e1a05e9ae1d7c484f74d554a503aa825e823725531d97e784dd9b1aacdb58d1f7076b90100000000000000000000000000b1185ede04202fe62d38f5db72f71e38ff3e830500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000570e0189b4ab1ef20763630df9743acf155865600daff200d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000064a7b3b6e00d000000000000000000000000000000000000000000000000000000000000000000").to_vec()], + ), + }, + }, + ) +} + +impl_benchmark_test_suite!( + IncentivizedInboundChannel, + crate::inbound::test::new_tester(Default::default()), + crate::inbound::test::Test, +); diff --git a/parachain/pallets/incentivized-channel/src/inbound/mod.rs b/parachain/pallets/incentivized-channel/src/inbound/mod.rs index b02d5f433d897..a33a496108156 100644 --- a/parachain/pallets/incentivized-channel/src/inbound/mod.rs +++ b/parachain/pallets/incentivized-channel/src/inbound/mod.rs @@ -4,6 +4,7 @@ use frame_support::{ traits::{Currency, Get, ExistenceRequirement::KeepAlive, WithdrawReasons, Imbalance}, storage::StorageValue, log, + weights::Weight, }; use frame_system::{self as system, ensure_signed}; use sp_core::{U256, H160}; @@ -18,6 +19,8 @@ use envelope::Envelope; use sp_runtime::{Perbill, traits::{Zero, Convert}}; +mod benchmarking; + #[cfg(test)] mod test; @@ -26,6 +29,16 @@ mod envelope; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type PositiveImbalanceOf = <::Currency as Currency<::AccountId>>::PositiveImbalance; +/// Weight functions needed for this pallet. +pub trait WeightInfo { + fn submit() -> Weight; +} + +impl WeightInfo for () { + fn submit() -> Weight { 0 } +} + + pub trait Config: system::Config { type Event: From + Into<::Event>; @@ -44,6 +57,9 @@ pub trait Config: system::Config { type TreasuryAccount: Get; type FeeConverter: Convert>; + + /// Weight information for extrinsics in this pallet + type WeightInfo: WeightInfo; } decl_storage! { @@ -79,7 +95,7 @@ decl_module! { fn deposit_event() = default; - #[weight = 0] + #[weight = T::WeightInfo::submit()] pub fn submit(origin, message: Message) -> DispatchResult { let relayer = ensure_signed(origin)?; // submit message to verifier for verification diff --git a/parachain/pallets/incentivized-channel/src/inbound/test.rs b/parachain/pallets/incentivized-channel/src/inbound/test.rs index db4d110b30027..26017439a48e9 100644 --- a/parachain/pallets/incentivized-channel/src/inbound/test.rs +++ b/parachain/pallets/incentivized-channel/src/inbound/test.rs @@ -138,6 +138,7 @@ impl incentivized_inbound_channel::Config for Test { type SourceAccount = SourceAccount; type TreasuryAccount = TreasuryAccount; type FeeConverter = FeeConverter; + type WeightInfo = (); } pub fn new_tester(source_channel: H160) -> sp_io::TestExternalities { diff --git a/parachain/pallets/verifier-lightclient/src/lib.rs b/parachain/pallets/verifier-lightclient/src/lib.rs index 983b1df1f5b25..cc6a0e9cb9e0e 100644 --- a/parachain/pallets/verifier-lightclient/src/lib.rs +++ b/parachain/pallets/verifier-lightclient/src/lib.rs @@ -34,7 +34,7 @@ mod mock; mod tests; /// Max number of finalized headers to keep. -const FINALIZED_HEADERS_TO_KEEP: u64 = 5_000; +const FINALIZED_HEADERS_TO_KEEP: u64 = 50_000; /// Max number of headers we're pruning in single import call. const HEADERS_TO_PRUNE_IN_SINGLE_IMPORT: u64 = 8; @@ -48,6 +48,9 @@ pub struct StoredHeader { pub header: EthereumHeader, /// Total difficulty of the chain. pub total_difficulty: U256, + /// Indicates if the header is part of the canonical chain, i.e. has + /// at least DescendantsUntilFinalized descendants. + pub finalized: bool, } /// Blocks range that we want to prune. @@ -295,19 +298,19 @@ impl Module { submitter: Some(sender.clone()), header: header.clone(), total_difficulty, + finalized: false, }; Headers::::insert(hash, header_to_store); if HeadersByNumber::contains_key(header.number) { - let mut mutate_failed = false; - HeadersByNumber::mutate(header.number, |option| { - match option.as_mut() { - Some(hashes) => hashes.push(hash), - None => mutate_failed = true, + HeadersByNumber::mutate(header.number, |option| -> DispatchResult { + if let Some(hashes) = option { + hashes.push(hash); + return Ok(()); } - }); - ensure!(!mutate_failed, Error::::Unknown); + Err(Error::::Unknown.into()) + })?; } else { HeadersByNumber::insert(header.number, vec![hash]); } @@ -329,6 +332,13 @@ impl Module { )?; if new_finalized_block_id != finalized_block_id { FinalizedBlock::put(new_finalized_block_id); + Headers::::mutate(new_finalized_block_id.hash, |option| -> DispatchResult { + if let Some(header) = option { + header.finalized = true; + return Ok(()); + } + Err(Error::::Unknown.into()) + })?; } // Clean up old headers @@ -428,50 +438,16 @@ impl Module { // in the block given by proof.block_hash. Inclusion is only // recognized if the block has been finalized. fn verify_receipt_inclusion(proof: &Proof) -> Result { - let header = Headers::::get(proof.block_hash) - .ok_or(Error::::MissingHeader)? - .header; + let stored_header = Headers::::get(proof.block_hash) + .ok_or(Error::::MissingHeader)?; - let receipt = header.check_receipt_proof(&proof.data.1) - .ok_or(Error::::InvalidProof)?; + ensure!(stored_header.finalized, Error::::HeaderNotFinalized); - let finalized_block = FinalizedBlock::get(); - Self::check_header_finality( - &EthereumHeaderId { hash: proof.block_hash, number: header.number }, - &finalized_block, - )?; + let receipt = stored_header.header.check_receipt_proof(&proof.data.1) + .ok_or(Error::::InvalidProof)?; Ok(receipt) } - - // Checks that the header is in the finalized chain - fn check_header_finality( - header: &EthereumHeaderId, - finalized_block: &EthereumHeaderId, - ) -> DispatchResult { - if header.number == finalized_block.number { - return if header.hash == finalized_block.hash { - Ok(()) - } else { - Err(Error::::HeaderOnStaleFork.into()) - } - } - - ensure!( - header.number < finalized_block.number, - Error::::HeaderNotFinalized, - ); - - let (finalized_hash_at_number, _) = ancestry::(finalized_block.hash) - .find(|(_, ancestor)| ancestor.number == header.number) - .ok_or(Error::::HeaderOnStaleFork)?; - ensure!( - header.hash == finalized_hash_at_number, - Error::::HeaderOnStaleFork, - ); - - Ok(()) - } } /// Return iterator over header ancestors, starting at given hash @@ -512,6 +488,7 @@ impl Verifier for Module { submitter: None, header: header.clone(), total_difficulty: total_difficulty, + finalized: false, }, ); HeadersByNumber::append(header.number, hash); @@ -556,6 +533,19 @@ impl Verifier for Module { hash: hash, number: header.number, }); + let mut next_hash = Ok(hash); + loop { + match next_hash { + Ok(hash) => next_hash = Headers::::mutate(hash, |option| { + if let Some(header) = option { + header.finalized = true; + return Ok(header.header.parent_hash); + } + Err("No header at hash") + }), + _ => break, + } + } } Ok(()) diff --git a/parachain/pallets/verifier-lightclient/src/tests.rs b/parachain/pallets/verifier-lightclient/src/tests.rs index c82654f253558..fbef2601bd057 100644 --- a/parachain/pallets/verifier-lightclient/src/tests.rs +++ b/parachain/pallets/verifier-lightclient/src/tests.rs @@ -85,6 +85,7 @@ fn it_tracks_only_one_finalized_ethereum_fork() { let block1 = child_of_genesis_ethereum_header(); let block1_hash = block1.compute_hash(); let block2 = child_of_header(&block1); + let block2_hash = block2.compute_hash(); let block3 = child_of_header(&block2); let block3_hash = block3.compute_hash(); let mut block4 = child_of_genesis_ethereum_header(); @@ -112,6 +113,8 @@ fn it_tracks_only_one_finalized_ethereum_fork() { } // Relies on DescendantsUntilFinalized = 2 assert_eq!(FinalizedBlock::get().hash, block1_hash); + assert!(Headers::::get(block1_hash).unwrap().finalized); + assert!(Headers::::get(block2_hash).unwrap().finalized == false); assert_eq!(BestBlock::get().0.hash, block3_hash); // With invalid forks (invalid since B1 is final): @@ -441,7 +444,7 @@ fn it_denies_receipt_inclusion_for_invalid_header() { Verifier::verify( &message_with_receipt_proof(log.clone(), block1_hash, receipt_proof.clone()), ), - Error::::HeaderOnStaleFork, + Error::::HeaderNotFinalized, ); assert_ok!(Verifier::import_header( @@ -455,7 +458,7 @@ fn it_denies_receipt_inclusion_for_invalid_header() { Verifier::verify( &message_with_receipt_proof(log.clone(), block1_hash, receipt_proof.clone()), ), - Error::::HeaderOnStaleFork, + Error::::HeaderNotFinalized, ); // Verification works for an ancestor of the finalized header assert_ok!(Verifier::verify( diff --git a/parachain/runtime/local/src/lib.rs b/parachain/runtime/local/src/lib.rs index 94a0c63c80961..c9a1d24ca3153 100644 --- a/parachain/runtime/local/src/lib.rs +++ b/parachain/runtime/local/src/lib.rs @@ -392,6 +392,7 @@ impl basic_channel_inbound::Config for Runtime { type Event = Event; type Verifier = verifier_lightclient::Module; type MessageDispatch = dispatch::Module; + type WeightInfo = (); } impl basic_channel_outbound::Config for Runtime { @@ -421,6 +422,7 @@ impl incentivized_channel_inbound::Config for Runtime { type SourceAccount = SourceAccount; type TreasuryAccount = TreasuryAccount; type FeeConverter = FeeConverter; + type WeightInfo = (); } impl incentivized_channel_outbound::Config for Runtime { @@ -704,7 +706,8 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_timestamp, Timestamp); add_benchmark!(params, batches, verifier_lightclient, VerifierLightclient); add_benchmark!(params, batches, assets, Assets); - add_benchmark!(params, batches, basic_channel_inbound, BasicInboundChannel); + add_benchmark!(params, batches, basic_channel::inbound, BasicInboundChannel); + add_benchmark!(params, batches, incentivized_channel::inbound, IncentivizedInboundChannel); add_benchmark!(params, batches, dot_app, DOT); add_benchmark!(params, batches, erc20_app, ERC20); add_benchmark!(params, batches, eth_app, ETH); diff --git a/parachain/runtime/rococo/src/lib.rs b/parachain/runtime/rococo/src/lib.rs index eb8d3e7acca97..2b9a740a77c92 100644 --- a/parachain/runtime/rococo/src/lib.rs +++ b/parachain/runtime/rococo/src/lib.rs @@ -394,6 +394,7 @@ impl basic_channel_inbound::Config for Runtime { type Event = Event; type Verifier = verifier_lightclient::Module; type MessageDispatch = dispatch::Module; + type WeightInfo = weights::basic_channel_inbound_weights::WeightInfo; } impl basic_channel_outbound::Config for Runtime { @@ -423,6 +424,7 @@ impl incentivized_channel_inbound::Config for Runtime { type SourceAccount = SourceAccount; type TreasuryAccount = TreasuryAccount; type FeeConverter = FeeConverter; + type WeightInfo = weights::incentivized_channel_inbound_weights::WeightInfo; } impl incentivized_channel_outbound::Config for Runtime { @@ -706,7 +708,8 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_timestamp, Timestamp); add_benchmark!(params, batches, verifier_lightclient, VerifierLightclient); add_benchmark!(params, batches, assets, Assets); - add_benchmark!(params, batches, basic_channel_inbound, BasicInboundChannel); + add_benchmark!(params, batches, basic_channel::inbound, BasicInboundChannel); + add_benchmark!(params, batches, incentivized_channel::inbound, IncentivizedInboundChannel); add_benchmark!(params, batches, dot_app, DOT); add_benchmark!(params, batches, erc20_app, ERC20); add_benchmark!(params, batches, eth_app, ETH); diff --git a/parachain/runtime/rococo/src/weights/basic_channel_inbound_weights.rs b/parachain/runtime/rococo/src/weights/basic_channel_inbound_weights.rs new file mode 100644 index 0000000000000..d0578a34d0cda --- /dev/null +++ b/parachain/runtime/rococo/src/weights/basic_channel_inbound_weights.rs @@ -0,0 +1,39 @@ + +//! Autogenerated weights for basic_channel::inbound +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-03-31, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: None, WASM-EXECUTION: Interpreted, CHAIN: Some("spec.json"), DB CACHE: 128 + +// Executed Command: +// target/release/artemis +// benchmark +// --chain +// spec.json +// --pallet +// basic_channel::inbound +// --extrinsic +// * +// --repeat +// 20 +// --steps +// 50 +// --output +// runtime/rococo/src/weights/basic_channel_inbound_weights.rs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for basic_channel::inbound. +pub struct WeightInfo(PhantomData); +impl basic_channel::inbound::WeightInfo for WeightInfo { + fn submit() -> Weight { + (54_471_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } +} diff --git a/parachain/runtime/rococo/src/weights/incentivized_channel_inbound_weights.rs b/parachain/runtime/rococo/src/weights/incentivized_channel_inbound_weights.rs new file mode 100644 index 0000000000000..2f11cc7acf867 --- /dev/null +++ b/parachain/runtime/rococo/src/weights/incentivized_channel_inbound_weights.rs @@ -0,0 +1,39 @@ + +//! Autogenerated weights for incentivized_channel::inbound +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-03-31, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: None, WASM-EXECUTION: Interpreted, CHAIN: Some("spec.json"), DB CACHE: 128 + +// Executed Command: +// target/release/artemis +// benchmark +// --chain +// spec.json +// --pallet +// incentivized_channel::inbound +// --extrinsic +// * +// --repeat +// 20 +// --steps +// 50 +// --output +// runtime/rococo/src/weights/incentivized_channel_inbound_weights.rs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for incentivized_channel::inbound. +pub struct WeightInfo(PhantomData); +impl incentivized_channel::inbound::WeightInfo for WeightInfo { + fn submit() -> Weight { + (54_232_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } +} diff --git a/parachain/runtime/rococo/src/weights/mod.rs b/parachain/runtime/rococo/src/weights/mod.rs index 693d58033d2cc..e959463b792dd 100644 --- a/parachain/runtime/rococo/src/weights/mod.rs +++ b/parachain/runtime/rococo/src/weights/mod.rs @@ -1,8 +1,10 @@ pub mod assets_weights; +pub mod basic_channel_inbound_weights; pub mod dot_app_weights; pub mod erc20_app_weights; pub mod eth_app_weights; pub mod frame_system_weights; +pub mod incentivized_channel_inbound_weights; pub mod pallet_balances_weights; pub mod pallet_timestamp_weights; pub mod verifier_lightclient_weights; diff --git a/parachain/runtime/snowbridge/src/lib.rs b/parachain/runtime/snowbridge/src/lib.rs index 8f74374b260c9..b339df85b0e6b 100644 --- a/parachain/runtime/snowbridge/src/lib.rs +++ b/parachain/runtime/snowbridge/src/lib.rs @@ -395,6 +395,7 @@ impl basic_channel_inbound::Config for Runtime { type Event = Event; type Verifier = verifier_lightclient::Module; type MessageDispatch = dispatch::Module; + type WeightInfo = weights::basic_channel_inbound_weights::WeightInfo; } impl basic_channel_outbound::Config for Runtime { @@ -424,6 +425,7 @@ impl incentivized_channel_inbound::Config for Runtime { type SourceAccount = SourceAccount; type TreasuryAccount = TreasuryAccount; type FeeConverter = FeeConverter; + type WeightInfo = weights::incentivized_channel_inbound_weights::WeightInfo; } impl incentivized_channel_outbound::Config for Runtime { @@ -707,7 +709,8 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_timestamp, Timestamp); add_benchmark!(params, batches, verifier_lightclient, VerifierLightclient); add_benchmark!(params, batches, assets, Assets); - add_benchmark!(params, batches, basic_channel_inbound, BasicInboundChannel); + add_benchmark!(params, batches, basic_channel::inbound, BasicInboundChannel); + add_benchmark!(params, batches, incentivized_channel::inbound, IncentivizedInboundChannel); add_benchmark!(params, batches, dot_app, DOT); add_benchmark!(params, batches, erc20_app, ERC20); add_benchmark!(params, batches, eth_app, ETH); diff --git a/parachain/runtime/snowbridge/src/weights/basic_channel_inbound_weights.rs b/parachain/runtime/snowbridge/src/weights/basic_channel_inbound_weights.rs new file mode 100644 index 0000000000000..d5a6878b8c7e4 --- /dev/null +++ b/parachain/runtime/snowbridge/src/weights/basic_channel_inbound_weights.rs @@ -0,0 +1,43 @@ + +//! Autogenerated weights for basic_channel::inbound +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-04-13, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("/tmp/artemis-benchmark-TIb/spec.json"), DB CACHE: 128 + +// Executed Command: +// target/release/artemis +// benchmark +// --chain +// /tmp/artemis-benchmark-TIb/spec.json +// --execution +// wasm +// --wasm-execution +// compiled +// --pallet +// basic_channel::inbound +// --extrinsic +// * +// --repeat +// 20 +// --steps +// 50 +// --output +// runtime/snowbridge/src/weights/basic_channel_inbound_weights.rs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for basic_channel::inbound. +pub struct WeightInfo(PhantomData); +impl basic_channel::inbound::WeightInfo for WeightInfo { + fn submit() -> Weight { + (177_324_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } +} diff --git a/parachain/runtime/snowbridge/src/weights/incentivized_channel_inbound_weights.rs b/parachain/runtime/snowbridge/src/weights/incentivized_channel_inbound_weights.rs new file mode 100644 index 0000000000000..31377119271ab --- /dev/null +++ b/parachain/runtime/snowbridge/src/weights/incentivized_channel_inbound_weights.rs @@ -0,0 +1,43 @@ + +//! Autogenerated weights for incentivized_channel::inbound +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-04-13, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("/tmp/artemis-benchmark-TIb/spec.json"), DB CACHE: 128 + +// Executed Command: +// target/release/artemis +// benchmark +// --chain +// /tmp/artemis-benchmark-TIb/spec.json +// --execution +// wasm +// --wasm-execution +// compiled +// --pallet +// incentivized_channel::inbound +// --extrinsic +// * +// --repeat +// 20 +// --steps +// 50 +// --output +// runtime/snowbridge/src/weights/incentivized_channel_inbound_weights.rs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for incentivized_channel::inbound. +pub struct WeightInfo(PhantomData); +impl incentivized_channel::inbound::WeightInfo for WeightInfo { + fn submit() -> Weight { + (272_146_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } +} diff --git a/parachain/runtime/snowbridge/src/weights/mod.rs b/parachain/runtime/snowbridge/src/weights/mod.rs index 693d58033d2cc..e959463b792dd 100644 --- a/parachain/runtime/snowbridge/src/weights/mod.rs +++ b/parachain/runtime/snowbridge/src/weights/mod.rs @@ -1,8 +1,10 @@ pub mod assets_weights; +pub mod basic_channel_inbound_weights; pub mod dot_app_weights; pub mod erc20_app_weights; pub mod eth_app_weights; pub mod frame_system_weights; +pub mod incentivized_channel_inbound_weights; pub mod pallet_balances_weights; pub mod pallet_timestamp_weights; pub mod verifier_lightclient_weights; diff --git a/parachain/scripts/benchmark.sh b/parachain/scripts/benchmark.sh index 3686d698aaedf..49b90ff4d0104 100755 --- a/parachain/scripts/benchmark.sh +++ b/parachain/scripts/benchmark.sh @@ -33,12 +33,13 @@ DOT_MODULE_ENDOWMENT="[ node ../test/scripts/helpers/overrideParachainSpec.js $TMP_DIR/spec.json \ genesis.runtime.palletBalances.balances.0 "$DOT_MODULE_ENDOWMENT" -PALLETS="assets dot_app erc20_app eth_app frame_system pallet_balances pallet_timestamp verifier_lightclient" +PALLETS="assets basic_channel::inbound dot_app erc20_app eth_app frame_system incentivized_channel::inbound pallet_balances pallet_timestamp verifier_lightclient" echo "Generating weights module for $RUNTIME_DIR with pallets $PALLETS" for pallet in $PALLETS do + MODULE_NAME="$(tr -s [:] _ <<< $pallet)_weights" target/release/artemis benchmark \ --chain $TMP_DIR/spec.json \ --execution wasm \ @@ -47,8 +48,8 @@ do --extrinsic "*" \ --repeat 20 \ --steps 50 \ - --output $RUNTIME_DIR/src/weights/${pallet}_weights.rs - echo "pub mod ${pallet}_weights;" >> $TMP_DIR/mod.rs + --output $RUNTIME_DIR/src/weights/$MODULE_NAME.rs + echo "pub mod $MODULE_NAME;" >> $TMP_DIR/mod.rs done mv $TMP_DIR/mod.rs $RUNTIME_DIR/src/weights/mod.rs