Skip to content

Commit f1693f5

Browse files
authored
refactor(core): ethrex cli (#2240)
**Motivation** To improve `ethrex`'s CLI readability and extensibility. **Description** This PR refactors de CLI to use clap derive instead of clap builder approach. Using the latter suited perfectly for the first version but as we keep adding flags/args and subcommands, using the the first is better for readability and also extensibility. In the new design, the CLI is modeled as the struct `CLI` as follows: ```Rust pub struct CLI { #[clap(flatten)] pub opts: Options, #[cfg(feature = "based")] #[clap(flatten)] pub based_opts: BasedOptions, #[command(subcommand)] pub command: Option<Subcommand>, } ``` where `opts` are the flags corresponding to `ethrex` common usage, `based_opts` are the flags needed when running `ethrex` with the `based` feature, and `command` is an enum containing the subcommands (`removedb`, and `import` for now) which is optional. If you'd want to add a new subcommand, simply add it to the `Subcommand` enum and implement its handler in the `Subcommand::run` `match`. The CLI args are contained in `Options` and `BasedOptions`. Adding a new flag/arg would mean to add a field on the corresponding struct, and if you want for example to add flags/args for the L2 feature it'd be good for you to create an `L2Options` struct with them. The `#[clap(flatten)]` basically "unpacks" the struct fields (args and flags) for the CLI. Running `cargo run --release --bin ethrex -- --help` displays: ```Shell Usage: ethrex [OPTIONS] [COMMAND] Commands: removedb Remove the database import Import blocks to the database help Print this message or the help of the given subcommand(s) Options: -h, --help Print help (see a summary with '-h') -V, --version Print version RPC options: --http.addr <ADDRESS> Listening address for the http rpc server. [default: localhost] --http.port <PORT> Listening port for the http rpc server. [default: 8545] --authrpc.addr <ADDRESS> Listening address for the authenticated rpc server. [default: localhost] --authrpc.port <PORT> Listening port for the authenticated rpc server. [default: 8551] --authrpc.jwtsecret <JWTSECRET_PATH> Receives the jwt secret used for authenticated rpc requests. [default: jwt.hex] Node options: --log.level <LOG_LEVEL> Possible values: info, debug, trace, warn, error [default: INFO] --network <GENESIS_FILE_PATH> Alternatively, the name of a known network can be provided instead to use its preset genesis file and include its preset bootnodes. The networks currently supported include Holesky, Sepolia and Mekong. --datadir <DATABASE_DIRECTORY> If the datadir is the word `memory`, ethrex will use the `InMemory Engine`. [default: ethrex] --metrics.port <PROMETHEUS_METRICS_PORT> --dev If set it will be considered as `true`. The Binary has to be built with the `dev` feature enabled. --evm <EVM_BACKEND> Has to be `levm` or `revm` [default: revm] P2P options: --p2p.enabled --p2p.addr <ADDRESS> [default: 0.0.0.0] --p2p.port <PORT> [default: 30303] --discovery.addr <ADDRESS> UDP address for P2P discovery. [default: 0.0.0.0] --discovery.port <PORT> UDP port for P2P discovery. [default: 30303] --bootnodes <BOOTNODE_LIST>... Comma separated enode URLs for P2P discovery bootstrap. --syncmode <SYNC_MODE> Can be either "full" or "snap" with "full" as default value. [default: full] ```
1 parent 0b51b10 commit f1693f5

File tree

13 files changed

+529
-496
lines changed

13 files changed

+529
-496
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -181,27 +181,102 @@ For more information about the different cli arguments check out the next sectio
181181

182182
### CLI Commands
183183

184-
ethrex supports the following command line arguments:
185-
- `--network <FILE>`: Receives a `Genesis` struct in json format. This is the only argument which is required. You can look at some example genesis files at `test_data/genesis*`. Alternatively, the name of a known network can be provided instead to use its preset genesis file and include its preset bootnodes. The networks currenlty supported include Holesky, Sepolia and Ephemery.
186-
- `--datadir <DIRECTORY>`: Receives the name of the directory where the Database is located.
187-
- If the datadir is the word `memory`, ethrex will use the `InMemory Engine`.
188-
- `--import <FILE>`: Receives an rlp encoded `Chain` object (aka a list of `Block`s). You can look at the example chain file at `test_data/chain.rlp`.
189-
- `--http.addr <ADDRESS>`: Listening address for the http rpc server. Default value: localhost.
190-
- `--http.port <PORT>`: Listening port for the http rpc server. Default value: 8545.
191-
- `--authrpc.addr <ADDRESS>`: Listening address for the authenticated rpc server. Default value: localhost.
192-
- `--authrpc.port <PORT>`: Listening port for the authenticated rpc server. Default value: 8551.
193-
- `--authrpc.jwtsecret <FILE>`: Receives the jwt secret used for authenticated rpc requests. Default value: jwt.hex.
194-
- `--p2p.addr <ADDRESS>`: Default value: 0.0.0.0.
195-
- `--p2p.port <PORT>`: Default value: 30303.
196-
- `--discovery.addr <ADDRESS>`: UDP address for P2P discovery. Default value: 0.0.0.0.
197-
- `--discovery.port <PORT>`: UDP port for P2P discovery. Default value: 30303.
198-
- `--bootnodes <BOOTNODE_LIST>`: Comma separated enode URLs for P2P discovery bootstrap.
199-
- `--log.level <LOG_LEVEL>`: The verbosity level used for logs. Default value: info. possible values: info, debug, trace, warn, error
200-
- `--syncmode <SYNC_MODE>`: The way in which the node will sync its state. Can be either "full" or "snap" with "full" as default value.
201-
- `--dev`: Used to create blocks without requiring a Consensus Client. Default value: false.
202-
- If set it will be considered as `true`.
203-
- The Binary has to be built with the `dev` feature enabled.
204-
- `--evm <EVM_BACKEND>`: Has to be `levm` or `revm`. Default value: `revm`.
184+
```
185+
> cargo run --release --bin ethrex -- --help
186+
187+
Usage: ethrex [OPTIONS] [COMMAND]
188+
189+
Commands:
190+
removedb Remove the database
191+
import Import blocks to the database
192+
help Print this message or the help of the given subcommand(s)
193+
194+
Options:
195+
-h, --help
196+
Print help (see a summary with '-h')
197+
198+
-V, --version
199+
Print version
200+
201+
RPC options:
202+
--http.addr <ADDRESS>
203+
Listening address for the http rpc server.
204+
205+
[default: localhost]
206+
207+
--http.port <PORT>
208+
Listening port for the http rpc server.
209+
210+
[default: 8545]
211+
212+
--authrpc.addr <ADDRESS>
213+
Listening address for the authenticated rpc server.
214+
215+
[default: localhost]
216+
217+
--authrpc.port <PORT>
218+
Listening port for the authenticated rpc server.
219+
220+
[default: 8551]
221+
222+
--authrpc.jwtsecret <JWTSECRET_PATH>
223+
Receives the jwt secret used for authenticated rpc requests.
224+
225+
[default: jwt.hex]
226+
227+
Node options:
228+
--log.level <LOG_LEVEL>
229+
Possible values: info, debug, trace, warn, error
230+
231+
[default: INFO]
232+
233+
--network <GENESIS_FILE_PATH>
234+
Alternatively, the name of a known network can be provided instead to use its preset genesis file and include its preset bootnodes. The networks currently supported include holesky, sepolia and ephemery.
235+
236+
--datadir <DATABASE_DIRECTORY>
237+
If the datadir is the word `memory`, ethrex will use the `InMemory Engine`.
238+
239+
[default: ethrex]
240+
241+
--metrics.port <PROMETHEUS_METRICS_PORT>
242+
243+
244+
--dev
245+
If set it will be considered as `true`. The Binary has to be built with the `dev` feature enabled.
246+
247+
--evm <EVM_BACKEND>
248+
Has to be `levm` or `revm`
249+
250+
[default: revm]
251+
252+
P2P options:
253+
--p2p.enabled
254+
255+
256+
--p2p.addr <ADDRESS>
257+
[default: 0.0.0.0]
258+
259+
--p2p.port <PORT>
260+
[default: 30303]
261+
262+
--discovery.addr <ADDRESS>
263+
UDP address for P2P discovery.
264+
265+
[default: 0.0.0.0]
266+
267+
--discovery.port <PORT>
268+
UDP port for P2P discovery.
269+
270+
[default: 30303]
271+
272+
--bootnodes <BOOTNODE_LIST>...
273+
Comma separated enode URLs for P2P discovery bootstrap.
274+
275+
--syncmode <SYNC_MODE>
276+
Can be either "full" or "snap" with "full" as default value.
277+
278+
[default: full]
279+
```
205280

206281
# ethrex L2
207282

bench/criterion_benchmark.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
use criterion::{black_box, criterion_group, criterion_main, Criterion};
44
use ethrex::{
5-
import,
65
initializers::{init_blockchain, init_store},
7-
removedb,
86
utils::set_datadir,
97
DEFAULT_DATADIR,
108
};
@@ -16,18 +14,28 @@ use tracing_subscriber::{filter::Directive, EnvFilter, FmtSubscriber};
1614
fn block_import() {
1715
let data_dir = DEFAULT_DATADIR;
1816
set_datadir(data_dir);
19-
removedb::remove_db(data_dir);
17+
18+
ethrex::cli::Subcommand::RemoveDB {
19+
datadir: data_dir.to_owned(),
20+
}
21+
.run(&ethrex::cli::Options::default())
22+
.unwrap();
2023

2124
let evm_engine = "revm".to_owned().try_into().unwrap();
2225

2326
let network = "../../test_data/genesis-l2-ci.json";
2427

25-
import::import_blocks_from_datadir(
26-
data_dir.to_owned(),
27-
evm_engine,
28-
network,
29-
"../../test_data/l2-1k-erc20.rlp",
30-
);
28+
ethrex::cli::Subcommand::Import {
29+
path: "../../test_data/l2-1k-erc20.rlp".to_owned(),
30+
removedb: false,
31+
}
32+
.run(&ethrex::cli::Options {
33+
datadir: data_dir.to_owned(),
34+
network: Some(network.to_owned()),
35+
evm: evm_engine,
36+
..Default::default()
37+
})
38+
.unwrap();
3139
}
3240

3341
pub fn criterion_benchmark(c: &mut Criterion) {

cmd/ethrex/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ hex.workspace = true
2020
tracing.workspace = true
2121
tracing-subscriber.workspace = true
2222
k256.workspace = true
23-
clap = { version = "4.5.4", features = ["cargo"] }
23+
clap = { version = "4.3", features = ["derive"] }
24+
clap_complete = "4.5.17"
25+
eyre = "0.6.12"
2426
directories = "5.0.1"
2527
serde_json.workspace = true
2628
tokio = { version = "1.38.0", features = ["full"] }

0 commit comments

Comments
 (0)