Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a --dev option #3866

Merged
merged 8 commits into from
Jul 25, 2023
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
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"))]
pistomat marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -111,12 +111,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 @@ -144,9 +147,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 @@ -180,7 +182,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 @@ -303,13 +305,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 @@ -790,6 +807,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 @@ -861,4 +880,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);
}
}
4 changes: 2 additions & 2 deletions 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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the best solution imo, even if it makes calling it slightly more verbose

) -> 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 Expand Up @@ -292,7 +292,7 @@ impl StorageInner {
trace!(target: "consensus::auto", transactions=?&block.body, "executing transactions");

let (post_state, gas_used) =
executor.execute_transactions(block, U256::ZERO, Some(senders.clone()))?;
executor.execute_transactions(block, U256::ZERO, Some(senders))?;

// apply post block changes
let post_state = executor.apply_post_block_changes(block, U256::ZERO, post_state)?;
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
Loading