From ef2e6d3907fc0ce05c1dd390ee0946abb1cdc7a6 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Thu, 13 Jan 2022 18:15:12 +0100 Subject: [PATCH 1/2] refactor crowdloan benchmarking --- Cargo.lock | 1 - frame/crowdloan-rewards/Cargo.toml | 18 +--- frame/crowdloan-rewards/src/benchmarking.rs | 104 +++++++++++++++++++- frame/crowdloan-rewards/src/lib.rs | 11 +-- frame/crowdloan-rewards/src/mocks.rs | 1 + 5 files changed, 113 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 674bc9f7e0f..aeebd7302f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6653,7 +6653,6 @@ dependencies = [ "hex", "hex-literal", "libsecp256k1", - "once_cell", "pallet-balances", "parity-scale-codec", "rustc-hex", diff --git a/frame/crowdloan-rewards/Cargo.toml b/frame/crowdloan-rewards/Cargo.toml index 8933c5efd7b..89a7984825c 100644 --- a/frame/crowdloan-rewards/Cargo.toml +++ b/frame/crowdloan-rewards/Cargo.toml @@ -23,27 +23,22 @@ libsecp256k1 = { version = "0.7.0", default-features = false, features = [ "static-context", ] } hex-literal = "0.3" -balances = { package = "pallet-balances", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false, features = [ - "std", -] } +balances = { package = "pallet-balances", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } [dependencies] ### Benchmarking hex-literal = { version = "0.3.3", optional = true } -once_cell = { version = "1.8.0", optional = true } libsecp256k1 = { version = "0.7.0", default-features = false, optional = true, features = [ "hmac", "static-context", ] } -balances = { package = "pallet-balances", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false, features = [ - "std", -], optional = true } - +balances = { package = "pallet-balances", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false, optional = true } frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } +sp-application-crypto = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } + frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } -sp-application-crypto = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } @@ -74,13 +69,10 @@ std = [ runtime-benchmarks = [ "hex-literal", - "once_cell", "libsecp256k1", "balances", + "frame-benchmarking", "sp-application-crypto", - "sp-core/full_crypto", - "sp-application-crypto/full_crypto", - "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", ] diff --git a/frame/crowdloan-rewards/src/benchmarking.rs b/frame/crowdloan-rewards/src/benchmarking.rs index 4b6126e382a..95466da9193 100644 --- a/frame/crowdloan-rewards/src/benchmarking.rs +++ b/frame/crowdloan-rewards/src/benchmarking.rs @@ -1,16 +1,22 @@ use super::*; -use crate::{mocks::generate_accounts, Pallet as CrowdloanReward}; +use crate::Pallet as CrowdloanReward; + +use crate::models::{EcdsaSignature, EthereumAddress, Proof, RemoteAccount}; use frame_benchmarking::{benchmarks, impl_benchmark_test_suite}; use frame_system::RawOrigin; +use sp_core::{ed25519, keccak_256, Pair}; use sp_runtime::AccountId32; use sp_std::prelude::*; +type RelayKey = ed25519::Pair; +type EthKey = libsecp256k1::SecretKey; type BlockNumber = u32; type Balance = u128; type AccountId = AccountId32; type RelayChainAccountId = [u8; 32]; +const PROOF_PREFIX: &[u8] = b"picasso-"; const MILLISECS_PER_BLOCK: u64 = 6000; const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); const HOURS: BlockNumber = MINUTES * 60; @@ -19,6 +25,101 @@ const WEEKS: BlockNumber = DAYS * 7; const VESTING_PERIOD: BlockNumber = 48 * WEEKS; +#[derive(Clone)] +enum ClaimKey { + Relay(RelayKey), + Eth(EthKey), +} + +impl ClaimKey { + pub fn as_remote_public(&self) -> RemoteAccount { + match self { + ClaimKey::Relay(relay_account) => + RemoteAccount::RelayChain(relay_account.public().into()), + ClaimKey::Eth(ethereum_account) => + RemoteAccount::Ethereum(ethereum_address(ethereum_account)), + } + } + pub fn proof(self, reward_account: AccountId32) -> Proof<[u8; 32]> { + match self { + ClaimKey::Relay(relay) => relay_proof(&relay, reward_account), + ClaimKey::Eth(eth) => ethereum_proof(ð, reward_account), + } + } +} + +fn relay_proof(relay_account: &RelayKey, reward_account: AccountId) -> Proof { + let mut msg = PROOF_PREFIX.to_vec(); + msg.append(&mut reward_account.using_encoded(|x| hex::encode(x).as_bytes().to_vec())); + Proof::RelayChain(relay_account.public().into(), relay_account.sign(&msg).into()) +} + +fn ethereum_proof( + ethereum_account: &EthKey, + reward_account: AccountId, +) -> Proof { + let msg = keccak_256( + &crate::ethereum_signable_message( + PROOF_PREFIX, + &reward_account.using_encoded(|x| hex::encode(x).as_bytes().to_vec()), + )[..], + ); + let (sig, recovery_id) = + libsecp256k1::sign(&libsecp256k1::Message::parse(&msg), ethereum_account); + let mut r = [0_u8; 65]; + r[0..64].copy_from_slice(&sig.serialize()[..]); + r[64] = recovery_id.serialize(); + Proof::Ethereum(EcdsaSignature(r)) +} + +fn ethereum_public(secret: &EthKey) -> libsecp256k1::PublicKey { + libsecp256k1::PublicKey::from_secret_key(secret) +} + +fn ethereum_address(secret: &EthKey) -> EthereumAddress { + let mut res = EthereumAddress::default(); + res.0 + .copy_from_slice(&keccak_256(ðereum_public(secret).serialize()[1..65])[12..]); + res +} + +fn relay_generate(count: u64) -> Vec<(AccountId, ClaimKey)> { + let seed: u128 = 12345678901234567890123456789012; + (0..count) + .map(|i| { + let account_id = + [[0_u8; 16], (&(i as u128 + 1)).to_le_bytes()].concat().try_into().unwrap(); + ( + AccountId::new(account_id), + ClaimKey::Relay(ed25519::Pair::from_seed(&keccak_256( + &[(&(seed + i as u128)).to_le_bytes(), (&(seed + i as u128)).to_le_bytes()] + .concat(), + ))), + ) + }) + .collect() +} + +fn ethereum_generate(count: u64) -> Vec<(AccountId, ClaimKey)> { + (0..count) + .map(|i| { + let account_id = + [(&(i as u128 + 1)).to_le_bytes(), [0_u8; 16]].concat().try_into().unwrap(); + ( + AccountId::new(account_id), + ClaimKey::Eth(EthKey::parse(&keccak_256(&i.to_le_bytes())).unwrap()), + ) + }) + .collect() +} + +fn generate_accounts(count: u64) -> Vec<(AccountId, ClaimKey)> { + let mut x = relay_generate(count / 2); + let mut y = ethereum_generate(count / 2); + x.append(&mut y); + x +} + benchmarks! { where_clause { where @@ -70,6 +171,7 @@ benchmarks! { frame_system::Pallet::::set_block_number(VESTING_PERIOD); }: _(RawOrigin::Signed(accounts[0 as usize].0.clone())) } + impl_benchmark_test_suite!( CrowdloanReward, crate::mocks::ExtBuilder::default().build(), diff --git a/frame/crowdloan-rewards/src/lib.rs b/frame/crowdloan-rewards/src/lib.rs index 253e441c8b4..7d77e6e9a12 100644 --- a/frame/crowdloan-rewards/src/lib.rs +++ b/frame/crowdloan-rewards/src/lib.rs @@ -59,17 +59,14 @@ use sp_runtime::traits::{DispatchInfoOf, SignedExtension, Zero}; pub mod models; -#[cfg(any(feature = "runtime-benchmarks", test))] -// NOTE(hussein-aitlahcen): benchmarks/tests are dependent on structures living in mocks, but it is -// not an intersection -// perhaps refactor to avoid the `dead_code` here: CU-1zv8y2t -#[allow(dead_code)] +#[cfg(test)] mod mocks; #[cfg(test)] mod tests; -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; +// #[cfg(feature = "runtime-benchmarks")] +// mod benchmarking; + pub mod weights; #[frame_support::pallet] diff --git a/frame/crowdloan-rewards/src/mocks.rs b/frame/crowdloan-rewards/src/mocks.rs index 48d57a144a5..0334f9ac4d6 100644 --- a/frame/crowdloan-rewards/src/mocks.rs +++ b/frame/crowdloan-rewards/src/mocks.rs @@ -12,6 +12,7 @@ use sp_runtime::{ traits::{BlakeTwo256, ConvertInto, IdentityLookup}, AccountId32, Perbill, }; +use sp_std::vec::Vec; use system::EnsureRoot; pub type RelayKey = ed25519::Pair; From f9cd27244950e1ac59e2adb3fb4086e4ea7e1a89 Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Thu, 13 Jan 2022 18:16:06 +0100 Subject: [PATCH 2/2] revert benchmarking integration of crowdloan rewards --- runtime/dali/Cargo.toml | 18 ++++++++++++------ runtime/dali/src/lib.rs | 2 -- runtime/picasso/Cargo.toml | 12 ++++++++++++ runtime/picasso/src/lib.rs | 2 -- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/runtime/dali/Cargo.toml b/runtime/dali/Cargo.toml index c11e0c614ae..9ec36dbff00 100644 --- a/runtime/dali/Cargo.toml +++ b/runtime/dali/Cargo.toml @@ -119,7 +119,7 @@ std = [ "sp-block-builder/std", "sp-transaction-pool/std", "sp-inherents/std", - "support/std", + "support/std", "executive/std", "frame-system/std", "utility/std", @@ -134,7 +134,7 @@ std = [ "identity/std", "multisig/std", "vault/std", - "assets/std", + "assets/std", "governance-registry/std", "call-filter/std", "currency-factory/std", @@ -161,14 +161,17 @@ std = [ "xcm-executor/std", "aura/std", "sp-consensus-aura/std", - "scale-info/std", + "scale-info/std", "orml-xtokens/std", - "orml-xcm-support/std", - "orml-unknown-tokens/std", + "orml-xcm-support/std", + "orml-unknown-tokens/std", "assets-registry/std", "assets/std", "governance-registry/std", "composable-traits/std", + "crowdloan-rewards/std", + "bonded-finance/std", + "vesting/std" ] runtime-benchmarks = [ "assets/runtime-benchmarks", @@ -199,5 +202,8 @@ runtime-benchmarks = [ "collective/runtime-benchmarks", "democracy/runtime-benchmarks", "utility/runtime-benchmarks", - "vault/runtime-benchmarks" + "vault/runtime-benchmarks", + "vesting/runtime-benchmarks", + "assets/runtime-benchmarks", + "bonded-finance/runtime-benchmarks", ] diff --git a/runtime/dali/src/lib.rs b/runtime/dali/src/lib.rs index 86b4d7089c0..4ae252bbf39 100644 --- a/runtime/dali/src/lib.rs +++ b/runtime/dali/src/lib.rs @@ -1076,7 +1076,6 @@ impl_runtime_apis! { list_benchmark!(list, extra, multisig, Multisig); list_benchmark!(list, extra, vault, Vault); list_benchmark!(list, extra, oracle, Oracle); - list_benchmark!(list, extra, crowdloan_rewards, CrowdloanRewards); list_benchmark!(list, extra, dutch_auction, DutchAuction); let storage_info = AllPalletsWithSystem::storage_info(); @@ -1127,7 +1126,6 @@ impl_runtime_apis! { add_benchmark!(params, batches, multisig, Multisig); add_benchmark!(params, batches, vault, Vault); add_benchmark!(params, batches, oracle, Oracle); - add_benchmark!(params, batches, crowdloan_rewards, CrowdloanRewards); add_benchmark!(params, batches, dutch_auction, DutchAuction); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } diff --git a/runtime/picasso/Cargo.toml b/runtime/picasso/Cargo.toml index 02d7ee46f61..00968ab44d1 100644 --- a/runtime/picasso/Cargo.toml +++ b/runtime/picasso/Cargo.toml @@ -172,7 +172,14 @@ std = [ "orml-xcm-support/std", "orml-unknown-tokens/std", "composable-traits/std", + "governance-registry/std", + "currency-factory/std", + "assets/std", + "vesting/std", + "bonded-finance/std", + "crowdloan-rewards/std", ] + runtime-benchmarks = [ "balances/runtime-benchmarks", "benchmarking", @@ -197,5 +204,10 @@ runtime-benchmarks = [ "collective/runtime-benchmarks", "democracy/runtime-benchmarks", "utility/runtime-benchmarks", + "crowdloan-rewards/runtime-benchmarks", + "currency-factory/runtime-benchmarks", + "assets/runtime-benchmarks", + "vesting/runtime-benchmarks", + "bonded-finance/runtime-benchmarks", ] diff --git a/runtime/picasso/src/lib.rs b/runtime/picasso/src/lib.rs index 63c6db1f682..64c36b9cbcf 100644 --- a/runtime/picasso/src/lib.rs +++ b/runtime/picasso/src/lib.rs @@ -977,7 +977,6 @@ impl_runtime_apis! { list_benchmark!(list, extra, utility, Utility); list_benchmark!(list, extra, identity, Identity); list_benchmark!(list, extra, multisig, Multisig); - list_benchmark!(list, extra, crowdloan_rewards, CrowdloanRewards); let storage_info = AllPalletsWithSystem::storage_info(); @@ -1025,7 +1024,6 @@ impl_runtime_apis! { add_benchmark!(params, batches, utility, Utility); add_benchmark!(params, batches, identity, Identity); add_benchmark!(params, batches, multisig, Multisig); - add_benchmark!(params, batches, crowdloan_rewards, CrowdloanRewards); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches)