diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 54fd8d02ece..4d1a1a9a4d3 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -159,7 +159,7 @@ jobs: - name: "ACTIONS: Setup environment variable" if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'E0-forcecoverage') run: echo "RUSTFLAGS=-Cinstrument-coverage" >> $GITHUB_ENV - + - name: "Buid: Init" run: ./scripts/gear.sh init cargo @@ -295,7 +295,6 @@ jobs: run: shell: msys2 {0} env: - RUSTC_WRAPPER: "cachepot" CARGO_INCREMENTAL: 0 steps: - name: Cancel Previous Runs diff --git a/core-processor/src/ext.rs b/core-processor/src/ext.rs index 052bfaeb61e..5f788daaf86 100644 --- a/core-processor/src/ext.rs +++ b/core-processor/src/ext.rs @@ -1041,11 +1041,58 @@ impl Ext { #[cfg(test)] mod tests { use super::*; + use alloc::vec; use gear_core::{ - message::{ContextSettings, IncomingDispatch}, + message::{ContextSettings, IncomingDispatch, Payload, MAX_PAYLOAD_SIZE}, pages::PageNumber, }; + struct MessageContextBuilder { + incoming_dispatch: IncomingDispatch, + program_id: ProgramId, + sending_fee: u64, + scheduled_sending_fee: u64, + waiting_fee: u64, + waking_fee: u64, + reservation_fee: u64, + outgoing_limit: u32, + } + + impl MessageContextBuilder { + fn new() -> Self { + Self { + incoming_dispatch: Default::default(), + program_id: Default::default(), + sending_fee: 0, + scheduled_sending_fee: 0, + waiting_fee: 0, + waking_fee: 0, + reservation_fee: 0, + outgoing_limit: 0, + } + } + + fn build(self) -> MessageContext { + MessageContext::new( + self.incoming_dispatch, + self.program_id, + ContextSettings::new( + self.sending_fee, + self.scheduled_sending_fee, + self.waiting_fee, + self.waking_fee, + self.reservation_fee, + self.outgoing_limit, + ), + ) + } + + fn with_outgoing_limit(mut self, outgoing_limit: u32) -> Self { + self.outgoing_limit = outgoing_limit; + self + } + } + struct ProcessorContextBuilder(ProcessorContext); impl ProcessorContextBuilder { @@ -1091,6 +1138,16 @@ mod tests { Self(default_pc) } + fn build(self) -> ProcessorContext { + self.0 + } + + fn with_message_context(mut self, context: MessageContext) -> Self { + self.0.message_context = context; + + self + } + fn with_gas(mut self, gas_counter: GasCounter) -> Self { self.0.gas_counter = gas_counter; @@ -1114,10 +1171,6 @@ mod tests { self } - - fn build(self) -> ProcessorContext { - self.0 - } } // Invariant: Refund never occurs in `free` call. @@ -1218,6 +1271,334 @@ mod tests { assert_eq!(0, allowance); } + #[test] + // This function tests: + // + // - `send_commit` on valid handle + // - `send_commit` on invalid handle + // - `send_commit` on used handle + // - `send_init` after limit is exceeded + fn test_send_commit() { + let mut ext = Ext::new( + ProcessorContextBuilder::new() + .with_message_context(MessageContextBuilder::new().with_outgoing_limit(1).build()) + .build(), + ); + + let data = HandlePacket::default(); + + let fake_handle = 0; + + let msg = ext.send_commit(fake_handle, data.clone(), 0); + assert_eq!( + msg.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::OutOfBounds)) + ); + + let handle = ext.send_init().expect("Outgoing limit is 1"); + + let msg = ext.send_commit(handle, data.clone(), 0); + assert!(msg.is_ok()); + + let msg = ext.send_commit(handle, data, 0); + assert_eq!( + msg.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::LateAccess)) + ); + + let handle = ext.send_init(); + assert_eq!( + handle.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message( + MessageError::OutgoingMessagesAmountLimitExceeded + )) + ); + } + + #[test] + // This function tests: + // + // - `send_push` on non-existent handle + // - `send_push` on valid handle + // - `send_push` on used handle + // - `send_push` with too large payload + // - `send_push` data is added to buffer + fn test_send_push() { + let mut ext = Ext::new( + ProcessorContextBuilder::new() + .with_message_context( + MessageContextBuilder::new() + .with_outgoing_limit(u32::MAX) + .build(), + ) + .build(), + ); + + let data = HandlePacket::default(); + + let fake_handle = 0; + + let res = ext.send_push(fake_handle, &[0, 0, 0]); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::OutOfBounds)) + ); + + let handle = ext.send_init().expect("Outgoing limit is u32::MAX"); + + let res = ext.send_push(handle, &[1, 2, 3]); + assert!(res.is_ok()); + + let res = ext.send_push(handle, &[4, 5, 6]); + assert!(res.is_ok()); + + let large_payload = vec![0u8; MAX_PAYLOAD_SIZE + 1]; + + let res = ext.send_push(handle, &large_payload); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message( + MessageError::MaxMessageSizeExceed + )) + ); + + let msg = ext.send_commit(handle, data, 0); + assert!(msg.is_ok()); + + let res = ext.send_push(handle, &[7, 8, 9]); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::LateAccess)) + ); + + let (outcome, _) = ext.context.message_context.drain(); + let ContextOutcomeDrain { + mut outgoing_dispatches, + .. + } = outcome.drain(); + let dispatch = outgoing_dispatches + .pop() + .map(|(dispatch, _, _)| dispatch) + .expect("Send commit was ok"); + + assert_eq!(dispatch.message().payload_bytes(), &[1, 2, 3, 4, 5, 6]); + } + + #[test] + // This function tests: + // + // - `send_push_input` on non-existent handle + // - `send_push_input` on valid handle + // - `send_push_input` on used handle + // - `send_push_input` data is added to buffer + fn test_send_push_input() { + let mut ext = Ext::new( + ProcessorContextBuilder::new() + .with_message_context( + MessageContextBuilder::new() + .with_outgoing_limit(u32::MAX) + .build(), + ) + .build(), + ); + + let data = HandlePacket::default(); + + let fake_handle = 0; + + let res = ext.send_push_input(fake_handle, 0, 1); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::OutOfBounds)) + ); + + let handle = ext.send_init().expect("Outgoing limit is u32::MAX"); + + let res = ext + .context + .message_context + .payload_mut() + .try_extend_from_slice(&[1, 2, 3, 4, 5, 6]); + assert!(res.is_ok()); + + let res = ext.send_push_input(handle, 2, 3); + assert!(res.is_ok()); + + let res = ext.send_push_input(handle, 8, 10); + assert!(res.is_ok()); + + let msg = ext.send_commit(handle, data, 0); + assert!(msg.is_ok()); + + let res = ext.send_push_input(handle, 0, 1); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::LateAccess)) + ); + + let (outcome, _) = ext.context.message_context.drain(); + let ContextOutcomeDrain { + mut outgoing_dispatches, + .. + } = outcome.drain(); + let dispatch = outgoing_dispatches + .pop() + .map(|(dispatch, _, _)| dispatch) + .expect("Send commit was ok"); + + assert_eq!(dispatch.message().payload_bytes(), &[3, 4, 5]); + } + + #[test] + // This function requires `reply_push` to work to add extra data. + // This function tests: + // + // - `reply_commit` with too much data + // - `reply_commit` with valid data + // - `reply_commit` duplicate reply + fn test_reply_commit() { + let mut ext = Ext::new( + ProcessorContextBuilder::new() + .with_gas(GasCounter::new(u64::MAX)) + .with_message_context( + MessageContextBuilder::new() + .with_outgoing_limit(u32::MAX) + .build(), + ) + .build(), + ); + + let res = ext.reply_push(&[0]); + assert!(res.is_ok()); + + let res = ext.reply_commit(ReplyPacket::new(Payload::filled_with(0), 0)); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message( + MessageError::MaxMessageSizeExceed + )) + ); + + let res = ext.reply_commit(ReplyPacket::auto()); + assert!(res.is_ok()); + + let res = ext.reply_commit(ReplyPacket::auto()); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::DuplicateReply)) + ); + } + + #[test] + // This function requires `reply_push` to work to add extra data. + // This function tests: + // + // - `reply_push` with valid data + // - `reply_push` with too much data + // - `reply_push` after `reply_commit` + // - `reply_push` data is added to buffer + fn test_reply_push() { + let mut ext = Ext::new( + ProcessorContextBuilder::new() + .with_gas(GasCounter::new(u64::MAX)) + .with_message_context( + MessageContextBuilder::new() + .with_outgoing_limit(u32::MAX) + .build(), + ) + .build(), + ); + + let res = ext.reply_push(&[1, 2, 3]); + assert!(res.is_ok()); + + let res = ext.reply_push(&[4, 5, 6]); + assert!(res.is_ok()); + + let large_payload = vec![0u8; MAX_PAYLOAD_SIZE + 1]; + + let res = ext.reply_push(&large_payload); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message( + MessageError::MaxMessageSizeExceed + )) + ); + + let res = ext.reply_commit(ReplyPacket::auto()); + assert!(res.is_ok()); + + let res = ext.reply_push(&[7, 8, 9]); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::LateAccess)) + ); + + let (outcome, _) = ext.context.message_context.drain(); + let ContextOutcomeDrain { + mut outgoing_dispatches, + .. + } = outcome.drain(); + let dispatch = outgoing_dispatches + .pop() + .map(|(dispatch, _, _)| dispatch) + .expect("Send commit was ok"); + + assert_eq!(dispatch.message().payload_bytes(), &[1, 2, 3, 4, 5, 6]); + } + + #[test] + // This function tests: + // + // - `reply_push_input` with valid data + // - `reply_push_input` after `reply_commit` + // - `reply_push_input` data is added to buffer + fn test_reply_push_input() { + let mut ext = Ext::new( + ProcessorContextBuilder::new() + .with_message_context( + MessageContextBuilder::new() + .with_outgoing_limit(u32::MAX) + .build(), + ) + .build(), + ); + + let res = ext + .context + .message_context + .payload_mut() + .try_extend_from_slice(&[1, 2, 3, 4, 5, 6]); + assert!(res.is_ok()); + + let res = ext.reply_push_input(2, 3); + assert!(res.is_ok()); + + let res = ext.reply_push_input(8, 10); + assert!(res.is_ok()); + + let msg = ext.reply_commit(ReplyPacket::auto()); + assert!(msg.is_ok()); + + let res = ext.reply_push_input(0, 1); + assert_eq!( + res.unwrap_err(), + FallibleExtError::Core(FallibleExtErrorCore::Message(MessageError::LateAccess)) + ); + + let (outcome, _) = ext.context.message_context.drain(); + let ContextOutcomeDrain { + mut outgoing_dispatches, + .. + } = outcome.drain(); + let dispatch = outgoing_dispatches + .pop() + .map(|(dispatch, _, _)| dispatch) + .expect("Send commit was ok"); + + assert_eq!(dispatch.message().payload_bytes(), &[3, 4, 5]); + } + mod property_tests { use super::*; use gear_core::{ diff --git a/gcli/tests/cmd/program.rs b/gcli/tests/cmd/program.rs index 94255e1def6..7464aa13153 100644 --- a/gcli/tests/cmd/program.rs +++ b/gcli/tests/cmd/program.rs @@ -94,7 +94,7 @@ Metadata { #[test] fn test_command_program_metadata_works() -> Result<()> { - let meta = env::example_path("new-meta/demo_new_meta.meta.txt"); + let meta = env::wasm_bin("demo_new_meta.meta.txt"); let args = Args::new("program").action("meta").meta(meta); let result = common::gcli(Vec::::from(args)).expect("run gcli failed"); @@ -109,7 +109,7 @@ fn test_command_program_metadata_works() -> Result<()> { #[test] fn test_command_program_metadata_derive_works() -> Result<()> { - let meta = env::example_path("new-meta/demo_new_meta.meta.txt"); + let meta = env::wasm_bin("demo_new_meta.meta.txt"); let args = Args::new("program") .action("meta") .meta(meta) diff --git a/gcli/tests/common/env.rs b/gcli/tests/common/env.rs index e5e7375cbb0..745287a80ee 100644 --- a/gcli/tests/common/env.rs +++ b/gcli/tests/common/env.rs @@ -53,8 +53,3 @@ pub fn bin(name: &str) -> String { pub fn wasm_bin(name: &str) -> String { bin_path(name, true) } - -/// path of `example/binaries` folders -pub fn example_path(name: &str) -> String { - ROOT.clone() + "/examples/" + name -} diff --git a/gcli/tests/gear.rs b/gcli/tests/gear.rs index 53d134d313a..e1915f81e3f 100644 --- a/gcli/tests/gear.rs +++ b/gcli/tests/gear.rs @@ -37,7 +37,7 @@ fn paths() { env::bin("gear"), env::bin("gcli"), env::wasm_bin("demo_new_meta.opt.wasm"), - env::example_path("new-meta/demo_new_meta.meta.txt"), + env::wasm_bin("demo_new_meta.meta.txt"), ] .into_iter() .for_each(|path| { diff --git a/pallets/airdrop/Cargo.toml b/pallets/airdrop/Cargo.toml index 524b19ddb48..56bcc784523 100644 --- a/pallets/airdrop/Cargo.toml +++ b/pallets/airdrop/Cargo.toml @@ -45,7 +45,7 @@ pallet-gear-gas = { workspace = true, features = ["std"] } frame-support-test = { workspace = true, features = ["std"] } [features] -default = ['std'] +default = ["std"] std = [ "common/std", "parity-scale-codec/std", diff --git a/pallets/airdrop/src/benchmarking.rs b/pallets/airdrop/src/benchmarking.rs index d7dd33c01a4..e93b2e13738 100644 --- a/pallets/airdrop/src/benchmarking.rs +++ b/pallets/airdrop/src/benchmarking.rs @@ -23,7 +23,8 @@ use common::{benchmarking, Origin}; use frame_benchmarking::{benchmarks, impl_benchmark_test_suite}; use frame_support::traits::Currency; use frame_system::RawOrigin; -use sp_runtime::traits::UniqueSaturatedInto; +use pallet_vesting::VestingInfo; +use sp_runtime::traits::{StaticLookup, UniqueSaturatedInto}; benchmarks! { where_clause { where @@ -37,12 +38,33 @@ benchmarks! { ::Currency::deposit_creating(&source, (1u128 << 60).unique_saturated_into()); let recipient: T::AccountId = benchmarking::account("recipient", 0, 0); // Keeping in mind the existential deposit - let amount = 100_000_u128.saturating_add(10_u128.saturating_mul(q.into())); + let amount = 10_000_000_000_000_u128.saturating_add(10_u128.saturating_mul(q.into())); }: _(RawOrigin::Root, source, recipient.clone(), amount.unique_saturated_into()) verify { assert_eq!(pallet_balances::Pallet::::total_balance(&recipient), amount.unique_saturated_into()); } + + transfer_vested { + let q in 1 .. 256; + + let source: T::AccountId = benchmarking::account("source", 0, 0); + let source_lookup = T::Lookup::unlookup(source.clone()); + ::Currency::deposit_creating(&source, (1u128 << 60).unique_saturated_into()); + let recipient: T::AccountId = benchmarking::account("recipient", 0, 0); + let amount = ::MinVestedTransfer::get().saturating_mul(q.into()); + + // create vesting schedule amount * 2 + let vested_amount = amount.saturating_mul(2u128.unique_saturated_into()); + let vesting_schedule = VestingInfo::new(vested_amount.unique_saturated_into(), 10u128.unique_saturated_into(), 1000u32.into()); + pallet_vesting::Pallet::::vested_transfer(RawOrigin::Signed(source.clone()).into(), source_lookup, vesting_schedule)?; + + }: _(RawOrigin::Root, source.clone(), recipient.clone(), 0, Some(amount)) + verify { + // check that the total vested amount is halved between the source and the recipient + assert_eq!(pallet_vesting::Pallet::::vesting_balance(&source), Some(amount)); + assert_eq!(::Currency::free_balance(&recipient), amount); + } } impl_benchmark_test_suite!(Airdrop, crate::mock::new_test_ext(), crate::mock::Test,); diff --git a/pallets/airdrop/src/lib.rs b/pallets/airdrop/src/lib.rs index 48fa3fd7cd6..613686b1c98 100644 --- a/pallets/airdrop/src/lib.rs +++ b/pallets/airdrop/src/lib.rs @@ -109,7 +109,7 @@ pub mod pallet { /// Emits the following events: /// - `TokensDeposited{ dest, amount }` #[pallet::call_index(0)] - #[pallet::weight(::WeightInfo::transfer())] + #[pallet::weight(::WeightInfo::transfer(1))] pub fn transfer( origin: OriginFor, source: T::AccountId, @@ -146,7 +146,7 @@ pub mod pallet { /// Emits the following events: /// - `VestingScheduleRemoved{ who, schedule_index }` #[pallet::call_index(1)] - #[pallet::weight(::WeightInfo::transfer())] + #[pallet::weight(::WeightInfo::transfer_vested(1))] pub fn transfer_vested( origin: OriginFor, source: T::AccountId, diff --git a/pallets/airdrop/src/mock.rs b/pallets/airdrop/src/mock.rs index 86eb8ab7bac..c4ec16432f8 100644 --- a/pallets/airdrop/src/mock.rs +++ b/pallets/airdrop/src/mock.rs @@ -203,6 +203,8 @@ impl pallet_vesting::Config for Test { const MAX_VESTING_SCHEDULES: u32 = 28; } +pub type VestingError = pallet_vesting::Error; + impl pallet_airdrop::Config for Test { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); diff --git a/pallets/airdrop/src/tests.rs b/pallets/airdrop/src/tests.rs index b02874f9d81..3e57371758c 100644 --- a/pallets/airdrop/src/tests.rs +++ b/pallets/airdrop/src/tests.rs @@ -19,7 +19,7 @@ use super::*; use crate::mock::{ new_test_ext, Airdrop, AirdropCall, AirdropError, Balances, RuntimeCall, RuntimeOrigin, Sudo, - Test, Vesting, ALICE, BOB, ROOT, + Test, Vesting, VestingError, ALICE, BOB, ROOT, }; use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::Config; @@ -77,6 +77,18 @@ fn vesting_transfer_works() { assert_eq!(Balances::total_balance(&ROOT), 100_000_000); assert_eq!(Balances::total_issuance(), 200_000_000); + // Vesting must exist on the source account + assert_err!( + Airdrop::transfer_vested(RuntimeOrigin::root(), ALICE, BOB, 1, Some(200_000_000)), + VestingError::NotVesting + ); + + // Schedule must exist on the source account + assert_err!( + Airdrop::transfer_vested(RuntimeOrigin::root(), BOB, ALICE, 1, Some(200_000_000)), + VestingError::ScheduleIndexOutOfBounds + ); + // Amount can't be bigger than locked funds assert_err!( Airdrop::transfer_vested(RuntimeOrigin::root(), BOB, ALICE, 0, Some(200_000_000)), diff --git a/pallets/airdrop/src/weights.rs b/pallets/airdrop/src/weights.rs index 50614d97c6f..ddaa539a3d9 100644 --- a/pallets/airdrop/src/weights.rs +++ b/pallets/airdrop/src/weights.rs @@ -1,7 +1,6 @@ - // This file is part of Gear. -// Copyright (C) 2021-2023 Gear Technologies Inc. +// Copyright (C) 2022-2023 Gear Technologies Inc. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program is free software: you can redistribute it and/or modify @@ -17,51 +16,80 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Autogenerated weights for pallet_gear +//! Autogenerated weights for pallet_airdrop //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-08-25, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("local"), DB CACHE: 128 +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("vara-dev"), DB CACHE: 1024 // Executed Command: -// ./target/release/gear-node -// benchmark -// pallet -// --pallet -// pallet_airdrop -// --extrinsic=transfer -// --steps -// 50 -// --repeat -// 20 -// --chain=vara-dev -// --output -// . +// ./target/production/gear benchmark pallet --chain=vara-dev --steps=50 --repeat=20 --pallet=pallet_airdrop --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=pallet_airdrop.rs --template=.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] -use frame_support::{traits::Get, weights::{constants::RocksDbWeight, Weight}}; +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions for pallet_airdrop. +/// Weight functions needed for pallet_airdrop. pub trait WeightInfo { - fn transfer() -> Weight; + fn transfer(q: u32, ) -> Weight; + fn transfer_vested(q: u32, ) -> Weight; } -/// Weight functions for `pallet_airdrop`. -pub struct AirdropWeight(PhantomData); -impl WeightInfo for AirdropWeight { - fn transfer() -> Weight { - (Weight::from_parts(18_000_000, 0)) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } +/// Weights for pallet_airdrop using the Gear node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// The range of component `q` is `[1, 256]`. + fn transfer(_q: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `6196` + // Minimum execution time: 25_027_000 picoseconds. + Weight::from_parts(25_985_030, 6196) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// The range of component `q` is `[1, 256]`. + fn transfer_vested(q: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `550` + // Estimated: `15482` + // Minimum execution time: 65_271_000 picoseconds. + Weight::from_parts(67_109_074, 15482) + // Standard Error: 328 + .saturating_add(Weight::from_parts(336, 0).saturating_mul(q.into())) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } } +// For backwards compatibility and tests impl WeightInfo for () { - fn transfer() -> Weight { - Weight::zero().saturating_add(RocksDbWeight::get().writes(1_u64)) + /// The range of component `q` is `[1, 256]`. + fn transfer(_q: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `6196` + // Minimum execution time: 25_027_000 picoseconds. + Weight::from_parts(25_985_030, 6196) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// The range of component `q` is `[1, 256]`. + fn transfer_vested(q: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `550` + // Estimated: `15482` + // Minimum execution time: 65_271_000 picoseconds. + Weight::from_parts(67_109_074, 15482) + // Standard Error: 328 + .saturating_add(Weight::from_parts(336, 0).saturating_mul(q.into())) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } } diff --git a/runtime/vara/src/lib.rs b/runtime/vara/src/lib.rs index 0aa07ce2256..0f160e0438b 100644 --- a/runtime/vara/src/lib.rs +++ b/runtime/vara/src/lib.rs @@ -816,7 +816,7 @@ impl pallet_gear_messenger::Config for Runtime { impl pallet_airdrop::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type WeightInfo = pallet_airdrop::weights::AirdropWeight; + type WeightInfo = weights::pallet_airdrop::SubstrateWeight; type VestingSchedule = Vesting; } @@ -1070,6 +1070,7 @@ mod benches { [pallet_timestamp, Timestamp] [pallet_utility, Utility] // Gear pallets + [pallet_airdrop, Airdrop] [pallet_gear, Gear] [pallet_gear_voucher, GearVoucher] ); diff --git a/runtime/vara/src/weights/mod.rs b/runtime/vara/src/weights/mod.rs index b4eebedfe52..170d6f59e22 100644 --- a/runtime/vara/src/weights/mod.rs +++ b/runtime/vara/src/weights/mod.rs @@ -19,6 +19,7 @@ //! A list of the different weight modules for our runtime. pub mod frame_system; +pub mod pallet_airdrop; pub mod pallet_balances; pub mod pallet_gear; pub mod pallet_gear_voucher; diff --git a/runtime/vara/src/weights/pallet_airdrop.rs b/runtime/vara/src/weights/pallet_airdrop.rs new file mode 100644 index 00000000000..62ae1a74e8d --- /dev/null +++ b/runtime/vara/src/weights/pallet_airdrop.rs @@ -0,0 +1,95 @@ +// This file is part of Gear. + +// Copyright (C) 2022-2023 Gear Technologies Inc. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! Autogenerated weights for pallet_airdrop +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("vara-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/production/gear benchmark pallet --chain=vara-dev --steps=50 --repeat=20 --pallet=pallet_airdrop --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=pallet_airdrop.rs --template=.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_airdrop. +pub trait WeightInfo { + fn transfer(q: u32, ) -> Weight; + fn transfer_vested(q: u32, ) -> Weight; +} + +/// Weights for pallet_airdrop using the Gear node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl pallet_airdrop::WeightInfo for SubstrateWeight { + /// The range of component `q` is `[1, 256]`. + fn transfer(_q: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `6196` + // Minimum execution time: 25_027_000 picoseconds. + Weight::from_parts(25_985_030, 6196) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// The range of component `q` is `[1, 256]`. + fn transfer_vested(q: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `550` + // Estimated: `15482` + // Minimum execution time: 65_271_000 picoseconds. + Weight::from_parts(67_109_074, 15482) + // Standard Error: 328 + .saturating_add(Weight::from_parts(336, 0).saturating_mul(q.into())) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// The range of component `q` is `[1, 256]`. + fn transfer(_q: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `6196` + // Minimum execution time: 25_027_000 picoseconds. + Weight::from_parts(25_985_030, 6196) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// The range of component `q` is `[1, 256]`. + fn transfer_vested(q: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `550` + // Estimated: `15482` + // Minimum execution time: 65_271_000 picoseconds. + Weight::from_parts(67_109_074, 15482) + // Standard Error: 328 + .saturating_add(Weight::from_parts(336, 0).saturating_mul(q.into())) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } +} diff --git a/utils/wasm-builder/src/optimize.rs b/utils/wasm-builder/src/optimize.rs index 0ad73346ecf..0702aa49ea6 100644 --- a/utils/wasm-builder/src/optimize.rs +++ b/utils/wasm-builder/src/optimize.rs @@ -225,6 +225,8 @@ pub fn do_optimization( .arg(format!("-O{optimization_level}")) .arg("-o") .arg(dest_optimized) + .arg("-mvp") + .arg("--enable-sign-ext") // the memory in our module is imported, `wasm-opt` needs to be told that // the memory is initialized to zeroes, otherwise it won't run the // memory-packing pre-pass. @@ -277,6 +279,8 @@ pub fn do_optimization( "z" => OptimizationOptions::new_optimize_for_size_aggressively(), _ => panic!("Invalid optimization level {}", optimization_level), } + .mvp_features_only() + .enable_feature(wasm_opt::Feature::SignExt) .shrink_level(wasm_opt::ShrinkLevel::Level2) .add_pass(Pass::Dae) .add_pass(Pass::Vacuum) diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index 579ad88445d..da77a64b9e0 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -214,6 +214,8 @@ impl WasmProject { let mut source_code = "#![no_std] pub use orig_project::*;\n".to_owned(); + fs::create_dir_all(&self.wasm_target_dir)?; + // Write metadata if let Some(metadata) = &self.project_type.metadata() { let file_base_name = self @@ -222,7 +224,7 @@ impl WasmProject { .expect("Run `WasmProject::create_project()` first"); let wasm_meta_path = self - .original_dir + .wasm_target_dir .join([file_base_name, ".meta.txt"].concat()); smart_fs::write_metadata(wasm_meta_path, metadata) @@ -397,7 +399,6 @@ extern "C" fn metahash() {{ .join(format!("{}.wasm", &file_base_name)); fs::create_dir_all(&self.target_dir)?; - fs::create_dir_all(&self.wasm_target_dir)?; if self.project_type.is_metawasm() { self.postprocess_meta(&original_wasm_path, file_base_name)?;