Skip to content

Commit

Permalink
feat(node): impl evm and eth
Browse files Browse the repository at this point in the history
  • Loading branch information
saiintbrisson committed Dec 12, 2024
1 parent fb2f014 commit bb83558
Show file tree
Hide file tree
Showing 17 changed files with 2,199 additions and 503 deletions.
1,307 changes: 935 additions & 372 deletions Cargo.lock

Large diffs are not rendered by default.

25 changes: 24 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,30 @@ test-utils.path = "./test-utils"
# Substrate
codec = { package = "parity-scale-codec", version = "3.6.12", default-features = false }
scale-info = { version = "2.11.1", default-features = false }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409-2", default-features = false }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "stable2409", default-features = false }

# Frontier
fc-api = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fc-cli = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fc-consensus = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fc-db = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fc-mapping-sync = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fc-rpc = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fc-rpc-core = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fc-storage = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fp-account = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333" }
fp-dynamic-fee = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
fp-evm = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
fp-rpc = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
fp-self-contained = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
pallet-base-fee = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
pallet-dynamic-fee = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
pallet-ethereum = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
pallet-evm = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
pallet-evm-chain-id = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
pallet-evm-precompile-modexp = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
pallet-evm-precompile-sha3fips = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }
pallet-evm-precompile-simple = { git = "https://github.com/paritytech/frontier.git", rev = "b9b1c620c8b418bdeeadc79725f9cfa4703c0333", default-features = false }

# CLI-specific dependencies
clap = { version = "4.5.22", features = ["derive"] }
Expand Down
8 changes: 2 additions & 6 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
run-localnet:
cargo xtask local --alice
# cargo xtask local --alice --chain-spec specs/local.json

# run-replica:
# cargo xtask replica --alice
run-localnet profile="--alice":
cargo xtask run local {{profile}}
18 changes: 17 additions & 1 deletion node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ clap = { workspace = true, features = ["derive"] }
futures = { workspace = true, features = ["thread-pool"] }
futures-timer.workspace = true
jsonrpsee = { workspace = true, features = ["server"] }
serde_json = { workspace = true, default-features = true }

