From c68070899a2518fbd1a8068e8adb997d3bb806ef Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Wed, 3 Aug 2022 01:58:31 +0400 Subject: [PATCH 01/12] A simple token claims integration --- Cargo.lock | 2 ++ crates/humanode-peer/src/chain_spec.rs | 11 ++++++- crates/humanode-runtime/Cargo.toml | 7 ++++- crates/humanode-runtime/src/eip712.rs | 30 +++++++++++++++++++ crates/humanode-runtime/src/lib.rs | 27 +++++++++++++++++ .../src/tests/fixed_supply.rs | 9 +++++- crates/humanode-runtime/src/vesting.rs | 25 ++++++++++++++++ 7 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 crates/humanode-runtime/src/vesting.rs diff --git a/Cargo.lock b/Cargo.lock index d59225a28..0d0731171 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3235,6 +3235,7 @@ dependencies = [ "crypto-utils", "eip712-account-claim", "eip712-common", + "eip712-token-claim", "fp-rpc", "fp-self-contained", "frame-benchmarking", @@ -3271,6 +3272,7 @@ dependencies = [ "pallet-session", "pallet-sudo", "pallet-timestamp", + "pallet-token-claims", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", diff --git a/crates/humanode-peer/src/chain_spec.rs b/crates/humanode-peer/src/chain_spec.rs index f82938268..313d620b2 100644 --- a/crates/humanode-peer/src/chain_spec.rs +++ b/crates/humanode-peer/src/chain_spec.rs @@ -8,7 +8,7 @@ use humanode_runtime::{ opaque::SessionKeys, robonode, AccountId, BabeConfig, Balance, BalancesConfig, BioauthConfig, BootnodesConfig, ChainPropertiesConfig, EVMConfig, EthereumChainIdConfig, EthereumConfig, EvmAccountsMappingConfig, GenesisConfig, GrandpaConfig, ImOnlineConfig, SessionConfig, - Signature, SudoConfig, SystemConfig, WASM_BINARY, + Signature, SudoConfig, SystemConfig, TokenClaimsConfig, WASM_BINARY, }; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sc_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup}; @@ -236,6 +236,10 @@ fn testnet_genesis( humanode_runtime::FeesPot::account_id(), EXISTANTIAL_DEPOSIT + DEV_ACCOUNT_BALANCE, ), + ( + humanode_runtime::TokenClaimsPot::account_id(), + EXISTANTIAL_DEPOSIT, + ), ]; pot_accounts .into_iter() @@ -333,6 +337,11 @@ fn testnet_genesis( transaction_payment: Default::default(), fees_pot: Default::default(), treasury_pot: Default::default(), + token_claims_pot: Default::default(), + token_claims: TokenClaimsConfig { + claims: vec![], + total_claimable: Some(0), + }, } } diff --git a/crates/humanode-runtime/Cargo.toml b/crates/humanode-runtime/Cargo.toml index 7fac63f64..8ebf14aa0 100644 --- a/crates/humanode-runtime/Cargo.toml +++ b/crates/humanode-runtime/Cargo.toml @@ -13,6 +13,7 @@ author-ext-api = { version = "0.1", path = "../author-ext-api", default-features bioauth-flow-api = { version = "0.1", path = "../bioauth-flow-api", default-features = false } eip712-account-claim = { version = "0.1", path = "../eip712-account-claim", default-features = false } eip712-common = { version = "0.1", path = "../eip712-common", default-features = false } +eip712-token-claim = { version = "0.1", path = "../eip712-token-claim", default-features = false } frontier-api = { version = "0.1", path = "../frontier-api", default-features = false } keystore-bioauth-account-id = { version = "0.1", path = "../keystore-bioauth-account-id", default-features = false } pallet-bioauth = { version = "0.1", path = "../pallet-bioauth", default-features = false } @@ -22,6 +23,7 @@ pallet-ethereum-chain-id = { version = "0.1", path = "../pallet-ethereum-chain-i pallet-evm-accounts-mapping = { version = "0.1", path = "../pallet-evm-accounts-mapping", default-features = false } pallet-humanode-session = { version = "0.1", path = "../pallet-humanode-session", default-features = false } pallet-pot = { version = "0.1", path = "../pallet-pot", default-features = false } +pallet-token-claims = { version = "0.1", path = "../pallet-token-claims", default-features = false } precompile-bioauth = { version = "0.1", path = "../precompile-bioauth", default-features = false } precompile-evm-accounts-mapping = { version = "0.1", path = "../precompile-evm-accounts-mapping", default-features = false } primitives-auth-ticket = { version = "0.1", path = "../primitives-auth-ticket", default-features = false } @@ -94,13 +96,15 @@ runtime-benchmarks = [ "pallet-balances/runtime-benchmarks", "pallet-ethereum/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-token-claims/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] std = [ "author-ext-api/std", "bioauth-flow-api/std", - "eip712-common/std", "eip712-account-claim/std", + "eip712-common/std", + "eip712-token-claim/std", "keystore-bioauth-account-id/std", "precompile-bioauth/std", "precompile-evm-accounts-mapping/std", @@ -136,6 +140,7 @@ std = [ "pallet-randomness-collective-flip/std", "pallet-session/std", "pallet-sudo/std", + "pallet-token-claims/std", "pallet-timestamp/std", "pallet-transaction-payment/std", "pallet-transaction-payment-rpc-runtime-api/std", diff --git a/crates/humanode-runtime/src/eip712.rs b/crates/humanode-runtime/src/eip712.rs index 16755c594..922b03aeb 100644 --- a/crates/humanode-runtime/src/eip712.rs +++ b/crates/humanode-runtime/src/eip712.rs @@ -24,3 +24,33 @@ impl pallet_evm_accounts_mapping::SignedClaimVerifier for AccountClaimVerifier { eip712_account_claim::verify_account_claim(signature, domain, account_id.as_ref()) } } + +/// The verifier for the EIP-712 signature of the token claim message. +pub enum TokenClaimVerifier {} + +const ETHEREUM_MAINNET_CHAIN_ID: u32 = 1; + +impl pallet_token_claims::traits::EthereumSignatureVerifier for TokenClaimVerifier { + type MessageParams = pallet_token_claims::types::EthereumSignatureMessageParams; + + fn recover_signer( + signature: &EcdsaSignature, + message_params: &Self::MessageParams, + ) -> Option { + let chain_id: [u8; 32] = U256::from(ETHEREUM_MAINNET_CHAIN_ID).into(); + let genesis_hash: [u8; 32] = System::block_hash(0).into(); + let mut verifying_contract = [0u8; 20]; + verifying_contract.copy_from_slice(&genesis_hash[0..20]); + let domain = eip712_common::Domain { + name: "Humanode Token Claim", + version: "1", + chain_id: &chain_id, + verifying_contract: &verifying_contract, + }; + eip712_token_claim::verify_token_claim( + signature, + domain, + message_params.account_id.as_ref(), + ) + } +} diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index d83751e74..f9f85c80a 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -65,6 +65,7 @@ use sp_version::NativeVersion; use sp_version::RuntimeVersion; mod frontier_precompiles; +mod vesting; use frontier_precompiles::FrontierPrecompiles; mod display_moment; @@ -368,10 +369,12 @@ impl pallet_authorship::Config for Runtime { parameter_types! { pub const TreasuryPotPalletId: PalletId = PalletId(*b"hmnd/tr1"); pub const FeesPotPalletId: PalletId = PalletId(*b"hmnd/fe1"); + pub const TokenClaimsPotPalletId: PalletId = PalletId(*b"hmnd/tc1"); } type PotInstanceTreasury = pallet_pot::Instance1; type PotInstanceFees = pallet_pot::Instance2; +type PotInstanceTokenClaims = pallet_pot::Instance3; impl pallet_pot::Config for Runtime { type Event = Event; @@ -385,6 +388,12 @@ impl pallet_pot::Config for Runtime { type Currency = Balances; } +impl pallet_pot::Config for Runtime { + type Event = Event; + type PalletId = TokenClaimsPotPalletId; + type Currency = Balances; +} + impl pallet_balances::Config for Runtime { type MaxLocks = ConstU32<50>; type MaxReserves = (); @@ -636,6 +645,20 @@ impl pallet_evm_accounts_mapping::Config for Runtime { type Verifier = eip712::AccountClaimVerifier; } +parameter_types! { + pub TokenClaimsPotAccountId: AccountId = TokenClaimsPot::account_id(); +} + +impl pallet_token_claims::Config for Runtime { + type Event = Event; + type Currency = Balances; + type PotAccountId = TokenClaimsPotAccountId; + type VestingSchedule = (); + type VestingInterface = vesting::TokenClaimsInterface; + type EthereumSignatureVerifier = eip712::TokenClaimVerifier; + type WeightInfo = (); +} + // Create the runtime by composing the FRAME pallets that were previously // configured. construct_runtime!( @@ -655,6 +678,7 @@ construct_runtime!( Balances: pallet_balances, TreasuryPot: pallet_pot::, FeesPot: pallet_pot::, + TokenClaimsPot: pallet_pot::, TransactionPayment: pallet_transaction_payment, Session: pallet_session, Offences: pallet_offences, @@ -670,6 +694,7 @@ construct_runtime!( BaseFee: pallet_base_fee, ImOnline: pallet_im_online, EvmAccountsMapping: pallet_evm_accounts_mapping, + TokenClaims: pallet_token_claims, } ); @@ -689,6 +714,7 @@ pub type SignedExtra = ( frame_system::CheckWeight, pallet_bioauth::CheckBioauthTx, pallet_transaction_payment::ChargeTransactionPayment, + pallet_token_claims::CheckTokenClaim, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = @@ -736,6 +762,7 @@ impl frame_system::offchain::CreateSignedTransaction for Runtime { frame_system::CheckWeight::::new(), pallet_bioauth::CheckBioauthTx::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + pallet_token_claims::CheckTokenClaim::::new(), ); let raw_payload = SignedPayload::new(call, extra).ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; diff --git a/crates/humanode-runtime/src/tests/fixed_supply.rs b/crates/humanode-runtime/src/tests/fixed_supply.rs index 284818ae7..1d9af466d 100644 --- a/crates/humanode-runtime/src/tests/fixed_supply.rs +++ b/crates/humanode-runtime/src/tests/fixed_supply.rs @@ -26,9 +26,16 @@ fn new_test_ext_with() -> sp_io::TestExternalities { let pot_accounts = vec![TreasuryPot::account_id(), FeesPot::account_id()]; endowed_accounts .iter() - .chain(pot_accounts.iter()) .cloned() + .chain(pot_accounts.into_iter()) .map(|k| (k, INIT_BALANCE)) + .chain( + [( + TokenClaimsPot::account_id(), + >::minimum_balance(), + )] + .into_iter(), + ) .collect() }, }, diff --git a/crates/humanode-runtime/src/vesting.rs b/crates/humanode-runtime/src/vesting.rs new file mode 100644 index 000000000..96d5d11e8 --- /dev/null +++ b/crates/humanode-runtime/src/vesting.rs @@ -0,0 +1,25 @@ +use frame_support::traits::{LockableCurrency, WithdrawReasons}; + +use super::*; + +pub enum TokenClaimsInterface {} + +impl pallet_token_claims::traits::VestingInterface for TokenClaimsInterface { + type AccountId = AccountId; + type Balance = Balance; + type Schedule = (); + + fn lock_under_vesting( + account: &Self::AccountId, + balance_to_lock: Self::Balance, + _schedule: Self::Schedule, + ) -> frame_support::pallet_prelude::DispatchResult { + >::set_lock( + *b"hmnd/tc1", + account, + balance_to_lock, + WithdrawReasons::RESERVE, + ); + Ok(()) + } +} From 873010af54fcf8b894e6b837050fbaec63bced5c Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 5 Aug 2022 18:00:43 +0400 Subject: [PATCH 02/12] A simple vesting integration --- Cargo.lock | 4 ++ crates/humanode-runtime/Cargo.toml | 9 +++++ crates/humanode-runtime/src/lib.rs | 22 ++++++++++- crates/humanode-runtime/src/vesting.rs | 51 ++++++++++++++++++++------ 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d0731171..d35650bfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3255,6 +3255,7 @@ dependencies = [ "pallet-bioauth", "pallet-bootnodes", "pallet-chain-properties", + "pallet-chain-start-moment", "pallet-dynamic-fee", "pallet-ethereum", "pallet-ethereum-chain-id", @@ -3275,6 +3276,7 @@ dependencies = [ "pallet-token-claims", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", + "pallet-vesting", "parity-scale-codec", "precompile-bioauth", "precompile-evm-accounts-mapping", @@ -3298,6 +3300,8 @@ dependencies = [ "sp-version", "static_assertions", "substrate-wasm-builder", + "vesting-schedule-linear", + "vesting-scheduling-timestamp", ] [[package]] diff --git a/crates/humanode-runtime/Cargo.toml b/crates/humanode-runtime/Cargo.toml index 8ebf14aa0..1fbadc7e1 100644 --- a/crates/humanode-runtime/Cargo.toml +++ b/crates/humanode-runtime/Cargo.toml @@ -19,15 +19,19 @@ keystore-bioauth-account-id = { version = "0.1", path = "../keystore-bioauth-acc pallet-bioauth = { version = "0.1", path = "../pallet-bioauth", default-features = false } pallet-bootnodes = { version = "0.1", path = "../pallet-bootnodes", default-features = false } pallet-chain-properties = { version = "0.1", path = "../pallet-chain-properties", default-features = false } +pallet-chain-start-moment = { version = "0.1", path = "../pallet-chain-start-moment", default-features = false } pallet-ethereum-chain-id = { version = "0.1", path = "../pallet-ethereum-chain-id", default-features = false } pallet-evm-accounts-mapping = { version = "0.1", path = "../pallet-evm-accounts-mapping", default-features = false } pallet-humanode-session = { version = "0.1", path = "../pallet-humanode-session", default-features = false } pallet-pot = { version = "0.1", path = "../pallet-pot", default-features = false } pallet-token-claims = { version = "0.1", path = "../pallet-token-claims", default-features = false } +pallet-vesting = { version = "0.1", path = "../pallet-vesting", default-features = false } precompile-bioauth = { version = "0.1", path = "../precompile-bioauth", default-features = false } precompile-evm-accounts-mapping = { version = "0.1", path = "../precompile-evm-accounts-mapping", default-features = false } primitives-auth-ticket = { version = "0.1", path = "../primitives-auth-ticket", default-features = false } robonode-crypto = { version = "0.1", path = "../robonode-crypto", default-features = false } +vesting-schedule-linear = { version = "0.1", path = "../vesting-schedule-linear", default-features = false } +vesting-scheduling-timestamp = { version = "0.1", path = "../vesting-scheduling-timestamp", default-features = false } chrono = { version = "0.4.19", default-features = false } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } @@ -97,6 +101,7 @@ runtime-benchmarks = [ "pallet-ethereum/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-token-claims/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] std = [ @@ -125,6 +130,7 @@ std = [ "pallet-balances/std", "pallet-base-fee/std", "pallet-chain-properties/std", + "pallet-chain-start-moment/std", "pallet-ethereum/std", "pallet-ethereum-chain-id/std", "pallet-evm-accounts-mapping/std", @@ -144,6 +150,7 @@ std = [ "pallet-timestamp/std", "pallet-transaction-payment/std", "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-vesting/std", "robonode-crypto/std", "sp-application-crypto/std", "sp-api/std", @@ -158,6 +165,8 @@ std = [ "sp-std/std", "sp-transaction-pool/std", "sp-version/std", + "vesting-schedule-linear/std", + "vesting-scheduling-timestamp/std", ] try-runtime = [ "frame-executive/try-runtime", diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index f9f85c80a..2e8845e3e 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -14,6 +14,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); // A few exports that help ease life for downstream crates. use codec::{alloc::string::ToString, Decode, Encode, MaxEncodedLen}; use fp_rpc::TransactionStatus; +use frame_support::traits::LockIdentifier; pub use frame_support::{ construct_runtime, parameter_types, traits::{ @@ -359,6 +360,10 @@ impl pallet_timestamp::Config for Runtime { type WeightInfo = (); } +impl pallet_chain_start_moment::Config for Runtime { + type Time = Timestamp; +} + impl pallet_authorship::Config for Runtime { type FindAuthor = find_author::FindAuthorFromSession; type UncleGenerations = ConstU32<5>; @@ -653,12 +658,25 @@ impl pallet_token_claims::Config for Runtime { type Event = Event; type Currency = Balances; type PotAccountId = TokenClaimsPotAccountId; - type VestingSchedule = (); + type VestingSchedule = ::Schedule; type VestingInterface = vesting::TokenClaimsInterface; type EthereumSignatureVerifier = eip712::TokenClaimVerifier; type WeightInfo = (); } +parameter_types! { + pub VestingLockId: LockIdentifier = *b"hmnd/vs1"; +} + +impl pallet_vesting::Config for Runtime { + type Event = Event; + type Currency = Balances; + type LockId = VestingLockId; + type Schedule = vesting::Schedule; + type SchedulingDriver = vesting::Driver; + type WeightInfo = (); +} + // Create the runtime by composing the FRAME pallets that were previously // configured. construct_runtime!( @@ -670,6 +688,7 @@ construct_runtime!( System: frame_system, RandomnessCollectiveFlip: pallet_randomness_collective_flip, Timestamp: pallet_timestamp, + ChainStartMoment: pallet_chain_start_moment, Bootnodes: pallet_bootnodes, Bioauth: pallet_bioauth, Babe: pallet_babe, @@ -695,6 +714,7 @@ construct_runtime!( ImOnline: pallet_im_online, EvmAccountsMapping: pallet_evm_accounts_mapping, TokenClaims: pallet_token_claims, + Vesting: pallet_vesting, } ); diff --git a/crates/humanode-runtime/src/vesting.rs b/crates/humanode-runtime/src/vesting.rs index 96d5d11e8..95d766071 100644 --- a/crates/humanode-runtime/src/vesting.rs +++ b/crates/humanode-runtime/src/vesting.rs @@ -1,5 +1,3 @@ -use frame_support::traits::{LockableCurrency, WithdrawReasons}; - use super::*; pub enum TokenClaimsInterface {} @@ -7,19 +5,48 @@ pub enum TokenClaimsInterface {} impl pallet_token_claims::traits::VestingInterface for TokenClaimsInterface { type AccountId = AccountId; type Balance = Balance; - type Schedule = (); + type Schedule = ::VestingSchedule; fn lock_under_vesting( account: &Self::AccountId, - balance_to_lock: Self::Balance, - _schedule: Self::Schedule, + _balance_to_lock: Self::Balance, + schedule: Self::Schedule, ) -> frame_support::pallet_prelude::DispatchResult { - >::set_lock( - *b"hmnd/tc1", - account, - balance_to_lock, - WithdrawReasons::RESERVE, - ); - Ok(()) + Vesting::lock_under_vesting(account, schedule) + } +} + +pub enum GetTimestampNow {} + +impl Get for GetTimestampNow { + fn get() -> UnixMilliseconds { + Timestamp::now() + } +} + +pub enum GetTimestampChainStart {} + +impl Get> for GetTimestampChainStart { + fn get() -> Option { + ChainStartMoment::chain_start() } } + +impl vesting_scheduling_timestamp::Config for Runtime { + type Balance = Balance; + type Timestamp = ::Moment; + type StartingPoint = GetTimestampChainStart; + type Now = GetTimestampNow; +} + +impl vesting_scheduling_timestamp::LinearScheduleConfig for Runtime { + type FracScale = + vesting_schedule_linear::traits::SimpleFracScaler; +} +impl vesting_scheduling_timestamp::MultiLinearScheduleConfig for Runtime { + type MaxSchedulesPerAccount = ConstU32<8>; +} + +pub type Schedule = vesting_scheduling_timestamp::MultiLinearScheduleOf; + +pub type Driver = vesting_scheduling_timestamp::Adapter; From 60bbe1970e68f0b3e545aae1713b25214f9c1044 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Sat, 13 Aug 2022 02:33:47 +0400 Subject: [PATCH 03/12] Add a sample claim to genesis --- crates/humanode-peer/src/chain_spec.rs | 21 ++++++++++++++------- crates/humanode-runtime/src/lib.rs | 2 ++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/crates/humanode-peer/src/chain_spec.rs b/crates/humanode-peer/src/chain_spec.rs index 313d620b2..1ca472746 100644 --- a/crates/humanode-peer/src/chain_spec.rs +++ b/crates/humanode-peer/src/chain_spec.rs @@ -5,10 +5,11 @@ use std::{collections::BTreeMap, str::FromStr}; use crypto_utils::{authority_keys_from_seed, get_account_id_from_seed}; use hex_literal::hex; use humanode_runtime::{ - opaque::SessionKeys, robonode, AccountId, BabeConfig, Balance, BalancesConfig, BioauthConfig, - BootnodesConfig, ChainPropertiesConfig, EVMConfig, EthereumChainIdConfig, EthereumConfig, - EvmAccountsMappingConfig, GenesisConfig, GrandpaConfig, ImOnlineConfig, SessionConfig, - Signature, SudoConfig, SystemConfig, TokenClaimsConfig, WASM_BINARY, + opaque::SessionKeys, robonode, token_claims::types::ClaimInfo, AccountId, BabeConfig, Balance, + BalancesConfig, BioauthConfig, BootnodesConfig, ChainPropertiesConfig, EVMConfig, + EthereumAddress, EthereumChainIdConfig, EthereumConfig, EvmAccountsMappingConfig, + GenesisConfig, GrandpaConfig, ImOnlineConfig, SessionConfig, Signature, SudoConfig, + SystemConfig, TokenClaimsConfig, WASM_BINARY, }; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sc_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup}; @@ -238,7 +239,7 @@ fn testnet_genesis( ), ( humanode_runtime::TokenClaimsPot::account_id(), - EXISTANTIAL_DEPOSIT, + EXISTANTIAL_DEPOSIT + DEV_ACCOUNT_BALANCE, ), ]; pot_accounts @@ -339,8 +340,14 @@ fn testnet_genesis( treasury_pot: Default::default(), token_claims_pot: Default::default(), token_claims: TokenClaimsConfig { - claims: vec![], - total_claimable: Some(0), + claims: vec![( + EthereumAddress(hex!("6be02d1d3665660d22ff9624b7be0551ee1ac91b")), + ClaimInfo { + balance: DEV_ACCOUNT_BALANCE, + vesting: vec![].try_into().unwrap(), + }, + )], + total_claimable: Some(DEV_ACCOUNT_BALANCE), }, } } diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index 2e8845e3e..128fef700 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -13,6 +13,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); // A few exports that help ease life for downstream crates. use codec::{alloc::string::ToString, Decode, Encode, MaxEncodedLen}; +pub use eip712_common::EthereumAddress; use fp_rpc::TransactionStatus; use frame_support::traits::LockIdentifier; pub use frame_support::{ @@ -39,6 +40,7 @@ use pallet_grandpa::{ use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use pallet_session::historical as pallet_session_historical; pub use pallet_timestamp::Call as TimestampCall; +pub use pallet_token_claims as token_claims; use primitives_auth_ticket::OpaqueAuthTicket; use scale_info::TypeInfo; #[cfg(feature = "std")] From a725897be63a8f89c1977868a6bbeaa534f29b5b Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 19 Aug 2022 16:52:41 +0400 Subject: [PATCH 04/12] Extract the dev utils and clean up the tests root mod --- crates/humanode-runtime/src/dev_utils.rs | 23 ++++++++++++++++++ crates/humanode-runtime/src/lib.rs | 2 ++ .../src/tests/fixed_supply.rs | 3 +++ crates/humanode-runtime/src/tests/mod.rs | 24 ------------------- 4 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 crates/humanode-runtime/src/dev_utils.rs diff --git a/crates/humanode-runtime/src/dev_utils.rs b/crates/humanode-runtime/src/dev_utils.rs new file mode 100644 index 000000000..f59acc64f --- /dev/null +++ b/crates/humanode-runtime/src/dev_utils.rs @@ -0,0 +1,23 @@ +use crypto_utils::{authority_keys_from_seed, get_account_id_from_seed}; +use sp_application_crypto::ByteArray; +use sp_runtime::app_crypto::sr25519; + +use super::*; + +/// The public key for the accounts. +pub type AccountPublic = ::Signer; + +/// A helper function to return [`AccountId`] based on runtime data and provided seed. +pub fn account_id(seed: &str) -> AccountId { + get_account_id_from_seed::(seed) +} + +/// A helper function to return authorities keys based on runtime data and provided seed. +pub fn authority_keys(seed: &str) -> (AccountId, BabeId, GrandpaId, ImOnlineId) { + authority_keys_from_seed::(seed) +} + +/// A helper function to get a corresponding EVM truncated address for provided AccountId. +pub fn evm_truncated_address(account_id: AccountId) -> H160 { + H160::from_slice(&account_id.as_slice()[0..20]) +} diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index 128fef700..68bdf9043 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -71,6 +71,8 @@ mod frontier_precompiles; mod vesting; use frontier_precompiles::FrontierPrecompiles; +#[cfg(test)] +mod dev_utils; mod display_moment; pub mod eip712; mod find_author; diff --git a/crates/humanode-runtime/src/tests/fixed_supply.rs b/crates/humanode-runtime/src/tests/fixed_supply.rs index 1d9af466d..ebae63642 100644 --- a/crates/humanode-runtime/src/tests/fixed_supply.rs +++ b/crates/humanode-runtime/src/tests/fixed_supply.rs @@ -3,6 +3,7 @@ use std::str::FromStr; use frame_support::{ + assert_ok, dispatch::DispatchInfo, weights::{DispatchClass, Pays}, }; @@ -10,6 +11,8 @@ use pallet_evm::AddressMapping; use sp_runtime::traits::SignedExtension; use super::*; +use crate::dev_utils::*; +use crate::opaque::SessionKeys; const INIT_BALANCE: u128 = 10u128.pow(18 + 6); diff --git a/crates/humanode-runtime/src/tests/mod.rs b/crates/humanode-runtime/src/tests/mod.rs index 76a135c48..0a4759c26 100644 --- a/crates/humanode-runtime/src/tests/mod.rs +++ b/crates/humanode-runtime/src/tests/mod.rs @@ -1,27 +1,3 @@ -use crypto_utils::{authority_keys_from_seed, get_account_id_from_seed}; -use frame_support::assert_ok; -use sp_application_crypto::ByteArray; -use sp_runtime::app_crypto::sr25519; - use super::*; -use crate::{opaque::SessionKeys, AccountId, Signature}; mod fixed_supply; - -/// The public key for the accounts. -type AccountPublic = ::Signer; - -/// A helper function to return [`AccountId`] based on runtime data and provided seed. -fn account_id(seed: &str) -> AccountId { - get_account_id_from_seed::(seed) -} - -/// A helper function to return authorities keys based on runtime data and provided seed. -fn authority_keys(seed: &str) -> (AccountId, BabeId, GrandpaId, ImOnlineId) { - authority_keys_from_seed::(seed) -} - -/// A helper function to get a corresponding EVM truncated address for provided AccountId. -fn evm_truncated_address(account_id: AccountId) -> H160 { - H160::from_slice(&account_id.as_slice()[0..20]) -} From 8be42bd6e8f5c9da96fb05513fae2406d350dc48 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 19 Aug 2022 16:54:18 +0400 Subject: [PATCH 05/12] Make benchmarking mods pub at pallet-token-claims and pallet-vesting --- crates/pallet-token-claims/src/lib.rs | 2 +- crates/pallet-vesting/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/pallet-token-claims/src/lib.rs b/crates/pallet-token-claims/src/lib.rs index f5314b5a1..851414492 100644 --- a/crates/pallet-token-claims/src/lib.rs +++ b/crates/pallet-token-claims/src/lib.rs @@ -20,7 +20,7 @@ pub mod types; pub mod weights; #[cfg(feature = "runtime-benchmarks")] -mod benchmarking; +pub mod benchmarking; #[cfg(test)] mod mock; #[cfg(test)] diff --git a/crates/pallet-vesting/src/lib.rs b/crates/pallet-vesting/src/lib.rs index 40115e83c..8b7c920dc 100644 --- a/crates/pallet-vesting/src/lib.rs +++ b/crates/pallet-vesting/src/lib.rs @@ -10,7 +10,7 @@ pub mod traits; pub mod weights; #[cfg(feature = "runtime-benchmarks")] -mod benchmarking; +pub mod benchmarking; #[cfg(test)] mod mock; #[cfg(test)] From 6b9ac0b84c96b6518fe3f60ceab3cafbb9304730 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 19 Aug 2022 17:48:33 +0400 Subject: [PATCH 06/12] Refactor the EIP-712 code to allow generating standalone messages --- crates/eip712-account-claim/src/lib.rs | 21 +++++++++++------ crates/eip712-common-test-utils/src/lib.rs | 6 ++--- crates/eip712-common/src/lib.rs | 21 ++++++++++------- crates/eip712-token-claim/src/lib.rs | 27 ++++++++++++++-------- crates/humanode-runtime/src/eip712.rs | 25 ++++++++++---------- 5 files changed, 59 insertions(+), 41 deletions(-) diff --git a/crates/eip712-account-claim/src/lib.rs b/crates/eip712-account-claim/src/lib.rs index c29503704..fbbe1c702 100644 --- a/crates/eip712-account-claim/src/lib.rs +++ b/crates/eip712-account-claim/src/lib.rs @@ -18,14 +18,21 @@ fn make_account_claim_hash(account: &EthBytes) -> [u8; 32] { keccak_256(&buf) } -/// Verify EIP-712 typed signature based on provided domain_separator and entire message. -pub fn verify_account_claim( +/// Prepare the EIP-712 message hash. +pub fn make_message_hash(domain: Domain<'_>, account: &[u8]) -> [u8; 32] { + let payload_hash = make_account_claim_hash(account); + eip712_common::make_message_hash(domain, &payload_hash) +} + +/// Verify EIP-712 typed signature based on provided domain and message params and recover +/// the signer address. +pub fn recover_signer( signature: &EcdsaSignature, domain: Domain<'_>, account: &[u8], ) -> Option { - let payload_hash = make_account_claim_hash(account); - eip712_common::verify_signature(signature, domain, &payload_hash) + let message = make_message_hash(domain, account); + eip712_common::recover_signer(signature, &message) } #[cfg(test)] @@ -85,7 +92,7 @@ mod tests { let signature = test_input(&pair); let domain = prepare_sample_domain(); - let ethereum_address = verify_account_claim(&signature, domain, &SAMPLE_ACCOUNT).unwrap(); + let ethereum_address = recover_signer(&signature, domain, &SAMPLE_ACCOUNT).unwrap(); assert_eq!(ethereum_address, ethereum_address_from_seed(b"Alice")); } @@ -95,7 +102,7 @@ mod tests { let signature = test_input(&pair); let domain = prepare_sample_domain(); - let ethereum_address = verify_account_claim(&signature, domain, &SAMPLE_ACCOUNT).unwrap(); + let ethereum_address = recover_signer(&signature, domain, &SAMPLE_ACCOUNT).unwrap(); assert_ne!(ethereum_address, ethereum_address_from_seed(b"Bob")); } @@ -113,7 +120,7 @@ mod tests { let signature = hex!("151d5f52e6c249db84b8705374c6f51dd08b50ddad5b1175ec20a7e00cbc48f55a23470ab0db16146b3b7d2a8565aaf2b700f548c9e9882a0034e654bd214e821b"); let ethereum_address = - verify_account_claim(&EcdsaSignature(signature), domain, &account_to_claim).unwrap(); + recover_signer(&EcdsaSignature(signature), domain, &account_to_claim).unwrap(); assert_eq!( ethereum_address.0, hex!("e9726f3d0a7736034e2a4c63ea28b3ab95622cb9"), diff --git a/crates/eip712-common-test-utils/src/lib.rs b/crates/eip712-common-test-utils/src/lib.rs index 78714f576..0921e0391 100644 --- a/crates/eip712-common-test-utils/src/lib.rs +++ b/crates/eip712-common-test-utils/src/lib.rs @@ -10,8 +10,8 @@ pub fn ecdsa_pair(seed: &[u8]) -> ecdsa::Pair { } /// Sign a given message with the given ECDSA keypair. -pub fn ecdsa_sign(pair: &ecdsa::Pair, msg: [u8; 32]) -> EcdsaSignature { - EcdsaSignature(pair.sign_prehashed(&msg).0) +pub fn ecdsa_sign(pair: &ecdsa::Pair, msg: &[u8; 32]) -> EcdsaSignature { + EcdsaSignature(pair.sign_prehashed(msg).0) } /// Sign a given EIP-712 typed data JSON with the given ECDSA keypair. @@ -20,7 +20,7 @@ pub fn ecdsa_sign_typed_data(pair: &ecdsa::Pair, type_data_json: &str) -> EcdsaS let msg_bytes: [u8; 32] = eth_eip_712::hash_structured_data(typed_data) .unwrap() .into(); - ecdsa_sign(pair, msg_bytes) + ecdsa_sign(pair, &msg_bytes) } /// Create an Ethereum address from the given seed. diff --git a/crates/eip712-common/src/lib.rs b/crates/eip712-common/src/lib.rs index 09b5347f3..c4165efa5 100644 --- a/crates/eip712-common/src/lib.rs +++ b/crates/eip712-common/src/lib.rs @@ -76,23 +76,28 @@ pub fn make_payload_hash<'a>( keccak_256(&buf) } +/// Prepare the EIP-712 message. +pub fn make_message_hash(domain: Domain<'_>, payload_hash: &[u8; 32]) -> [u8; 32] { + let domain_hash = make_domain_hash(domain); + make_eip712_message_hash(&domain_hash, payload_hash) +} + +/// Extract the signer address from the signatue and the message. +pub fn recover_signer(sig: &EcdsaSignature, msg: &[u8; 32]) -> Option { + let pubkey = sp_io::crypto::secp256k1_ecdsa_recover(&sig.0, msg).ok()?; + Some(ecdsa_public_key_to_ethereum_address(&pubkey)) +} + /// Verify EIP-712 typed signature based on provided domain and payload hash. pub fn verify_signature( signature: &EcdsaSignature, domain: Domain<'_>, payload_hash: &[u8; 32], ) -> Option { - let domain_hash = make_domain_hash(domain); - let msg_hash = make_eip712_message_hash(&domain_hash, payload_hash); + let msg_hash = make_message_hash(domain, payload_hash); recover_signer(signature, &msg_hash) } -/// Extract the signer address from the signatue and the message. -fn recover_signer(sig: &EcdsaSignature, msg: &[u8; 32]) -> Option { - let pubkey = sp_io::crypto::secp256k1_ecdsa_recover(&sig.0, msg).ok()?; - Some(ecdsa_public_key_to_ethereum_address(&pubkey)) -} - /// Convert the ECDSA public key to Ethereum address. fn ecdsa_public_key_to_ethereum_address(pubkey: &[u8; 64]) -> EthereumAddress { let mut address = [0u8; 20]; diff --git a/crates/eip712-token-claim/src/lib.rs b/crates/eip712-token-claim/src/lib.rs index 5bb290268..9c37e71ed 100644 --- a/crates/eip712-token-claim/src/lib.rs +++ b/crates/eip712-token-claim/src/lib.rs @@ -15,17 +15,24 @@ fn hash_token_claim_data(substrate_address: &EthBytes) -> [u8; 32] { keccak_256(substrate_address) } -/// Verify EIP-712 typed signature based on provided domain_separator and entire message. -pub fn verify_token_claim( - signature: &EcdsaSignature, - domain: Domain<'_>, - substrate_address: &[u8], -) -> Option { +/// Prepare the EIP-712 message hash. +pub fn make_message_hash(domain: Domain<'_>, substrate_address: &[u8]) -> [u8; 32] { let payload_hash = make_payload_hash( &TOKEN_CLAIM_TYPEHASH, [&hash_token_claim_data(substrate_address)], ); - eip712_common::verify_signature(signature, domain, &payload_hash) + eip712_common::make_message_hash(domain, &payload_hash) +} + +/// Verify EIP-712 typed signature based on provided domain and message params and recover +/// the signer address. +pub fn recover_signer( + signature: &EcdsaSignature, + domain: Domain<'_>, + substrate_address: &[u8], +) -> Option { + let message = make_message_hash(domain, substrate_address); + eip712_common::recover_signer(signature, &message) } #[cfg(test)] @@ -83,7 +90,7 @@ mod tests { let signature = test_input(&pair); let domain = prepare_sample_domain(); - let ethereum_address = verify_token_claim(&signature, domain, &SAMPLE_ACCOUNT).unwrap(); + let ethereum_address = recover_signer(&signature, domain, &SAMPLE_ACCOUNT).unwrap(); assert_eq!(ethereum_address, ethereum_address_from_seed(b"Alice")); } @@ -93,7 +100,7 @@ mod tests { let signature = test_input(&pair); let domain = prepare_sample_domain(); - let ethereum_address = verify_token_claim(&signature, domain, &SAMPLE_ACCOUNT).unwrap(); + let ethereum_address = recover_signer(&signature, domain, &SAMPLE_ACCOUNT).unwrap(); assert_ne!(ethereum_address, ethereum_address_from_seed(b"Bob")); } @@ -114,7 +121,7 @@ mod tests { let signature = hex!("3027e569de1d835350ffa4f07218d3be7298de65f12ffc767c6d80ab16ee704245e158f660817433f3748563cf83cf8a53a5ab569e7751bf158d9215f0e9b58b1b"); let ethereum_address = - verify_token_claim(&EcdsaSignature(signature), domain, &substrate_account).unwrap(); + recover_signer(&EcdsaSignature(signature), domain, &substrate_account).unwrap(); assert_eq!( ethereum_address.0, hex!("6be02d1d3665660d22ff9624b7be0551ee1ac91b"), diff --git a/crates/humanode-runtime/src/eip712.rs b/crates/humanode-runtime/src/eip712.rs index 922b03aeb..038192376 100644 --- a/crates/humanode-runtime/src/eip712.rs +++ b/crates/humanode-runtime/src/eip712.rs @@ -4,6 +4,13 @@ use eip712_common::{EcdsaSignature, EthereumAddress}; use super::*; +pub(crate) fn genesis_verifying_contract() -> [u8; 20] { + let genesis_hash: [u8; 32] = System::block_hash(0).into(); + let mut verifying_contract = [0u8; 20]; + verifying_contract.copy_from_slice(&genesis_hash[0..20]); + verifying_contract +} + /// The verifier for the EIP-712 signature of the EVM accout claim message. pub enum AccountClaimVerifier {} @@ -12,23 +19,21 @@ impl pallet_evm_accounts_mapping::SignedClaimVerifier for AccountClaimVerifier { fn verify(account_id: &Self::AccountId, signature: &EcdsaSignature) -> Option { let chain_id: [u8; 32] = U256::from(EthereumChainId::chain_id()).into(); - let genesis_hash: [u8; 32] = System::block_hash(0).into(); - let mut verifying_contract = [0u8; 20]; - verifying_contract.copy_from_slice(&genesis_hash[0..20]); + let verifying_contract = genesis_verifying_contract(); let domain = eip712_common::Domain { name: "Humanode EVM Account Claim", version: "1", chain_id: &chain_id, verifying_contract: &verifying_contract, }; - eip712_account_claim::verify_account_claim(signature, domain, account_id.as_ref()) + eip712_account_claim::recover_signer(signature, domain, account_id.as_ref()) } } /// The verifier for the EIP-712 signature of the token claim message. pub enum TokenClaimVerifier {} -const ETHEREUM_MAINNET_CHAIN_ID: u32 = 1; +pub(crate) const ETHEREUM_MAINNET_CHAIN_ID: u32 = 1; impl pallet_token_claims::traits::EthereumSignatureVerifier for TokenClaimVerifier { type MessageParams = pallet_token_claims::types::EthereumSignatureMessageParams; @@ -38,19 +43,13 @@ impl pallet_token_claims::traits::EthereumSignatureVerifier for TokenClaimVerifi message_params: &Self::MessageParams, ) -> Option { let chain_id: [u8; 32] = U256::from(ETHEREUM_MAINNET_CHAIN_ID).into(); - let genesis_hash: [u8; 32] = System::block_hash(0).into(); - let mut verifying_contract = [0u8; 20]; - verifying_contract.copy_from_slice(&genesis_hash[0..20]); + let verifying_contract = genesis_verifying_contract(); let domain = eip712_common::Domain { name: "Humanode Token Claim", version: "1", chain_id: &chain_id, verifying_contract: &verifying_contract, }; - eip712_token_claim::verify_token_claim( - signature, - domain, - message_params.account_id.as_ref(), - ) + eip712_token_claim::recover_signer(signature, domain, message_params.account_id.as_ref()) } } From b07bc3dba363dc34900baaf7302d9db816682c2e Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 19 Aug 2022 17:48:44 +0400 Subject: [PATCH 07/12] Add tokens and vesting to the runtime benchmarks --- Cargo.lock | 1 + crates/humanode-runtime/Cargo.toml | 5 ++ crates/humanode-runtime/src/benchmarking.rs | 56 +++++++++++++++++++++ crates/humanode-runtime/src/dev_utils.rs | 6 +++ crates/humanode-runtime/src/lib.rs | 8 ++- 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 crates/humanode-runtime/src/benchmarking.rs diff --git a/Cargo.lock b/Cargo.lock index d35650bfa..9f30d13aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3235,6 +3235,7 @@ dependencies = [ "crypto-utils", "eip712-account-claim", "eip712-common", + "eip712-common-test-utils", "eip712-token-claim", "fp-rpc", "fp-self-contained", diff --git a/crates/humanode-runtime/Cargo.toml b/crates/humanode-runtime/Cargo.toml index 1fbadc7e1..88fcaad71 100644 --- a/crates/humanode-runtime/Cargo.toml +++ b/crates/humanode-runtime/Cargo.toml @@ -11,8 +11,10 @@ substrate-wasm-builder = { git = "https://github.com/humanode-network/substrate" [dependencies] author-ext-api = { version = "0.1", path = "../author-ext-api", default-features = false } bioauth-flow-api = { version = "0.1", path = "../bioauth-flow-api", default-features = false } +crypto-utils = { version = "0.1", path = "../crypto-utils", optional = true } eip712-account-claim = { version = "0.1", path = "../eip712-account-claim", default-features = false } eip712-common = { version = "0.1", path = "../eip712-common", default-features = false } +eip712-common-test-utils = { version = "0.1", path = "../eip712-common-test-utils", optional = true } eip712-token-claim = { version = "0.1", path = "../eip712-token-claim", default-features = false } frontier-api = { version = "0.1", path = "../frontier-api", default-features = false } keystore-bioauth-account-id = { version = "0.1", path = "../keystore-bioauth-account-id", default-features = false } @@ -85,6 +87,7 @@ static_assertions = { version = "1.1.0", default-features = false } [dev-dependencies] crypto-utils = { version = "0.1", path = "../crypto-utils" } +eip712-common-test-utils = { version = "0.1", path = "../eip712-common-test-utils" } sp-io = { git = "https://github.com/humanode-network/substrate", branch = "master" } @@ -103,6 +106,8 @@ runtime-benchmarks = [ "pallet-token-claims/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "crypto-utils", + "eip712-common-test-utils", ] std = [ "author-ext-api/std", diff --git a/crates/humanode-runtime/src/benchmarking.rs b/crates/humanode-runtime/src/benchmarking.rs new file mode 100644 index 000000000..cdbf202e2 --- /dev/null +++ b/crates/humanode-runtime/src/benchmarking.rs @@ -0,0 +1,56 @@ +//! The benchmarking utilities. + +use eip712_common::{EcdsaSignature, EthereumAddress}; +use eip712_common_test_utils::{ecdsa_pair, ecdsa_sign, ethereum_address_from_seed}; + +use super::*; +use crate::dev_utils::*; + +impl pallet_token_claims::benchmarking::Interface for Runtime { + fn account_id_to_claim_to() -> ::AccountId { + account_id("Alice") + } + + fn ethereum_address() -> EthereumAddress { + ethereum_address_from_seed(b"Alice") + } + + fn create_ecdsa_signature( + account_id: &::AccountId, + ethereum_address: &EthereumAddress, + ) -> EcdsaSignature { + if ethereum_address != ðereum_address_from_seed(b"Alice") { + panic!("bad ethereum address"); + } + + let chain_id: [u8; 32] = U256::from(crate::eip712::ETHEREUM_MAINNET_CHAIN_ID).into(); + let verifying_contract = crate::eip712::genesis_verifying_contract(); + let domain = eip712_common::Domain { + name: "Humanode Token Claim", + version: "1", + chain_id: &chain_id, + verifying_contract: &verifying_contract, + }; + + let pair = ecdsa_pair(b"Alice"); + let msg_hash = eip712_token_claim::make_message_hash(domain, account_id.as_ref()); + ecdsa_sign(&pair, &msg_hash) + } +} + +impl pallet_vesting::benchmarking::Interface for Runtime { + fn account_id() -> ::AccountId { + account_id("Alice") + } + + fn schedule() -> ::Schedule { + use vesting_schedule_linear::LinearSchedule; + vec![LinearSchedule { + balance: 100, + cliff: 10 * 24 * 60 * 60 * 1000, // 10 days + vesting: 10 * 24 * 60 * 60 * 1000, // 10 days + }] + .try_into() + .unwrap() + } +} diff --git a/crates/humanode-runtime/src/dev_utils.rs b/crates/humanode-runtime/src/dev_utils.rs index f59acc64f..9b73a1091 100644 --- a/crates/humanode-runtime/src/dev_utils.rs +++ b/crates/humanode-runtime/src/dev_utils.rs @@ -1,3 +1,9 @@ +//! The utils we share among tests and benches - generally consider them both `dev`. + +// The code may or may not be used depending on the feature flags - so omit the noise altogether and +// disable the check for the entire module. +#![allow(dead_code)] + use crypto_utils::{authority_keys_from_seed, get_account_id_from_seed}; use sp_application_crypto::ByteArray; use sp_runtime::app_crypto::sr25519; diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index 68bdf9043..3985c5555 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -71,7 +71,9 @@ mod frontier_precompiles; mod vesting; use frontier_precompiles::FrontierPrecompiles; -#[cfg(test)] +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +#[cfg(any(test, feature = "runtime-benchmarks"))] mod dev_utils; mod display_moment; pub mod eip712; @@ -1289,6 +1291,8 @@ impl_runtime_apis! { list_benchmark!(list, extra, pallet_balances, Balances); list_benchmark!(list, extra, pallet_timestamp, Timestamp); list_benchmark!(list, extra, pallet_bioauth, Bioauth); + list_benchmark!(list, extra, pallet_token_claims, TokenClaims); + list_benchmark!(list, extra, pallet_vesting, Vesting); let storage_info = AllPalletsWithSystem::storage_info(); @@ -1332,6 +1336,8 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_balances, Balances); add_benchmark!(params, batches, pallet_timestamp, Timestamp); add_benchmark!(params, batches, pallet_bioauth, Bioauth); + add_benchmark!(params, batches, pallet_token_claims, TokenClaims); + add_benchmark!(params, batches, pallet_vesting, Vesting); Ok(batches) } From a4deea5b9379d101ebb3e1ad4c0ee6d26d7c3df2 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 19 Aug 2022 18:33:21 +0400 Subject: [PATCH 08/12] Make some packages no_std compatible --- crates/crypto-utils/Cargo.toml | 12 ++++++++---- crates/crypto-utils/src/lib.rs | 2 ++ crates/eip712-common-test-utils/Cargo.toml | 16 ++++++++++------ crates/eip712-common-test-utils/src/lib.rs | 2 ++ crates/humanode-runtime/Cargo.toml | 4 ++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/crates/crypto-utils/Cargo.toml b/crates/crypto-utils/Cargo.toml index af5459627..3fd0f54c2 100644 --- a/crates/crypto-utils/Cargo.toml +++ b/crates/crypto-utils/Cargo.toml @@ -5,7 +5,11 @@ edition = "2021" publish = false [dependencies] -pallet-im-online = { git = "https://github.com/humanode-network/substrate", branch = "master" } -sp-consensus-babe = { git = "https://github.com/humanode-network/substrate", branch = "master" } -sp-finality-grandpa = { git = "https://github.com/humanode-network/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/humanode-network/substrate", branch = "master" } +pallet-im-online = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } +sp-consensus-babe = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } +sp-finality-grandpa = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } +sp-runtime = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } + +[features] +default = ["std"] +std = ["pallet-im-online/std", "sp-consensus-babe/std", "sp-finality-grandpa/std", "sp-runtime/std"] diff --git a/crates/crypto-utils/src/lib.rs b/crates/crypto-utils/src/lib.rs index d6d5958b5..449a3a9f1 100644 --- a/crates/crypto-utils/src/lib.rs +++ b/crates/crypto-utils/src/lib.rs @@ -1,5 +1,7 @@ //! Various crypto helper functions. +#![cfg_attr(not(feature = "std"), no_std)] + use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sp_consensus_babe::AuthorityId as BabeId; use sp_finality_grandpa::AuthorityId as GrandpaId; diff --git a/crates/eip712-common-test-utils/Cargo.toml b/crates/eip712-common-test-utils/Cargo.toml index e2a6c506c..728d70f9e 100644 --- a/crates/eip712-common-test-utils/Cargo.toml +++ b/crates/eip712-common-test-utils/Cargo.toml @@ -4,11 +4,15 @@ version = "0.1.0" edition = "2021" [dependencies] -eip712-common = { version = "0.1", path = "../eip712-common" } -primitives-ethereum = { version = "0.1", path = "../primitives-ethereum" } +eip712-common = { default-features = false, version = "0.1", path = "../eip712-common" } +primitives-ethereum = { default-features = false, version = "0.1", path = "../primitives-ethereum" } -eth-eip-712 = { package = "eip-712", version = "=0.1.0" } +eth-eip-712 = { package = "eip-712", version = "=0.1.0", optional = true } hex-literal = "0.3" -secp256k1 = "0.22" -serde_json = "1" -sp-core = { git = "https://github.com/humanode-network/substrate", branch = "master" } +secp256k1 = { version = "0.22", optional = true } +serde_json = { version = "1", optional = true } +sp-core = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } + +[features] +default = ["std"] +std = ["eth-eip-712", "secp256k1", "serde_json", "eip712-common/std", "primitives-ethereum/std", "sp-core/std"] diff --git a/crates/eip712-common-test-utils/src/lib.rs b/crates/eip712-common-test-utils/src/lib.rs index 0921e0391..05746c864 100644 --- a/crates/eip712-common-test-utils/src/lib.rs +++ b/crates/eip712-common-test-utils/src/lib.rs @@ -1,5 +1,7 @@ //! Common test utils for EIP-712 typed data message construction and signature verification. +#![cfg_attr(not(feature = "std"), no_std)] + use eip712_common::*; use primitives_ethereum::{EcdsaSignature, EthereumAddress}; pub use sp_core::{crypto::Pair, ecdsa, H256, U256}; diff --git a/crates/humanode-runtime/Cargo.toml b/crates/humanode-runtime/Cargo.toml index 88fcaad71..e18cbf37a 100644 --- a/crates/humanode-runtime/Cargo.toml +++ b/crates/humanode-runtime/Cargo.toml @@ -11,10 +11,10 @@ substrate-wasm-builder = { git = "https://github.com/humanode-network/substrate" [dependencies] author-ext-api = { version = "0.1", path = "../author-ext-api", default-features = false } bioauth-flow-api = { version = "0.1", path = "../bioauth-flow-api", default-features = false } -crypto-utils = { version = "0.1", path = "../crypto-utils", optional = true } +crypto-utils = { version = "0.1", path = "../crypto-utils", default-features = false, optional = true } eip712-account-claim = { version = "0.1", path = "../eip712-account-claim", default-features = false } eip712-common = { version = "0.1", path = "../eip712-common", default-features = false } -eip712-common-test-utils = { version = "0.1", path = "../eip712-common-test-utils", optional = true } +eip712-common-test-utils = { version = "0.1", path = "../eip712-common-test-utils", default-features = false, optional = true } eip712-token-claim = { version = "0.1", path = "../eip712-token-claim", default-features = false } frontier-api = { version = "0.1", path = "../frontier-api", default-features = false } keystore-bioauth-account-id = { version = "0.1", path = "../keystore-bioauth-account-id", default-features = false } From f937d56f7360998750db57abc13d7764cb2efc12 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 19 Aug 2022 18:45:51 +0400 Subject: [PATCH 09/12] Fix typos --- crates/eip712-common/src/lib.rs | 2 +- crates/pallet-token-claims/src/tests.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/eip712-common/src/lib.rs b/crates/eip712-common/src/lib.rs index c4165efa5..a07bd1c93 100644 --- a/crates/eip712-common/src/lib.rs +++ b/crates/eip712-common/src/lib.rs @@ -82,7 +82,7 @@ pub fn make_message_hash(domain: Domain<'_>, payload_hash: &[u8; 32]) -> [u8; 32 make_eip712_message_hash(&domain_hash, payload_hash) } -/// Extract the signer address from the signatue and the message. +/// Extract the signer address from the signature and the message. pub fn recover_signer(sig: &EcdsaSignature, msg: &[u8; 32]) -> Option { let pubkey = sp_io::crypto::secp256k1_ecdsa_recover(&sig.0, msg).ok()?; Some(ecdsa_public_key_to_ethereum_address(&pubkey)) diff --git a/crates/pallet-token-claims/src/tests.rs b/crates/pallet-token-claims/src/tests.rs index 82ca9dab1..9a75ef931 100644 --- a/crates/pallet-token-claims/src/tests.rs +++ b/crates/pallet-token-claims/src/tests.rs @@ -762,7 +762,7 @@ fn signed_ext_validate_works() { /// This test verifies that signed extension's `validate` properly fails when the eth signature is /// invalid. #[test] -fn signed_ext_validate_fails_invalid_eth_signatue() { +fn signed_ext_validate_fails_invalid_eth_signature() { new_test_ext().execute_with_ext(|_| { // Check test preconditions. assert!(>::contains_key(ð(EthAddr::Existing))); From 297ea49cd542ae82668287a8aab342d86446023e Mon Sep 17 00:00:00 2001 From: Dmitry Lavrenov Date: Tue, 23 Aug 2022 16:25:49 +0300 Subject: [PATCH 10/12] Fix benchmarking no_std --- Cargo.lock | 1 + crates/humanode-runtime/Cargo.toml | 5 +-- crates/humanode-runtime/src/benchmarking.rs | 40 ++++++++++++++++----- crates/humanode-runtime/src/lib.rs | 2 +- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9f30d13aa..582a28358 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3249,6 +3249,7 @@ dependencies = [ "frontier-api", "hex-literal", "keystore-bioauth-account-id", + "libsecp256k1 0.7.0", "pallet-authorship", "pallet-babe", "pallet-balances", diff --git a/crates/humanode-runtime/Cargo.toml b/crates/humanode-runtime/Cargo.toml index e18cbf37a..3dc27417f 100644 --- a/crates/humanode-runtime/Cargo.toml +++ b/crates/humanode-runtime/Cargo.toml @@ -47,6 +47,7 @@ frame-system-benchmarking = { default-features = false, optional = true, git = " frame-system-rpc-runtime-api = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } frame-try-runtime = { default-features = false, optional = true, git = "https://github.com/humanode-network/substrate", branch = "master" } hex-literal = { version = "0.3", optional = true } +libsecp256k1 = { version = "0.7.0", default-features = false } pallet-authorship = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } pallet-babe = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } pallet-balances = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } @@ -106,8 +107,8 @@ runtime-benchmarks = [ "pallet-token-claims/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "crypto-utils", - "eip712-common-test-utils", + "libsecp256k1/hmac", + "libsecp256k1/static-context", ] std = [ "author-ext-api/std", diff --git a/crates/humanode-runtime/src/benchmarking.rs b/crates/humanode-runtime/src/benchmarking.rs index cdbf202e2..28eee89c2 100644 --- a/crates/humanode-runtime/src/benchmarking.rs +++ b/crates/humanode-runtime/src/benchmarking.rs @@ -1,25 +1,48 @@ //! The benchmarking utilities. -use eip712_common::{EcdsaSignature, EthereumAddress}; -use eip712_common_test_utils::{ecdsa_pair, ecdsa_sign, ethereum_address_from_seed}; +use eip712_common::{keccak_256, EcdsaSignature, EthereumAddress}; use super::*; -use crate::dev_utils::*; + +const ALICE: [u8; 32] = + hex_literal::hex!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"); + +fn alice_secret() -> libsecp256k1::SecretKey { + libsecp256k1::SecretKey::parse(&keccak_256(b"Alice")).unwrap() +} + +fn alice_ethereum_address() -> EthereumAddress { + let mut ethereum_address = [0u8; 20]; + ethereum_address.copy_from_slice( + &keccak_256(&libsecp256k1::PublicKey::from_secret_key(&alice_secret()).serialize()[1..65]) + [12..], + ); + EthereumAddress(ethereum_address) +} + +fn alice_sign(msg_hash: &[u8; 32]) -> EcdsaSignature { + let (sig, recovery_id) = + libsecp256k1::sign(&libsecp256k1::Message::parse(&msg_hash), &alice_secret()); + let mut ecdsa_signature = [0u8; 65]; + ecdsa_signature[0..64].copy_from_slice(&sig.serialize()[..]); + ecdsa_signature[64] = recovery_id.serialize(); + EcdsaSignature(ecdsa_signature) +} impl pallet_token_claims::benchmarking::Interface for Runtime { fn account_id_to_claim_to() -> ::AccountId { - account_id("Alice") + AccountId::from(ALICE) } fn ethereum_address() -> EthereumAddress { - ethereum_address_from_seed(b"Alice") + alice_ethereum_address() } fn create_ecdsa_signature( account_id: &::AccountId, ethereum_address: &EthereumAddress, ) -> EcdsaSignature { - if ethereum_address != ðereum_address_from_seed(b"Alice") { + if ethereum_address != &alice_ethereum_address() { panic!("bad ethereum address"); } @@ -32,15 +55,14 @@ impl pallet_token_claims::benchmarking::Interface for Runtime { verifying_contract: &verifying_contract, }; - let pair = ecdsa_pair(b"Alice"); let msg_hash = eip712_token_claim::make_message_hash(domain, account_id.as_ref()); - ecdsa_sign(&pair, &msg_hash) + alice_sign(&msg_hash) } } impl pallet_vesting::benchmarking::Interface for Runtime { fn account_id() -> ::AccountId { - account_id("Alice") + AccountId::from(ALICE) } fn schedule() -> ::Schedule { diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index 3985c5555..d0b372eff 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -73,7 +73,7 @@ use frontier_precompiles::FrontierPrecompiles; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -#[cfg(any(test, feature = "runtime-benchmarks"))] +#[cfg(test)] mod dev_utils; mod display_moment; pub mod eip712; From 5d056b4337f593ae167429146a1b7536900c13a7 Mon Sep 17 00:00:00 2001 From: Dmitry Lavrenov Date: Tue, 23 Aug 2022 18:02:36 +0300 Subject: [PATCH 11/12] Use alice ethereum address at chain spec --- crates/humanode-peer/src/chain_spec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/humanode-peer/src/chain_spec.rs b/crates/humanode-peer/src/chain_spec.rs index 1ca472746..46423b65a 100644 --- a/crates/humanode-peer/src/chain_spec.rs +++ b/crates/humanode-peer/src/chain_spec.rs @@ -341,7 +341,7 @@ fn testnet_genesis( token_claims_pot: Default::default(), token_claims: TokenClaimsConfig { claims: vec![( - EthereumAddress(hex!("6be02d1d3665660d22ff9624b7be0551ee1ac91b")), + EthereumAddress(hex!("bf0b5a4099f0bf6c8bc4252ebec548bae95602ea")), ClaimInfo { balance: DEV_ACCOUNT_BALANCE, vesting: vec![].try_into().unwrap(), From 36e6ddde79717b9912cacf3c35e0484f3a6dba77 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Sun, 28 Aug 2022 23:11:49 +0400 Subject: [PATCH 12/12] Temporarily disable benchmarks --- crates/humanode-runtime/src/lib.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index d0b372eff..80180dff8 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -1291,8 +1291,9 @@ impl_runtime_apis! { list_benchmark!(list, extra, pallet_balances, Balances); list_benchmark!(list, extra, pallet_timestamp, Timestamp); list_benchmark!(list, extra, pallet_bioauth, Bioauth); - list_benchmark!(list, extra, pallet_token_claims, TokenClaims); - list_benchmark!(list, extra, pallet_vesting, Vesting); + // TODO(#447): re-add token-claims and vesting benches + // list_benchmark!(list, extra, pallet_token_claims, TokenClaims); + // list_benchmark!(list, extra, pallet_vesting, Vesting); let storage_info = AllPalletsWithSystem::storage_info(); @@ -1336,8 +1337,9 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_balances, Balances); add_benchmark!(params, batches, pallet_timestamp, Timestamp); add_benchmark!(params, batches, pallet_bioauth, Bioauth); - add_benchmark!(params, batches, pallet_token_claims, TokenClaims); - add_benchmark!(params, batches, pallet_vesting, Vesting); + // TODO(#447): re-add token-claims and vesting benches + // add_benchmark!(params, batches, pallet_token_claims, TokenClaims); + // add_benchmark!(params, batches, pallet_vesting, Vesting); Ok(batches) }