mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat: add secret-key command line option (#1946)
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -4447,6 +4447,7 @@ dependencies = [
|
|||||||
"eyre",
|
"eyre",
|
||||||
"fdlimit",
|
"fdlimit",
|
||||||
"futures",
|
"futures",
|
||||||
|
"hex",
|
||||||
"human_bytes",
|
"human_bytes",
|
||||||
"hyper",
|
"hyper",
|
||||||
"jsonrpsee",
|
"jsonrpsee",
|
||||||
@ -4478,10 +4479,12 @@ dependencies = [
|
|||||||
"reth-tasks",
|
"reth-tasks",
|
||||||
"reth-tracing",
|
"reth-tracing",
|
||||||
"reth-transaction-pool",
|
"reth-transaction-pool",
|
||||||
|
"secp256k1 0.26.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tui",
|
"tui",
|
||||||
|
|||||||
@ -34,6 +34,13 @@ reth-net-nat = { path = "../../crates/net/nat" }
|
|||||||
reth-miner = { path = "../../crates/miner" }
|
reth-miner = { path = "../../crates/miner" }
|
||||||
reth-discv4 = { path = "../../crates/net/discv4" }
|
reth-discv4 = { path = "../../crates/net/discv4" }
|
||||||
|
|
||||||
|
# crypto
|
||||||
|
secp256k1 = { version = "0.26.0", features = [
|
||||||
|
"global-context",
|
||||||
|
"rand-std",
|
||||||
|
"recovery",
|
||||||
|
] }
|
||||||
|
|
||||||
# tracing
|
# tracing
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
||||||
@ -72,3 +79,5 @@ eyre = "0.6.8"
|
|||||||
clap = { version = "4", features = ["derive", "cargo"] }
|
clap = { version = "4", features = ["derive", "cargo"] }
|
||||||
tempfile = { version = "3.3.0" }
|
tempfile = { version = "3.3.0" }
|
||||||
backon = "0.4"
|
backon = "0.4"
|
||||||
|
hex = "0.4"
|
||||||
|
thiserror = "1.0"
|
||||||
@ -11,3 +11,6 @@ pub use rpc_server_args::RpcServerArgs;
|
|||||||
/// DebugArgs struct for debugging purposes
|
/// DebugArgs struct for debugging purposes
|
||||||
mod debug_args;
|
mod debug_args;
|
||||||
pub use debug_args::DebugArgs;
|
pub use debug_args::DebugArgs;
|
||||||
|
|
||||||
|
mod secret_key;
|
||||||
|
pub use secret_key::{get_secret_key, SecretKeyError};
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use reth_net_nat::NatResolver;
|
|||||||
use reth_network::NetworkConfigBuilder;
|
use reth_network::NetworkConfigBuilder;
|
||||||
use reth_primitives::{mainnet_nodes, ChainSpec, NodeRecord};
|
use reth_primitives::{mainnet_nodes, ChainSpec, NodeRecord};
|
||||||
use reth_staged_sync::Config;
|
use reth_staged_sync::Config;
|
||||||
|
use secp256k1::SecretKey;
|
||||||
use std::{path::PathBuf, sync::Arc};
|
use std::{path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
/// Parameters for configuring the network more granularity via CLI
|
/// Parameters for configuring the network more granularity via CLI
|
||||||
@ -57,11 +58,12 @@ impl NetworkArgs {
|
|||||||
&self,
|
&self,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
chain_spec: Arc<ChainSpec>,
|
chain_spec: Arc<ChainSpec>,
|
||||||
|
secret_key: SecretKey,
|
||||||
) -> NetworkConfigBuilder {
|
) -> NetworkConfigBuilder {
|
||||||
let chain_bootnodes = chain_spec.chain.bootnodes().unwrap_or_else(mainnet_nodes);
|
let chain_bootnodes = chain_spec.chain.bootnodes().unwrap_or_else(mainnet_nodes);
|
||||||
|
|
||||||
let network_config_builder = config
|
let network_config_builder = config
|
||||||
.network_config(self.nat, self.persistent_peers_file())
|
.network_config(self.nat, self.persistent_peers_file(), secret_key)
|
||||||
.boot_nodes(self.bootnodes.clone().unwrap_or(chain_bootnodes))
|
.boot_nodes(self.bootnodes.clone().unwrap_or(chain_bootnodes))
|
||||||
.chain_spec(chain_spec);
|
.chain_spec(chain_spec);
|
||||||
|
|
||||||
|
|||||||
49
bin/reth/src/args/secret_key.rs
Normal file
49
bin/reth/src/args/secret_key.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use crate::dirs::{PlatformPath, SecretKeyPath};
|
||||||
|
use hex::encode as hex_encode;
|
||||||
|
use reth_network::config::rng_secret_key;
|
||||||
|
use secp256k1::{Error as SecretKeyBaseError, SecretKey};
|
||||||
|
use std::fs::read_to_string;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// Errors returned by loading a [`SecretKey`][secp256k1::SecretKey], including IO errors.
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub enum SecretKeyError {
|
||||||
|
#[error(transparent)]
|
||||||
|
SecretKeyDecodeError(#[from] SecretKeyBaseError),
|
||||||
|
#[error("An I/O error occurred: {0}")]
|
||||||
|
IOError(#[from] std::io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to load a [`SecretKey`] from a specified path. If no file exists
|
||||||
|
/// there, then it generates a secret key and stores it in the default path. I/O
|
||||||
|
/// errors might occur during write operations in the form of a
|
||||||
|
/// [`SecretKeyError`]
|
||||||
|
pub fn get_secret_key(
|
||||||
|
secret_key_path: &PlatformPath<SecretKeyPath>,
|
||||||
|
) -> Result<SecretKey, SecretKeyError> {
|
||||||
|
let fpath = secret_key_path.as_ref();
|
||||||
|
let exists = fpath.try_exists();
|
||||||
|
|
||||||
|
match exists {
|
||||||
|
Ok(true) => {
|
||||||
|
let contents = read_to_string(fpath)?;
|
||||||
|
(contents.as_str().parse::<SecretKey>()).map_err(SecretKeyError::SecretKeyDecodeError)
|
||||||
|
}
|
||||||
|
Ok(false) => {
|
||||||
|
let default_path = PlatformPath::<SecretKeyPath>::default();
|
||||||
|
let fpath = default_path.as_ref();
|
||||||
|
|
||||||
|
if let Some(dir) = fpath.parent() {
|
||||||
|
// Create parent directory
|
||||||
|
std::fs::create_dir_all(dir)?
|
||||||
|
}
|
||||||
|
|
||||||
|
let secret = rng_secret_key();
|
||||||
|
let hex = hex_encode(secret.as_ref());
|
||||||
|
std::fs::write(fpath, hex)?;
|
||||||
|
Ok(secret)
|
||||||
|
}
|
||||||
|
Err(e) => Err(SecretKeyError::IOError(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -56,6 +56,13 @@ pub fn net_dir() -> Option<PathBuf> {
|
|||||||
data_dir().map(|root| root.join("net"))
|
data_dir().map(|root| root.join("net"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the path to the reth secret key directory.
|
||||||
|
///
|
||||||
|
/// Refer to [dirs_next::data_dir] for cross-platform behavior.
|
||||||
|
pub fn p2p_secret_key_dir() -> Option<PathBuf> {
|
||||||
|
data_dir().map(|root| root.join("p2p"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the path to the reth database.
|
/// Returns the path to the reth database.
|
||||||
///
|
///
|
||||||
/// Refer to [dirs_next::data_dir] for cross-platform behavior.
|
/// Refer to [dirs_next::data_dir] for cross-platform behavior.
|
||||||
@ -121,6 +128,19 @@ impl XdgPath for LogsDir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the path to the default reth secret key directory.
|
||||||
|
///
|
||||||
|
/// Refer to [dirs_next::data_dir] for cross-platform behavior.
|
||||||
|
#[derive(Default, Debug, Clone)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub struct SecretKeyPath;
|
||||||
|
|
||||||
|
impl XdgPath for SecretKeyPath {
|
||||||
|
fn resolve() -> Option<PathBuf> {
|
||||||
|
p2p_secret_key_dir().map(|p| p.join("secret"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A small helper trait for unit structs that represent a standard path following the XDG
|
/// A small helper trait for unit structs that represent a standard path following the XDG
|
||||||
/// path specification.
|
/// path specification.
|
||||||
pub trait XdgPath {
|
pub trait XdgPath {
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
//!
|
//!
|
||||||
//! Starts the client
|
//! Starts the client
|
||||||
use crate::{
|
use crate::{
|
||||||
args::{DebugArgs, NetworkArgs, RpcServerArgs},
|
args::{get_secret_key, DebugArgs, NetworkArgs, RpcServerArgs},
|
||||||
dirs::{ConfigPath, DbPath, PlatformPath},
|
dirs::{ConfigPath, DbPath, PlatformPath, SecretKeyPath},
|
||||||
prometheus_exporter,
|
prometheus_exporter,
|
||||||
runner::CliContext,
|
runner::CliContext,
|
||||||
utils::get_single_header,
|
utils::get_single_header,
|
||||||
@ -59,6 +59,7 @@ use reth_stages::{
|
|||||||
};
|
};
|
||||||
use reth_tasks::TaskExecutor;
|
use reth_tasks::TaskExecutor;
|
||||||
use reth_transaction_pool::{EthTransactionValidator, TransactionPool};
|
use reth_transaction_pool::{EthTransactionValidator, TransactionPool};
|
||||||
|
use secp256k1::SecretKey;
|
||||||
use std::{
|
use std::{
|
||||||
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
|
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
@ -109,6 +110,12 @@ pub struct Command {
|
|||||||
)]
|
)]
|
||||||
chain: Arc<ChainSpec>,
|
chain: Arc<ChainSpec>,
|
||||||
|
|
||||||
|
/// Secret key to use for this node.
|
||||||
|
///
|
||||||
|
/// This also will deterministically set the peer ID.
|
||||||
|
#[arg(long, value_name = "PATH", global = true, required = false, default_value_t)]
|
||||||
|
p2p_secret_key: PlatformPath<SecretKeyPath>,
|
||||||
|
|
||||||
/// Enable Prometheus metrics.
|
/// Enable Prometheus metrics.
|
||||||
///
|
///
|
||||||
/// The metrics will be served at the given interface and port.
|
/// The metrics will be served at the given interface and port.
|
||||||
@ -168,8 +175,13 @@ impl Command {
|
|||||||
info!(target: "reth::cli", "Test transaction pool initialized");
|
info!(target: "reth::cli", "Test transaction pool initialized");
|
||||||
|
|
||||||
info!(target: "reth::cli", "Connecting to P2P network");
|
info!(target: "reth::cli", "Connecting to P2P network");
|
||||||
let network_config =
|
let secret_key = get_secret_key(&self.p2p_secret_key)?;
|
||||||
self.load_network_config(&config, Arc::clone(&db), ctx.task_executor.clone());
|
let network_config = self.load_network_config(
|
||||||
|
&config,
|
||||||
|
Arc::clone(&db),
|
||||||
|
ctx.task_executor.clone(),
|
||||||
|
secret_key,
|
||||||
|
);
|
||||||
let network = self
|
let network = self
|
||||||
.start_network(network_config, &ctx.task_executor, transaction_pool.clone())
|
.start_network(network_config, &ctx.task_executor, transaction_pool.clone())
|
||||||
.await?;
|
.await?;
|
||||||
@ -548,11 +560,12 @@ impl Command {
|
|||||||
config: &Config,
|
config: &Config,
|
||||||
db: Arc<Env<WriteMap>>,
|
db: Arc<Env<WriteMap>>,
|
||||||
executor: TaskExecutor,
|
executor: TaskExecutor,
|
||||||
|
secret_key: SecretKey,
|
||||||
) -> NetworkConfig<ShareableDatabase<Arc<Env<WriteMap>>>> {
|
) -> NetworkConfig<ShareableDatabase<Arc<Env<WriteMap>>>> {
|
||||||
let head = self.lookup_head(Arc::clone(&db)).expect("the head block is missing");
|
let head = self.lookup_head(Arc::clone(&db)).expect("the head block is missing");
|
||||||
|
|
||||||
self.network
|
self.network
|
||||||
.network_config(config, self.chain.clone())
|
.network_config(config, self.chain.clone(), secret_key)
|
||||||
.with_task_executor(Box::new(executor))
|
.with_task_executor(Box::new(executor))
|
||||||
.set_head(head)
|
.set_head(head)
|
||||||
.listener_addr(SocketAddr::V4(SocketAddrV4::new(
|
.listener_addr(SocketAddr::V4(SocketAddrV4::new(
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
//! P2P Debugging tool
|
//! P2P Debugging tool
|
||||||
use crate::{
|
use crate::{
|
||||||
args::DiscoveryArgs,
|
args::{get_secret_key, DiscoveryArgs},
|
||||||
dirs::{ConfigPath, PlatformPath},
|
dirs::{ConfigPath, PlatformPath, SecretKeyPath},
|
||||||
utils::get_single_header,
|
utils::get_single_header,
|
||||||
};
|
};
|
||||||
use backon::{ConstantBuilder, Retryable};
|
use backon::{ConstantBuilder, Retryable};
|
||||||
@ -41,6 +41,12 @@ pub struct Command {
|
|||||||
)]
|
)]
|
||||||
chain: Arc<ChainSpec>,
|
chain: Arc<ChainSpec>,
|
||||||
|
|
||||||
|
/// Secret key to use for this node.
|
||||||
|
///
|
||||||
|
/// This also will deterministically set the peer ID.
|
||||||
|
#[arg(long, value_name = "PATH", global = true, required = false, default_value_t)]
|
||||||
|
p2p_secret_key: PlatformPath<SecretKeyPath>,
|
||||||
|
|
||||||
/// Disable the discovery service.
|
/// Disable the discovery service.
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
pub discovery: DiscoveryArgs,
|
pub discovery: DiscoveryArgs,
|
||||||
@ -98,8 +104,10 @@ impl Command {
|
|||||||
|
|
||||||
config.peers.connect_trusted_nodes_only = self.trusted_only;
|
config.peers.connect_trusted_nodes_only = self.trusted_only;
|
||||||
|
|
||||||
|
let p2p_secret_key = get_secret_key(&self.p2p_secret_key)?;
|
||||||
|
|
||||||
let mut network_config_builder =
|
let mut network_config_builder =
|
||||||
config.network_config(self.nat, None).chain_spec(self.chain.clone());
|
config.network_config(self.nat, None, p2p_secret_key).chain_spec(self.chain.clone());
|
||||||
|
|
||||||
network_config_builder = self.discovery.apply_to_builder(network_config_builder);
|
network_config_builder = self.discovery.apply_to_builder(network_config_builder);
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
//!
|
//!
|
||||||
//! Stage debugging tool
|
//! Stage debugging tool
|
||||||
use crate::{
|
use crate::{
|
||||||
args::NetworkArgs,
|
args::{get_secret_key, NetworkArgs},
|
||||||
dirs::{ConfigPath, DbPath, PlatformPath},
|
dirs::{ConfigPath, DbPath, PlatformPath, SecretKeyPath},
|
||||||
prometheus_exporter, StageEnum,
|
prometheus_exporter, StageEnum,
|
||||||
};
|
};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
@ -56,6 +56,12 @@ pub struct Command {
|
|||||||
)]
|
)]
|
||||||
chain: Arc<ChainSpec>,
|
chain: Arc<ChainSpec>,
|
||||||
|
|
||||||
|
/// Secret key to use for this node.
|
||||||
|
///
|
||||||
|
/// This also will deterministically set the peer ID.
|
||||||
|
#[arg(long, value_name = "PATH", global = true, required = false, default_value_t)]
|
||||||
|
p2p_secret_key: PlatformPath<SecretKeyPath>,
|
||||||
|
|
||||||
/// Enable Prometheus metrics.
|
/// Enable Prometheus metrics.
|
||||||
///
|
///
|
||||||
/// The metrics will be served at the given interface and port.
|
/// The metrics will be served at the given interface and port.
|
||||||
@ -125,9 +131,11 @@ impl Command {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let p2p_secret_key = get_secret_key(&self.p2p_secret_key)?;
|
||||||
|
|
||||||
let network = self
|
let network = self
|
||||||
.network
|
.network
|
||||||
.network_config(&config, self.chain.clone())
|
.network_config(&config, self.chain.clone(), p2p_secret_key)
|
||||||
.build(Arc::new(ShareableDatabase::new(db.clone(), self.chain.clone())))
|
.build(Arc::new(ShareableDatabase::new(db.clone(), self.chain.clone())))
|
||||||
.start_network()
|
.start_network()
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@ -30,6 +30,11 @@ tracing = "0.1.37"
|
|||||||
|
|
||||||
# crypto
|
# crypto
|
||||||
rand = { version = "0.8", optional = true }
|
rand = { version = "0.8", optional = true }
|
||||||
|
secp256k1 = { version = "0.26.0", features = [
|
||||||
|
"global-context",
|
||||||
|
"rand-std",
|
||||||
|
"recovery",
|
||||||
|
] }
|
||||||
|
|
||||||
# errors
|
# errors
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
|
|||||||
@ -4,7 +4,8 @@ use reth_downloaders::{
|
|||||||
bodies::bodies::BodiesDownloaderBuilder,
|
bodies::bodies::BodiesDownloaderBuilder,
|
||||||
headers::reverse_headers::ReverseHeadersDownloaderBuilder,
|
headers::reverse_headers::ReverseHeadersDownloaderBuilder,
|
||||||
};
|
};
|
||||||
use reth_network::{config::rng_secret_key, NetworkConfigBuilder, PeersConfig};
|
use reth_network::{NetworkConfigBuilder, PeersConfig};
|
||||||
|
use secp256k1::SecretKey;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
@ -25,15 +26,17 @@ impl Config {
|
|||||||
&self,
|
&self,
|
||||||
nat_resolution_method: reth_net_nat::NatResolver,
|
nat_resolution_method: reth_net_nat::NatResolver,
|
||||||
peers_file: Option<PathBuf>,
|
peers_file: Option<PathBuf>,
|
||||||
|
secret_key: SecretKey,
|
||||||
) -> NetworkConfigBuilder {
|
) -> NetworkConfigBuilder {
|
||||||
let peer_config = self
|
let peer_config = self
|
||||||
.peers
|
.peers
|
||||||
.clone()
|
.clone()
|
||||||
.with_basic_nodes_from_file(peers_file)
|
.with_basic_nodes_from_file(peers_file)
|
||||||
.unwrap_or_else(|_| self.peers.clone());
|
.unwrap_or_else(|_| self.peers.clone());
|
||||||
|
|
||||||
let discv4 =
|
let discv4 =
|
||||||
Discv4Config::builder().external_ip_resolver(Some(nat_resolution_method)).clone();
|
Discv4Config::builder().external_ip_resolver(Some(nat_resolution_method)).clone();
|
||||||
NetworkConfigBuilder::new(rng_secret_key()).peer_config(peer_config).discovery(discv4)
|
NetworkConfigBuilder::new(secret_key).peer_config(peer_config).discovery(discv4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user