polkadot-sdk = { workspace = true, features = [
"std",
"sc-allocator",
Expand Down Expand Up @@ -69,6 +71,7 @@ polkadot-sdk = { workspace = true, features = [
"sp-maybe-compressed-blob",
"sp-panic-handler",
"sp-rpc",
"pallet-transaction-payment-rpc",
"staging-chain-spec-builder",
"staging-node-inspect",
"staging-tracking-allocator",
Expand All @@ -78,7 +81,20 @@ polkadot-sdk = { workspace = true, features = [
"substrate-prometheus-endpoint",
"substrate-rpc-client",
] }
serde_json = { workspace = true, default-features = true }

# Frontier
fc-api.workspace = true
fc-cli.workspace = true
fc-consensus.workspace = true
fc-db.workspace = true
fc-mapping-sync.workspace = true
fc-rpc = { workspace = true, features = ["txpool"] }
fc-rpc-core.workspace = true
fc-storage.workspace = true
fp-account.workspace = true
fp-dynamic-fee = { workspace = true, features = ["default"] }
fp-evm = { workspace = true, features = ["default"] }
fp-rpc = { workspace = true, features = ["default"] }

torus-runtime.workspace = true

Expand Down
2 changes: 1 addition & 1 deletion node/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ fn testnet_genesis() -> Value {
"balances": BalancesConfig { balances },
"sudo": SudoConfig { key: Some(Sr25519Keyring::Alice.to_account_id()) },
"aura": {
"authorities": aura.iter().map(|x| (dbg!(x.public().to_string()))).collect::<Vec<_>>(),
"authorities": aura.iter().map(|x| (x.public().to_string())).collect::<Vec<_>>(),
},
"grandpa": {
"authorities": grandpa.iter().map(|x| (x.public().to_string(), 1)).collect::<Vec<_>>(),
Expand Down
7 changes: 6 additions & 1 deletion node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

use polkadot_sdk::{sc_cli::RunCmd, *};

pub mod eth;

#[derive(Clone, Copy, Debug, Default)]
pub enum Consensus {
#[default]
Expand Down Expand Up @@ -46,11 +48,14 @@ pub struct Cli {
#[command(subcommand)]
pub subcommand: Option<Subcommand>,

#[clap(long, default_value = "aura")]
#[arg(long, default_value = "aura")]
pub consensus: Consensus,

#[clap(flatten)]
pub run: RunCmd,

#[command(flatten)]
pub eth: eth::EthConfiguration,
}

#[derive(Debug, clap::Subcommand)]
Expand Down
162 changes: 162 additions & 0 deletions node/src/cli/eth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use std::{
collections::BTreeMap,
path::PathBuf,
sync::{Arc, Mutex},
time::Duration,
};

use fc_rpc::EthTask;
pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool};
pub use fc_storage::StorageOverride;
use futures::{future, prelude::*};
use polkadot_sdk::{
sc_client_api::BlockchainEvents,
sc_network_sync::SyncingService,
sc_service::{error::Error as ServiceError, Configuration, TaskManager},
};
use torus_runtime::interface::Block;

use crate::service::{FullBackend, FullClient};

pub fn db_config_dir(config: &Configuration) -> PathBuf {
config.base_path.config_dir(config.chain_spec.id())
}

/// Avalailable frontier backend types.
#[derive(Debug, Copy, Clone, Default, clap::ValueEnum)]
pub enum BackendType {
/// Either RocksDb or ParityDb as per inherited from the global backend settings.
#[default]
KeyValue,
/// Sql database with custom log indexing.
Sql,
}

/// The ethereum-compatibility configuration used to run a node.
#[derive(Clone, Debug, clap::Parser)]
pub struct EthConfiguration {
/// Maximum number of logs in a query.
#[arg(long, default_value = "10000")]
pub max_past_logs: u32,

/// Maximum fee history cache size.
#[arg(long, default_value = "2048")]
pub fee_history_limit: u64,

#[arg(long)]
pub enable_dev_signer: bool,

/// The dynamic-fee pallet target gas price set by block author
#[arg(long, default_value = "1")]
pub target_gas_price: u64,

/// Maximum allowed gas limit will be `block.gas_limit * execute_gas_limit_multiplier`
/// when using eth_call/eth_estimateGas.
#[arg(long, default_value = "10")]
pub execute_gas_limit_multiplier: u64,

/// Size in bytes of the LRU cache for block data.
#[arg(long, default_value = "50")]
pub eth_log_block_cache: usize,

/// Size in bytes of the LRU cache for transactions statuses data.
#[arg(long, default_value = "50")]
pub eth_statuses_cache: usize,

/// Sets the frontier backend type (KeyValue or Sql)
#[arg(long, value_enum, ignore_case = true, default_value_t = BackendType::default())]
pub frontier_backend_type: BackendType,

// Sets the SQL backend's pool size.
#[arg(long, default_value = "100")]
pub frontier_sql_backend_pool_size: u32,

/// Sets the SQL backend's query timeout in number of VM ops.
#[arg(long, default_value = "10000000")]
pub frontier_sql_backend_num_ops_timeout: u32,

/// Sets the SQL backend's auxiliary thread limit.
#[arg(long, default_value = "4")]
pub frontier_sql_backend_thread_count: u32,

/// Sets the SQL backend's query timeout in number of VM ops.
/// Default value is 200MB.
#[arg(long, default_value = "209715200")]
pub frontier_sql_backend_cache_size: u64,
}

pub struct FrontierPartialComponents {
pub filter_pool: Option<FilterPool>,
pub fee_history_cache: FeeHistoryCache,
pub fee_history_cache_limit: FeeHistoryCacheLimit,
}

pub fn new_frontier_partial(
config: &EthConfiguration,
) -> Result<FrontierPartialComponents, ServiceError> {
Ok(FrontierPartialComponents {
filter_pool: Some(Arc::new(Mutex::new(BTreeMap::new()))),
fee_history_cache: Arc::new(Mutex::new(BTreeMap::new())),
fee_history_cache_limit: config.fee_history_limit,
})
}

#[allow(clippy::too_many_arguments)]
pub async fn spawn_frontier_tasks(
task_manager: &TaskManager,
client: Arc<FullClient>,
backend: Arc<FullBackend>,
frontier_backend: Arc<fc_db::kv::Backend<Block, FullClient>>,
filter_pool: Option<FilterPool>,
storage_override: Arc<dyn StorageOverride<Block>>,
fee_history_cache: FeeHistoryCache,
fee_history_cache_limit: FeeHistoryCacheLimit,
sync: Arc<SyncingService<Block>>,
pubsub_notification_sinks: Arc<
fc_mapping_sync::EthereumBlockNotificationSinks<
fc_mapping_sync::EthereumBlockNotification<Block>,
>,
>,
) {
task_manager.spawn_essential_handle().spawn(
"frontier-mapping-sync-worker",
Some("frontier"),
fc_mapping_sync::kv::MappingSyncWorker::new(
client.import_notification_stream(),
Duration::new(6, 0),
client.clone(),
backend,
storage_override.clone(),
frontier_backend.clone(),
3,
0,
fc_mapping_sync::SyncStrategy::Normal,
sync,
pubsub_notification_sinks,
)
.for_each(|()| future::ready(())),
);

// Spawn Frontier EthFilterApi maintenance task.
if let Some(filter_pool) = filter_pool {
// Each filter is allowed to stay in the pool for 100 blocks.
const FILTER_RETAIN_THRESHOLD: u64 = 100;
task_manager.spawn_essential_handle().spawn(
"frontier-filter-pool",
Some("frontier"),
EthTask::filter_pool_task(client.clone(), filter_pool, FILTER_RETAIN_THRESHOLD),
);
}

// Spawn Frontier FeeHistory cache maintenance task.
task_manager.spawn_essential_handle().spawn(
"frontier-fee-history",
Some("frontier"),
EthTask::fee_history_task(
client,
storage_override,
fee_history_cache,
fee_history_cache_limit,
),
);
}
37 changes: 23 additions & 14 deletions node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
cli::{Cli, Subcommand},
service,
};
use futures::TryFutureExt;
use polkadot_sdk::{sc_cli::SubstrateCli, sc_service::PartialComponents, *};

impl SubstrateCli for Cli {
Expand Down Expand Up @@ -75,7 +76,7 @@ pub fn run() -> sc_cli::Result<()> {
task_manager,
import_queue,
..
} = service::new_partial(&config, Default::default())?;
} = service::new_partial(&config, &cli.eth, Default::default())?;
Ok((cmd.run(client, import_queue), task_manager))
})
}
Expand All @@ -86,7 +87,7 @@ pub fn run() -> sc_cli::Result<()> {
client,
task_manager,
..
} = service::new_partial(&config, Default::default())?;
} = service::new_partial(&config, &cli.eth, Default::default())?;
Ok((cmd.run(client, config.database), task_manager))
})
}
Expand All @@ -97,7 +98,7 @@ pub fn run() -> sc_cli::Result<()> {
client,
task_manager,
..
} = service::new_partial(&config, Default::default())?;
} = service::new_partial(&config, &cli.eth, Default::default())?;
Ok((cmd.run(client, config.chain_spec), task_manager))
})
}
Expand All @@ -109,7 +110,7 @@ pub fn run() -> sc_cli::Result<()> {
task_manager,
import_queue,
..
} = service::new_partial(&config, Default::default())?;
} = service::new_partial(&config, &cli.eth, Default::default())?;
Ok((cmd.run(client, import_queue), task_manager))
})
}
Expand All @@ -125,28 +126,36 @@ pub fn run() -> sc_cli::Result<()> {
task_manager,
backend,
..
} = service::new_partial(&config, Default::default())?;
} = service::new_partial(&config, &cli.eth, Default::default())?;
Ok((cmd.run(client, backend, None), task_manager))
})
}
Some(Subcommand::ChainInfo(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| cmd.run::<torus_runtime::interface::OpaqueBlock>(&config))
runner.sync_run(|config| cmd.run::<torus_runtime::interface::Block>(&config))
}
None => {
let runner = cli.create_runner(&cli.run)?;
runner.run_node_until_exit(|config| async move {
match config.network.network_backend {
sc_network::config::NetworkBackendType::Libp2p => {
service::new_full::<sc_network::NetworkWorker<_, _>>(config, cli.consensus)
.map_err(sc_cli::Error::Service)
service::new_full::<sc_network::NetworkWorker<_, _>>(
config,
cli.eth,
cli.consensus,
)
.map_err(sc_cli::Error::Service)
.await
}
sc_network::config::NetworkBackendType::Litep2p => {
service::new_full::<sc_network::Litep2pNetworkBackend>(
config,
cli.eth,
cli.consensus,
)
.map_err(sc_cli::Error::Service)
.await
}
sc_network::config::NetworkBackendType::Litep2p => service::new_full::<
sc_network::Litep2pNetworkBackend,
>(
config, cli.consensus
)
.map_err(sc_cli::Error::Service),
}
})
}
Expand Down
Loading

0 comments on commit bb83558

Please sign in to comment.