Skip to content

Commit

Permalink
feat: add a --dev option (#3866)
Browse files Browse the repository at this point in the history
  • Loading branch information
pistomat authored Jul 25, 2023
1 parent 34fc89b commit 1b31a55
Show file tree
Hide file tree
Showing 12 changed files with 291 additions and 17 deletions.
99 changes: 99 additions & 0 deletions bin/reth/src/args/dev_args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//! clap [Args](clap::Args) for Dev testnet configuration
use std::time::Duration;

use clap::Args;
use humantime::parse_duration;

/// Parameters for Dev testnet configuration
#[derive(Debug, Args, PartialEq, Default, Clone, Copy)]
#[command(next_help_heading = "Dev testnet")]
pub struct DevArgs {
/// Start the node in dev mode
///
/// This mode uses a local proof-of-authority consensus engine with either fixed block times
/// or automatically mined blocks.
/// Disables network discovery and enables local http server.
/// Prefunds 20 accounts derived by mnemonic "test test test test test test test test test test
/// test junk" with 10 000 ETH each.
#[arg(long = "dev", alias = "auto-mine", help_heading = "Dev testnet", verbatim_doc_comment)]
pub dev: bool,

/// How many transactions to mine per block.
#[arg(
long = "dev.block_max_transactions",
help_heading = "Dev testnet",
conflicts_with = "block_time"
)]
pub block_max_transactions: Option<usize>,

/// Interval between blocks.
///
/// Parses strings using [humantime::parse_duration]
/// --dev.block_time 12s
#[arg(
long = "dev.block_time",
help_heading = "Dev testnet",
conflicts_with = "block_max_transactions",
value_parser = parse_duration,
verbatim_doc_comment
)]
pub block_time: Option<Duration>,
}

#[cfg(test)]
mod tests {
use super::*;
use clap::Parser;

/// A helper type to parse Args more easily
#[derive(Parser)]
struct CommandParser<T: Args> {
#[clap(flatten)]
args: T,
}

#[test]
fn test_parse_dev_args() {
let args = CommandParser::<DevArgs>::parse_from(["reth"]).args;
assert_eq!(args, DevArgs { dev: false, block_max_transactions: None, block_time: None });

let args = CommandParser::<DevArgs>::parse_from(["reth", "--dev"]).args;
assert_eq!(args, DevArgs { dev: true, block_max_transactions: None, block_time: None });

let args = CommandParser::<DevArgs>::parse_from(["reth", "--auto-mine"]).args;
assert_eq!(args, DevArgs { dev: true, block_max_transactions: None, block_time: None });

let args = CommandParser::<DevArgs>::parse_from([
"reth",
"--dev",
"--dev.block_max_transactions",
"2",
])
.args;
assert_eq!(args, DevArgs { dev: true, block_max_transactions: Some(2), block_time: None });

let args =
CommandParser::<DevArgs>::parse_from(["reth", "--dev", "--dev.block_time", "1s"]).args;
assert_eq!(
args,
DevArgs {
dev: true,
block_max_transactions: None,
block_time: Some(std::time::Duration::from_secs(1))
}
);
}

#[test]
fn test_parse_dev_args_conflicts() {
let args = CommandParser::<DevArgs>::try_parse_from([
"reth",
"--dev",
"--dev.block_max_transactions",
"2",
"--dev.block_time",
"1s",
]);
assert!(args.is_err());
}
}
4 changes: 4 additions & 0 deletions bin/reth/src/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ pub use gas_price_oracle_args::GasPriceOracleArgs;
mod txpool_args;
pub use txpool_args::TxPoolArgs;

/// DevArgs for configuring the dev testnet
mod dev_args;
pub use dev_args::DevArgs;

