Skip to content

Commit

Permalink
feat: Add enable-relayer flag to fuel-core CLI (#1279)
Browse files Browse the repository at this point in the history
Related issues:
- #1236

This PR adds a new CLI flag to enable the Relayer service
`--enable-relayer`, and disable the Relayer service by default.

When supplying the `--enable-relayer` flag, the `--relayer` argument
becomes mandatory, and omitting it is an error. Similarly, providing a
`--relayer` argument without the `--enable-relayer` flag is an error.

Lastly, providing the `--keypair` or `--network` arguments will also
produce an error if the `--enable-p2p` flag is not set.
  • Loading branch information
Brandon Vrooman authored Aug 15, 2023
1 parent 6dbe2dd commit c522c60
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 109 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Description of the upcoming release here.
- [#1293](https://github.com/FuelLabs/fuel-core/issues/1293): Parallelized the `estimate_predicates` endpoint to utilize all available threads.

#### Breaking
- [#1279](https://github.com/FuelLabs/fuel-core/pull/1279): Added a new CLI flag to enable the Relayer service `--enable-relayer`, and disabled the Relayer service by default. When supplying the `--enable-relayer` flag, the `--relayer` argument becomes mandatory, and omitting it is an error. Similarly, providing a `--relayer` argument without the `--enable-relayer` flag is an error. Lastly, providing the `--keypair` or `--network` arguments will also produce an error if the `--enable-p2p` flag is not set.
- [#1262](https://github.com/FuelLabs/fuel-core/pull/1262): The `ConsensusParameters` aggregates all configuration data related to the consensus. It contains many fields that are segregated by the usage. The API of some functions was affected to use lesser types instead the whole `ConsensusParameters`. It is a huge breaking change requiring repetitively monotonically updating all places that use the `ConsensusParameters`. But during updating, consider that maybe you can use lesser types. Usage of them may simplify signatures of methods and make them more user-friendly and transparent.
- [#1290](https://github.com/FuelLabs/fuel-core/pull/1290): Standardize CLI args to use `-` instead of `_`

Expand Down
12 changes: 8 additions & 4 deletions bin/fuel-core/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ pub struct Command {
#[arg(long = "coinbase-recipient", env)]
pub coinbase_recipient: Option<String>,

#[cfg_attr(feature = "relayer", clap(flatten))]
#[cfg(feature = "relayer")]
#[clap(flatten)]
pub relayer_args: relayer::RelayerArgs,

#[cfg_attr(feature = "p2p", clap(flatten))]
Expand Down Expand Up @@ -236,6 +236,9 @@ impl Command {

let chain_conf: ChainConfig = chain_config.as_str().parse()?;

#[cfg(feature = "relayer")]
let relayer_cfg = relayer_args.into_config();

#[cfg(feature = "p2p")]
let p2p_cfg = p2p_args.into_config(metrics)?;

Expand Down Expand Up @@ -314,7 +317,7 @@ impl Command {
block_executor: Default::default(),
block_importer: Default::default(),
#[cfg(feature = "relayer")]
relayer: relayer_args.into(),
relayer: relayer_cfg,
#[cfg(feature = "p2p")]
p2p: p2p_cfg,
#[cfg(feature = "p2p")]
Expand Down Expand Up @@ -342,8 +345,9 @@ pub async fn exec(command: Command) -> anyhow::Result<()> {
.unwrap_or_else(|| "default_network".to_string())
}
#[cfg(not(feature = "p2p"))]
"default_network".to_string()
};
"default_network"
}
.to_string();
// log fuel-core version
info!("Fuel Core version v{}", env!("CARGO_PKG_VERSION"));
trace!("Initializing in TRACE mode.");
Expand Down
169 changes: 86 additions & 83 deletions bin/fuel-core/src/cli/run/p2p.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use anyhow::anyhow;
use clap::Args;
use clap::{
builder::ArgPredicate::IsPresent,
Args,
};
use fuel_core::{
p2p::{
config::{
Expand Down Expand Up @@ -34,17 +37,19 @@ const MAX_RESPONSE_SIZE_STR: &str = const_format::formatcp!("{MAX_RESPONSE_SIZE}
pub struct P2PArgs {
/// Enable P2P. By default, P2P is disabled, even when the binary is compiled with the "p2p"
/// feature flag. Providing `--enable-p2p` will enable the P2P service.
#[clap(long, short, action)]
#[clap(long = "enable-p2p", action)]
pub enable_p2p: bool,

/// Peering secret key. Supports either a hex encoded secret key inline or a path to bip32 mnemonic encoded secret file.
#[clap(long = "keypair", env, value_parser = KeypairArg::try_from_string)]
#[arg(required_if_eq("enable_p2p", "true"))]
#[arg(requires_if(IsPresent, "enable_p2p"))]
pub keypair: Option<KeypairArg>,

/// The name of the p2p Network
#[clap(long = "network", env)]
#[arg(required_if_eq("enable_p2p", "true"))]
#[arg(requires_if(IsPresent, "enable_p2p"))]
pub network: Option<String>,

/// p2p network's IP Address
Expand Down Expand Up @@ -217,88 +222,86 @@ impl P2PArgs {
self,
metrics: bool,
) -> anyhow::Result<Option<Config<NotInitialized>>> {
if self.enable_p2p {
let local_keypair = {
match self.keypair.expect("mandatory value") {
KeypairArg::Path(path) => {
let phrase = std::fs::read_to_string(path)?;
let secret_key =
fuel_crypto::SecretKey::new_from_mnemonic_phrase_with_path(
&phrase,
"m/44'/60'/0'/0/0",
)?;

convert_to_libp2p_keypair(&mut secret_key.to_vec())?
}
KeypairArg::InlineSecret(secret_key) => {
convert_to_libp2p_keypair(&mut secret_key.to_vec())?
}
}
};

let gossipsub_config = default_gossipsub_builder()
.mesh_n(self.ideal_mesh_size)
.mesh_n_low(self.min_mesh_size)
.mesh_n_high(self.max_mesh_size)
.history_length(self.history_length)
.history_gossip(self.history_gossip)
.heartbeat_interval(Duration::from_secs(self.gossip_heartbeat_interval))
.max_transmit_size(self.max_transmit_size)
.build()
.expect("valid gossipsub configuration");

let random_walk = if self.random_walk == 0 {
None
} else {
Some(Duration::from_secs(self.random_walk))
};

let heartbeat_config = {
let send_duration = Duration::from_secs(self.heartbeat_send_duration);
let idle_duration = Duration::from_secs(self.heartbeat_idle_duration);
HeartbeatConfig::new(
send_duration,
idle_duration,
self.heartbeat_max_failures,
)
};

let config = Config {
keypair: local_keypair,
network_name: self.network.expect("mandatory value"),
checksum: Default::default(),
address: self
.address
.unwrap_or_else(|| IpAddr::V4(Ipv4Addr::from([0, 0, 0, 0]))),
public_address: self.public_address,
tcp_port: self.peering_port,
max_block_size: self.max_block_size,
bootstrap_nodes: self.bootstrap_nodes,
reserved_nodes: self.reserved_nodes,
reserved_nodes_only_mode: self.reserved_nodes_only_mode,
enable_mdns: self.enable_mdns,
max_peers_connected: self.max_peers_connected,
max_connections_per_peer: self.max_connections_per_peer,
allow_private_addresses: self.allow_private_addresses,
random_walk,
connection_idle_timeout: Some(Duration::from_secs(
self.connection_idle_timeout,
)),
gossipsub_config,
heartbeat_config,
set_request_timeout: Duration::from_secs(self.request_timeout),
set_connection_keep_alive: Duration::from_secs(
self.connection_keep_alive,
),
info_interval: Some(Duration::from_secs(self.info_interval)),
identify_interval: Some(Duration::from_secs(self.identify_interval)),
metrics,
state: NotInitialized,
};
Ok(Some(config))
} else {
if !self.enable_p2p {
tracing::info!("P2P service disabled");
Ok(None)
return Ok(None)
}

let local_keypair = {
match self.keypair.expect("mandatory value") {
KeypairArg::Path(path) => {
let phrase = std::fs::read_to_string(path)?;
let secret_key =
fuel_crypto::SecretKey::new_from_mnemonic_phrase_with_path(
&phrase,
"m/44'/60'/0'/0/0",
)?;

convert_to_libp2p_keypair(&mut secret_key.to_vec())?
}
KeypairArg::InlineSecret(secret_key) => {
convert_to_libp2p_keypair(&mut secret_key.to_vec())?
}
}
};

let gossipsub_config = default_gossipsub_builder()
.mesh_n(self.ideal_mesh_size)
.mesh_n_low(self.min_mesh_size)
.mesh_n_high(self.max_mesh_size)
.history_length(self.history_length)
.history_gossip(self.history_gossip)
.heartbeat_interval(Duration::from_secs(self.gossip_heartbeat_interval))
.max_transmit_size(self.max_transmit_size)
.build()
.expect("valid gossipsub configuration");

let random_walk = if self.random_walk == 0 {
None
} else {
Some(Duration::from_secs(self.random_walk))
};

let heartbeat_config = {
let send_duration = Duration::from_secs(self.heartbeat_send_duration);
let idle_duration = Duration::from_secs(self.heartbeat_idle_duration);
HeartbeatConfig::new(
send_duration,
idle_duration,
self.heartbeat_max_failures,
)
};

let config = Config {
keypair: local_keypair,
network_name: self.network.expect("mandatory value"),
checksum: Default::default(),
address: self
.address
.unwrap_or_else(|| IpAddr::V4(Ipv4Addr::from([0, 0, 0, 0]))),
public_address: self.public_address,
tcp_port: self.peering_port,
max_block_size: self.max_block_size,
bootstrap_nodes: self.bootstrap_nodes,
reserved_nodes: self.reserved_nodes,
reserved_nodes_only_mode: self.reserved_nodes_only_mode,
enable_mdns: self.enable_mdns,
max_peers_connected: self.max_peers_connected,
max_connections_per_peer: self.max_connections_per_peer,
allow_private_addresses: self.allow_private_addresses,
random_walk,
connection_idle_timeout: Some(Duration::from_secs(
self.connection_idle_timeout,
)),
gossipsub_config,
heartbeat_config,
set_request_timeout: Duration::from_secs(self.request_timeout),
set_connection_keep_alive: Duration::from_secs(self.connection_keep_alive),
info_interval: Some(Duration::from_secs(self.info_interval)),
identify_interval: Some(Duration::from_secs(self.identify_interval)),
metrics,
state: NotInitialized,
};
Ok(Some(config))
}
}
43 changes: 30 additions & 13 deletions bin/fuel-core/src/cli/run/relayer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use clap::Args;
use clap::{
builder::ArgPredicate::IsPresent,
Args,
};
use core::time::Duration;
use fuel_core::{
relayer::{
Expand All @@ -11,9 +14,17 @@ use std::str::FromStr;

#[derive(Debug, Clone, Args)]
pub struct RelayerArgs {
/// Enable the Relayer. By default, the Relayer is disabled, even when the binary is compiled
/// with the "relayer" feature flag. Providing `--enable-relayer` will enable the relayer
/// service.
#[clap(long = "enable-relayer", action)]
pub enable_relayer: bool,

/// Uri address to ethereum client. It can be in format of `http://localhost:8545/` or `ws://localhost:8545/`.
/// If not set relayer will not start.
#[arg(long = "relayer", env)]
#[arg(required_if_eq("enable_relayer", "true"))]
#[arg(requires_if(IsPresent, "enable_relayer"))]
pub eth_client: Option<url::Url>,

/// Ethereum contract address. Create EthAddress into fuel_types
Expand Down Expand Up @@ -50,18 +61,24 @@ pub fn parse_h160(input: &str) -> Result<H160, <H160 as FromStr>::Err> {
H160::from_str(input)
}

impl From<RelayerArgs> for Config {
fn from(args: RelayerArgs) -> Self {
Config {
da_deploy_height: DaBlockHeight(args.da_deploy_height),
da_finalization: DaBlockHeight(args.da_finalization),
eth_client: args.eth_client,
eth_v2_listening_contracts: args.eth_v2_listening_contracts,
log_page_size: args.log_page_size,
sync_minimum_duration: Duration::from_secs(args.sync_minimum_duration_secs),
syncing_call_frequency: Duration::from_secs(args.syncing_call_frequency_secs),
syncing_log_frequency: Duration::from_secs(args.syncing_log_frequency_secs),
metrics: false,
impl RelayerArgs {
pub fn into_config(self) -> Option<Config> {
if !self.enable_relayer {
tracing::info!("Relayer service disabled");
return None
}

let config = Config {
da_deploy_height: DaBlockHeight(self.da_deploy_height),
da_finalization: DaBlockHeight(self.da_finalization),
eth_client: self.eth_client,
eth_v2_listening_contracts: self.eth_v2_listening_contracts,
log_page_size: self.log_page_size,
sync_minimum_duration: Duration::from_secs(self.sync_minimum_duration_secs),
syncing_call_frequency: Duration::from_secs(self.syncing_call_frequency_secs),
syncing_log_frequency: Duration::from_secs(self.syncing_log_frequency_secs),
metrics: false,
};
Some(config)
}
}
7 changes: 5 additions & 2 deletions crates/fuel-core/src/service/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ use fuel_core_p2p::config::{
NotInitialized,
};

#[cfg(feature = "relayer")]
use fuel_core_relayer::Config as RelayerConfig;

pub use fuel_core_poa::Trigger;

#[derive(Clone, Debug)]
Expand All @@ -46,7 +49,7 @@ pub struct Config {
pub block_executor: fuel_core_executor::Config,
pub block_importer: fuel_core_importer::Config,
#[cfg(feature = "relayer")]
pub relayer: fuel_core_relayer::Config,
pub relayer: Option<RelayerConfig>,
#[cfg(feature = "p2p")]
pub p2p: Option<P2PConfig<NotInitialized>>,
#[cfg(feature = "p2p")]
Expand Down Expand Up @@ -92,7 +95,7 @@ impl Config {
block_executor: Default::default(),
block_importer: Default::default(),
#[cfg(feature = "relayer")]
relayer: Default::default(),
relayer: None,
#[cfg(feature = "p2p")]
p2p: Some(P2PConfig::<NotInitialized>::default("test_network")),
#[cfg(feature = "p2p")]
Expand Down
14 changes: 11 additions & 3 deletions crates/fuel-core/src/service/sub_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ use fuel_core_poa::Trigger;
use std::sync::Arc;
use tokio::sync::Mutex;

#[cfg(feature = "relayer")]
use crate::relayer::Config as RelayerConfig;
#[cfg(feature = "relayer")]
use fuel_core_types::blockchain::primitives::DaBlockHeight;

pub type PoAService =
fuel_core_poa::Service<TxPoolAdapter, BlockProducerAdapter, BlockImporterAdapter>;
#[cfg(feature = "relayer")]
Expand All @@ -46,10 +51,10 @@ pub fn init_sub_services(
"The blockchain is not initialized with any block"
))?;
#[cfg(feature = "relayer")]
let relayer_service = if config.relayer.eth_client.is_some() {
let relayer_service = if let Some(config) = &config.relayer {
Some(fuel_core_relayer::new_service(
database.clone(),
config.relayer.clone(),
config.clone(),
)?)
} else {
None
Expand All @@ -60,7 +65,10 @@ pub fn init_sub_services(
#[cfg(feature = "relayer")]
relayer_synced: relayer_service.as_ref().map(|r| r.shared.clone()),
#[cfg(feature = "relayer")]
da_deploy_height: config.relayer.da_deploy_height,
da_deploy_height: config.relayer.as_ref().map_or(
DaBlockHeight(RelayerConfig::DEFAULT_DA_DEPLOY_HEIGHT),
|config| config.da_deploy_height,
),
};

let executor = ExecutorAdapter {
Expand Down
Loading

0 comments on commit c522c60

Please sign in to comment.