diff --git a/node/src/eth.rs b/node/src/eth.rs index 545326224..0a75ee3af 100644 --- a/node/src/eth.rs +++ b/node/src/eth.rs @@ -30,7 +30,7 @@ pub use fc_consensus::FrontierBlockImport; use fc_rpc::{EthTask, OverrideHandle}; pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool}; // Local -use tangle_testnet_runtime::opaque::Block; +use tangle_primitives::Block; use crate::service::{FullBackend, FullClient}; diff --git a/node/src/rpc/mod.rs b/node/src/rpc/mod.rs index 86efa13f4..3ed570aab 100644 --- a/node/src/rpc/mod.rs +++ b/node/src/rpc/mod.rs @@ -36,10 +36,10 @@ use sp_consensus::SelectChain; use sp_consensus_babe::BabeApi; use sp_keystore::KeystorePtr; use sp_runtime::traits::Block as BlockT; +use tangle_primitives::Block; use tangle_runtime::BlockNumber; - // Runtime -use tangle_runtime::{opaque::Block, AccountId, Balance, Hash, Index}; +use tangle_runtime::{AccountId, Balance, Hash, Index}; pub mod eth; pub mod tracing; diff --git a/node/src/service.rs b/node/src/service.rs index 3a7146cd3..f1595500b 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -30,16 +30,16 @@ pub use sc_executor::NativeElseWasmExecutor; use sc_service::{error::Error as ServiceError, Configuration, TaskManager}; use sc_telemetry::{Telemetry, TelemetryWorker}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; - use sp_core::U256; +use tangle_primitives::Block; use std::{path::Path, sync::Arc, time::Duration}; #[cfg(not(feature = "testnet"))] -use tangle_runtime::{self, opaque::Block, RuntimeApi, TransactionConverter}; +use tangle_runtime::{self, RuntimeApi, TransactionConverter}; #[cfg(feature = "testnet")] -use tangle_testnet_runtime::{self, opaque::Block, RuntimeApi, TransactionConverter}; +use tangle_testnet_runtime::{self, RuntimeApi, TransactionConverter}; /// The minimum period of blocks on which justifications will be /// imported and generated. diff --git a/primitives/src/impls.rs b/primitives/src/impls.rs new file mode 100644 index 000000000..39cc643c2 --- /dev/null +++ b/primitives/src/impls.rs @@ -0,0 +1,65 @@ +// This file is part of Tangle. + +// Copyright (C) 2022-2024 Webb Technologies Inc. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Common implementations + +#[macro_export] +macro_rules! impl_to_author { + () => { + /// Logic for the author to get a portion of fees. + pub struct ToAuthor(sp_std::marker::PhantomData); + impl OnUnbalanced> for ToAuthor + where + R: pallet_balances::Config + pallet_authorship::Config, + ::RuntimeEvent: From>, + { + fn on_nonzero_unbalanced(amount: NegativeImbalance) { + if let Some(author) = >::author() { + let _numeric_amount = amount.peek(); + >::resolve_creating(&author, amount); + } + } + } + }; +} + +#[macro_export] +macro_rules! impl_deal_with_fees { + () => { + pub struct DealWithFees(sp_std::marker::PhantomData); + impl OnUnbalanced> for DealWithFees + where + R: pallet_balances::Config + pallet_treasury::Config + pallet_authorship::Config, + pallet_treasury::Pallet: OnUnbalanced>, + ::RuntimeEvent: From>, + { + fn on_unbalanceds(mut fees_then_tips: impl Iterator>) { + if let Some(fees) = fees_then_tips.next() { + // for fees, 80% to treasury, 20% to author + let mut split = fees.ration(80, 20); + if let Some(tips) = fees_then_tips.next() { + // for tips, if any, 100% to author + tips.merge_into(&mut split.1); + } + + as OnUnbalanced<_>>::on_unbalanced(split.0); + as OnUnbalanced<_>>::on_unbalanced(split.1); + } + } + } + }; +} diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 6f88abd38..2e4ef1765 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -29,7 +29,9 @@ use sp_runtime::{ pub mod types; pub use types::*; +pub mod impls; pub mod traits; +pub use impls::*; #[cfg(feature = "verifying")] pub mod verifier; @@ -132,6 +134,137 @@ pub mod fee { } } +pub mod evm { + /// Current approximation of the gas/s consumption considering + /// EVM execution over compiled WASM (on 4.4Ghz CPU). + /// Given the 500ms Weight, from which 75% only are used for transactions, + /// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000. + pub const GAS_PER_SECOND: u64 = 40_000_000; + + /// Approximate ratio of the amount of Weight per Gas. + /// u64 works for approximations because Weight is a very small unit compared to gas. + pub const WEIGHT_PER_GAS: u64 = frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND + .saturating_div(GAS_PER_SECOND); + + /// The amount of gas per pov. A ratio of 4 if we convert ref_time to gas and we compare + /// it with the pov_size for a block. E.g. + /// ceil( + /// (max_extrinsic.ref_time() / max_extrinsic.proof_size()) / WEIGHT_PER_GAS + /// ) + pub const GAS_LIMIT_POV_SIZE_RATIO: u64 = 4; + + #[macro_export] + macro_rules! impl_proxy_type { + () => { + #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] + #[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, MaxEncodedLen, TypeInfo, + )] + pub enum ProxyType { + /// All calls can be proxied. This is the trivial/most permissive filter. + Any = 0, + /// Only extrinsics related to governance (democracy and collectives). + Governance = 1, + /// Allow to veto an announced proxy call. + CancelProxy = 2, + /// Allow extrinsic related to Balances. + Balances = 3, + } + + impl Default for ProxyType { + fn default() -> Self { + Self::Any + } + } + + fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bool { + matches!( + precompile_name, + PrecompileName::DemocracyPrecompile | PrecompileName::PreimagePrecompile + ) + } + + // Be careful: Each time this filter is modified, the substrate filter must also be modified + // consistently. + impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { + fn is_evm_proxy_call_allowed( + &self, + call: &pallet_evm_precompile_proxy::EvmSubCall, + recipient_has_code: bool, + gas: u64, + ) -> precompile_utils::EvmResult { + Ok(match self { + ProxyType::Any => true, + ProxyType::Governance => + call.value == U256::zero() && + matches!( + PrecompileName::from_address(call.to.0), + Some(ref precompile) if is_governance_precompile(precompile) + ), + // The proxy precompile does not contain method cancel_proxy + ProxyType::CancelProxy => false, + ProxyType::Balances => { + // Allow only "simple" accounts as recipient (no code nor precompile). + // Note: Checking the presence of the code is not enough because some precompiles + // have no code. + !recipient_has_code && + !precompile_utils::precompile_set::is_precompile_or_fail::( + call.to.0, gas, + )? + }, + }) + } + } + } + } +} + +pub mod democracy { + use crate::{currency::UNIT, time::MINUTES, Balance, BlockNumber}; + + pub const LAUNCH_PERIOD: BlockNumber = 28 * 24 * 60 * MINUTES; + pub const VOTING_PERIOD: BlockNumber = 28 * 24 * 60 * MINUTES; + pub const FASTTRACK_VOTING_PERIOD: BlockNumber = 3 * 24 * 60 * MINUTES; + pub const MINIMUM_DEPOSIT: Balance = 100 * UNIT; + pub const ENACTMENT_PERIOD: BlockNumber = 30 * 24 * 60 * MINUTES; + pub const COOLOFF_PERIOD: BlockNumber = 28 * 24 * 60 * MINUTES; + pub const MAX_PROPOSALS: u32 = 100; +} + +pub mod elections { + use crate::{currency::UNIT, time::DAYS, Balance, BlockNumber}; + + pub const CANDIDACY_BOND: Balance = 10 * UNIT; + pub const TERM_DURATION: BlockNumber = 7 * DAYS; + pub const DESIRED_MEMBERS: u32 = 13; + pub const DESIRED_RUNNERS_UP: u32 = 7; + pub const MAX_CANDIDATES: u32 = 10; + pub const MAX_VOTERS: u32 = 5; + pub const ELECTIONS_PHRAGMEN_PALLET_ID: frame_support::traits::LockIdentifier = *b"phrelect"; +} + +pub mod treasury { + use crate::{ + currency::{CENT, UNIT}, + time::DAYS, + Balance, BlockNumber, + }; + use frame_support::PalletId; + use sp_runtime::{Percent, Permill}; + + pub const PROPOSAL_BOND: Permill = Permill::from_percent(5); + pub const PROPOSAL_BOND_MINIMUM: Balance = UNIT; + pub const SPEND_PERIOD: BlockNumber = DAYS; + pub const BURN: Permill = Permill::from_percent(50); + pub const TIP_COUNTDOWN: BlockNumber = DAYS; + pub const TIP_FINDERS_FEE: Percent = Percent::from_percent(20); + pub const TIP_REPORT_DEPOSIT_BASE: Balance = UNIT; + pub const DATA_DEPOSIT_PER_BYTE: Balance = CENT; + pub const TREASURY_PALLET_ID: PalletId = PalletId(*b"py/trsry"); + pub const MAXIMUM_REASON_LENGTH: u32 = 300; + pub const MAX_APPROVALS: u32 = 100; +} + /// We assume that ~10% of the block weight is consumed by `on_initialize` handlers. This is /// used to limit the maximal weight of a single extrinsic. pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); diff --git a/runtime/mainnet/src/frontier_evm.rs b/runtime/mainnet/src/frontier_evm.rs index ff2f0d086..867936d24 100644 --- a/runtime/mainnet/src/frontier_evm.rs +++ b/runtime/mainnet/src/frontier_evm.rs @@ -19,18 +19,17 @@ use crate::{ precompiles::{PrecompileName, WebbPrecompiles}, *, }; -use frame_support::{ - pallet_prelude::*, - parameter_types, - traits::FindAuthor, - weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, -}; +use frame_support::{pallet_prelude::*, parameter_types, traits::FindAuthor, weights::Weight}; use sp_core::{crypto::ByteArray, H160, U256}; use sp_runtime::{traits::BlakeTwo256, ConsensusEngineId, Permill}; use sp_std::{marker::PhantomData, prelude::*}; // Frontier use pallet_ethereum::PostLogContent; use pallet_evm::HashedAddressMapping; +use tangle_primitives::{ + evm::{GAS_LIMIT_POV_SIZE_RATIO, WEIGHT_PER_GAS}, + impl_proxy_type, +}; impl pallet_evm_chain_id::Config for Runtime {} @@ -48,87 +47,12 @@ impl> FindAuthor for FindAuthorTruncated { } } -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] -#[derive( - Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, MaxEncodedLen, TypeInfo, -)] -pub enum ProxyType { - /// All calls can be proxied. This is the trivial/most permissive filter. - Any = 0, - /// Only extrinsics related to governance (democracy and collectives). - Governance = 1, - /// Allow to veto an announced proxy call. - CancelProxy = 2, - /// Allow extrinsic related to Balances. - Balances = 3, -} - -impl Default for ProxyType { - fn default() -> Self { - Self::Any - } -} - -fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bool { - matches!( - precompile_name, - PrecompileName::DemocracyPrecompile | PrecompileName::PreimagePrecompile - ) -} - -// Be careful: Each time this filter is modified, the substrate filter must also be modified -// consistently. -impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { - fn is_evm_proxy_call_allowed( - &self, - call: &pallet_evm_precompile_proxy::EvmSubCall, - recipient_has_code: bool, - gas: u64, - ) -> precompile_utils::EvmResult { - Ok(match self { - ProxyType::Any => true, - ProxyType::Governance => - call.value == U256::zero() && - matches!( - PrecompileName::from_address(call.to.0), - Some(ref precompile) if is_governance_precompile(precompile) - ), - // The proxy precompile does not contain method cancel_proxy - ProxyType::CancelProxy => false, - ProxyType::Balances => { - // Allow only "simple" accounts as recipient (no code nor precompile). - // Note: Checking the presence of the code is not enough because some precompiles - // have no code. - !recipient_has_code && - !precompile_utils::precompile_set::is_precompile_or_fail::( - call.to.0, gas, - )? - }, - }) - } -} - -/// Current approximation of the gas/s consumption considering -/// EVM execution over compiled WASM (on 4.4Ghz CPU). -/// Given the 500ms Weight, from which 75% only are used for transactions, -/// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000. -pub const GAS_PER_SECOND: u64 = 40_000_000; - -/// Approximate ratio of the amount of Weight per Gas. -/// u64 works for approximations because Weight is a very small unit compared to gas. -pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND.saturating_div(GAS_PER_SECOND); - parameter_types! { /// EVM gas limit pub BlockGasLimit: U256 = U256::from( NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS ); - /// The amount of gas per pov. A ratio of 4 if we convert ref_time to gas and we compare - /// it with the pov_size for a block. E.g. - /// ceil( - /// (max_extrinsic.ref_time() / max_extrinsic.proof_size()) / WEIGHT_PER_GAS - /// ) - pub const GasLimitPovSizeRatio: u64 = 4; + pub const GasLimitPovSizeRatio: u64 = GAS_LIMIT_POV_SIZE_RATIO; pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0); pub PrecompilesValue: WebbPrecompiles = WebbPrecompiles::<_>::new(); } @@ -168,6 +92,8 @@ impl pallet_ethereum::Config for Runtime { type ExtraDataLength = ConstU32<30>; } +impl_proxy_type!(); + parameter_types! { pub BoundDivision: U256 = U256::from(1024); } diff --git a/runtime/mainnet/src/impls.rs b/runtime/mainnet/src/impls.rs index 75106b488..c06e2bb15 100644 --- a/runtime/mainnet/src/impls.rs +++ b/runtime/mainnet/src/impls.rs @@ -17,40 +17,7 @@ use crate::NegativeImbalance; use frame_support::traits::{Currency, Imbalance, OnUnbalanced}; +use tangle_primitives::{impl_deal_with_fees, impl_to_author}; -/// Logic for the author to get a portion of fees. -pub struct ToAuthor(sp_std::marker::PhantomData); -impl OnUnbalanced> for ToAuthor -where - R: pallet_balances::Config + pallet_authorship::Config, - ::RuntimeEvent: From>, -{ - fn on_nonzero_unbalanced(amount: NegativeImbalance) { - if let Some(author) = >::author() { - let _numeric_amount = amount.peek(); - >::resolve_creating(&author, amount); - } - } -} - -pub struct DealWithFees(sp_std::marker::PhantomData); -impl OnUnbalanced> for DealWithFees -where - R: pallet_balances::Config + pallet_treasury::Config + pallet_authorship::Config, - pallet_treasury::Pallet: OnUnbalanced>, - ::RuntimeEvent: From>, -{ - fn on_unbalanceds(mut fees_then_tips: impl Iterator>) { - if let Some(fees) = fees_then_tips.next() { - // for fees, 80% to treasury, 20% to author - let mut split = fees.ration(80, 20); - if let Some(tips) = fees_then_tips.next() { - // for tips, if any, 100% to author - tips.merge_into(&mut split.1); - } - - as OnUnbalanced<_>>::on_unbalanced(split.0); - as OnUnbalanced<_>>::on_unbalanced(split.1); - } - } -} +impl_to_author!(); +impl_deal_with_fees!(); diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs index 883ba0f93..8f4877f53 100644 --- a/runtime/mainnet/src/lib.rs +++ b/runtime/mainnet/src/lib.rs @@ -96,13 +96,27 @@ use sp_runtime::generic::Era; pub use sp_runtime::BuildStorage; pub use sp_runtime::{MultiAddress, Perbill, Percent, Permill}; +use pallet_airdrop_claims::TestWeightInfo; pub use tangle_primitives::{ currency::*, fee::*, time::*, AccountId, AccountIndex, Address, Balance, BlockNumber, Hash, Header, Index, Moment, Signature, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, }; - -use pallet_airdrop_claims::TestWeightInfo; +use tangle_primitives::{ + democracy::{ + COOLOFF_PERIOD, ENACTMENT_PERIOD, FASTTRACK_VOTING_PERIOD, LAUNCH_PERIOD, MAX_PROPOSALS, + MINIMUM_DEPOSIT, VOTING_PERIOD, + }, + elections::{ + CANDIDACY_BOND, DESIRED_MEMBERS, DESIRED_RUNNERS_UP, ELECTIONS_PHRAGMEN_PALLET_ID, + MAX_CANDIDATES, MAX_VOTERS, TERM_DURATION, + }, + treasury::{ + BURN, DATA_DEPOSIT_PER_BYTE, MAXIMUM_REASON_LENGTH, MAX_APPROVALS, PROPOSAL_BOND, + PROPOSAL_BOND_MINIMUM, SPEND_PERIOD, TIP_COUNTDOWN, TIP_FINDERS_FEE, + TIP_REPORT_DEPOSIT_BASE, TREASURY_PALLET_ID, + }, +}; // Frontier use fp_rpc::TransactionStatus; @@ -130,11 +144,6 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { state_version: 0, }; -pub const fn deposit(items: u32, bytes: u32) -> Balance { - // map to 1/10 of what the kusama relay chain charges (v9020) - (items as Balance * 2_000 * CENT + (bytes as Balance) * 100 * MILLIUNIT) / 10 -} - /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { @@ -162,10 +171,6 @@ pub mod opaque { pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; - /// Opaque block header type. - pub type Header = generic::Header; - /// Opaque block type. - pub type Block = generic::Block; /// Opaque block identifier type. pub type BlockId = generic::BlockId; @@ -450,13 +455,13 @@ impl pallet_staking::Config for Runtime { } parameter_types! { - pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; - pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; - pub const FastTrackVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES; - pub const MinimumDeposit: Balance = 100 * UNIT; - pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES; - pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; - pub const MaxProposals: u32 = 100; + pub const LaunchPeriod: BlockNumber = LAUNCH_PERIOD; + pub const VotingPeriod: BlockNumber = VOTING_PERIOD; + pub const FastTrackVotingPeriod: BlockNumber = FASTTRACK_VOTING_PERIOD; + pub const MinimumDeposit: Balance = MINIMUM_DEPOSIT; + pub const EnactmentPeriod: BlockNumber = ENACTMENT_PERIOD; + pub const CooloffPeriod: BlockNumber = COOLOFF_PERIOD; + pub const MaxProposals: u32 = MAX_PROPOSALS; } type EnsureRootOrHalfCouncil = EitherOfDiverse< @@ -822,17 +827,17 @@ impl pallet_offences::Config for Runtime { } parameter_types! { - pub const CandidacyBond: Balance = 10 * UNIT; + pub const CandidacyBond: Balance = CANDIDACY_BOND; // 1 storage item created, key size is 32 bytes, value size is 16+16. pub const VotingBondBase: Balance = deposit(1, 64); // additional data per vote is 32 bytes (account id). pub const VotingBondFactor: Balance = deposit(0, 32); - pub const TermDuration: BlockNumber = 7 * DAYS; - pub const DesiredMembers: u32 = 13; - pub const DesiredRunnersUp: u32 = 7; - pub const MaxCandidates: u32 = 10; - pub const MaxVoters: u32 = 5; - pub const ElectionsPhragmenPalletId: LockIdentifier = *b"phrelect"; + pub const TermDuration: BlockNumber = TERM_DURATION; + pub const DesiredMembers: u32 = DESIRED_MEMBERS; + pub const DesiredRunnersUp: u32 = DESIRED_RUNNERS_UP; + pub const MaxCandidates: u32 = MAX_CANDIDATES; + pub const MaxVoters: u32 = MAX_VOTERS; + pub const ElectionsPhragmenPalletId: LockIdentifier = ELECTIONS_PHRAGMEN_PALLET_ID; } // Make sure that there are no more than `MaxMembers` members elected via @@ -863,17 +868,17 @@ impl pallet_elections_phragmen::Config for Runtime { } parameter_types! { - pub const ProposalBond: Permill = Permill::from_percent(5); - pub const ProposalBondMinimum: Balance = UNIT; - pub const SpendPeriod: BlockNumber = DAYS; - pub const Burn: Permill = Permill::from_percent(50); - pub const TipCountdown: BlockNumber = DAYS; - pub const TipFindersFee: Percent = Percent::from_percent(20); - pub const TipReportDepositBase: Balance = UNIT; - pub const DataDepositPerByte: Balance = CENT; - pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); - pub const MaximumReasonLength: u32 = 300; - pub const MaxApprovals: u32 = 100; + pub const ProposalBond: Permill = PROPOSAL_BOND; + pub const ProposalBondMinimum: Balance = PROPOSAL_BOND_MINIMUM; + pub const SpendPeriod: BlockNumber = SPEND_PERIOD; + pub const Burn: Permill = BURN; + pub const TipCountdown: BlockNumber = TIP_COUNTDOWN; + pub const TipFindersFee: Percent = TIP_FINDERS_FEE; + pub const TipReportDepositBase: Balance = TIP_REPORT_DEPOSIT_BASE; + pub const DataDepositPerByte: Balance = DATA_DEPOSIT_PER_BYTE; + pub const TreasuryPalletId: PalletId = TREASURY_PALLET_ID; + pub const MaximumReasonLength: u32 = MAXIMUM_REASON_LENGTH; + pub const MaxApprovals: u32 = MAX_APPROVALS; } impl pallet_treasury::Config for Runtime { @@ -1007,7 +1012,7 @@ impl pallet_eth2_light_client::Config for Runtime { parameter_types! { pub Prefix: &'static [u8] = b"Claim TNTs to the account:"; - pub const MaxVestingSchedules: u32 = 28; + pub const MaxVestingSchedules: u32 = 100; } impl pallet_airdrop_claims::Config for Runtime { diff --git a/runtime/testnet/src/frontier_evm.rs b/runtime/testnet/src/frontier_evm.rs index ff2f0d086..c636895e0 100644 --- a/runtime/testnet/src/frontier_evm.rs +++ b/runtime/testnet/src/frontier_evm.rs @@ -19,18 +19,17 @@ use crate::{ precompiles::{PrecompileName, WebbPrecompiles}, *, }; -use frame_support::{ - pallet_prelude::*, - parameter_types, - traits::FindAuthor, - weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, -}; +use frame_support::{pallet_prelude::*, parameter_types, traits::FindAuthor, weights::Weight}; use sp_core::{crypto::ByteArray, H160, U256}; use sp_runtime::{traits::BlakeTwo256, ConsensusEngineId, Permill}; use sp_std::{marker::PhantomData, prelude::*}; // Frontier use pallet_ethereum::PostLogContent; use pallet_evm::HashedAddressMapping; +use tangle_primitives::{ + evm::{GAS_LIMIT_POV_SIZE_RATIO, WEIGHT_PER_GAS}, + impl_proxy_type, +}; impl pallet_evm_chain_id::Config for Runtime {} @@ -48,87 +47,14 @@ impl> FindAuthor for FindAuthorTruncated { } } -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] -#[derive( - Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, MaxEncodedLen, TypeInfo, -)] -pub enum ProxyType { - /// All calls can be proxied. This is the trivial/most permissive filter. - Any = 0, - /// Only extrinsics related to governance (democracy and collectives). - Governance = 1, - /// Allow to veto an announced proxy call. - CancelProxy = 2, - /// Allow extrinsic related to Balances. - Balances = 3, -} - -impl Default for ProxyType { - fn default() -> Self { - Self::Any - } -} - -fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bool { - matches!( - precompile_name, - PrecompileName::DemocracyPrecompile | PrecompileName::PreimagePrecompile - ) -} - -// Be careful: Each time this filter is modified, the substrate filter must also be modified -// consistently. -impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { - fn is_evm_proxy_call_allowed( - &self, - call: &pallet_evm_precompile_proxy::EvmSubCall, - recipient_has_code: bool, - gas: u64, - ) -> precompile_utils::EvmResult { - Ok(match self { - ProxyType::Any => true, - ProxyType::Governance => - call.value == U256::zero() && - matches!( - PrecompileName::from_address(call.to.0), - Some(ref precompile) if is_governance_precompile(precompile) - ), - // The proxy precompile does not contain method cancel_proxy - ProxyType::CancelProxy => false, - ProxyType::Balances => { - // Allow only "simple" accounts as recipient (no code nor precompile). - // Note: Checking the presence of the code is not enough because some precompiles - // have no code. - !recipient_has_code && - !precompile_utils::precompile_set::is_precompile_or_fail::( - call.to.0, gas, - )? - }, - }) - } -} - -/// Current approximation of the gas/s consumption considering -/// EVM execution over compiled WASM (on 4.4Ghz CPU). -/// Given the 500ms Weight, from which 75% only are used for transactions, -/// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000. -pub const GAS_PER_SECOND: u64 = 40_000_000; - -/// Approximate ratio of the amount of Weight per Gas. -/// u64 works for approximations because Weight is a very small unit compared to gas. -pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND.saturating_div(GAS_PER_SECOND); +impl_proxy_type!(); parameter_types! { /// EVM gas limit pub BlockGasLimit: U256 = U256::from( NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS ); - /// The amount of gas per pov. A ratio of 4 if we convert ref_time to gas and we compare - /// it with the pov_size for a block. E.g. - /// ceil( - /// (max_extrinsic.ref_time() / max_extrinsic.proof_size()) / WEIGHT_PER_GAS - /// ) - pub const GasLimitPovSizeRatio: u64 = 4; + pub const GasLimitPovSizeRatio: u64 = GAS_LIMIT_POV_SIZE_RATIO; pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0); pub PrecompilesValue: WebbPrecompiles = WebbPrecompiles::<_>::new(); } diff --git a/runtime/testnet/src/impls.rs b/runtime/testnet/src/impls.rs index 75106b488..c06e2bb15 100644 --- a/runtime/testnet/src/impls.rs +++ b/runtime/testnet/src/impls.rs @@ -17,40 +17,7 @@ use crate::NegativeImbalance; use frame_support::traits::{Currency, Imbalance, OnUnbalanced}; +use tangle_primitives::{impl_deal_with_fees, impl_to_author}; -/// Logic for the author to get a portion of fees. -pub struct ToAuthor(sp_std::marker::PhantomData); -impl OnUnbalanced> for ToAuthor -where - R: pallet_balances::Config + pallet_authorship::Config, - ::RuntimeEvent: From>, -{ - fn on_nonzero_unbalanced(amount: NegativeImbalance) { - if let Some(author) = >::author() { - let _numeric_amount = amount.peek(); - >::resolve_creating(&author, amount); - } - } -} - -pub struct DealWithFees(sp_std::marker::PhantomData); -impl OnUnbalanced> for DealWithFees -where - R: pallet_balances::Config + pallet_treasury::Config + pallet_authorship::Config, - pallet_treasury::Pallet: OnUnbalanced>, - ::RuntimeEvent: From>, -{ - fn on_unbalanceds(mut fees_then_tips: impl Iterator>) { - if let Some(fees) = fees_then_tips.next() { - // for fees, 80% to treasury, 20% to author - let mut split = fees.ration(80, 20); - if let Some(tips) = fees_then_tips.next() { - // for tips, if any, 100% to author - tips.merge_into(&mut split.1); - } - - as OnUnbalanced<_>>::on_unbalanced(split.0); - as OnUnbalanced<_>>::on_unbalanced(split.1); - } - } -} +impl_to_author!(); +impl_deal_with_fees!(); diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 62c3e4155..833b94774 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -112,6 +112,21 @@ pub use tangle_primitives::{ AccountId, AccountIndex, Address, BabeId, Balance, BlockNumber, Hash, Header, Index, Moment, Signature, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, }; +use tangle_primitives::{ + democracy::{ + COOLOFF_PERIOD, ENACTMENT_PERIOD, FASTTRACK_VOTING_PERIOD, LAUNCH_PERIOD, MAX_PROPOSALS, + MINIMUM_DEPOSIT, VOTING_PERIOD, + }, + elections::{ + CANDIDACY_BOND, DESIRED_MEMBERS, DESIRED_RUNNERS_UP, ELECTIONS_PHRAGMEN_PALLET_ID, + MAX_CANDIDATES, MAX_VOTERS, TERM_DURATION, + }, + treasury::{ + BURN, DATA_DEPOSIT_PER_BYTE, MAXIMUM_REASON_LENGTH, MAX_APPROVALS, PROPOSAL_BOND, + PROPOSAL_BOND_MINIMUM, SPEND_PERIOD, TIP_COUNTDOWN, TIP_FINDERS_FEE, + TIP_REPORT_DEPOSIT_BASE, TREASURY_PALLET_ID, + }, +}; use pallet_airdrop_claims::TestWeightInfo; @@ -141,11 +156,6 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { state_version: 0, }; -pub const fn deposit(items: u32, bytes: u32) -> Balance { - // map to 1/10 of what the kusama relay chain charges (v9020) - (items as Balance * 2_000 * CENT + (bytes as Balance) * 100 * MILLIUNIT) / 10 -} - /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { @@ -173,10 +183,6 @@ pub mod opaque { pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; - /// Opaque block header type. - pub type Header = generic::Header; - /// Opaque block type. - pub type Block = generic::Block; /// Opaque block identifier type. pub type BlockId = generic::BlockId; @@ -462,13 +468,13 @@ impl pallet_staking::Config for Runtime { } parameter_types! { - pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; - pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; - pub const FastTrackVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES; - pub const MinimumDeposit: Balance = 100 * UNIT; - pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES; - pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; - pub const MaxProposals: u32 = 100; + pub const LaunchPeriod: BlockNumber = LAUNCH_PERIOD; + pub const VotingPeriod: BlockNumber = VOTING_PERIOD; + pub const FastTrackVotingPeriod: BlockNumber = FASTTRACK_VOTING_PERIOD; + pub const MinimumDeposit: Balance = MINIMUM_DEPOSIT; + pub const EnactmentPeriod: BlockNumber = ENACTMENT_PERIOD; + pub const CooloffPeriod: BlockNumber = COOLOFF_PERIOD; + pub const MaxProposals: u32 = MAX_PROPOSALS; } type EnsureRootOrHalfCouncil = EitherOfDiverse< @@ -834,17 +840,17 @@ impl pallet_offences::Config for Runtime { } parameter_types! { - pub const CandidacyBond: Balance = 10 * UNIT; + pub const CandidacyBond: Balance = CANDIDACY_BOND; // 1 storage item created, key size is 32 bytes, value size is 16+16. pub const VotingBondBase: Balance = deposit(1, 64); // additional data per vote is 32 bytes (account id). pub const VotingBondFactor: Balance = deposit(0, 32); - pub const TermDuration: BlockNumber = 7 * DAYS; - pub const DesiredMembers: u32 = 13; - pub const DesiredRunnersUp: u32 = 7; - pub const MaxCandidates: u32 = 10; - pub const MaxVoters: u32 = 5; - pub const ElectionsPhragmenPalletId: LockIdentifier = *b"phrelect"; + pub const TermDuration: BlockNumber = TERM_DURATION; + pub const DesiredMembers: u32 = DESIRED_MEMBERS; + pub const DesiredRunnersUp: u32 = DESIRED_RUNNERS_UP; + pub const MaxCandidates: u32 = MAX_CANDIDATES; + pub const MaxVoters: u32 = MAX_VOTERS; + pub const ElectionsPhragmenPalletId: LockIdentifier = ELECTIONS_PHRAGMEN_PALLET_ID; } // Make sure that there are no more than `MaxMembers` members elected via @@ -875,17 +881,17 @@ impl pallet_elections_phragmen::Config for Runtime { } parameter_types! { - pub const ProposalBond: Permill = Permill::from_percent(5); - pub const ProposalBondMinimum: Balance = UNIT; - pub const SpendPeriod: BlockNumber = DAYS; - pub const Burn: Permill = Permill::from_percent(50); - pub const TipCountdown: BlockNumber = DAYS; - pub const TipFindersFee: Percent = Percent::from_percent(20); - pub const TipReportDepositBase: Balance = UNIT; - pub const DataDepositPerByte: Balance = CENT; - pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); - pub const MaximumReasonLength: u32 = 300; - pub const MaxApprovals: u32 = 100; + pub const ProposalBond: Permill = PROPOSAL_BOND; + pub const ProposalBondMinimum: Balance = PROPOSAL_BOND_MINIMUM; + pub const SpendPeriod: BlockNumber = SPEND_PERIOD; + pub const Burn: Permill = BURN; + pub const TipCountdown: BlockNumber = TIP_COUNTDOWN; + pub const TipFindersFee: Percent = TIP_FINDERS_FEE; + pub const TipReportDepositBase: Balance = TIP_REPORT_DEPOSIT_BASE; + pub const DataDepositPerByte: Balance = DATA_DEPOSIT_PER_BYTE; + pub const TreasuryPalletId: PalletId = TREASURY_PALLET_ID; + pub const MaximumReasonLength: u32 = MAXIMUM_REASON_LENGTH; + pub const MaxApprovals: u32 = MAX_APPROVALS; } impl pallet_treasury::Config for Runtime {