pub mod utils;
2 changes: 1 addition & 1 deletion bin/reth/src/args/network_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl NetworkArgs {
#[derive(Debug, Args)]
pub struct DiscoveryArgs {
/// Disable the discovery service.
#[arg(short, long)]
#[arg(short, long, default_value_if("dev", "true", "true"))]
pub disable_discovery: bool,

/// Disable the DNS discovery.
Expand Down
2 changes: 1 addition & 1 deletion bin/reth/src/args/rpc_server_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub(crate) const RPC_DEFAULT_MAX_TRACING_REQUESTS: u32 = 25;
#[command(next_help_heading = "RPC")]
pub struct RpcServerArgs {
/// Enable the HTTP-RPC server
#[arg(long)]
#[arg(long, default_value_if("dev", "true", "true"))]
pub http: bool,

/// Http server address to listen on
Expand Down
4 changes: 3 additions & 1 deletion bin/reth/src/args/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Clap parser utilities

use reth_primitives::{
fs, AllGenesisFormats, BlockHashOrNumber, ChainSpec, GOERLI, MAINNET, SEPOLIA,
fs, AllGenesisFormats, BlockHashOrNumber, ChainSpec, DEV, GOERLI, MAINNET, SEPOLIA,
};
use reth_revm::primitives::B256 as H256;
use std::{
Expand All @@ -25,6 +25,7 @@ pub fn chain_spec_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Er
"mainnet" => MAINNET.clone(),
"goerli" => GOERLI.clone(),
"sepolia" => SEPOLIA.clone(),
"dev" => DEV.clone(),
_ => {
let raw = fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?;
serde_json::from_str(&raw)?
Expand All @@ -39,6 +40,7 @@ pub fn genesis_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Error
"mainnet" => MAINNET.clone(),
"goerli" => GOERLI.clone(),
"sepolia" => SEPOLIA.clone(),
"dev" => DEV.clone(),
_ => {
let raw = fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?;
let genesis: AllGenesisFormats = serde_json::from_str(&raw)?;
Expand Down
53 changes: 45 additions & 8 deletions bin/reth/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! Starts the client
use crate::{
args::{get_secret_key, DebugArgs, NetworkArgs, RpcServerArgs, TxPoolArgs},
args::{get_secret_key, DebugArgs, DevArgs, NetworkArgs, RpcServerArgs, TxPoolArgs},
dirs::DataDirPath,
init::init_genesis,
prometheus_exporter,
Expand All @@ -14,7 +14,7 @@ use clap::Parser;
use eyre::Context;
use fdlimit::raise_fd_limit;
use futures::{future::Either, pin_mut, stream, stream_select, StreamExt};
use reth_auto_seal_consensus::{AutoSealBuilder, AutoSealConsensus};
use reth_auto_seal_consensus::{AutoSealBuilder, AutoSealConsensus, MiningMode};
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
use reth_beacon_consensus::{BeaconConsensus, BeaconConsensusEngine, MIN_BLOCKS_FOR_PIPELINE_RUN};
use reth_blockchain_tree::{
Expand Down Expand Up @@ -112,12 +112,15 @@ pub struct Command {
/// - mainnet
/// - goerli
/// - sepolia
/// - dev
#[arg(
long,
value_name = "CHAIN_OR_PATH",
verbatim_doc_comment,
default_value = "mainnet",
value_parser = genesis_value_parser
default_value_if("dev", "true", "dev"),
value_parser = genesis_value_parser,
required = false,
)]
chain: Arc<ChainSpec>,

Expand Down Expand Up @@ -145,9 +148,8 @@ pub struct Command {
#[clap(flatten)]
db: DatabaseArgs,

/// Automatically mine blocks for new transactions
#[arg(long)]
auto_mine: bool,
#[clap(flatten)]
dev: DevArgs,
}

impl Command {
Expand Down Expand Up @@ -181,7 +183,7 @@ impl Command {

info!(target: "reth::cli", "{}", DisplayHardforks::from(self.chain.hardforks().clone()));

let consensus: Arc<dyn Consensus> = if self.auto_mine {
let consensus: Arc<dyn Consensus> = if self.dev.dev {
debug!(target: "reth::cli", "Using auto seal");
Arc::new(AutoSealConsensus::new(Arc::clone(&self.chain)))
} else {
Expand Down Expand Up @@ -304,13 +306,28 @@ impl Command {
};

// Configure the pipeline
let (mut pipeline, client) = if self.auto_mine {
let (mut pipeline, client) = if self.dev.dev {
info!(target: "reth::cli", "Starting Reth in dev mode");

let mining_mode = if let Some(interval) = self.dev.block_time {
MiningMode::interval(interval)
} else if let Some(max_transactions) = self.dev.block_max_transactions {
MiningMode::instant(
max_transactions,
transaction_pool.pending_transactions_listener(),
)
} else {
info!(target: "reth::cli", "No mining mode specified, defaulting to ReadyTransaction");
MiningMode::instant(1, transaction_pool.pending_transactions_listener())
};

let (_, client, mut task) = AutoSealBuilder::new(
Arc::clone(&self.chain),
blockchain_db.clone(),
transaction_pool.clone(),
consensus_engine_tx.clone(),
canon_state_notification_sender,
mining_mode,
)
.build();

Expand Down Expand Up @@ -798,6 +815,8 @@ async fn run_network_until_shutdown<C>(

#[cfg(test)]
mod tests {
use reth_primitives::DEV;

use super::*;
use std::{net::IpAddr, path::Path};

Expand Down Expand Up @@ -869,4 +888,22 @@ mod tests {
let db_path = data_dir.db_path();
assert_eq!(db_path, Path::new("my/custom/path/db"));
}

#[test]
fn parse_dev() {
let cmd = Command::parse_from(["reth", "--dev"]);
let chain = DEV.clone();
assert_eq!(cmd.chain.chain, chain.chain);
assert_eq!(cmd.chain.genesis_hash, chain.genesis_hash);
assert_eq!(
cmd.chain.paris_block_and_final_difficulty,
chain.paris_block_and_final_difficulty
);
assert_eq!(cmd.chain.hardforks, chain.hardforks);

assert!(cmd.rpc.http);
assert!(cmd.network.discovery.disable_discovery);

assert!(cmd.dev.dev);
}
}
2 changes: 1 addition & 1 deletion crates/consensus/auto-seal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ where
pool: Pool,
to_engine: UnboundedSender<BeaconEngineMessage>,
canon_state_notification: CanonStateNotificationSender,
mode: MiningMode,
) -> Self {
let latest_header = client
.latest_header()
.ok()
.flatten()
.unwrap_or_else(|| chain_spec.sealed_genesis_header());
let mode = MiningMode::interval(std::time::Duration::from_secs(1));

Self {
storage: Storage::new(latest_header),
Expand Down
75 changes: 75 additions & 0 deletions crates/primitives/res/genesis/dev.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"nonce": "0x0",
"timestamp": "0x6490fdd2",
"extraData": "0x",
"gasLimit": "0x1c9c380",
"difficulty": "0x0",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494",
"alloc": {
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x90F79bf6EB2c4f870365E785982E1f101E93b906": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x976EA74026E726554dB657fA54763abd0C3a0aa9": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x14dC79964da2C08b23698B3D3cc7Ca32193d9955": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0xa0Ee7A142d267C1f36714E4a8F75612F20a79720": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0xBcd4042DE499D14e55001CcbB24a551F3b954096": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x71bE63f3384f5fb98995898A86B02Fb2426c5788": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0xFABB0ac9d68B0B445fB7357272Ff202C5651694a": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0xcd3B766CCDd6AE721141F452C550Ca635964ce71": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x2546BcD3c84621e976D8185a91A922aE77ECEc30": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0xbDA5747bFD65F08deb54cb465eB87D40e51B197E": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0xdD2FD4581271e230360230F9337D5c0430Bf44C0": {
"balance": "0xD3C21BCECCEDA1000000"
},
"0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199": {
"balance": "0xD3C21BCECCEDA1000000"
}
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
7 changes: 6 additions & 1 deletion crates/primitives/src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{fmt, str::FromStr};
mod spec;
pub use spec::{
AllGenesisFormats, ChainSpec, ChainSpecBuilder, DisplayHardforks, ForkCondition,
ForkTimestamps, GOERLI, MAINNET, SEPOLIA,
ForkTimestamps, DEV, GOERLI, MAINNET, SEPOLIA,
};

// The chain info module.
Expand Down Expand Up @@ -44,6 +44,11 @@ impl Chain {
Chain::Named(ethers_core::types::Chain::Sepolia)
}

/// Returns the dev chain.
pub const fn dev() -> Self {
Chain::Named(ethers_core::types::Chain::Dev)
}

/// The id of the chain
pub fn id(&self) -> u64 {
match self {
Expand Down
Loading

0 comments on commit 1b31a55

Please sign in to comment.