mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
implement part of reth p2p rlpx ping (#9762)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -6560,11 +6560,14 @@ dependencies = [
|
||||
"reth-db-common",
|
||||
"reth-discv4",
|
||||
"reth-downloaders",
|
||||
"reth-ecies",
|
||||
"reth-eth-wire",
|
||||
"reth-evm",
|
||||
"reth-exex",
|
||||
"reth-fs-util",
|
||||
"reth-network",
|
||||
"reth-network-p2p",
|
||||
"reth-network-peers",
|
||||
"reth-node-builder",
|
||||
"reth-node-core",
|
||||
"reth-node-events",
|
||||
@ -6577,6 +6580,7 @@ dependencies = [
|
||||
"reth-static-file-types",
|
||||
"reth-trie",
|
||||
"reth-trie-db",
|
||||
"secp256k1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
|
||||
@ -62,6 +62,8 @@
|
||||
- [`reth p2p`](./cli/reth/p2p.md)
|
||||
- [`reth p2p header`](./cli/reth/p2p/header.md)
|
||||
- [`reth p2p body`](./cli/reth/p2p/body.md)
|
||||
- [`reth p2p rlpx`](./cli/reth/p2p/rlpx.md)
|
||||
- [`reth p2p rlpx ping`](./cli/reth/p2p/rlpx/ping.md)
|
||||
- [`reth config`](./cli/reth/config.md)
|
||||
- [`reth debug`](./cli/reth/debug.md)
|
||||
- [`reth debug execution`](./cli/reth/debug/execution.md)
|
||||
|
||||
2
book/cli/SUMMARY.md
vendored
2
book/cli/SUMMARY.md
vendored
@ -32,6 +32,8 @@
|
||||
- [`reth p2p`](./reth/p2p.md)
|
||||
- [`reth p2p header`](./reth/p2p/header.md)
|
||||
- [`reth p2p body`](./reth/p2p/body.md)
|
||||
- [`reth p2p rlpx`](./reth/p2p/rlpx.md)
|
||||
- [`reth p2p rlpx ping`](./reth/p2p/rlpx/ping.md)
|
||||
- [`reth config`](./reth/config.md)
|
||||
- [`reth debug`](./reth/debug.md)
|
||||
- [`reth debug execution`](./reth/debug/execution.md)
|
||||
|
||||
1
book/cli/reth/p2p.md
vendored
1
book/cli/reth/p2p.md
vendored
@ -9,6 +9,7 @@ Usage: reth p2p [OPTIONS] <COMMAND>
|
||||
Commands:
|
||||
header Download block header
|
||||
body Download block body
|
||||
rlpx RLPx commands
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
|
||||
104
book/cli/reth/p2p/rlpx.md
vendored
Normal file
104
book/cli/reth/p2p/rlpx.md
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
# reth p2p rlpx
|
||||
|
||||
RLPx commands
|
||||
|
||||
```bash
|
||||
$ reth p2p rlpx --help
|
||||
Usage: reth p2p rlpx [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
ping ping node
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
--instance <INSTANCE>
|
||||
Add a new instance of a node.
|
||||
|
||||
Configures the ports of the node to avoid conflicts with the defaults. This is useful for running multiple nodes on the same machine.
|
||||
|
||||
Max number of instances is 200. It is chosen in a way so that it's not possible to have port numbers that conflict with each other.
|
||||
|
||||
Changes to the following port numbers: - `DISCOVERY_PORT`: default + `instance` - 1 - `AUTH_PORT`: default + `instance` * 100 - 100 - `HTTP_RPC_PORT`: default - `instance` + 1 - `WS_RPC_PORT`: default + `instance` * 2 - 2
|
||||
|
||||
[default: 1]
|
||||
|
||||
-h, --help
|
||||
Print help (see a summary with '-h')
|
||||
|
||||
Logging:
|
||||
--log.stdout.format <FORMAT>
|
||||
The format to use for logs written to stdout
|
||||
|
||||
[default: terminal]
|
||||
|
||||
Possible values:
|
||||
- json: Represents JSON formatting for logs. This format outputs log records as JSON objects, making it suitable for structured logging
|
||||
- log-fmt: Represents logfmt (key=value) formatting for logs. This format is concise and human-readable, typically used in command-line applications
|
||||
- terminal: Represents terminal-friendly formatting for logs
|
||||
|
||||
--log.stdout.filter <FILTER>
|
||||
The filter to use for logs written to stdout
|
||||
|
||||
[default: ]
|
||||
|
||||
--log.file.format <FORMAT>
|
||||
The format to use for logs written to the log file
|
||||
|
||||
[default: terminal]
|
||||
|
||||
Possible values:
|
||||
- json: Represents JSON formatting for logs. This format outputs log records as JSON objects, making it suitable for structured logging
|
||||
- log-fmt: Represents logfmt (key=value) formatting for logs. This format is concise and human-readable, typically used in command-line applications
|
||||
- terminal: Represents terminal-friendly formatting for logs
|
||||
|
||||
--log.file.filter <FILTER>
|
||||
The filter to use for logs written to the log file
|
||||
|
||||
[default: debug]
|
||||
|
||||
--log.file.directory <PATH>
|
||||
The path to put log files in
|
||||
|
||||
[default: <CACHE_DIR>/logs]
|
||||
|
||||
--log.file.max-size <SIZE>
|
||||
The maximum size (in MB) of one log file
|
||||
|
||||
[default: 200]
|
||||
|
||||
--log.file.max-files <COUNT>
|
||||
The maximum amount of log files that will be stored. If set to 0, background file logging is disabled
|
||||
|
||||
[default: 5]
|
||||
|
||||
--log.journald
|
||||
Write logs to journald
|
||||
|
||||
--log.journald.filter <FILTER>
|
||||
The filter to use for logs written to journald
|
||||
|
||||
[default: error]
|
||||
|
||||
--color <COLOR>
|
||||
Sets whether or not the formatter emits ANSI terminal escape codes for colors and other text formatting
|
||||
|
||||
[default: always]
|
||||
|
||||
Possible values:
|
||||
- always: Colors on
|
||||
- auto: Colors on
|
||||
- never: Colors off
|
||||
|
||||
Display:
|
||||
-v, --verbosity...
|
||||
Set the minimum log level.
|
||||
|
||||
-v Errors
|
||||
-vv Warnings
|
||||
-vvv Info
|
||||
-vvvv Debug
|
||||
-vvvvv Traces (warning: very verbose!)
|
||||
|
||||
-q, --quiet
|
||||
Silence all log output
|
||||
```
|
||||
104
book/cli/reth/p2p/rlpx/ping.md
vendored
Normal file
104
book/cli/reth/p2p/rlpx/ping.md
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
# reth p2p rlpx ping
|
||||
|
||||
ping node
|
||||
|
||||
```bash
|
||||
$ reth p2p rlpx ping --help
|
||||
Usage: reth p2p rlpx ping [OPTIONS] <NODE>
|
||||
|
||||
Arguments:
|
||||
<NODE>
|
||||
The node to ping
|
||||
|
||||
Options:
|
||||
--instance <INSTANCE>
|
||||
Add a new instance of a node.
|
||||
|
||||
Configures the ports of the node to avoid conflicts with the defaults. This is useful for running multiple nodes on the same machine.
|
||||
|
||||
Max number of instances is 200. It is chosen in a way so that it's not possible to have port numbers that conflict with each other.
|
||||
|
||||
Changes to the following port numbers: - `DISCOVERY_PORT`: default + `instance` - 1 - `AUTH_PORT`: default + `instance` * 100 - 100 - `HTTP_RPC_PORT`: default - `instance` + 1 - `WS_RPC_PORT`: default + `instance` * 2 - 2
|
||||
|
||||
[default: 1]
|
||||
|
||||
-h, --help
|
||||
Print help (see a summary with '-h')
|
||||
|
||||
Logging:
|
||||
--log.stdout.format <FORMAT>
|
||||
The format to use for logs written to stdout
|
||||
|
||||
[default: terminal]
|
||||
|
||||
Possible values:
|
||||
- json: Represents JSON formatting for logs. This format outputs log records as JSON objects, making it suitable for structured logging
|
||||
- log-fmt: Represents logfmt (key=value) formatting for logs. This format is concise and human-readable, typically used in command-line applications
|
||||
- terminal: Represents terminal-friendly formatting for logs
|
||||
|
||||
--log.stdout.filter <FILTER>
|
||||
The filter to use for logs written to stdout
|
||||
|
||||
[default: ]
|
||||
|
||||
--log.file.format <FORMAT>
|
||||
The format to use for logs written to the log file
|
||||
|
||||
[default: terminal]
|
||||
|
||||
Possible values:
|
||||
- json: Represents JSON formatting for logs. This format outputs log records as JSON objects, making it suitable for structured logging
|
||||
- log-fmt: Represents logfmt (key=value) formatting for logs. This format is concise and human-readable, typically used in command-line applications
|
||||
- terminal: Represents terminal-friendly formatting for logs
|
||||
|
||||
--log.file.filter <FILTER>
|
||||
The filter to use for logs written to the log file
|
||||
|
||||
[default: debug]
|
||||
|
||||
--log.file.directory <PATH>
|
||||
The path to put log files in
|
||||
|
||||
[default: <CACHE_DIR>/logs]
|
||||
|
||||
--log.file.max-size <SIZE>
|
||||
The maximum size (in MB) of one log file
|
||||
|
||||
[default: 200]
|
||||
|
||||
--log.file.max-files <COUNT>
|
||||
The maximum amount of log files that will be stored. If set to 0, background file logging is disabled
|
||||
|
||||
[default: 5]
|
||||
|
||||
--log.journald
|
||||
Write logs to journald
|
||||
|
||||
--log.journald.filter <FILTER>
|
||||
The filter to use for logs written to journald
|
||||
|
||||
[default: error]
|
||||
|
||||
--color <COLOR>
|
||||
Sets whether or not the formatter emits ANSI terminal escape codes for colors and other text formatting
|
||||
|
||||
[default: always]
|
||||
|
||||
Possible values:
|
||||
- always: Colors on
|
||||
- auto: Colors on
|
||||
- never: Colors off
|
||||
|
||||
Display:
|
||||
-v, --verbosity...
|
||||
Set the minimum log level.
|
||||
|
||||
-v Errors
|
||||
-vv Warnings
|
||||
-vvv Info
|
||||
-vvvv Debug
|
||||
-vvvvv Traces (warning: very verbose!)
|
||||
|
||||
-q, --quiet
|
||||
Silence all log output
|
||||
```
|
||||
@ -20,11 +20,14 @@ reth-db = { workspace = true, features = ["mdbx"] }
|
||||
reth-db-api.workspace = true
|
||||
reth-db-common.workspace = true
|
||||
reth-downloaders.workspace = true
|
||||
reth-ecies.workspace = true
|
||||
reth-eth-wire.workspace = true
|
||||
reth-evm.workspace = true
|
||||
reth-exex.workspace = true
|
||||
reth-fs-util.workspace = true
|
||||
reth-network = { workspace = true, features = ["serde"] }
|
||||
reth-network-p2p.workspace = true
|
||||
reth-network-peers = { workspace = true, features = ["secp256k1"] }
|
||||
reth-node-builder.workspace = true
|
||||
reth-node-core.workspace = true
|
||||
reth-node-events.workspace = true
|
||||
@ -51,6 +54,7 @@ serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
tracing.workspace = true
|
||||
backon.workspace = true
|
||||
secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery"] }
|
||||
|
||||
# io
|
||||
fdlimit.workspace = true
|
||||
|
||||
@ -18,6 +18,8 @@ use reth_node_core::{
|
||||
};
|
||||
use reth_primitives::BlockHashOrNumber;
|
||||
|
||||
mod rlpx;
|
||||
|
||||
/// `reth p2p` command
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Command {
|
||||
@ -69,10 +71,12 @@ pub enum Subcommands {
|
||||
#[arg(value_parser = hash_or_num_value_parser)]
|
||||
id: BlockHashOrNumber,
|
||||
},
|
||||
// RLPx utilities
|
||||
Rlpx(rlpx::Command),
|
||||
}
|
||||
impl Command {
|
||||
/// Execute `p2p` command
|
||||
pub async fn execute(&self) -> eyre::Result<()> {
|
||||
pub async fn execute(self) -> eyre::Result<()> {
|
||||
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain);
|
||||
let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
|
||||
|
||||
@ -152,6 +156,9 @@ impl Command {
|
||||
let body = result.into_iter().next().unwrap();
|
||||
println!("Successfully downloaded body: {body:?}")
|
||||
}
|
||||
Subcommands::Rlpx(command) => {
|
||||
command.execute().await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
51
crates/cli/commands/src/p2p/rlpx.rs
Normal file
51
crates/cli/commands/src/p2p/rlpx.rs
Normal file
@ -0,0 +1,51 @@
|
||||
//! RLPx subcommand of P2P Debugging tool.
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use reth_ecies::stream::ECIESStream;
|
||||
use reth_eth_wire::{HelloMessage, UnauthedP2PStream};
|
||||
use reth_network::config::rng_secret_key;
|
||||
use reth_network_peers::{pk2id, AnyNode};
|
||||
use secp256k1::SECP256K1;
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
/// RLPx commands
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct Command {
|
||||
#[clap(subcommand)]
|
||||
subcommand: Subcommands,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
// Execute `p2p rlpx` command.
|
||||
pub async fn execute(self) -> eyre::Result<()> {
|
||||
match self.subcommand {
|
||||
Subcommands::Ping { node } => {
|
||||
let key = rng_secret_key();
|
||||
let node_record = node
|
||||
.node_record()
|
||||
.ok_or_else(|| eyre::eyre!("failed to parse node {}", node))?;
|
||||
let outgoing =
|
||||
TcpStream::connect((node_record.address, node_record.tcp_port)).await?;
|
||||
let ecies_stream = ECIESStream::connect(outgoing, key, node_record.id).await?;
|
||||
|
||||
let peer_id = pk2id(&key.public_key(SECP256K1));
|
||||
let hello = HelloMessage::builder(peer_id).build();
|
||||
|
||||
let (_, their_hello) =
|
||||
UnauthedP2PStream::new(ecies_stream).handshake(hello).await?;
|
||||
|
||||
println!("{:#?}", their_hello);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum Subcommands {
|
||||
/// ping node
|
||||
Ping {
|
||||
/// The node to ping.
|
||||
node: AnyNode,
|
||||
},
|
||||
}
|
||||
@ -302,7 +302,7 @@ impl<S> P2PStream<S> {
|
||||
}
|
||||
|
||||
/// Queues in a _snappy_ encoded [`P2PMessage::Ping`] message.
|
||||
fn send_ping(&mut self) {
|
||||
pub fn send_ping(&mut self) {
|
||||
self.outgoing_messages.push_back(Bytes::from(alloy_rlp::encode(P2PMessage::Ping)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user