Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion node/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
4 changes: 2 additions & 2 deletions node/src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
65 changes: 65 additions & 0 deletions primitives/src/impls.rs
Original file line number Diff line number Diff line change
@@ -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<R>(sp_std::marker::PhantomData<R>);
impl<R> OnUnbalanced<NegativeImbalance<R>> for ToAuthor<R>
where
R: pallet_balances::Config + pallet_authorship::Config,
<R as frame_system::Config>::RuntimeEvent: From<pallet_balances::Event<R>>,
{
fn on_nonzero_unbalanced(amount: NegativeImbalance<R>) {
if let Some(author) = <pallet_authorship::Pallet<R>>::author() {
let _numeric_amount = amount.peek();
<pallet_balances::Pallet<R>>::resolve_creating(&author, amount);
}
}
}
};
}

#[macro_export]
macro_rules! impl_deal_with_fees {
() => {
pub struct DealWithFees<R>(sp_std::marker::PhantomData<R>);
impl<R> OnUnbalanced<NegativeImbalance<R>> for DealWithFees<R>
where
R: pallet_balances::Config + pallet_treasury::Config + pallet_authorship::Config,
pallet_treasury::Pallet<R>: OnUnbalanced<NegativeImbalance<R>>,
<R as frame_system::Config>::RuntimeEvent: From<pallet_balances::Event<R>>,
{
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance<R>>) {
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);
}

<pallet_treasury::Pallet<R> as OnUnbalanced<_>>::on_unbalanced(split.0);
<ToAuthor<R> as OnUnbalanced<_>>::on_unbalanced(split.1);
}
}
}
};
}
133 changes: 133 additions & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<bool> {
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::<Runtime>(
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);
Expand Down
90 changes: 8 additions & 82 deletions runtime/mainnet/src/frontier_evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}

Expand All @@ -48,87 +47,12 @@ impl<F: FindAuthor<u32>> FindAuthor<H160> for FindAuthorTruncated<F> {
}
}

#[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<bool> {
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::<Runtime>(
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<Runtime> = WebbPrecompiles::<_>::new();
}
Expand Down Expand Up @@ -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);
}
Expand Down
Loading