Merge branch 'eip4844' into deneb-free-blobs
This commit is contained in:
commit
4a39e43f96
@ -203,6 +203,9 @@ pub enum ProduceBlockVerification {
|
|||||||
pub struct PrePayloadAttributes {
|
pub struct PrePayloadAttributes {
|
||||||
pub proposer_index: u64,
|
pub proposer_index: u64,
|
||||||
pub prev_randao: Hash256,
|
pub prev_randao: Hash256,
|
||||||
|
/// The parent block number is not part of the payload attributes sent to the EL, but *is*
|
||||||
|
/// sent to builders via SSE.
|
||||||
|
pub parent_block_number: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Define whether a forkchoiceUpdate needs to be checked for an override (`Yes`) or has already
|
/// Define whether a forkchoiceUpdate needs to be checked for an override (`Yes`) or has already
|
||||||
@ -3977,16 +3980,21 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
proposer as u64
|
proposer as u64
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the `prev_randao` value.
|
// Get the `prev_randao` and parent block number.
|
||||||
let prev_randao = if proposer_head == parent_block_root {
|
let head_block_number = cached_head.head_block_number()?;
|
||||||
cached_head.parent_random()
|
let (prev_randao, parent_block_number) = if proposer_head == parent_block_root {
|
||||||
|
(
|
||||||
|
cached_head.parent_random()?,
|
||||||
|
head_block_number.saturating_sub(1),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
cached_head.head_random()
|
(cached_head.head_random()?, head_block_number)
|
||||||
}?;
|
};
|
||||||
|
|
||||||
Ok(Some(PrePayloadAttributes {
|
Ok(Some(PrePayloadAttributes {
|
||||||
proposer_index,
|
proposer_index,
|
||||||
prev_randao,
|
prev_randao,
|
||||||
|
parent_block_number,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5116,6 +5124,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
proposal_slot: prepare_slot,
|
proposal_slot: prepare_slot,
|
||||||
proposer_index: proposer,
|
proposer_index: proposer,
|
||||||
parent_block_root: head_root,
|
parent_block_root: head_root,
|
||||||
|
parent_block_number: pre_payload_attributes.parent_block_number,
|
||||||
parent_block_hash: forkchoice_update_params.head_hash.unwrap_or_default(),
|
parent_block_hash: forkchoice_update_params.head_hash.unwrap_or_default(),
|
||||||
payload_attributes: payload_attributes.into(),
|
payload_attributes: payload_attributes.into(),
|
||||||
},
|
},
|
||||||
|
@ -167,6 +167,17 @@ impl<E: EthSpec> CachedHead<E> {
|
|||||||
.map(|payload| payload.prev_randao())
|
.map(|payload| payload.prev_randao())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the execution block number of the block at the head of the chain.
|
||||||
|
///
|
||||||
|
/// Returns an error if the chain is prior to Bellatrix.
|
||||||
|
pub fn head_block_number(&self) -> Result<u64, BeaconStateError> {
|
||||||
|
self.snapshot
|
||||||
|
.beacon_block
|
||||||
|
.message()
|
||||||
|
.execution_payload()
|
||||||
|
.map(|payload| payload.block_number())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the active validator count for the current epoch of the head state.
|
/// Returns the active validator count for the current epoch of the head state.
|
||||||
///
|
///
|
||||||
/// Should only return `None` if the caches have not been built on the head state (this should
|
/// Should only return `None` if the caches have not been built on the head state (this should
|
||||||
|
@ -65,43 +65,43 @@ impl<T: EthSpec> ServerSentEventHandler<T> {
|
|||||||
EventKind::Attestation(_) => self
|
EventKind::Attestation(_) => self
|
||||||
.attestation_tx
|
.attestation_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "attestation")),
|
.map(|count| log_count("attestation", count)),
|
||||||
EventKind::Block(_) => self
|
EventKind::Block(_) => self
|
||||||
.block_tx
|
.block_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "block")),
|
.map(|count| log_count("block", count)),
|
||||||
EventKind::FinalizedCheckpoint(_) => self
|
EventKind::FinalizedCheckpoint(_) => self
|
||||||
.finalized_tx
|
.finalized_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "finalized checkpoint")),
|
.map(|count| log_count("finalized checkpoint", count)),
|
||||||
EventKind::Head(_) => self
|
EventKind::Head(_) => self
|
||||||
.head_tx
|
.head_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "head")),
|
.map(|count| log_count("head", count)),
|
||||||
EventKind::VoluntaryExit(_) => self
|
EventKind::VoluntaryExit(_) => self
|
||||||
.exit_tx
|
.exit_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "exit")),
|
.map(|count| log_count("exit", count)),
|
||||||
EventKind::ChainReorg(_) => self
|
EventKind::ChainReorg(_) => self
|
||||||
.chain_reorg_tx
|
.chain_reorg_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "chain reorg")),
|
.map(|count| log_count("chain reorg", count)),
|
||||||
EventKind::ContributionAndProof(_) => self
|
EventKind::ContributionAndProof(_) => self
|
||||||
.contribution_tx
|
.contribution_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "contribution and proof")),
|
.map(|count| log_count("contribution and proof", count)),
|
||||||
EventKind::PayloadAttributes(_) => self
|
EventKind::PayloadAttributes(_) => self
|
||||||
.payload_attributes_tx
|
.payload_attributes_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "payload attributes")),
|
.map(|count| log_count("payload attributes", count)),
|
||||||
EventKind::LateHead(_) => self
|
EventKind::LateHead(_) => self
|
||||||
.late_head
|
.late_head
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "late head")),
|
.map(|count| log_count("late head", count)),
|
||||||
EventKind::BlockReward(_) => self
|
EventKind::BlockReward(_) => self
|
||||||
.block_reward_tx
|
.block_reward_tx
|
||||||
.send(kind)
|
.send(kind)
|
||||||
.map(|count| log_count(count, "block reward")),
|
.map(|count| log_count("block reward", count)),
|
||||||
};
|
};
|
||||||
if let Err(SendError(event)) = result {
|
if let Err(SendError(event)) = result {
|
||||||
trace!(self.log, "No receivers registered to listen for event"; "event" => ?event);
|
trace!(self.log, "No receivers registered to listen for event"; "event" => ?event);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#![recursion_limit = "128"] // For lazy-static
|
|
||||||
pub mod attestation_rewards;
|
pub mod attestation_rewards;
|
||||||
pub mod attestation_verification;
|
pub mod attestation_verification;
|
||||||
mod attester_cache;
|
mod attester_cache;
|
||||||
|
@ -468,7 +468,7 @@ where
|
|||||||
builder_threshold: Option<u128>,
|
builder_threshold: Option<u128>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Get a random unused port
|
// Get a random unused port
|
||||||
let port = unused_port::unused_tcp_port().unwrap();
|
let port = unused_port::unused_tcp4_port().unwrap();
|
||||||
let builder_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
let builder_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
||||||
|
|
||||||
let spec = self.spec.clone().expect("cannot build without spec");
|
let spec = self.spec.clone().expect("cannot build without spec");
|
||||||
|
@ -46,9 +46,18 @@ impl<T: BeaconChainTypes> Client<T> {
|
|||||||
self.http_metrics_listen_addr
|
self.http_metrics_listen_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the port of the client's libp2p stack, if it was started.
|
/// Returns the ipv4 port of the client's libp2p stack, if it was started.
|
||||||
pub fn libp2p_listen_port(&self) -> Option<u16> {
|
pub fn libp2p_listen_ipv4_port(&self) -> Option<u16> {
|
||||||
self.network_globals.as_ref().map(|n| n.listen_port_tcp())
|
self.network_globals
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|n| n.listen_port_tcp4())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the ipv6 port of the client's libp2p stack, if it was started.
|
||||||
|
pub fn libp2p_listen_ipv6_port(&self) -> Option<u16> {
|
||||||
|
self.network_globals
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|n| n.listen_port_tcp6())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the list of libp2p addresses the client is listening to.
|
/// Returns the list of libp2p addresses the client is listening to.
|
||||||
|
@ -57,7 +57,7 @@ use types::{
|
|||||||
|
|
||||||
mod block_hash;
|
mod block_hash;
|
||||||
mod engine_api;
|
mod engine_api;
|
||||||
mod engines;
|
pub mod engines;
|
||||||
mod keccak;
|
mod keccak;
|
||||||
mod metrics;
|
mod metrics;
|
||||||
pub mod payload_cache;
|
pub mod payload_cache;
|
||||||
@ -342,6 +342,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
|
|||||||
.map_err(Error::InvalidJWTSecret)
|
.map_err(Error::InvalidJWTSecret)
|
||||||
} else {
|
} else {
|
||||||
// Create a new file and write a randomly generated secret to it if file does not exist
|
// Create a new file and write a randomly generated secret to it if file does not exist
|
||||||
|
warn!(log, "No JWT found on disk. Generating"; "path" => %secret_file.display());
|
||||||
std::fs::File::options()
|
std::fs::File::options()
|
||||||
.write(true)
|
.write(true)
|
||||||
.create_new(true)
|
.create_new(true)
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#![recursion_limit = "256"]
|
|
||||||
//! This crate contains a HTTP server which serves the endpoints listed here:
|
//! This crate contains a HTTP server which serves the endpoints listed here:
|
||||||
//!
|
//!
|
||||||
//! https://github.com/ethereum/beacon-APIs
|
//! https://github.com/ethereum/beacon-APIs
|
||||||
@ -72,7 +71,8 @@ use warp::Reply;
|
|||||||
use warp::{http::Response, Filter};
|
use warp::{http::Response, Filter};
|
||||||
use warp_utils::{
|
use warp_utils::{
|
||||||
query::multi_key_query,
|
query::multi_key_query,
|
||||||
task::{blocking_json_task, blocking_task},
|
task::{blocking_json_task, blocking_response_task},
|
||||||
|
uor::UnifyingOrFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
const API_PREFIX: &str = "eth";
|
const API_PREFIX: &str = "eth";
|
||||||
@ -1126,7 +1126,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
log: Logger| async move {
|
log: Logger| async move {
|
||||||
publish_blocks::publish_block(None, block, chain, &network_tx, log)
|
publish_blocks::publish_block(None, block, chain, &network_tx, log)
|
||||||
.await
|
.await
|
||||||
.map(|()| warp::reply())
|
.map(|()| warp::reply().into_response())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1146,7 +1146,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
log: Logger| async move {
|
log: Logger| async move {
|
||||||
publish_blocks::publish_blinded_block(block, chain, &network_tx, log)
|
publish_blocks::publish_blinded_block(block, chain, &network_tx, log)
|
||||||
.await
|
.await
|
||||||
.map(|()| warp::reply())
|
.map(|()| warp::reply().into_response())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1252,7 +1252,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
|block_id: BlockId,
|
|block_id: BlockId,
|
||||||
chain: Arc<BeaconChain<T>>,
|
chain: Arc<BeaconChain<T>>,
|
||||||
accept_header: Option<api_types::Accept>| {
|
accept_header: Option<api_types::Accept>| {
|
||||||
blocking_task(move || {
|
blocking_response_task(move || {
|
||||||
let (block, execution_optimistic) = block_id.blinded_block(&chain)?;
|
let (block, execution_optimistic) = block_id.blinded_block(&chain)?;
|
||||||
let fork_name = block
|
let fork_name = block
|
||||||
.fork_name(&chain.spec)
|
.fork_name(&chain.spec)
|
||||||
@ -1764,7 +1764,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and(eth1_service_filter.clone())
|
.and(eth1_service_filter.clone())
|
||||||
.and_then(
|
.and_then(
|
||||||
|accept_header: Option<api_types::Accept>, eth1_service: eth1::Service| {
|
|accept_header: Option<api_types::Accept>, eth1_service: eth1::Service| {
|
||||||
blocking_task(move || match accept_header {
|
blocking_response_task(move || match accept_header {
|
||||||
Some(api_types::Accept::Json) | None => {
|
Some(api_types::Accept::Json) | None => {
|
||||||
let snapshot = eth1_service.get_deposit_snapshot();
|
let snapshot = eth1_service.get_deposit_snapshot();
|
||||||
Ok(
|
Ok(
|
||||||
@ -1983,7 +1983,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
state_id: StateId,
|
state_id: StateId,
|
||||||
accept_header: Option<api_types::Accept>,
|
accept_header: Option<api_types::Accept>,
|
||||||
chain: Arc<BeaconChain<T>>| {
|
chain: Arc<BeaconChain<T>>| {
|
||||||
blocking_task(move || match accept_header {
|
blocking_response_task(move || match accept_header {
|
||||||
Some(api_types::Accept::Ssz) => {
|
Some(api_types::Accept::Ssz) => {
|
||||||
// We can ignore the optimistic status for the "fork" since it's a
|
// We can ignore the optimistic status for the "fork" since it's a
|
||||||
// specification constant that doesn't change across competing heads of the
|
// specification constant that doesn't change across competing heads of the
|
||||||
@ -1996,7 +1996,9 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.status(200)
|
.status(200)
|
||||||
.header("Content-Type", "application/octet-stream")
|
.header("Content-Type", "application/octet-stream")
|
||||||
.body(state.as_ssz_bytes().into())
|
.body(state.as_ssz_bytes().into())
|
||||||
.map(|resp| add_consensus_version_header(resp, fork_name))
|
.map(|resp: warp::reply::Response| {
|
||||||
|
add_consensus_version_header(resp, fork_name)
|
||||||
|
})
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
warp_utils::reject::custom_server_error(format!(
|
warp_utils::reject::custom_server_error(format!(
|
||||||
"failed to create response: {}",
|
"failed to create response: {}",
|
||||||
@ -2159,7 +2161,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(network_globals.clone())
|
.and(network_globals.clone())
|
||||||
.and_then(|network_globals: Arc<NetworkGlobals<T::EthSpec>>| {
|
.and_then(|network_globals: Arc<NetworkGlobals<T::EthSpec>>| {
|
||||||
blocking_task(move || match *network_globals.sync_state.read() {
|
blocking_response_task(move || match *network_globals.sync_state.read() {
|
||||||
SyncState::SyncingFinalized { .. }
|
SyncState::SyncingFinalized { .. }
|
||||||
| SyncState::SyncingHead { .. }
|
| SyncState::SyncingHead { .. }
|
||||||
| SyncState::SyncTransition
|
| SyncState::SyncTransition
|
||||||
@ -2426,7 +2428,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
build_block_contents::build_block_contents(fork_name, chain, block);
|
build_block_contents::build_block_contents(fork_name, chain, block);
|
||||||
|
|
||||||
fork_versioned_response(endpoint_version, fork_name, block_contents?)
|
fork_versioned_response(endpoint_version, fork_name, block_contents?)
|
||||||
.map(|response| warp::reply::json(&response))
|
.map(|response| warp::reply::json(&response).into_response())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2483,7 +2485,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
|
|
||||||
// Pose as a V2 endpoint so we return the fork `version`.
|
// Pose as a V2 endpoint so we return the fork `version`.
|
||||||
fork_versioned_response(V2, fork_name, block)
|
fork_versioned_response(V2, fork_name, block)
|
||||||
.map(|response| warp::reply::json(&response))
|
.map(|response| warp::reply::json(&response).into_response())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2856,7 +2858,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok::<_, warp::reject::Rejection>(warp::reply::json(&()))
|
Ok::<_, warp::reject::Rejection>(warp::reply::json(&()).into_response())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2965,7 +2967,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
builder
|
builder
|
||||||
.post_builder_validators(&filtered_registration_data)
|
.post_builder_validators(&filtered_registration_data)
|
||||||
.await
|
.await
|
||||||
.map(|resp| warp::reply::json(&resp))
|
.map(|resp| warp::reply::json(&resp).into_response())
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
warn!(
|
warn!(
|
||||||
log,
|
log,
|
||||||
@ -3227,7 +3229,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(chain_filter.clone())
|
.and(chain_filter.clone())
|
||||||
.and_then(|chain: Arc<BeaconChain<T>>| {
|
.and_then(|chain: Arc<BeaconChain<T>>| {
|
||||||
blocking_task(move || {
|
blocking_response_task(move || {
|
||||||
Ok::<_, warp::Rejection>(warp::reply::json(&api_types::GenericResponseRef::from(
|
Ok::<_, warp::Rejection>(warp::reply::json(&api_types::GenericResponseRef::from(
|
||||||
chain
|
chain
|
||||||
.canonical_head
|
.canonical_head
|
||||||
@ -3346,7 +3348,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and(warp::path::end())
|
.and(warp::path::end())
|
||||||
.and(chain_filter.clone())
|
.and(chain_filter.clone())
|
||||||
.and_then(|state_id: StateId, chain: Arc<BeaconChain<T>>| {
|
.and_then(|state_id: StateId, chain: Arc<BeaconChain<T>>| {
|
||||||
blocking_task(move || {
|
blocking_response_task(move || {
|
||||||
// This debug endpoint provides no indication of optimistic status.
|
// This debug endpoint provides no indication of optimistic status.
|
||||||
let (state, _execution_optimistic) = state_id.state(&chain)?;
|
let (state, _execution_optimistic) = state_id.state(&chain)?;
|
||||||
Response::builder()
|
Response::builder()
|
||||||
@ -3482,9 +3484,10 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and(chain_filter.clone())
|
.and(chain_filter.clone())
|
||||||
.and_then(|chain: Arc<BeaconChain<T>>| async move {
|
.and_then(|chain: Arc<BeaconChain<T>>| async move {
|
||||||
let merge_readiness = chain.check_merge_readiness().await;
|
let merge_readiness = chain.check_merge_readiness().await;
|
||||||
Ok::<_, warp::reject::Rejection>(warp::reply::json(&api_types::GenericResponse::from(
|
Ok::<_, warp::reject::Rejection>(
|
||||||
merge_readiness,
|
warp::reply::json(&api_types::GenericResponse::from(merge_readiness))
|
||||||
)))
|
.into_response(),
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// GET lighthouse/beacon/blobs_sidecars/{block_id}
|
// GET lighthouse/beacon/blobs_sidecars/{block_id}
|
||||||
@ -3530,7 +3533,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.and_then(
|
.and_then(
|
||||||
|topics_res: Result<api_types::EventQuery, warp::Rejection>,
|
|topics_res: Result<api_types::EventQuery, warp::Rejection>,
|
||||||
chain: Arc<BeaconChain<T>>| {
|
chain: Arc<BeaconChain<T>>| {
|
||||||
blocking_task(move || {
|
blocking_response_task(move || {
|
||||||
let topics = topics_res?;
|
let topics = topics_res?;
|
||||||
// for each topic subscribed spawn a new subscription
|
// for each topic subscribed spawn a new subscription
|
||||||
let mut receivers = Vec::with_capacity(topics.topics.len());
|
let mut receivers = Vec::with_capacity(topics.topics.len());
|
||||||
@ -3597,109 +3600,111 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Define the ultimate set of routes that will be provided to the server.
|
// Define the ultimate set of routes that will be provided to the server.
|
||||||
|
// Use `uor` rather than `or` in order to simplify types (see `UnifyingOrFilter`).
|
||||||
let routes = warp::get()
|
let routes = warp::get()
|
||||||
.and(
|
.and(
|
||||||
get_beacon_genesis
|
get_beacon_genesis
|
||||||
.boxed()
|
.uor(get_beacon_state_root)
|
||||||
.or(get_beacon_state_root.boxed())
|
.uor(get_beacon_state_fork)
|
||||||
.or(get_beacon_state_fork.boxed())
|
.uor(get_beacon_state_finality_checkpoints)
|
||||||
.or(get_beacon_state_finality_checkpoints.boxed())
|
.uor(get_beacon_state_validator_balances)
|
||||||
.or(get_beacon_state_validator_balances.boxed())
|
.uor(get_beacon_state_validators_id)
|
||||||
.or(get_beacon_state_validators_id.boxed())
|
.uor(get_beacon_state_validators)
|
||||||
.or(get_beacon_state_validators.boxed())
|
.uor(get_beacon_state_committees)
|
||||||
.or(get_beacon_state_committees.boxed())
|
.uor(get_beacon_state_sync_committees)
|
||||||
.or(get_beacon_state_sync_committees.boxed())
|
.uor(get_beacon_state_randao)
|
||||||
.or(get_beacon_state_randao.boxed())
|
.uor(get_beacon_headers)
|
||||||
.or(get_beacon_headers.boxed())
|
.uor(get_beacon_headers_block_id)
|
||||||
.or(get_beacon_headers_block_id.boxed())
|
.uor(get_beacon_block)
|
||||||
.or(get_beacon_block.boxed())
|
.uor(get_beacon_block_attestations)
|
||||||
.or(get_beacon_block_attestations.boxed())
|
.uor(get_beacon_blinded_block)
|
||||||
.or(get_beacon_blinded_block.boxed())
|
.uor(get_beacon_block_root)
|
||||||
.or(get_beacon_block_root.boxed())
|
.uor(get_beacon_pool_attestations)
|
||||||
.or(get_beacon_pool_attestations.boxed())
|
.uor(get_beacon_pool_attester_slashings)
|
||||||
.or(get_beacon_pool_attester_slashings.boxed())
|
.uor(get_beacon_pool_proposer_slashings)
|
||||||
.or(get_beacon_pool_proposer_slashings.boxed())
|
.uor(get_beacon_pool_voluntary_exits)
|
||||||
.or(get_beacon_pool_voluntary_exits.boxed())
|
.uor(get_beacon_pool_bls_to_execution_changes)
|
||||||
.or(get_beacon_pool_bls_to_execution_changes.boxed())
|
.uor(get_beacon_deposit_snapshot)
|
||||||
.or(get_beacon_deposit_snapshot.boxed())
|
.uor(get_beacon_rewards_blocks)
|
||||||
.or(get_beacon_rewards_blocks.boxed())
|
.uor(get_config_fork_schedule)
|
||||||
.or(get_config_fork_schedule.boxed())
|
.uor(get_config_spec)
|
||||||
.or(get_config_spec.boxed())
|
.uor(get_config_deposit_contract)
|
||||||
.or(get_config_deposit_contract.boxed())
|
.uor(get_debug_beacon_states)
|
||||||
.or(get_debug_beacon_states.boxed())
|
.uor(get_debug_beacon_heads)
|
||||||
.or(get_debug_beacon_heads.boxed())
|
.uor(get_node_identity)
|
||||||
.or(get_node_identity.boxed())
|
.uor(get_node_version)
|
||||||
.or(get_node_version.boxed())
|
.uor(get_node_syncing)
|
||||||
.or(get_node_syncing.boxed())
|
.uor(get_node_health)
|
||||||
.or(get_node_health.boxed())
|
.uor(get_node_peers_by_id)
|
||||||
.or(get_node_peers_by_id.boxed())
|
.uor(get_node_peers)
|
||||||
.or(get_node_peers.boxed())
|
.uor(get_node_peer_count)
|
||||||
.or(get_node_peer_count.boxed())
|
.uor(get_validator_duties_proposer)
|
||||||
.or(get_validator_duties_proposer.boxed())
|
.uor(get_validator_blocks)
|
||||||
.or(get_validator_blocks.boxed())
|
.uor(get_validator_blinded_blocks)
|
||||||
.or(get_validator_blinded_blocks.boxed())
|
.uor(get_validator_attestation_data)
|
||||||
.or(get_validator_attestation_data.boxed())
|
.uor(get_validator_aggregate_attestation)
|
||||||
.or(get_validator_aggregate_attestation.boxed())
|
.uor(get_validator_sync_committee_contribution)
|
||||||
.or(get_validator_sync_committee_contribution.boxed())
|
.uor(get_lighthouse_health)
|
||||||
.or(get_lighthouse_health.boxed())
|
.uor(get_lighthouse_ui_health)
|
||||||
.or(get_lighthouse_ui_health.boxed())
|
.uor(get_lighthouse_ui_validator_count)
|
||||||
.or(get_lighthouse_ui_validator_count.boxed())
|
.uor(get_lighthouse_syncing)
|
||||||
.or(get_lighthouse_syncing.boxed())
|
.uor(get_lighthouse_nat)
|
||||||
.or(get_lighthouse_nat.boxed())
|
.uor(get_lighthouse_peers)
|
||||||
.or(get_lighthouse_peers.boxed())
|
.uor(get_lighthouse_peers_connected)
|
||||||
.or(get_lighthouse_peers_connected.boxed())
|
.uor(get_lighthouse_proto_array)
|
||||||
.or(get_lighthouse_proto_array.boxed())
|
.uor(get_lighthouse_validator_inclusion_global)
|
||||||
.or(get_lighthouse_validator_inclusion_global.boxed())
|
.uor(get_lighthouse_validator_inclusion)
|
||||||
.or(get_lighthouse_validator_inclusion.boxed())
|
.uor(get_lighthouse_eth1_syncing)
|
||||||
.or(get_lighthouse_eth1_syncing.boxed())
|
.uor(get_lighthouse_eth1_block_cache)
|
||||||
.or(get_lighthouse_eth1_block_cache.boxed())
|
.uor(get_lighthouse_eth1_deposit_cache)
|
||||||
.or(get_lighthouse_eth1_deposit_cache.boxed())
|
.uor(get_lighthouse_beacon_states_ssz)
|
||||||
.or(get_lighthouse_beacon_states_ssz.boxed())
|
.uor(get_lighthouse_staking)
|
||||||
.or(get_lighthouse_staking.boxed())
|
.uor(get_lighthouse_database_info)
|
||||||
.or(get_lighthouse_database_info.boxed())
|
.uor(get_lighthouse_block_rewards)
|
||||||
.or(get_lighthouse_block_rewards.boxed())
|
.uor(get_lighthouse_attestation_performance)
|
||||||
.or(get_lighthouse_attestation_performance.boxed())
|
.uor(get_lighthouse_block_packing_efficiency)
|
||||||
.or(get_lighthouse_block_packing_efficiency.boxed())
|
.uor(get_lighthouse_merge_readiness)
|
||||||
.or(get_lighthouse_merge_readiness.boxed())
|
.uor(get_lighthouse_blobs_sidecars.boxed())
|
||||||
.or(get_lighthouse_blobs_sidecars.boxed())
|
.uor(get_events)
|
||||||
.or(get_events.boxed())
|
|
||||||
.recover(warp_utils::reject::handle_rejection),
|
.recover(warp_utils::reject::handle_rejection),
|
||||||
)
|
)
|
||||||
.boxed()
|
.boxed()
|
||||||
.or(warp::post().and(
|
.uor(
|
||||||
|
warp::post().and(
|
||||||
post_beacon_blocks
|
post_beacon_blocks
|
||||||
.boxed()
|
.uor(post_beacon_blinded_blocks)
|
||||||
.or(post_beacon_blinded_blocks.boxed())
|
.uor(post_beacon_pool_attestations)
|
||||||
.or(post_beacon_pool_attestations.boxed())
|
.uor(post_beacon_pool_attester_slashings)
|
||||||
.or(post_beacon_pool_attester_slashings.boxed())
|
.uor(post_beacon_pool_proposer_slashings)
|
||||||
.or(post_beacon_pool_proposer_slashings.boxed())
|
.uor(post_beacon_pool_voluntary_exits)
|
||||||
.or(post_beacon_pool_voluntary_exits.boxed())
|
.uor(post_beacon_pool_sync_committees)
|
||||||
.or(post_beacon_pool_sync_committees.boxed())
|
.uor(post_beacon_pool_bls_to_execution_changes)
|
||||||
.or(post_beacon_pool_bls_to_execution_changes.boxed())
|
.uor(post_beacon_rewards_attestations)
|
||||||
.or(post_beacon_rewards_attestations.boxed())
|
.uor(post_beacon_rewards_sync_committee)
|
||||||
.or(post_beacon_rewards_sync_committee.boxed())
|
.uor(post_validator_duties_attester)
|
||||||
.or(post_validator_duties_attester.boxed())
|
.uor(post_validator_duties_sync)
|
||||||
.or(post_validator_duties_sync.boxed())
|
.uor(post_validator_aggregate_and_proofs)
|
||||||
.or(post_validator_aggregate_and_proofs.boxed())
|
.uor(post_validator_contribution_and_proofs)
|
||||||
.or(post_validator_contribution_and_proofs.boxed())
|
.uor(post_validator_beacon_committee_subscriptions)
|
||||||
.or(post_validator_beacon_committee_subscriptions.boxed())
|
.uor(post_validator_sync_committee_subscriptions)
|
||||||
.or(post_validator_sync_committee_subscriptions.boxed())
|
.uor(post_validator_prepare_beacon_proposer)
|
||||||
.or(post_validator_prepare_beacon_proposer.boxed())
|
.uor(post_validator_register_validator)
|
||||||
.or(post_validator_register_validator.boxed())
|
.uor(post_lighthouse_liveness)
|
||||||
.or(post_lighthouse_liveness.boxed())
|
.uor(post_lighthouse_database_reconstruct)
|
||||||
.or(post_lighthouse_database_reconstruct.boxed())
|
.uor(post_lighthouse_database_historical_blocks)
|
||||||
.or(post_lighthouse_database_historical_blocks.boxed())
|
.uor(post_lighthouse_block_rewards)
|
||||||
.or(post_lighthouse_block_rewards.boxed())
|
.uor(post_lighthouse_ui_validator_metrics)
|
||||||
.or(post_lighthouse_ui_validator_metrics.boxed())
|
.uor(post_lighthouse_ui_validator_info)
|
||||||
.or(post_lighthouse_ui_validator_info.boxed())
|
|
||||||
.recover(warp_utils::reject::handle_rejection),
|
.recover(warp_utils::reject::handle_rejection),
|
||||||
))
|
),
|
||||||
|
)
|
||||||
.recover(warp_utils::reject::handle_rejection)
|
.recover(warp_utils::reject::handle_rejection)
|
||||||
.with(slog_logging(log.clone()))
|
.with(slog_logging(log.clone()))
|
||||||
.with(prometheus_metrics())
|
.with(prometheus_metrics())
|
||||||
// Add a `Server` header.
|
// Add a `Server` header.
|
||||||
.map(|reply| warp::reply::with_header(reply, "Server", &version_with_platform()))
|
.map(|reply| warp::reply::with_header(reply, "Server", &version_with_platform()))
|
||||||
.with(cors_builder.build());
|
.with(cors_builder.build())
|
||||||
|
.boxed();
|
||||||
|
|
||||||
let http_socket: SocketAddr = SocketAddr::new(config.listen_addr, config.listen_port);
|
let http_socket: SocketAddr = SocketAddr::new(config.listen_addr, config.listen_port);
|
||||||
let http_server: HttpServer = match config.tls_config {
|
let http_server: HttpServer = match config.tls_config {
|
||||||
|
@ -4,7 +4,7 @@ use serde::Serialize;
|
|||||||
use types::{
|
use types::{
|
||||||
ExecutionOptimisticForkVersionedResponse, ForkName, ForkVersionedResponse, InconsistentFork,
|
ExecutionOptimisticForkVersionedResponse, ForkName, ForkVersionedResponse, InconsistentFork,
|
||||||
};
|
};
|
||||||
use warp::reply::{self, Reply, WithHeader};
|
use warp::reply::{self, Reply, Response};
|
||||||
|
|
||||||
pub const V1: EndpointVersion = EndpointVersion(1);
|
pub const V1: EndpointVersion = EndpointVersion(1);
|
||||||
pub const V2: EndpointVersion = EndpointVersion(2);
|
pub const V2: EndpointVersion = EndpointVersion(2);
|
||||||
@ -48,8 +48,8 @@ pub fn execution_optimistic_fork_versioned_response<T: Serialize>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add the `Eth-Consensus-Version` header to a response.
|
/// Add the `Eth-Consensus-Version` header to a response.
|
||||||
pub fn add_consensus_version_header<T: Reply>(reply: T, fork_name: ForkName) -> WithHeader<T> {
|
pub fn add_consensus_version_header<T: Reply>(reply: T, fork_name: ForkName) -> Response {
|
||||||
reply::with_header(reply, CONSENSUS_VERSION_HEADER, fork_name.to_string())
|
reply::with_header(reply, CONSENSUS_VERSION_HEADER, fork_name.to_string()).into_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inconsistent_fork_rejection(error: InconsistentFork) -> warp::reject::Rejection {
|
pub fn inconsistent_fork_rejection(error: InconsistentFork) -> warp::reject::Rejection {
|
||||||
|
@ -127,7 +127,7 @@ pub async fn create_api_server<T: BeaconChainTypes>(
|
|||||||
log: Logger,
|
log: Logger,
|
||||||
) -> ApiServer<T::EthSpec, impl Future<Output = ()>> {
|
) -> ApiServer<T::EthSpec, impl Future<Output = ()>> {
|
||||||
// Get a random unused port.
|
// Get a random unused port.
|
||||||
let port = unused_port::unused_tcp_port().unwrap();
|
let port = unused_port::unused_tcp4_port().unwrap();
|
||||||
create_api_server_on_port(chain, log, port).await
|
create_api_server_on_port(chain, log, port).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,8 +148,8 @@ pub async fn create_api_server_on_port<T: BeaconChainTypes>(
|
|||||||
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||||
let network_globals = Arc::new(NetworkGlobals::new(
|
let network_globals = Arc::new(NetworkGlobals::new(
|
||||||
enr.clone(),
|
enr.clone(),
|
||||||
TCP_PORT,
|
Some(TCP_PORT),
|
||||||
UDP_PORT,
|
None,
|
||||||
meta_data,
|
meta_data,
|
||||||
vec![],
|
vec![],
|
||||||
&log,
|
&log,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#![cfg(not(debug_assertions))] // Tests are too slow in debug.
|
#![cfg(not(debug_assertions))] // Tests are too slow in debug.
|
||||||
#![recursion_limit = "256"]
|
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod fork_tests;
|
pub mod fork_tests;
|
||||||
|
@ -112,7 +112,7 @@ impl ApiTester {
|
|||||||
pub async fn new_from_config(config: ApiTesterConfig) -> Self {
|
pub async fn new_from_config(config: ApiTesterConfig) -> Self {
|
||||||
// Get a random unused port
|
// Get a random unused port
|
||||||
let spec = config.spec;
|
let spec = config.spec;
|
||||||
let port = unused_port::unused_tcp_port().unwrap();
|
let port = unused_port::unused_tcp4_port().unwrap();
|
||||||
let beacon_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
let beacon_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
||||||
|
|
||||||
let harness = Arc::new(
|
let harness = Arc::new(
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::listen_addr::{ListenAddr, ListenAddress};
|
||||||
use crate::rpc::config::OutboundRateLimiterConfig;
|
use crate::rpc::config::OutboundRateLimiterConfig;
|
||||||
use crate::types::GossipKind;
|
use crate::types::GossipKind;
|
||||||
use crate::{Enr, PeerIdSerialized};
|
use crate::{Enr, PeerIdSerialized};
|
||||||
@ -12,6 +13,7 @@ use libp2p::gossipsub::{
|
|||||||
use libp2p::Multiaddr;
|
use libp2p::Multiaddr;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -57,24 +59,24 @@ pub struct Config {
|
|||||||
/// Data directory where node's keyfile is stored
|
/// Data directory where node's keyfile is stored
|
||||||
pub network_dir: PathBuf,
|
pub network_dir: PathBuf,
|
||||||
|
|
||||||
/// IP address to listen on.
|
/// IP addresses to listen on.
|
||||||
pub listen_address: std::net::IpAddr,
|
listen_addresses: ListenAddress,
|
||||||
|
|
||||||
/// The TCP port that libp2p listens on.
|
|
||||||
pub libp2p_port: u16,
|
|
||||||
|
|
||||||
/// UDP port that discovery listens on.
|
|
||||||
pub discovery_port: u16,
|
|
||||||
|
|
||||||
/// The address to broadcast to peers about which address we are listening on. None indicates
|
/// The address to broadcast to peers about which address we are listening on. None indicates
|
||||||
/// that no discovery address has been set in the CLI args.
|
/// that no discovery address has been set in the CLI args.
|
||||||
pub enr_address: Option<std::net::IpAddr>,
|
pub enr_address: (Option<Ipv4Addr>, Option<Ipv6Addr>),
|
||||||
|
|
||||||
/// The udp port to broadcast to peers in order to reach back for discovery.
|
/// The udp4 port to broadcast to peers in order to reach back for discovery.
|
||||||
pub enr_udp_port: Option<u16>,
|
pub enr_udp4_port: Option<u16>,
|
||||||
|
|
||||||
/// The tcp port to broadcast to peers in order to reach back for libp2p services.
|
/// The tcp4 port to broadcast to peers in order to reach back for libp2p services.
|
||||||
pub enr_tcp_port: Option<u16>,
|
pub enr_tcp4_port: Option<u16>,
|
||||||
|
|
||||||
|
/// The udp6 port to broadcast to peers in order to reach back for discovery.
|
||||||
|
pub enr_udp6_port: Option<u16>,
|
||||||
|
|
||||||
|
/// The tcp6 port to broadcast to peers in order to reach back for libp2p services.
|
||||||
|
pub enr_tcp6_port: Option<u16>,
|
||||||
|
|
||||||
/// Target number of connected peers.
|
/// Target number of connected peers.
|
||||||
pub target_peers: usize,
|
pub target_peers: usize,
|
||||||
@ -139,6 +141,105 @@ pub struct Config {
|
|||||||
pub outbound_rate_limiter_config: Option<OutboundRateLimiterConfig>,
|
pub outbound_rate_limiter_config: Option<OutboundRateLimiterConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
/// Sets the listening address to use an ipv4 address. The discv5 ip_mode and table filter are
|
||||||
|
/// adjusted accordingly to ensure addresses that are present in the enr are globally
|
||||||
|
/// reachable.
|
||||||
|
pub fn set_ipv4_listening_address(&mut self, addr: Ipv4Addr, tcp_port: u16, udp_port: u16) {
|
||||||
|
self.listen_addresses = ListenAddress::V4(ListenAddr {
|
||||||
|
addr,
|
||||||
|
udp_port,
|
||||||
|
tcp_port,
|
||||||
|
});
|
||||||
|
self.discv5_config.ip_mode = discv5::IpMode::Ip4;
|
||||||
|
self.discv5_config.table_filter = |enr| enr.ip4().as_ref().map_or(false, is_global_ipv4)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the listening address to use an ipv6 address. The discv5 ip_mode and table filter is
|
||||||
|
/// adjusted accordingly to ensure addresses that are present in the enr are globally
|
||||||
|
/// reachable.
|
||||||
|
pub fn set_ipv6_listening_address(&mut self, addr: Ipv6Addr, tcp_port: u16, udp_port: u16) {
|
||||||
|
self.listen_addresses = ListenAddress::V6(ListenAddr {
|
||||||
|
addr,
|
||||||
|
udp_port,
|
||||||
|
tcp_port,
|
||||||
|
});
|
||||||
|
self.discv5_config.ip_mode = discv5::IpMode::Ip6 {
|
||||||
|
enable_mapped_addresses: false,
|
||||||
|
};
|
||||||
|
self.discv5_config.table_filter = |enr| enr.ip6().as_ref().map_or(false, is_global_ipv6)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the listening address to use both an ipv4 and ipv6 address. The discv5 ip_mode and
|
||||||
|
/// table filter is adjusted accordingly to ensure addresses that are present in the enr are
|
||||||
|
/// globally reachable.
|
||||||
|
pub fn set_ipv4_ipv6_listening_addresses(
|
||||||
|
&mut self,
|
||||||
|
v4_addr: Ipv4Addr,
|
||||||
|
tcp4_port: u16,
|
||||||
|
udp4_port: u16,
|
||||||
|
v6_addr: Ipv6Addr,
|
||||||
|
tcp6_port: u16,
|
||||||
|
udp6_port: u16,
|
||||||
|
) {
|
||||||
|
self.listen_addresses = ListenAddress::DualStack(
|
||||||
|
ListenAddr {
|
||||||
|
addr: v4_addr,
|
||||||
|
udp_port: udp4_port,
|
||||||
|
tcp_port: tcp4_port,
|
||||||
|
},
|
||||||
|
ListenAddr {
|
||||||
|
addr: v6_addr,
|
||||||
|
udp_port: udp6_port,
|
||||||
|
tcp_port: tcp6_port,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
self.discv5_config.ip_mode = discv5::IpMode::Ip6 {
|
||||||
|
enable_mapped_addresses: true,
|
||||||
|
};
|
||||||
|
self.discv5_config.table_filter = |enr| match (&enr.ip4(), &enr.ip6()) {
|
||||||
|
(None, None) => false,
|
||||||
|
(None, Some(ip6)) => is_global_ipv6(ip6),
|
||||||
|
(Some(ip4), None) => is_global_ipv4(ip4),
|
||||||
|
(Some(ip4), Some(ip6)) => is_global_ipv4(ip4) && is_global_ipv6(ip6),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_listening_addr(&mut self, listen_addr: ListenAddress) {
|
||||||
|
match listen_addr {
|
||||||
|
ListenAddress::V4(ListenAddr {
|
||||||
|
addr,
|
||||||
|
udp_port,
|
||||||
|
tcp_port,
|
||||||
|
}) => self.set_ipv4_listening_address(addr, tcp_port, udp_port),
|
||||||
|
ListenAddress::V6(ListenAddr {
|
||||||
|
addr,
|
||||||
|
udp_port,
|
||||||
|
tcp_port,
|
||||||
|
}) => self.set_ipv6_listening_address(addr, tcp_port, udp_port),
|
||||||
|
ListenAddress::DualStack(
|
||||||
|
ListenAddr {
|
||||||
|
addr: ip4addr,
|
||||||
|
udp_port: udp4_port,
|
||||||
|
tcp_port: tcp4_port,
|
||||||
|
},
|
||||||
|
ListenAddr {
|
||||||
|
addr: ip6addr,
|
||||||
|
udp_port: udp6_port,
|
||||||
|
tcp_port: tcp6_port,
|
||||||
|
},
|
||||||
|
) => self.set_ipv4_ipv6_listening_addresses(
|
||||||
|
ip4addr, tcp4_port, udp4_port, ip6addr, tcp6_port, udp6_port,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn listen_addrs(&self) -> &ListenAddress {
|
||||||
|
&self.listen_addresses
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
/// Generate a default network configuration.
|
/// Generate a default network configuration.
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@ -183,7 +284,7 @@ impl Default for Config {
|
|||||||
.filter_rate_limiter(filter_rate_limiter)
|
.filter_rate_limiter(filter_rate_limiter)
|
||||||
.filter_max_bans_per_ip(Some(5))
|
.filter_max_bans_per_ip(Some(5))
|
||||||
.filter_max_nodes_per_ip(Some(10))
|
.filter_max_nodes_per_ip(Some(10))
|
||||||
.table_filter(|enr| enr.ip4().map_or(false, |ip| is_global(&ip))) // Filter non-global IPs
|
.table_filter(|enr| enr.ip4().map_or(false, |ip| is_global_ipv4(&ip))) // Filter non-global IPs
|
||||||
.ban_duration(Some(Duration::from_secs(3600)))
|
.ban_duration(Some(Duration::from_secs(3600)))
|
||||||
.ping_interval(Duration::from_secs(300))
|
.ping_interval(Duration::from_secs(300))
|
||||||
.build();
|
.build();
|
||||||
@ -191,12 +292,16 @@ impl Default for Config {
|
|||||||
// NOTE: Some of these get overridden by the corresponding CLI default values.
|
// NOTE: Some of these get overridden by the corresponding CLI default values.
|
||||||
Config {
|
Config {
|
||||||
network_dir,
|
network_dir,
|
||||||
listen_address: "0.0.0.0".parse().expect("valid ip address"),
|
listen_addresses: ListenAddress::V4(ListenAddr {
|
||||||
libp2p_port: 9000,
|
addr: Ipv4Addr::UNSPECIFIED,
|
||||||
discovery_port: 9000,
|
udp_port: 9000,
|
||||||
enr_address: None,
|
tcp_port: 9000,
|
||||||
enr_udp_port: None,
|
}),
|
||||||
enr_tcp_port: None,
|
enr_address: (None, None),
|
||||||
|
enr_udp4_port: None,
|
||||||
|
enr_tcp4_port: None,
|
||||||
|
enr_udp6_port: None,
|
||||||
|
enr_tcp6_port: None,
|
||||||
target_peers: 50,
|
target_peers: 50,
|
||||||
gs_config,
|
gs_config,
|
||||||
discv5_config,
|
discv5_config,
|
||||||
@ -363,7 +468,7 @@ pub fn gossipsub_config(network_load: u8, fork_context: Arc<ForkContext>) -> Gos
|
|||||||
/// Helper function to determine if the IpAddr is a global address or not. The `is_global()`
|
/// Helper function to determine if the IpAddr is a global address or not. The `is_global()`
|
||||||
/// function is not yet stable on IpAddr.
|
/// function is not yet stable on IpAddr.
|
||||||
#[allow(clippy::nonminimal_bool)]
|
#[allow(clippy::nonminimal_bool)]
|
||||||
fn is_global(addr: &std::net::Ipv4Addr) -> bool {
|
fn is_global_ipv4(addr: &Ipv4Addr) -> bool {
|
||||||
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
|
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
|
||||||
// globally routable addresses in the 192.0.0.0/24 range.
|
// globally routable addresses in the 192.0.0.0/24 range.
|
||||||
if u32::from_be_bytes(addr.octets()) == 0xc0000009
|
if u32::from_be_bytes(addr.octets()) == 0xc0000009
|
||||||
@ -384,3 +489,60 @@ fn is_global(addr: &std::net::Ipv4Addr) -> bool {
|
|||||||
// Make sure the address is not in 0.0.0.0/8
|
// Make sure the address is not in 0.0.0.0/8
|
||||||
&& addr.octets()[0] != 0
|
&& addr.octets()[0] != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// NOTE: Docs taken from https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.is_global
|
||||||
|
///
|
||||||
|
/// Returns true if the address appears to be globally reachable as specified by the IANA IPv6
|
||||||
|
/// Special-Purpose Address Registry. Whether or not an address is practically reachable will
|
||||||
|
/// depend on your network configuration.
|
||||||
|
///
|
||||||
|
/// Most IPv6 addresses are globally reachable; unless they are specifically defined as not
|
||||||
|
/// globally reachable.
|
||||||
|
///
|
||||||
|
/// Non-exhaustive list of notable addresses that are not globally reachable:
|
||||||
|
///
|
||||||
|
/// - The unspecified address (is_unspecified)
|
||||||
|
/// - The loopback address (is_loopback)
|
||||||
|
/// - IPv4-mapped addresses
|
||||||
|
/// - Addresses reserved for benchmarking
|
||||||
|
/// - Addresses reserved for documentation (is_documentation)
|
||||||
|
/// - Unique local addresses (is_unique_local)
|
||||||
|
/// - Unicast addresses with link-local scope (is_unicast_link_local)
|
||||||
|
// TODO: replace with [`Ipv6Addr::is_global`] once
|
||||||
|
// [Ip](https://github.com/rust-lang/rust/issues/27709) is stable.
|
||||||
|
pub const fn is_global_ipv6(addr: &Ipv6Addr) -> bool {
|
||||||
|
const fn is_documentation(addr: &Ipv6Addr) -> bool {
|
||||||
|
(addr.segments()[0] == 0x2001) && (addr.segments()[1] == 0xdb8)
|
||||||
|
}
|
||||||
|
const fn is_unique_local(addr: &Ipv6Addr) -> bool {
|
||||||
|
(addr.segments()[0] & 0xfe00) == 0xfc00
|
||||||
|
}
|
||||||
|
const fn is_unicast_link_local(addr: &Ipv6Addr) -> bool {
|
||||||
|
(addr.segments()[0] & 0xffc0) == 0xfe80
|
||||||
|
}
|
||||||
|
!(addr.is_unspecified()
|
||||||
|
|| addr.is_loopback()
|
||||||
|
// IPv4-mapped Address (`::ffff:0:0/96`)
|
||||||
|
|| matches!(addr.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
|
||||||
|
// IPv4-IPv6 Translat. (`64:ff9b:1::/48`)
|
||||||
|
|| matches!(addr.segments(), [0x64, 0xff9b, 1, _, _, _, _, _])
|
||||||
|
// Discard-Only Address Block (`100::/64`)
|
||||||
|
|| matches!(addr.segments(), [0x100, 0, 0, 0, _, _, _, _])
|
||||||
|
// IETF Protocol Assignments (`2001::/23`)
|
||||||
|
|| (matches!(addr.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200)
|
||||||
|
&& !(
|
||||||
|
// Port Control Protocol Anycast (`2001:1::1`)
|
||||||
|
u128::from_be_bytes(addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001
|
||||||
|
// Traversal Using Relays around NAT Anycast (`2001:1::2`)
|
||||||
|
|| u128::from_be_bytes(addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002
|
||||||
|
// AMT (`2001:3::/32`)
|
||||||
|
|| matches!(addr.segments(), [0x2001, 3, _, _, _, _, _, _])
|
||||||
|
// AS112-v6 (`2001:4:112::/48`)
|
||||||
|
|| matches!(addr.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
|
||||||
|
// ORCHIDv2 (`2001:20::/28`)
|
||||||
|
|| matches!(addr.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F)
|
||||||
|
))
|
||||||
|
|| is_documentation(addr)
|
||||||
|
|| is_unique_local(addr)
|
||||||
|
|| is_unicast_link_local(addr))
|
||||||
|
}
|
||||||
|
@ -145,16 +145,39 @@ pub fn create_enr_builder_from_config<T: EnrKey>(
|
|||||||
enable_tcp: bool,
|
enable_tcp: bool,
|
||||||
) -> EnrBuilder<T> {
|
) -> EnrBuilder<T> {
|
||||||
let mut builder = EnrBuilder::new("v4");
|
let mut builder = EnrBuilder::new("v4");
|
||||||
if let Some(enr_address) = config.enr_address {
|
let (maybe_ipv4_address, maybe_ipv6_address) = &config.enr_address;
|
||||||
builder.ip(enr_address);
|
|
||||||
|
if let Some(ip) = maybe_ipv4_address {
|
||||||
|
builder.ip4(*ip);
|
||||||
}
|
}
|
||||||
if let Some(udp_port) = config.enr_udp_port {
|
|
||||||
builder.udp4(udp_port);
|
if let Some(ip) = maybe_ipv6_address {
|
||||||
|
builder.ip6(*ip);
|
||||||
}
|
}
|
||||||
// we always give it our listening tcp port
|
|
||||||
|
if let Some(udp4_port) = config.enr_udp4_port {
|
||||||
|
builder.udp4(udp4_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(udp6_port) = config.enr_udp6_port {
|
||||||
|
builder.udp6(udp6_port);
|
||||||
|
}
|
||||||
|
|
||||||
if enable_tcp {
|
if enable_tcp {
|
||||||
let tcp_port = config.enr_tcp_port.unwrap_or(config.libp2p_port);
|
// If the ENR port is not set, and we are listening over that ip version, use the listening port instead.
|
||||||
builder.tcp4(tcp_port);
|
let tcp4_port = config
|
||||||
|
.enr_tcp4_port
|
||||||
|
.or_else(|| config.listen_addrs().v4().map(|v4_addr| v4_addr.tcp_port));
|
||||||
|
if let Some(tcp4_port) = tcp4_port {
|
||||||
|
builder.tcp4(tcp4_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
let tcp6_port = config
|
||||||
|
.enr_tcp6_port
|
||||||
|
.or_else(|| config.listen_addrs().v6().map(|v6_addr| v6_addr.tcp_port));
|
||||||
|
if let Some(tcp6_port) = tcp6_port {
|
||||||
|
builder.tcp6(tcp6_port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
builder
|
builder
|
||||||
}
|
}
|
||||||
|
@ -201,8 +201,13 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
info!(log, "ENR Initialised"; "enr" => local_enr.to_base64(), "seq" => local_enr.seq(), "id"=> %local_enr.node_id(),
|
info!(log, "ENR Initialised"; "enr" => local_enr.to_base64(), "seq" => local_enr.seq(), "id"=> %local_enr.node_id(),
|
||||||
"ip4" => ?local_enr.ip4(), "udp4"=> ?local_enr.udp4(), "tcp4" => ?local_enr.tcp6()
|
"ip4" => ?local_enr.ip4(), "udp4"=> ?local_enr.udp4(), "tcp4" => ?local_enr.tcp6()
|
||||||
);
|
);
|
||||||
|
let listen_socket = match config.listen_addrs() {
|
||||||
let listen_socket = SocketAddr::new(config.listen_address, config.discovery_port);
|
crate::listen_addr::ListenAddress::V4(v4_addr) => v4_addr.udp_socket_addr(),
|
||||||
|
crate::listen_addr::ListenAddress::V6(v6_addr) => v6_addr.udp_socket_addr(),
|
||||||
|
crate::listen_addr::ListenAddress::DualStack(_v4_addr, v6_addr) => {
|
||||||
|
v6_addr.udp_socket_addr()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// convert the keypair into an ENR key
|
// convert the keypair into an ENR key
|
||||||
let enr_key: CombinedKey = CombinedKey::from_libp2p(local_key)?;
|
let enr_key: CombinedKey = CombinedKey::from_libp2p(local_key)?;
|
||||||
@ -1015,15 +1020,28 @@ impl<TSpec: EthSpec> NetworkBehaviour for Discovery<TSpec> {
|
|||||||
*self.network_globals.local_enr.write() = enr;
|
*self.network_globals.local_enr.write() = enr;
|
||||||
// A new UDP socket has been detected.
|
// A new UDP socket has been detected.
|
||||||
// Build a multiaddr to report to libp2p
|
// Build a multiaddr to report to libp2p
|
||||||
let mut address = Multiaddr::from(socket_addr.ip());
|
let addr = match socket_addr.ip() {
|
||||||
|
IpAddr::V4(v4_addr) => {
|
||||||
|
self.network_globals.listen_port_tcp4().map(|tcp4_port| {
|
||||||
|
Multiaddr::from(v4_addr).with(Protocol::Tcp(tcp4_port))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
IpAddr::V6(v6_addr) => {
|
||||||
|
self.network_globals.listen_port_tcp6().map(|tcp6_port| {
|
||||||
|
Multiaddr::from(v6_addr).with(Protocol::Tcp(tcp6_port))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(address) = addr {
|
||||||
// NOTE: This doesn't actually track the external TCP port. More sophisticated NAT handling
|
// NOTE: This doesn't actually track the external TCP port. More sophisticated NAT handling
|
||||||
// should handle this.
|
// should handle this.
|
||||||
address.push(Protocol::Tcp(self.network_globals.listen_port_tcp()));
|
|
||||||
return Poll::Ready(NBAction::ReportObservedAddr {
|
return Poll::Ready(NBAction::ReportObservedAddr {
|
||||||
address,
|
address,
|
||||||
score: AddressScore::Finite(1),
|
score: AddressScore::Finite(1),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Discv5Event::EnrAdded { .. }
|
Discv5Event::EnrAdded { .. }
|
||||||
| Discv5Event::TalkRequest(_)
|
| Discv5Event::TalkRequest(_)
|
||||||
| Discv5Event::NodeInserted { .. }
|
| Discv5Event::NodeInserted { .. }
|
||||||
@ -1087,7 +1105,6 @@ mod tests {
|
|||||||
use enr::EnrBuilder;
|
use enr::EnrBuilder;
|
||||||
use slog::{o, Drain};
|
use slog::{o, Drain};
|
||||||
use types::{BitVector, MinimalEthSpec, SubnetId};
|
use types::{BitVector, MinimalEthSpec, SubnetId};
|
||||||
use unused_port::unused_udp_port;
|
|
||||||
|
|
||||||
type E = MinimalEthSpec;
|
type E = MinimalEthSpec;
|
||||||
|
|
||||||
@ -1105,17 +1122,15 @@ mod tests {
|
|||||||
|
|
||||||
async fn build_discovery() -> Discovery<E> {
|
async fn build_discovery() -> Discovery<E> {
|
||||||
let keypair = libp2p::identity::Keypair::generate_secp256k1();
|
let keypair = libp2p::identity::Keypair::generate_secp256k1();
|
||||||
let config = NetworkConfig {
|
let mut config = NetworkConfig::default();
|
||||||
discovery_port: unused_udp_port().unwrap(),
|
config.set_listening_addr(crate::ListenAddress::unused_v4_ports());
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let enr_key: CombinedKey = CombinedKey::from_libp2p(&keypair).unwrap();
|
let enr_key: CombinedKey = CombinedKey::from_libp2p(&keypair).unwrap();
|
||||||
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default()).unwrap();
|
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default()).unwrap();
|
||||||
let log = build_log(slog::Level::Debug, false);
|
let log = build_log(slog::Level::Debug, false);
|
||||||
let globals = NetworkGlobals::new(
|
let globals = NetworkGlobals::new(
|
||||||
enr,
|
enr,
|
||||||
9000,
|
Some(9000),
|
||||||
9000,
|
None,
|
||||||
MetaData::V2(MetaDataV2 {
|
MetaData::V2(MetaDataV2 {
|
||||||
seq_number: 0,
|
seq_number: 0,
|
||||||
attnets: Default::default(),
|
attnets: Default::default(),
|
||||||
|
@ -10,12 +10,14 @@ pub mod service;
|
|||||||
|
|
||||||
#[allow(clippy::mutable_key_type)] // PeerId in hashmaps are no longer permitted by clippy
|
#[allow(clippy::mutable_key_type)] // PeerId in hashmaps are no longer permitted by clippy
|
||||||
pub mod discovery;
|
pub mod discovery;
|
||||||
|
pub mod listen_addr;
|
||||||
pub mod metrics;
|
pub mod metrics;
|
||||||
pub mod peer_manager;
|
pub mod peer_manager;
|
||||||
pub mod rpc;
|
pub mod rpc;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
pub use config::gossip_max_size;
|
pub use config::gossip_max_size;
|
||||||
|
pub use listen_addr::*;
|
||||||
|
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
97
beacon_node/lighthouse_network/src/listen_addr.rs
Normal file
97
beacon_node/lighthouse_network/src/listen_addr.rs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||||
|
|
||||||
|
use libp2p::{multiaddr::Protocol, Multiaddr};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// A listening address composed by an Ip, an UDP port and a TCP port.
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ListenAddr<Ip> {
|
||||||
|
pub addr: Ip,
|
||||||
|
pub udp_port: u16,
|
||||||
|
pub tcp_port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Ip: Into<IpAddr> + Clone> ListenAddr<Ip> {
|
||||||
|
pub fn udp_socket_addr(&self) -> SocketAddr {
|
||||||
|
(self.addr.clone().into(), self.udp_port).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tcp_socket_addr(&self) -> SocketAddr {
|
||||||
|
(self.addr.clone().into(), self.tcp_port).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Types of listening addresses Lighthouse can accept.
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub enum ListenAddress {
|
||||||
|
V4(ListenAddr<Ipv4Addr>),
|
||||||
|
V6(ListenAddr<Ipv6Addr>),
|
||||||
|
DualStack(ListenAddr<Ipv4Addr>, ListenAddr<Ipv6Addr>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListenAddress {
|
||||||
|
/// Return the listening address over IpV4 if any.
|
||||||
|
pub fn v4(&self) -> Option<&ListenAddr<Ipv4Addr>> {
|
||||||
|
match self {
|
||||||
|
ListenAddress::V4(v4_addr) | ListenAddress::DualStack(v4_addr, _) => Some(v4_addr),
|
||||||
|
ListenAddress::V6(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the listening address over IpV6 if any.
|
||||||
|
pub fn v6(&self) -> Option<&ListenAddr<Ipv6Addr>> {
|
||||||
|
match self {
|
||||||
|
ListenAddress::V6(v6_addr) | ListenAddress::DualStack(_, v6_addr) => Some(v6_addr),
|
||||||
|
ListenAddress::V4(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the TCP addresses.
|
||||||
|
pub fn tcp_addresses(&self) -> impl Iterator<Item = Multiaddr> + '_ {
|
||||||
|
let v4_multiaddr = self
|
||||||
|
.v4()
|
||||||
|
.map(|v4_addr| Multiaddr::from(v4_addr.addr).with(Protocol::Tcp(v4_addr.tcp_port)));
|
||||||
|
let v6_multiaddr = self
|
||||||
|
.v6()
|
||||||
|
.map(|v6_addr| Multiaddr::from(v6_addr.addr).with(Protocol::Tcp(v6_addr.tcp_port)));
|
||||||
|
v4_multiaddr.into_iter().chain(v6_multiaddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn unused_v4_ports() -> Self {
|
||||||
|
ListenAddress::V4(ListenAddr {
|
||||||
|
addr: Ipv4Addr::UNSPECIFIED,
|
||||||
|
udp_port: unused_port::unused_udp4_port().unwrap(),
|
||||||
|
tcp_port: unused_port::unused_tcp4_port().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn unused_v6_ports() -> Self {
|
||||||
|
ListenAddress::V6(ListenAddr {
|
||||||
|
addr: Ipv6Addr::UNSPECIFIED,
|
||||||
|
udp_port: unused_port::unused_udp6_port().unwrap(),
|
||||||
|
tcp_port: unused_port::unused_tcp6_port().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl slog::KV for ListenAddress {
|
||||||
|
fn serialize(
|
||||||
|
&self,
|
||||||
|
_record: &slog::Record,
|
||||||
|
serializer: &mut dyn slog::Serializer,
|
||||||
|
) -> slog::Result {
|
||||||
|
if let Some(v4_addr) = self.v4() {
|
||||||
|
serializer.emit_arguments("ip4_address", &format_args!("{}", v4_addr.addr))?;
|
||||||
|
serializer.emit_u16("udp4_port", v4_addr.udp_port)?;
|
||||||
|
serializer.emit_u16("tcp4_port", v4_addr.tcp_port)?;
|
||||||
|
}
|
||||||
|
if let Some(v6_addr) = self.v6() {
|
||||||
|
serializer.emit_arguments("ip6_address", &format_args!("{}", v6_addr.addr))?;
|
||||||
|
serializer.emit_u16("udp6_port", v6_addr.udp_port)?;
|
||||||
|
serializer.emit_u16("tcp6_port", v6_addr.tcp_port)?;
|
||||||
|
}
|
||||||
|
slog::Result::Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -159,7 +159,7 @@ pub fn check_nat() {
|
|||||||
if NAT_OPEN.as_ref().map(|v| v.get()).unwrap_or(0) != 0 {
|
if NAT_OPEN.as_ref().map(|v| v.get()).unwrap_or(0) != 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ADDRESS_UPDATE_COUNT.as_ref().map(|v| v.get()).unwrap_or(0) == 0
|
if ADDRESS_UPDATE_COUNT.as_ref().map(|v| v.get()).unwrap_or(0) != 0
|
||||||
|| NETWORK_INBOUND_PEERS.as_ref().map(|v| v.get()).unwrap_or(0) != 0_i64
|
|| NETWORK_INBOUND_PEERS.as_ref().map(|v| v.get()).unwrap_or(0) != 0_i64
|
||||||
{
|
{
|
||||||
inc_counter(&NAT_OPEN);
|
inc_counter(&NAT_OPEN);
|
||||||
|
@ -165,8 +165,8 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
|||||||
let meta_data = utils::load_or_build_metadata(&config.network_dir, &log);
|
let meta_data = utils::load_or_build_metadata(&config.network_dir, &log);
|
||||||
let globals = NetworkGlobals::new(
|
let globals = NetworkGlobals::new(
|
||||||
enr,
|
enr,
|
||||||
config.libp2p_port,
|
config.listen_addrs().v4().map(|v4_addr| v4_addr.tcp_port),
|
||||||
config.discovery_port,
|
config.listen_addrs().v6().map(|v6_addr| v6_addr.tcp_port),
|
||||||
meta_data,
|
meta_data,
|
||||||
config
|
config
|
||||||
.trusted_peers
|
.trusted_peers
|
||||||
@ -391,20 +391,9 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
|||||||
async fn start(&mut self, config: &crate::NetworkConfig) -> error::Result<()> {
|
async fn start(&mut self, config: &crate::NetworkConfig) -> error::Result<()> {
|
||||||
let enr = self.network_globals.local_enr();
|
let enr = self.network_globals.local_enr();
|
||||||
info!(self.log, "Libp2p Starting"; "peer_id" => %enr.peer_id(), "bandwidth_config" => format!("{}-{}", config.network_load, NetworkLoad::from(config.network_load).name));
|
info!(self.log, "Libp2p Starting"; "peer_id" => %enr.peer_id(), "bandwidth_config" => format!("{}-{}", config.network_load, NetworkLoad::from(config.network_load).name));
|
||||||
let discovery_string = if config.disable_discovery {
|
debug!(self.log, "Attempting to open listening ports"; config.listen_addrs(), "discovery_enabled" => !config.disable_discovery);
|
||||||
"None".into()
|
|
||||||
} else {
|
|
||||||
config.discovery_port.to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!(self.log, "Attempting to open listening ports"; "address" => ?config.listen_address, "tcp_port" => config.libp2p_port, "udp_port" => discovery_string);
|
|
||||||
|
|
||||||
let listen_multiaddr = {
|
|
||||||
let mut m = Multiaddr::from(config.listen_address);
|
|
||||||
m.push(MProtocol::Tcp(config.libp2p_port));
|
|
||||||
m
|
|
||||||
};
|
|
||||||
|
|
||||||
|
for listen_multiaddr in config.listen_addrs().tcp_addresses() {
|
||||||
match self.swarm.listen_on(listen_multiaddr.clone()) {
|
match self.swarm.listen_on(listen_multiaddr.clone()) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let mut log_address = listen_multiaddr;
|
let mut log_address = listen_multiaddr;
|
||||||
@ -421,6 +410,7 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
|||||||
return Err("Libp2p was unable to listen on the given listen address.".into());
|
return Err("Libp2p was unable to listen on the given listen address.".into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// helper closure for dialing peers
|
// helper closure for dialing peers
|
||||||
let mut dial = |mut multiaddr: Multiaddr| {
|
let mut dial = |mut multiaddr: Multiaddr| {
|
||||||
|
@ -7,7 +7,6 @@ use crate::EnrExt;
|
|||||||
use crate::{Enr, GossipTopic, Multiaddr, PeerId};
|
use crate::{Enr, GossipTopic, Multiaddr, PeerId};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::atomic::{AtomicU16, Ordering};
|
|
||||||
use types::EthSpec;
|
use types::EthSpec;
|
||||||
|
|
||||||
pub struct NetworkGlobals<TSpec: EthSpec> {
|
pub struct NetworkGlobals<TSpec: EthSpec> {
|
||||||
@ -17,10 +16,10 @@ pub struct NetworkGlobals<TSpec: EthSpec> {
|
|||||||
pub peer_id: RwLock<PeerId>,
|
pub peer_id: RwLock<PeerId>,
|
||||||
/// Listening multiaddrs.
|
/// Listening multiaddrs.
|
||||||
pub listen_multiaddrs: RwLock<Vec<Multiaddr>>,
|
pub listen_multiaddrs: RwLock<Vec<Multiaddr>>,
|
||||||
/// The TCP port that the libp2p service is listening on
|
/// The TCP port that the libp2p service is listening on over Ipv4.
|
||||||
pub listen_port_tcp: AtomicU16,
|
listen_port_tcp4: Option<u16>,
|
||||||
/// The UDP port that the discovery service is listening on
|
/// The TCP port that the libp2p service is listening on over Ipv6.
|
||||||
pub listen_port_udp: AtomicU16,
|
listen_port_tcp6: Option<u16>,
|
||||||
/// The collection of known peers.
|
/// The collection of known peers.
|
||||||
pub peers: RwLock<PeerDB<TSpec>>,
|
pub peers: RwLock<PeerDB<TSpec>>,
|
||||||
// The local meta data of our node.
|
// The local meta data of our node.
|
||||||
@ -36,8 +35,8 @@ pub struct NetworkGlobals<TSpec: EthSpec> {
|
|||||||
impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
enr: Enr,
|
enr: Enr,
|
||||||
tcp_port: u16,
|
listen_port_tcp4: Option<u16>,
|
||||||
udp_port: u16,
|
listen_port_tcp6: Option<u16>,
|
||||||
local_metadata: MetaData<TSpec>,
|
local_metadata: MetaData<TSpec>,
|
||||||
trusted_peers: Vec<PeerId>,
|
trusted_peers: Vec<PeerId>,
|
||||||
log: &slog::Logger,
|
log: &slog::Logger,
|
||||||
@ -46,8 +45,8 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
|||||||
local_enr: RwLock::new(enr.clone()),
|
local_enr: RwLock::new(enr.clone()),
|
||||||
peer_id: RwLock::new(enr.peer_id()),
|
peer_id: RwLock::new(enr.peer_id()),
|
||||||
listen_multiaddrs: RwLock::new(Vec::new()),
|
listen_multiaddrs: RwLock::new(Vec::new()),
|
||||||
listen_port_tcp: AtomicU16::new(tcp_port),
|
listen_port_tcp4,
|
||||||
listen_port_udp: AtomicU16::new(udp_port),
|
listen_port_tcp6,
|
||||||
local_metadata: RwLock::new(local_metadata),
|
local_metadata: RwLock::new(local_metadata),
|
||||||
peers: RwLock::new(PeerDB::new(trusted_peers, log)),
|
peers: RwLock::new(PeerDB::new(trusted_peers, log)),
|
||||||
gossipsub_subscriptions: RwLock::new(HashSet::new()),
|
gossipsub_subscriptions: RwLock::new(HashSet::new()),
|
||||||
@ -73,13 +72,13 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the libp2p TCP port that this node has been configured to listen on.
|
/// Returns the libp2p TCP port that this node has been configured to listen on.
|
||||||
pub fn listen_port_tcp(&self) -> u16 {
|
pub fn listen_port_tcp4(&self) -> Option<u16> {
|
||||||
self.listen_port_tcp.load(Ordering::Relaxed)
|
self.listen_port_tcp4
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the UDP discovery port that this node has been configured to listen on.
|
/// Returns the UDP discovery port that this node has been configured to listen on.
|
||||||
pub fn listen_port_udp(&self) -> u16 {
|
pub fn listen_port_tcp6(&self) -> Option<u16> {
|
||||||
self.listen_port_udp.load(Ordering::Relaxed)
|
self.listen_port_tcp6
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of libp2p connected peers.
|
/// Returns the number of libp2p connected peers.
|
||||||
@ -137,8 +136,8 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
|||||||
let enr = discv5::enr::EnrBuilder::new("v4").build(&enr_key).unwrap();
|
let enr = discv5::enr::EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||||
NetworkGlobals::new(
|
NetworkGlobals::new(
|
||||||
enr,
|
enr,
|
||||||
9000,
|
Some(9000),
|
||||||
9000,
|
None,
|
||||||
MetaData::V2(MetaDataV2 {
|
MetaData::V2(MetaDataV2 {
|
||||||
seq_number: 0,
|
seq_number: 0,
|
||||||
attnets: Default::default(),
|
attnets: Default::default(),
|
||||||
|
@ -13,7 +13,7 @@ use tokio::runtime::Runtime;
|
|||||||
use types::{
|
use types::{
|
||||||
ChainSpec, EnrForkId, Epoch, EthSpec, ForkContext, ForkName, Hash256, MinimalEthSpec, Slot,
|
ChainSpec, EnrForkId, Epoch, EthSpec, ForkContext, ForkName, Hash256, MinimalEthSpec, Slot,
|
||||||
};
|
};
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
|
|
||||||
type E = MinimalEthSpec;
|
type E = MinimalEthSpec;
|
||||||
type ReqId = usize;
|
type ReqId = usize;
|
||||||
@ -78,11 +78,9 @@ pub fn build_config(port: u16, mut boot_nodes: Vec<Enr>) -> NetworkConfig {
|
|||||||
.tempdir()
|
.tempdir()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
config.libp2p_port = port; // tcp port
|
config.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, port, port);
|
||||||
config.discovery_port = port; // udp port
|
config.enr_udp4_port = Some(port);
|
||||||
config.enr_tcp_port = Some(port);
|
config.enr_address = (Some(std::net::Ipv4Addr::LOCALHOST), None);
|
||||||
config.enr_udp_port = Some(port);
|
|
||||||
config.enr_address = Some("127.0.0.1".parse().unwrap());
|
|
||||||
config.boot_nodes_enr.append(&mut boot_nodes);
|
config.boot_nodes_enr.append(&mut boot_nodes);
|
||||||
config.network_dir = path.into_path();
|
config.network_dir = path.into_path();
|
||||||
// Reduce gossipsub heartbeat parameters
|
// Reduce gossipsub heartbeat parameters
|
||||||
@ -100,7 +98,7 @@ pub async fn build_libp2p_instance(
|
|||||||
log: slog::Logger,
|
log: slog::Logger,
|
||||||
fork_name: ForkName,
|
fork_name: ForkName,
|
||||||
) -> Libp2pInstance {
|
) -> Libp2pInstance {
|
||||||
let port = unused_tcp_port().unwrap();
|
let port = unused_tcp4_port().unwrap();
|
||||||
let config = build_config(port, boot_nodes);
|
let config = build_config(port, boot_nodes);
|
||||||
// launch libp2p service
|
// launch libp2p service
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ const SMALL_CHAIN: u64 = 2;
|
|||||||
const LONG_CHAIN: u64 = SLOTS_PER_EPOCH * 2;
|
const LONG_CHAIN: u64 = SLOTS_PER_EPOCH * 2;
|
||||||
|
|
||||||
const TCP_PORT: u16 = 42;
|
const TCP_PORT: u16 = 42;
|
||||||
const UDP_PORT: u16 = 42;
|
|
||||||
const SEQ_NUMBER: u64 = 0;
|
const SEQ_NUMBER: u64 = 0;
|
||||||
|
|
||||||
/// The default time to wait for `BeaconProcessor` events.
|
/// The default time to wait for `BeaconProcessor` events.
|
||||||
@ -177,8 +176,8 @@ impl TestRig {
|
|||||||
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||||
let network_globals = Arc::new(NetworkGlobals::new(
|
let network_globals = Arc::new(NetworkGlobals::new(
|
||||||
enr,
|
enr,
|
||||||
TCP_PORT,
|
Some(TCP_PORT),
|
||||||
UDP_PORT,
|
None,
|
||||||
meta_data,
|
meta_data,
|
||||||
vec![],
|
vec![],
|
||||||
&log,
|
&log,
|
||||||
|
@ -20,13 +20,13 @@ pub struct UPnPConfig {
|
|||||||
disable_discovery: bool,
|
disable_discovery: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&NetworkConfig> for UPnPConfig {
|
impl UPnPConfig {
|
||||||
fn from(config: &NetworkConfig) -> Self {
|
pub fn from_config(config: &NetworkConfig) -> Option<Self> {
|
||||||
UPnPConfig {
|
config.listen_addrs().v4().map(|v4_addr| UPnPConfig {
|
||||||
tcp_port: config.libp2p_port,
|
tcp_port: v4_addr.tcp_port,
|
||||||
udp_port: config.discovery_port,
|
udp_port: v4_addr.udp_port,
|
||||||
disable_discovery: config.disable_discovery,
|
disable_discovery: config.disable_discovery,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,17 +228,22 @@ impl<T: BeaconChainTypes> NetworkService<T> {
|
|||||||
let (network_senders, network_recievers) = NetworkSenders::new();
|
let (network_senders, network_recievers) = NetworkSenders::new();
|
||||||
|
|
||||||
// try and construct UPnP port mappings if required.
|
// try and construct UPnP port mappings if required.
|
||||||
let upnp_config = crate::nat::UPnPConfig::from(config);
|
if let Some(upnp_config) = crate::nat::UPnPConfig::from_config(config) {
|
||||||
let upnp_log = network_log.new(o!("service" => "UPnP"));
|
let upnp_log = network_log.new(o!("service" => "UPnP"));
|
||||||
let upnp_network_send = network_senders.network_send();
|
let upnp_network_send = network_senders.network_send();
|
||||||
if config.upnp_enabled {
|
if config.upnp_enabled {
|
||||||
executor.spawn_blocking(
|
executor.spawn_blocking(
|
||||||
move || {
|
move || {
|
||||||
crate::nat::construct_upnp_mappings(upnp_config, upnp_network_send, upnp_log)
|
crate::nat::construct_upnp_mappings(
|
||||||
|
upnp_config,
|
||||||
|
upnp_network_send,
|
||||||
|
upnp_log,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
"UPnP",
|
"UPnP",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get a reference to the beacon chain store
|
// get a reference to the beacon chain store
|
||||||
let store = beacon_chain.store.clone();
|
let store = beacon_chain.store.clone();
|
||||||
|
@ -61,10 +61,9 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut config = NetworkConfig::default();
|
let mut config = NetworkConfig::default();
|
||||||
|
config.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, 21212, 21212);
|
||||||
config.discv5_config.table_filter = |_| true; // Do not ignore local IPs
|
config.discv5_config.table_filter = |_| true; // Do not ignore local IPs
|
||||||
config.libp2p_port = 21212;
|
|
||||||
config.upnp_enabled = false;
|
config.upnp_enabled = false;
|
||||||
config.discovery_port = 21212;
|
|
||||||
config.boot_nodes_enr = enrs.clone();
|
config.boot_nodes_enr = enrs.clone();
|
||||||
runtime.block_on(async move {
|
runtime.block_on(async move {
|
||||||
// Create a new network service which implicitly gets dropped at the
|
// Create a new network service which implicitly gets dropped at the
|
||||||
|
@ -78,7 +78,16 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
Arg::with_name("listen-address")
|
Arg::with_name("listen-address")
|
||||||
.long("listen-address")
|
.long("listen-address")
|
||||||
.value_name("ADDRESS")
|
.value_name("ADDRESS")
|
||||||
.help("The address lighthouse will listen for UDP and TCP connections.")
|
.help("The address lighthouse will listen for UDP and TCP connections. To listen \
|
||||||
|
over IpV4 and IpV6 set this flag twice with the different values.\n\
|
||||||
|
Examples:\n\
|
||||||
|
- --listen-address '0.0.0.0' will listen over Ipv4.\n\
|
||||||
|
- --listen-address '::' will listen over Ipv6.\n\
|
||||||
|
- --listen-address '0.0.0.0' --listen-address '::' will listen over both \
|
||||||
|
Ipv4 and Ipv6. The order of the given addresses is not relevant. However, \
|
||||||
|
multiple Ipv4, or multiple Ipv6 addresses will not be accepted.")
|
||||||
|
.multiple(true)
|
||||||
|
.max_values(2)
|
||||||
.default_value("0.0.0.0")
|
.default_value("0.0.0.0")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
)
|
)
|
||||||
@ -86,10 +95,21 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
Arg::with_name("port")
|
Arg::with_name("port")
|
||||||
.long("port")
|
.long("port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("The TCP/UDP port to listen on. The UDP port can be modified by the --discovery-port flag.")
|
.help("The TCP/UDP port to listen on. The UDP port can be modified by the \
|
||||||
|
--discovery-port flag. If listening over both Ipv4 and Ipv6 the --port flag \
|
||||||
|
will apply to the Ipv4 address and --port6 to the Ipv6 address.")
|
||||||
.default_value("9000")
|
.default_value("9000")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("port6")
|
||||||
|
.long("port6")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The TCP/UDP port to listen on over IpV6 when listening over both Ipv4 and \
|
||||||
|
Ipv6. Defaults to 9090 when required.")
|
||||||
|
.default_value("9090")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("discovery-port")
|
Arg::with_name("discovery-port")
|
||||||
.long("discovery-port")
|
.long("discovery-port")
|
||||||
@ -97,6 +117,15 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.help("The UDP port that discovery will listen on. Defaults to `port`")
|
.help("The UDP port that discovery will listen on. Defaults to `port`")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("discovery-port6")
|
||||||
|
.long("discovery-port6")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The UDP port that discovery will listen on over IpV6 if listening over \
|
||||||
|
both Ipv4 and IpV6. Defaults to `port6`")
|
||||||
|
.hidden(true) // TODO: implement dual stack via two sockets in discv5.
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("target-peers")
|
Arg::with_name("target-peers")
|
||||||
.long("target-peers")
|
.long("target-peers")
|
||||||
@ -137,27 +166,49 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
Arg::with_name("enr-udp-port")
|
Arg::with_name("enr-udp-port")
|
||||||
.long("enr-udp-port")
|
.long("enr-udp-port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("The UDP port of the local ENR. Set this only if you are sure other nodes can connect to your local node on this port.")
|
.help("The UDP4 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
|
can connect to your local node on this port over IpV4.")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("enr-udp6-port")
|
||||||
|
.long("enr-udp6-port")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The UDP6 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
|
can connect to your local node on this port over IpV6.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("enr-tcp-port")
|
Arg::with_name("enr-tcp-port")
|
||||||
.long("enr-tcp-port")
|
.long("enr-tcp-port")
|
||||||
.value_name("PORT")
|
.value_name("PORT")
|
||||||
.help("The TCP port of the local ENR. Set this only if you are sure other nodes can connect to your local node on this port.\
|
.help("The TCP4 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
The --port flag is used if this is not set.")
|
can connect to your local node on this port over IpV4. The --port flag is \
|
||||||
|
used if this is not set.")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("enr-tcp6-port")
|
||||||
|
.long("enr-tcp6-port")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The TCP6 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
|
can connect to your local node on this port over IpV6. The --port6 flag is \
|
||||||
|
used if this is not set.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("enr-address")
|
Arg::with_name("enr-address")
|
||||||
.long("enr-address")
|
.long("enr-address")
|
||||||
.value_name("ADDRESS")
|
.value_name("ADDRESS")
|
||||||
.help("The IP address/ DNS address to broadcast to other peers on how to reach this node. \
|
.help("The IP address/ DNS address to broadcast to other peers on how to reach \
|
||||||
If a DNS address is provided, the enr-address is set to the IP address it resolves to and \
|
this node. If a DNS address is provided, the enr-address is set to the IP \
|
||||||
does not auto-update based on PONG responses in discovery. \
|
address it resolves to and does not auto-update based on PONG responses in \
|
||||||
Set this only if you are sure other nodes can connect to your local node on this address. \
|
discovery. Set this only if you are sure other nodes can connect to your \
|
||||||
Discovery will automatically find your external address, if possible.")
|
local node on this address. This will update the `ip4` or `ip6` ENR fields \
|
||||||
|
accordingly. To update both, set this flag twice with the different values.")
|
||||||
.requires("enr-udp-port")
|
.requires("enr-udp-port")
|
||||||
|
.multiple(true)
|
||||||
|
.max_values(2)
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
@ -165,7 +216,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.short("e")
|
.short("e")
|
||||||
.long("enr-match")
|
.long("enr-match")
|
||||||
.help("Sets the local ENR IP address and port to match those set for lighthouse. \
|
.help("Sets the local ENR IP address and port to match those set for lighthouse. \
|
||||||
Specifically, the IP address will be the value of --listen-address and the UDP port will be --discovery-port.")
|
Specifically, the IP address will be the value of --listen-address and the \
|
||||||
|
UDP port will be --discovery-port.")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("disable-enr-auto-update")
|
Arg::with_name("disable-enr-auto-update")
|
||||||
|
@ -11,13 +11,13 @@ use environment::RuntimeContext;
|
|||||||
use execution_layer::DEFAULT_JWT_FILE;
|
use execution_layer::DEFAULT_JWT_FILE;
|
||||||
use genesis::Eth1Endpoint;
|
use genesis::Eth1Endpoint;
|
||||||
use http_api::TlsConfig;
|
use http_api::TlsConfig;
|
||||||
|
use lighthouse_network::ListenAddress;
|
||||||
use lighthouse_network::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSerialized};
|
use lighthouse_network::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSerialized};
|
||||||
use sensitive_url::SensitiveUrl;
|
use sensitive_url::SensitiveUrl;
|
||||||
use slog::{info, warn, Logger};
|
use slog::{info, warn, Logger};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::fmt::Write;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::net::Ipv6Addr;
|
use std::net::Ipv6Addr;
|
||||||
use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
|
use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
|
||||||
@ -25,7 +25,6 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use types::{Checkpoint, Epoch, EthSpec, Hash256, PublicKeyBytes, GRAFFITI_BYTES_LEN};
|
use types::{Checkpoint, Epoch, EthSpec, Hash256, PublicKeyBytes, GRAFFITI_BYTES_LEN};
|
||||||
use unused_port::{unused_tcp_port, unused_udp_port};
|
|
||||||
|
|
||||||
/// Gets the fully-initialized global client.
|
/// Gets the fully-initialized global client.
|
||||||
///
|
///
|
||||||
@ -79,13 +78,7 @@ pub fn get_config<E: EthSpec>(
|
|||||||
|
|
||||||
let data_dir_ref = client_config.data_dir().clone();
|
let data_dir_ref = client_config.data_dir().clone();
|
||||||
|
|
||||||
set_network_config(
|
set_network_config(&mut client_config.network, cli_args, &data_dir_ref, log)?;
|
||||||
&mut client_config.network,
|
|
||||||
cli_args,
|
|
||||||
&data_dir_ref,
|
|
||||||
log,
|
|
||||||
false,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Staking flag
|
* Staking flag
|
||||||
@ -441,13 +434,6 @@ pub fn get_config<E: EthSpec>(
|
|||||||
* Discovery address is set to localhost by default.
|
* Discovery address is set to localhost by default.
|
||||||
*/
|
*/
|
||||||
if cli_args.is_present("zero-ports") {
|
if cli_args.is_present("zero-ports") {
|
||||||
if client_config.network.enr_address == Some(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))) {
|
|
||||||
client_config.network.enr_address = None
|
|
||||||
}
|
|
||||||
client_config.network.libp2p_port =
|
|
||||||
unused_tcp_port().map_err(|e| format!("Failed to get port for libp2p: {}", e))?;
|
|
||||||
client_config.network.discovery_port =
|
|
||||||
unused_udp_port().map_err(|e| format!("Failed to get port for discovery: {}", e))?;
|
|
||||||
client_config.http_api.listen_port = 0;
|
client_config.http_api.listen_port = 0;
|
||||||
client_config.http_metrics.listen_port = 0;
|
client_config.http_metrics.listen_port = 0;
|
||||||
}
|
}
|
||||||
@ -798,13 +784,177 @@ pub fn get_config<E: EthSpec>(
|
|||||||
Ok(client_config)
|
Ok(client_config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the network config from the command line arguments
|
/// Gets the listening_addresses for lighthouse based on the cli options.
|
||||||
|
pub fn parse_listening_addresses(
|
||||||
|
cli_args: &ArgMatches,
|
||||||
|
log: &Logger,
|
||||||
|
) -> Result<ListenAddress, String> {
|
||||||
|
let listen_addresses_str = cli_args
|
||||||
|
.values_of("listen-address")
|
||||||
|
.expect("--listen_addresses has a default value");
|
||||||
|
|
||||||
|
let use_zero_ports = cli_args.is_present("zero-ports");
|
||||||
|
|
||||||
|
// parse the possible ips
|
||||||
|
let mut maybe_ipv4 = None;
|
||||||
|
let mut maybe_ipv6 = None;
|
||||||
|
for addr_str in listen_addresses_str {
|
||||||
|
let addr = addr_str.parse::<IpAddr>().map_err(|parse_error| {
|
||||||
|
format!("Failed to parse listen-address ({addr_str}) as an Ip address: {parse_error}")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
IpAddr::V4(v4_addr) => match &maybe_ipv4 {
|
||||||
|
Some(first_ipv4_addr) => {
|
||||||
|
return Err(format!(
|
||||||
|
"When setting the --listen-address option twice, use an IpV4 address and an Ipv6 address. \
|
||||||
|
Got two IpV4 addresses {first_ipv4_addr} and {v4_addr}"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
None => maybe_ipv4 = Some(v4_addr),
|
||||||
|
},
|
||||||
|
IpAddr::V6(v6_addr) => match &maybe_ipv6 {
|
||||||
|
Some(first_ipv6_addr) => {
|
||||||
|
return Err(format!(
|
||||||
|
"When setting the --listen-address option twice, use an IpV4 address and an Ipv6 address. \
|
||||||
|
Got two IpV6 addresses {first_ipv6_addr} and {v6_addr}"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
None => maybe_ipv6 = Some(v6_addr),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the possible tcp ports
|
||||||
|
let port = cli_args
|
||||||
|
.value_of("port")
|
||||||
|
.expect("--port has a default value")
|
||||||
|
.parse::<u16>()
|
||||||
|
.map_err(|parse_error| format!("Failed to parse --port as an integer: {parse_error}"))?;
|
||||||
|
let port6 = cli_args
|
||||||
|
.value_of("port6")
|
||||||
|
.map(str::parse::<u16>)
|
||||||
|
.transpose()
|
||||||
|
.map_err(|parse_error| format!("Failed to parse --port6 as an integer: {parse_error}"))?
|
||||||
|
.unwrap_or(9090);
|
||||||
|
|
||||||
|
// parse the possible udp ports
|
||||||
|
let maybe_udp_port = cli_args
|
||||||
|
.value_of("discovery-port")
|
||||||
|
.map(str::parse::<u16>)
|
||||||
|
.transpose()
|
||||||
|
.map_err(|parse_error| {
|
||||||
|
format!("Failed to parse --discovery-port as an integer: {parse_error}")
|
||||||
|
})?;
|
||||||
|
let maybe_udp6_port = cli_args
|
||||||
|
.value_of("discovery-port6")
|
||||||
|
.map(str::parse::<u16>)
|
||||||
|
.transpose()
|
||||||
|
.map_err(|parse_error| {
|
||||||
|
format!("Failed to parse --discovery-port6 as an integer: {parse_error}")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Now put everything together
|
||||||
|
let listening_addresses = match (maybe_ipv4, maybe_ipv6) {
|
||||||
|
(None, None) => {
|
||||||
|
// This should never happen unless clap is broken
|
||||||
|
return Err("No listening addresses provided".into());
|
||||||
|
}
|
||||||
|
(None, Some(ipv6)) => {
|
||||||
|
// A single ipv6 address was provided. Set the ports
|
||||||
|
|
||||||
|
if cli_args.is_present("port6") {
|
||||||
|
warn!(log, "When listening only over IpV6, use the --port flag. The value of --port6 will be ignored.")
|
||||||
|
}
|
||||||
|
// use zero ports if required. If not, use the given port.
|
||||||
|
let tcp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_tcp6_port)
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(port);
|
||||||
|
|
||||||
|
if maybe_udp6_port.is_some() {
|
||||||
|
warn!(log, "When listening only over IpV6, use the --discovery-port flag. The value of --discovery-port6 will be ignored.")
|
||||||
|
}
|
||||||
|
// use zero ports if required. If not, use the specific udp port. If none given, use
|
||||||
|
// the tcp port.
|
||||||
|
let udp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_udp6_port)
|
||||||
|
.transpose()?
|
||||||
|
.or(maybe_udp_port)
|
||||||
|
.unwrap_or(port);
|
||||||
|
|
||||||
|
ListenAddress::V6(lighthouse_network::ListenAddr {
|
||||||
|
addr: ipv6,
|
||||||
|
udp_port,
|
||||||
|
tcp_port,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(Some(ipv4), None) => {
|
||||||
|
// A single ipv4 address was provided. Set the ports
|
||||||
|
|
||||||
|
// use zero ports if required. If not, use the given port.
|
||||||
|
let tcp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_tcp4_port)
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(port);
|
||||||
|
// use zero ports if required. If not, use the specific udp port. If none given, use
|
||||||
|
// the tcp port.
|
||||||
|
let udp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_udp4_port)
|
||||||
|
.transpose()?
|
||||||
|
.or(maybe_udp_port)
|
||||||
|
.unwrap_or(port);
|
||||||
|
ListenAddress::V4(lighthouse_network::ListenAddr {
|
||||||
|
addr: ipv4,
|
||||||
|
udp_port,
|
||||||
|
tcp_port,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(Some(ipv4), Some(ipv6)) => {
|
||||||
|
let ipv4_tcp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_tcp4_port)
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(port);
|
||||||
|
let ipv4_udp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_udp4_port)
|
||||||
|
.transpose()?
|
||||||
|
.or(maybe_udp_port)
|
||||||
|
.unwrap_or(ipv4_tcp_port);
|
||||||
|
|
||||||
|
// Defaults to 9090 when required
|
||||||
|
let ipv6_tcp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_tcp6_port)
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(port6);
|
||||||
|
let ipv6_udp_port = use_zero_ports
|
||||||
|
.then(unused_port::unused_udp6_port)
|
||||||
|
.transpose()?
|
||||||
|
.or(maybe_udp6_port)
|
||||||
|
.unwrap_or(ipv6_tcp_port);
|
||||||
|
ListenAddress::DualStack(
|
||||||
|
lighthouse_network::ListenAddr {
|
||||||
|
addr: ipv4,
|
||||||
|
udp_port: ipv4_udp_port,
|
||||||
|
tcp_port: ipv4_tcp_port,
|
||||||
|
},
|
||||||
|
lighthouse_network::ListenAddr {
|
||||||
|
addr: ipv6,
|
||||||
|
udp_port: ipv6_udp_port,
|
||||||
|
tcp_port: ipv6_tcp_port,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(listening_addresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the network config from the command line arguments.
|
||||||
pub fn set_network_config(
|
pub fn set_network_config(
|
||||||
config: &mut NetworkConfig,
|
config: &mut NetworkConfig,
|
||||||
cli_args: &ArgMatches,
|
cli_args: &ArgMatches,
|
||||||
data_dir: &Path,
|
data_dir: &Path,
|
||||||
log: &Logger,
|
log: &Logger,
|
||||||
use_listening_port_as_enr_port_by_default: bool,
|
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// If a network dir has been specified, override the `datadir` definition.
|
// If a network dir has been specified, override the `datadir` definition.
|
||||||
if let Some(dir) = cli_args.value_of("network-dir") {
|
if let Some(dir) = cli_args.value_of("network-dir") {
|
||||||
@ -825,12 +975,7 @@ pub fn set_network_config(
|
|||||||
config.shutdown_after_sync = true;
|
config.shutdown_after_sync = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(listen_address_str) = cli_args.value_of("listen-address") {
|
config.set_listening_addr(parse_listening_addresses(cli_args, log)?);
|
||||||
let listen_address = listen_address_str
|
|
||||||
.parse()
|
|
||||||
.map_err(|_| format!("Invalid listen address: {:?}", listen_address_str))?;
|
|
||||||
config.listen_address = listen_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(target_peers_str) = cli_args.value_of("target-peers") {
|
if let Some(target_peers_str) = cli_args.value_of("target-peers") {
|
||||||
config.target_peers = target_peers_str
|
config.target_peers = target_peers_str
|
||||||
@ -838,21 +983,6 @@ pub fn set_network_config(
|
|||||||
.map_err(|_| format!("Invalid number of target peers: {}", target_peers_str))?;
|
.map_err(|_| format!("Invalid number of target peers: {}", target_peers_str))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(port_str) = cli_args.value_of("port") {
|
|
||||||
let port = port_str
|
|
||||||
.parse::<u16>()
|
|
||||||
.map_err(|_| format!("Invalid port: {}", port_str))?;
|
|
||||||
config.libp2p_port = port;
|
|
||||||
config.discovery_port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(port_str) = cli_args.value_of("discovery-port") {
|
|
||||||
let port = port_str
|
|
||||||
.parse::<u16>()
|
|
||||||
.map_err(|_| format!("Invalid port: {}", port_str))?;
|
|
||||||
config.discovery_port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(value) = cli_args.value_of("network-load") {
|
if let Some(value) = cli_args.value_of("network-load") {
|
||||||
let network_load = value
|
let network_load = value
|
||||||
.parse::<u8>()
|
.parse::<u8>()
|
||||||
@ -908,7 +1038,7 @@ pub fn set_network_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp-port") {
|
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp-port") {
|
||||||
config.enr_udp_port = Some(
|
config.enr_udp4_port = Some(
|
||||||
enr_udp_port_str
|
enr_udp_port_str
|
||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.map_err(|_| format!("Invalid discovery port: {}", enr_udp_port_str))?,
|
.map_err(|_| format!("Invalid discovery port: {}", enr_udp_port_str))?,
|
||||||
@ -916,7 +1046,23 @@ pub fn set_network_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enr_tcp_port_str) = cli_args.value_of("enr-tcp-port") {
|
if let Some(enr_tcp_port_str) = cli_args.value_of("enr-tcp-port") {
|
||||||
config.enr_tcp_port = Some(
|
config.enr_tcp4_port = Some(
|
||||||
|
enr_tcp_port_str
|
||||||
|
.parse::<u16>()
|
||||||
|
.map_err(|_| format!("Invalid ENR TCP port: {}", enr_tcp_port_str))?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp6-port") {
|
||||||
|
config.enr_udp6_port = Some(
|
||||||
|
enr_udp_port_str
|
||||||
|
.parse::<u16>()
|
||||||
|
.map_err(|_| format!("Invalid discovery port: {}", enr_udp_port_str))?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(enr_tcp_port_str) = cli_args.value_of("enr-tcp6-port") {
|
||||||
|
config.enr_tcp6_port = Some(
|
||||||
enr_tcp_port_str
|
enr_tcp_port_str
|
||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.map_err(|_| format!("Invalid ENR TCP port: {}", enr_tcp_port_str))?,
|
.map_err(|_| format!("Invalid ENR TCP port: {}", enr_tcp_port_str))?,
|
||||||
@ -924,58 +1070,106 @@ pub fn set_network_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cli_args.is_present("enr-match") {
|
if cli_args.is_present("enr-match") {
|
||||||
|
// Match the Ip and UDP port in the enr.
|
||||||
|
|
||||||
// set the enr address to localhost if the address is unspecified
|
// set the enr address to localhost if the address is unspecified
|
||||||
if config.listen_address == IpAddr::V4(Ipv4Addr::UNSPECIFIED) {
|
if let Some(ipv4_addr) = config.listen_addrs().v4().cloned() {
|
||||||
config.enr_address = Some(IpAddr::V4(Ipv4Addr::LOCALHOST));
|
let ipv4_enr_addr = if ipv4_addr.addr == Ipv4Addr::UNSPECIFIED {
|
||||||
} else if config.listen_address == IpAddr::V6(Ipv6Addr::UNSPECIFIED) {
|
Ipv4Addr::LOCALHOST
|
||||||
config.enr_address = Some(IpAddr::V6(Ipv6Addr::LOCALHOST));
|
|
||||||
} else {
|
} else {
|
||||||
config.enr_address = Some(config.listen_address);
|
ipv4_addr.addr
|
||||||
}
|
};
|
||||||
config.enr_udp_port = Some(config.discovery_port);
|
config.enr_address.0 = Some(ipv4_enr_addr);
|
||||||
|
config.enr_udp4_port = Some(ipv4_addr.udp_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enr_address) = cli_args.value_of("enr-address") {
|
if let Some(ipv6_addr) = config.listen_addrs().v6().cloned() {
|
||||||
let resolved_addr = match enr_address.parse::<IpAddr>() {
|
let ipv6_enr_addr = if ipv6_addr.addr == Ipv6Addr::UNSPECIFIED {
|
||||||
Ok(addr) => addr, // // Input is an IpAddr
|
Ipv6Addr::LOCALHOST
|
||||||
|
} else {
|
||||||
|
ipv6_addr.addr
|
||||||
|
};
|
||||||
|
config.enr_address.1 = Some(ipv6_enr_addr);
|
||||||
|
config.enr_udp6_port = Some(ipv6_addr.udp_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(enr_addresses) = cli_args.values_of("enr-address") {
|
||||||
|
let mut enr_ip4 = None;
|
||||||
|
let mut enr_ip6 = None;
|
||||||
|
let mut resolved_enr_ip4 = None;
|
||||||
|
let mut resolved_enr_ip6 = None;
|
||||||
|
|
||||||
|
for addr in enr_addresses {
|
||||||
|
match addr.parse::<IpAddr>() {
|
||||||
|
Ok(IpAddr::V4(v4_addr)) => {
|
||||||
|
if let Some(used) = enr_ip4.as_ref() {
|
||||||
|
warn!(log, "More than one Ipv4 ENR address provided"; "used" => %used, "ignored" => %v4_addr)
|
||||||
|
} else {
|
||||||
|
enr_ip4 = Some(v4_addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(IpAddr::V6(v6_addr)) => {
|
||||||
|
if let Some(used) = enr_ip6.as_ref() {
|
||||||
|
warn!(log, "More than one Ipv6 ENR address provided"; "used" => %used, "ignored" => %v6_addr)
|
||||||
|
} else {
|
||||||
|
enr_ip6 = Some(v6_addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let mut addr = enr_address.to_string();
|
// Try to resolve the address
|
||||||
// Appending enr-port to the dns hostname to appease `to_socket_addrs()` parsing.
|
|
||||||
// Since enr-update is disabled with a dns address, not setting the enr-udp-port
|
// NOTE: From checking the `to_socket_addrs` code I don't think the port
|
||||||
// will make the node undiscoverable.
|
// actually matters. Just use the udp port.
|
||||||
if let Some(enr_udp_port) =
|
|
||||||
config
|
let port = match config.listen_addrs() {
|
||||||
.enr_udp_port
|
ListenAddress::V4(v4_addr) => v4_addr.udp_port,
|
||||||
.or(if use_listening_port_as_enr_port_by_default {
|
ListenAddress::V6(v6_addr) => v6_addr.udp_port,
|
||||||
Some(config.discovery_port)
|
ListenAddress::DualStack(v4_addr, _v6_addr) => {
|
||||||
} else {
|
// NOTE: slight preference for ipv4 that I don't think is of importance.
|
||||||
None
|
v4_addr.udp_port
|
||||||
})
|
|
||||||
{
|
|
||||||
write!(addr, ":{}", enr_udp_port)
|
|
||||||
.map_err(|e| format!("Failed to write enr address {}", e))?;
|
|
||||||
} else {
|
|
||||||
return Err(
|
|
||||||
"enr-udp-port must be set for node to be discoverable with dns address"
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// `to_socket_addr()` does the dns resolution
|
|
||||||
// Note: `to_socket_addrs()` is a blocking call
|
|
||||||
let resolved_addr = if let Ok(mut resolved_addrs) = addr.to_socket_addrs() {
|
|
||||||
// Pick the first ip from the list of resolved addresses
|
|
||||||
resolved_addrs
|
|
||||||
.next()
|
|
||||||
.map(|a| a.ip())
|
|
||||||
.ok_or("Resolved dns addr contains no entries")?
|
|
||||||
} else {
|
|
||||||
return Err(format!("Failed to parse enr-address: {}", enr_address));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let addr_str = format!("{addr}:{port}");
|
||||||
|
match addr_str.to_socket_addrs() {
|
||||||
|
Err(_e) => {
|
||||||
|
return Err(format!("Failed to parse or resolve address {addr}."))
|
||||||
|
}
|
||||||
|
Ok(resolved_addresses) => {
|
||||||
|
for socket_addr in resolved_addresses {
|
||||||
|
// Use the first ipv4 and first ipv6 addresses present.
|
||||||
|
|
||||||
|
// NOTE: this means that if two dns addresses are provided, we
|
||||||
|
// might end up using the ipv4 and ipv6 resolved addresses of just
|
||||||
|
// the first.
|
||||||
|
match socket_addr.ip() {
|
||||||
|
IpAddr::V4(v4_addr) => {
|
||||||
|
if resolved_enr_ip4.is_none() {
|
||||||
|
resolved_enr_ip4 = Some(v4_addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IpAddr::V6(v6_addr) => {
|
||||||
|
if resolved_enr_ip6.is_none() {
|
||||||
|
resolved_enr_ip6 = Some(v6_addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The ENR addresses given as ips should take preference over any resolved address
|
||||||
|
let used_host_resolution = resolved_enr_ip4.is_some() || resolved_enr_ip6.is_some();
|
||||||
|
let ip4 = enr_ip4.or(resolved_enr_ip4);
|
||||||
|
let ip6 = enr_ip6.or(resolved_enr_ip6);
|
||||||
|
config.enr_address = (ip4, ip6);
|
||||||
|
if used_host_resolution {
|
||||||
config.discv5_config.enr_update = false;
|
config.discv5_config.enr_update = false;
|
||||||
resolved_addr
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
config.enr_address = Some(resolved_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if cli_args.is_present("disable-enr-auto-update") {
|
if cli_args.is_present("disable-enr-auto-update") {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#![cfg(test)]
|
#![cfg(test)]
|
||||||
#![recursion_limit = "512"]
|
|
||||||
|
|
||||||
use beacon_chain::StateSkipConfig;
|
use beacon_chain::StateSkipConfig;
|
||||||
use node_test_rig::{
|
use node_test_rig::{
|
||||||
|
@ -53,6 +53,14 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.conflicts_with("network-dir")
|
.conflicts_with("network-dir")
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("enr-udp6-port")
|
||||||
|
.long("enr-udp6-port")
|
||||||
|
.value_name("PORT")
|
||||||
|
.help("The UDP6 port of the local ENR. Set this only if you are sure other nodes \
|
||||||
|
can connect to your local node on this port over IpV6.")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("enable-enr-auto-update")
|
Arg::with_name("enable-enr-auto-update")
|
||||||
.short("x")
|
.short("x")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use beacon_node::{get_data_dir, set_network_config};
|
use beacon_node::{get_data_dir, set_network_config};
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use eth2_network_config::Eth2NetworkConfig;
|
use eth2_network_config::Eth2NetworkConfig;
|
||||||
use lighthouse_network::discv5::enr::EnrBuilder;
|
use lighthouse_network::discovery::create_enr_builder_from_config;
|
||||||
use lighthouse_network::discv5::IpMode;
|
use lighthouse_network::discv5::IpMode;
|
||||||
use lighthouse_network::discv5::{enr::CombinedKey, Discv5Config, Enr};
|
use lighthouse_network::discv5::{enr::CombinedKey, Discv5Config, Enr};
|
||||||
use lighthouse_network::{
|
use lighthouse_network::{
|
||||||
@ -57,12 +57,24 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
|||||||
|
|
||||||
let logger = slog_scope::logger();
|
let logger = slog_scope::logger();
|
||||||
|
|
||||||
set_network_config(&mut network_config, matches, &data_dir, &logger, true)?;
|
set_network_config(&mut network_config, matches, &data_dir, &logger)?;
|
||||||
|
|
||||||
// Set the enr-udp-port to the default listening port if it was not specified.
|
// Set the Enr UDP ports to the listening ports if not present.
|
||||||
if !matches.is_present("enr-udp-port") {
|
if let Some(listening_addr_v4) = network_config.listen_addrs().v4() {
|
||||||
network_config.enr_udp_port = Some(network_config.discovery_port);
|
network_config.enr_udp4_port = Some(
|
||||||
}
|
network_config
|
||||||
|
.enr_udp4_port
|
||||||
|
.unwrap_or(listening_addr_v4.udp_port),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(listening_addr_v6) = network_config.listen_addrs().v6() {
|
||||||
|
network_config.enr_udp6_port = Some(
|
||||||
|
network_config
|
||||||
|
.enr_udp6_port
|
||||||
|
.unwrap_or(listening_addr_v6.udp_port),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// By default this is enabled. If it is not set, revert to false.
|
// By default this is enabled. If it is not set, revert to false.
|
||||||
if !matches.is_present("enable-enr-auto-update") {
|
if !matches.is_present("enable-enr-auto-update") {
|
||||||
@ -70,17 +82,29 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the address to listen on
|
// the address to listen on
|
||||||
let listen_socket =
|
let listen_socket = match network_config.listen_addrs().clone() {
|
||||||
SocketAddr::new(network_config.listen_address, network_config.discovery_port);
|
lighthouse_network::ListenAddress::V4(v4_addr) => {
|
||||||
if listen_socket.is_ipv6() {
|
// Set explicitly as ipv4 otherwise
|
||||||
|
network_config.discv5_config.ip_mode = IpMode::Ip4;
|
||||||
|
v4_addr.udp_socket_addr()
|
||||||
|
}
|
||||||
|
lighthouse_network::ListenAddress::V6(v6_addr) => {
|
||||||
|
// create ipv6 sockets and enable ipv4 mapped addresses.
|
||||||
|
network_config.discv5_config.ip_mode = IpMode::Ip6 {
|
||||||
|
enable_mapped_addresses: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
v6_addr.udp_socket_addr()
|
||||||
|
}
|
||||||
|
lighthouse_network::ListenAddress::DualStack(_v4_addr, v6_addr) => {
|
||||||
// create ipv6 sockets and enable ipv4 mapped addresses.
|
// create ipv6 sockets and enable ipv4 mapped addresses.
|
||||||
network_config.discv5_config.ip_mode = IpMode::Ip6 {
|
network_config.discv5_config.ip_mode = IpMode::Ip6 {
|
||||||
enable_mapped_addresses: true,
|
enable_mapped_addresses: true,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
// Set explicitly as ipv4 otherwise
|
v6_addr.udp_socket_addr()
|
||||||
network_config.discv5_config.ip_mode = IpMode::Ip4;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let private_key = load_private_key(&network_config, &logger);
|
let private_key = load_private_key(&network_config, &logger);
|
||||||
let local_key = CombinedKey::from_libp2p(&private_key)?;
|
let local_key = CombinedKey::from_libp2p(&private_key)?;
|
||||||
@ -115,30 +139,8 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
|||||||
// Build the local ENR
|
// Build the local ENR
|
||||||
|
|
||||||
let mut local_enr = {
|
let mut local_enr = {
|
||||||
let mut builder = EnrBuilder::new("v4");
|
let enable_tcp = false;
|
||||||
// Set the enr address if specified. Set also the port.
|
let mut builder = create_enr_builder_from_config(&network_config, enable_tcp);
|
||||||
// NOTE: if the port is specified but the the address is not, the port won't be
|
|
||||||
// set since it can't be known if it's an ipv6 or ipv4 udp port.
|
|
||||||
if let Some(enr_address) = network_config.enr_address {
|
|
||||||
match enr_address {
|
|
||||||
std::net::IpAddr::V4(ipv4_addr) => {
|
|
||||||
builder.ip4(ipv4_addr);
|
|
||||||
if let Some(port) = network_config.enr_udp_port {
|
|
||||||
builder.udp4(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::net::IpAddr::V6(ipv6_addr) => {
|
|
||||||
builder.ip6(ipv6_addr);
|
|
||||||
if let Some(port) = network_config.enr_udp_port {
|
|
||||||
builder.udp6(port);
|
|
||||||
// We are enabling mapped addresses in the boot node in this case,
|
|
||||||
// so advertise an udp4 port as well.
|
|
||||||
builder.udp4(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we know of the ENR field, add it to the initial construction
|
// If we know of the ENR field, add it to the initial construction
|
||||||
if let Some(enr_fork_bytes) = enr_fork {
|
if let Some(enr_fork_bytes) = enr_fork {
|
||||||
builder.add_value("eth2", enr_fork_bytes.as_slice());
|
builder.add_value("eth2", enr_fork_bytes.as_slice());
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#![recursion_limit = "256"]
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
@ -921,6 +921,8 @@ pub struct SseExtendedPayloadAttributesGeneric<T> {
|
|||||||
#[serde(with = "eth2_serde_utils::quoted_u64")]
|
#[serde(with = "eth2_serde_utils::quoted_u64")]
|
||||||
pub proposer_index: u64,
|
pub proposer_index: u64,
|
||||||
pub parent_block_root: Hash256,
|
pub parent_block_root: Hash256,
|
||||||
|
#[serde(with = "eth2_serde_utils::quoted_u64")]
|
||||||
|
pub parent_block_number: u64,
|
||||||
pub parent_block_hash: ExecutionBlockHash,
|
pub parent_block_hash: ExecutionBlockHash,
|
||||||
pub payload_attributes: T,
|
pub payload_attributes: T,
|
||||||
}
|
}
|
||||||
@ -958,6 +960,7 @@ impl ForkVersionDeserialize for SseExtendedPayloadAttributes {
|
|||||||
proposal_slot: helper.proposal_slot,
|
proposal_slot: helper.proposal_slot,
|
||||||
proposer_index: helper.proposer_index,
|
proposer_index: helper.proposer_index,
|
||||||
parent_block_root: helper.parent_block_root,
|
parent_block_root: helper.parent_block_root,
|
||||||
|
parent_block_number: helper.parent_block_number,
|
||||||
parent_block_hash: helper.parent_block_hash,
|
parent_block_hash: helper.parent_block_hash,
|
||||||
payload_attributes: SsePayloadAttributes::deserialize_by_fork::<D>(
|
payload_attributes: SsePayloadAttributes::deserialize_by_fork::<D>(
|
||||||
helper.payload_attributes,
|
helper.payload_attributes,
|
||||||
|
@ -6,14 +6,30 @@ pub enum Transport {
|
|||||||
Udp,
|
Udp,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A convenience function for `unused_port(Transport::Tcp)`.
|
#[derive(Copy, Clone)]
|
||||||
pub fn unused_tcp_port() -> Result<u16, String> {
|
pub enum IpVersion {
|
||||||
unused_port(Transport::Tcp)
|
Ipv4,
|
||||||
|
Ipv6,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A convenience function for `unused_port(Transport::Tcp)`.
|
/// A convenience wrapper over [`zero_port`].
|
||||||
pub fn unused_udp_port() -> Result<u16, String> {
|
pub fn unused_tcp4_port() -> Result<u16, String> {
|
||||||
unused_port(Transport::Udp)
|
zero_port(Transport::Tcp, IpVersion::Ipv4)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A convenience wrapper over [`zero_port`].
|
||||||
|
pub fn unused_udp4_port() -> Result<u16, String> {
|
||||||
|
zero_port(Transport::Udp, IpVersion::Ipv4)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A convenience wrapper over [`zero_port`].
|
||||||
|
pub fn unused_tcp6_port() -> Result<u16, String> {
|
||||||
|
zero_port(Transport::Tcp, IpVersion::Ipv6)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A convenience wrapper over [`zero_port`].
|
||||||
|
pub fn unused_udp6_port() -> Result<u16, String> {
|
||||||
|
zero_port(Transport::Udp, IpVersion::Ipv6)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A bit of hack to find an unused port.
|
/// A bit of hack to find an unused port.
|
||||||
@ -26,10 +42,15 @@ pub fn unused_udp_port() -> Result<u16, String> {
|
|||||||
/// It is possible that users are unable to bind to the ports returned by this function as the OS
|
/// It is possible that users are unable to bind to the ports returned by this function as the OS
|
||||||
/// has a buffer period where it doesn't allow binding to the same port even after the socket is
|
/// has a buffer period where it doesn't allow binding to the same port even after the socket is
|
||||||
/// closed. We might have to use SO_REUSEADDR socket option from `std::net2` crate in that case.
|
/// closed. We might have to use SO_REUSEADDR socket option from `std::net2` crate in that case.
|
||||||
pub fn unused_port(transport: Transport) -> Result<u16, String> {
|
pub fn zero_port(transport: Transport, ipv: IpVersion) -> Result<u16, String> {
|
||||||
|
let localhost = match ipv {
|
||||||
|
IpVersion::Ipv4 => std::net::Ipv4Addr::LOCALHOST.into(),
|
||||||
|
IpVersion::Ipv6 => std::net::Ipv6Addr::LOCALHOST.into(),
|
||||||
|
};
|
||||||
|
let socket_addr = std::net::SocketAddr::new(localhost, 0);
|
||||||
let local_addr = match transport {
|
let local_addr = match transport {
|
||||||
Transport::Tcp => {
|
Transport::Tcp => {
|
||||||
let listener = TcpListener::bind("127.0.0.1:0").map_err(|e| {
|
let listener = TcpListener::bind(socket_addr).map_err(|e| {
|
||||||
format!("Failed to create TCP listener to find unused port: {:?}", e)
|
format!("Failed to create TCP listener to find unused port: {:?}", e)
|
||||||
})?;
|
})?;
|
||||||
listener.local_addr().map_err(|e| {
|
listener.local_addr().map_err(|e| {
|
||||||
@ -40,7 +61,7 @@ pub fn unused_port(transport: Transport) -> Result<u16, String> {
|
|||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
Transport::Udp => {
|
Transport::Udp => {
|
||||||
let socket = UdpSocket::bind("127.0.0.1:0")
|
let socket = UdpSocket::bind(socket_addr)
|
||||||
.map_err(|e| format!("Failed to create UDP socket to find unused port: {:?}", e))?;
|
.map_err(|e| format!("Failed to create UDP socket to find unused port: {:?}", e))?;
|
||||||
socket.local_addr().map_err(|e| {
|
socket.local_addr().map_err(|e| {
|
||||||
format!(
|
format!(
|
||||||
|
@ -6,3 +6,4 @@ pub mod metrics;
|
|||||||
pub mod query;
|
pub mod query;
|
||||||
pub mod reject;
|
pub mod reject;
|
||||||
pub mod task;
|
pub mod task;
|
||||||
|
pub mod uor;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use warp::reply::{Reply, Response};
|
||||||
|
|
||||||
/// A convenience wrapper around `blocking_task`.
|
/// A convenience wrapper around `blocking_task`.
|
||||||
pub async fn blocking_task<F, T>(func: F) -> Result<T, warp::Rejection>
|
pub async fn blocking_task<F, T>(func: F) -> Result<T, warp::Rejection>
|
||||||
@ -8,16 +9,29 @@ where
|
|||||||
{
|
{
|
||||||
tokio::task::spawn_blocking(func)
|
tokio::task::spawn_blocking(func)
|
||||||
.await
|
.await
|
||||||
.unwrap_or_else(|_| Err(warp::reject::reject())) // This should really be a 500
|
.unwrap_or_else(|_| Err(warp::reject::reject()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A convenience wrapper around `blocking_task` that returns a `warp::reply::Response`.
|
||||||
|
///
|
||||||
|
/// Using this method consistently makes it possible to simplify types using `.unify()` or `.uor()`.
|
||||||
|
pub async fn blocking_response_task<F, T>(func: F) -> Result<Response, warp::Rejection>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> Result<T, warp::Rejection> + Send + 'static,
|
||||||
|
T: Reply + Send + 'static,
|
||||||
|
{
|
||||||
|
blocking_task(func).await.map(Reply::into_response)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A convenience wrapper around `blocking_task` for use with `warp` JSON responses.
|
/// A convenience wrapper around `blocking_task` for use with `warp` JSON responses.
|
||||||
pub async fn blocking_json_task<F, T>(func: F) -> Result<warp::reply::Json, warp::Rejection>
|
pub async fn blocking_json_task<F, T>(func: F) -> Result<Response, warp::Rejection>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Result<T, warp::Rejection> + Send + 'static,
|
F: FnOnce() -> Result<T, warp::Rejection> + Send + 'static,
|
||||||
T: Serialize + Send + 'static,
|
T: Serialize + Send + 'static,
|
||||||
{
|
{
|
||||||
blocking_task(func)
|
blocking_response_task(|| {
|
||||||
|
let response = func()?;
|
||||||
|
Ok(warp::reply::json(&response))
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
.map(|resp| warp::reply::json(&resp))
|
|
||||||
}
|
}
|
||||||
|
25
common/warp_utils/src/uor.rs
Normal file
25
common/warp_utils/src/uor.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use warp::{filters::BoxedFilter, Filter, Rejection};
|
||||||
|
|
||||||
|
/// Mixin trait for `Filter` providing the unifying-or method.
|
||||||
|
pub trait UnifyingOrFilter: Filter<Error = Rejection> + Sized + Send + Sync + 'static
|
||||||
|
where
|
||||||
|
Self::Extract: Send,
|
||||||
|
{
|
||||||
|
/// Unifying `or`.
|
||||||
|
///
|
||||||
|
/// This is a shorthand for `self.or(other).unify().boxed()`, which is useful because it keeps
|
||||||
|
/// the filter type simple and prevents type-checker explosions.
|
||||||
|
fn uor<F>(self, other: F) -> BoxedFilter<Self::Extract>
|
||||||
|
where
|
||||||
|
F: Filter<Extract = Self::Extract, Error = Rejection> + Clone + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
self.or(other).unify().boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> UnifyingOrFilter for F
|
||||||
|
where
|
||||||
|
F: Filter<Error = Rejection> + Sized + Send + Sync + 'static,
|
||||||
|
F::Extract: Send,
|
||||||
|
{
|
||||||
|
}
|
@ -1698,7 +1698,6 @@ mod tests {
|
|||||||
|
|
||||||
fn get_queued_attestations() -> Vec<QueuedAttestation> {
|
fn get_queued_attestations() -> Vec<QueuedAttestation> {
|
||||||
(1..4)
|
(1..4)
|
||||||
.into_iter()
|
|
||||||
.map(|i| QueuedAttestation {
|
.map(|i| QueuedAttestation {
|
||||||
slot: Slot::new(i),
|
slot: Slot::new(i),
|
||||||
attesting_indices: vec![],
|
attesting_indices: vec![],
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#![recursion_limit = "256"]
|
|
||||||
//! Provides procedural derive macros for the `Encode` and `Decode` traits of the `eth2_ssz` crate.
|
//! Provides procedural derive macros for the `Encode` and `Decode` traits of the `eth2_ssz` crate.
|
||||||
//!
|
//!
|
||||||
//! ## Attributes
|
//! ## Attributes
|
||||||
|
@ -106,7 +106,7 @@ fn tx_peek_blob_versioned_hashes<T: EthSpec>(
|
|||||||
.safe_sub(blob_versioned_hashes_offset as usize)?
|
.safe_sub(blob_versioned_hashes_offset as usize)?
|
||||||
.safe_div(32)?;
|
.safe_div(32)?;
|
||||||
|
|
||||||
Ok((0..num_hashes).into_iter().map(move |i| {
|
Ok((0..num_hashes).map(move |i| {
|
||||||
let next_version_hash_index =
|
let next_version_hash_index =
|
||||||
(blob_versioned_hashes_offset as usize).safe_add(i.safe_mul(32)?)?;
|
(blob_versioned_hashes_offset as usize).safe_add(i.safe_mul(32)?)?;
|
||||||
let bytes = opaque_tx
|
let bytes = opaque_tx
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#![recursion_limit = "256"]
|
|
||||||
use darling::FromDeriveInput;
|
use darling::FromDeriveInput;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
//! Ethereum 2.0 types
|
//! Ethereum 2.0 types
|
||||||
// Required for big type-level numbers
|
|
||||||
#![recursion_limit = "128"]
|
|
||||||
// Clippy lint set up
|
// Clippy lint set up
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
not(test),
|
not(test),
|
||||||
|
@ -266,7 +266,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Hashes the `self.serialize()` bytes.
|
/// Hashes the `self.serialize()` bytes.
|
||||||
#[allow(clippy::derive_hash_xor_eq)]
|
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||||
impl<Pub, AggPub, Sig, AggSig> Hash for GenericAggregateSignature<Pub, AggPub, Sig, AggSig>
|
impl<Pub, AggPub, Sig, AggSig> Hash for GenericAggregateSignature<Pub, AggPub, Sig, AggSig>
|
||||||
where
|
where
|
||||||
Sig: TSignature<Pub>,
|
Sig: TSignature<Pub>,
|
||||||
|
@ -3,15 +3,14 @@ use lighthouse_network::{
|
|||||||
discovery::{build_enr, CombinedKey, CombinedKeyExt, Keypair, ENR_FILENAME},
|
discovery::{build_enr, CombinedKey, CombinedKeyExt, Keypair, ENR_FILENAME},
|
||||||
NetworkConfig, NETWORK_KEY_FILENAME,
|
NetworkConfig, NETWORK_KEY_FILENAME,
|
||||||
};
|
};
|
||||||
use std::fs;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::net::IpAddr;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::{fs, net::Ipv4Addr};
|
||||||
use types::{ChainSpec, EnrForkId, Epoch, EthSpec, Hash256};
|
use types::{ChainSpec, EnrForkId, Epoch, EthSpec, Hash256};
|
||||||
|
|
||||||
pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
|
pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
|
||||||
let ip: IpAddr = clap_utils::parse_required(matches, "ip")?;
|
let ip: Ipv4Addr = clap_utils::parse_required(matches, "ip")?;
|
||||||
let udp_port: u16 = clap_utils::parse_required(matches, "udp-port")?;
|
let udp_port: u16 = clap_utils::parse_required(matches, "udp-port")?;
|
||||||
let tcp_port: u16 = clap_utils::parse_required(matches, "tcp-port")?;
|
let tcp_port: u16 = clap_utils::parse_required(matches, "tcp-port")?;
|
||||||
let output_dir: PathBuf = clap_utils::parse_required(matches, "output-dir")?;
|
let output_dir: PathBuf = clap_utils::parse_required(matches, "output-dir")?;
|
||||||
@ -25,12 +24,10 @@ pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = NetworkConfig {
|
let mut config = NetworkConfig::default();
|
||||||
enr_address: Some(ip),
|
config.enr_address = (Some(ip), None);
|
||||||
enr_udp_port: Some(udp_port),
|
config.enr_udp4_port = Some(udp_port);
|
||||||
enr_tcp_port: Some(tcp_port),
|
config.enr_tcp6_port = Some(tcp_port);
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let local_keypair = Keypair::generate_secp256k1();
|
let local_keypair = Keypair::generate_secp256k1();
|
||||||
let enr_key = CombinedKey::from_libp2p(&local_keypair)?;
|
let enr_key = CombinedKey::from_libp2p(&local_keypair)?;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#![recursion_limit = "256"]
|
|
||||||
|
|
||||||
mod metrics;
|
mod metrics;
|
||||||
|
|
||||||
use beacon_node::ProductionBeaconNode;
|
use beacon_node::ProductionBeaconNode;
|
||||||
|
@ -8,7 +8,7 @@ use eth1::Eth1Endpoint;
|
|||||||
use lighthouse_network::PeerId;
|
use lighthouse_network::PeerId;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::net::IpAddr;
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@ -16,7 +16,7 @@ use std::string::ToString;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use types::{Address, Checkpoint, Epoch, ExecutionBlockHash, ForkName, Hash256, MainnetEthSpec};
|
use types::{Address, Checkpoint, Epoch, ExecutionBlockHash, ForkName, Hash256, MainnetEthSpec};
|
||||||
use unused_port::{unused_tcp_port, unused_udp_port};
|
use unused_port::{unused_tcp4_port, unused_tcp6_port, unused_udp4_port, unused_udp6_port};
|
||||||
|
|
||||||
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/";
|
||||||
|
|
||||||
@ -851,37 +851,188 @@ fn network_shutdown_after_sync_disabled_flag() {
|
|||||||
.with_config(|config| assert!(!config.network.shutdown_after_sync));
|
.with_config(|config| assert!(!config.network.shutdown_after_sync));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_listen_address_flag() {
|
fn network_listen_address_flag_v4() {
|
||||||
let addr = "127.0.0.2".parse::<IpAddr>().unwrap();
|
let addr = "127.0.0.2".parse::<Ipv4Addr>().unwrap();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("listen-address", Some("127.0.0.2"))
|
.flag("listen-address", Some("127.0.0.2"))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.listen_address, addr));
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v4().map(|addr| addr.addr),
|
||||||
|
Some(addr)
|
||||||
|
)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_port_flag() {
|
fn network_listen_address_flag_v6() {
|
||||||
let port = unused_tcp_port().expect("Unable to find unused port.");
|
const ADDR: &str = "::1";
|
||||||
|
let addr = ADDR.parse::<Ipv6Addr>().unwrap();
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some(ADDR))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v6().map(|addr| addr.addr),
|
||||||
|
Some(addr)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_listen_address_flag_dual_stack() {
|
||||||
|
const V4_ADDR: &str = "127.0.0.1";
|
||||||
|
const V6_ADDR: &str = "::1";
|
||||||
|
let ipv6_addr = V6_ADDR.parse::<Ipv6Addr>().unwrap();
|
||||||
|
let ipv4_addr = V4_ADDR.parse::<Ipv4Addr>().unwrap();
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some(V6_ADDR))
|
||||||
|
.flag("listen-address", Some(V4_ADDR))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v6().map(|addr| addr.addr),
|
||||||
|
Some(ipv6_addr)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v4().map(|addr| addr.addr),
|
||||||
|
Some(ipv4_addr)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn network_listen_address_flag_wrong_double_v4_value_config() {
|
||||||
|
// It's actually possible to listen over multiple sockets in libp2p over the same ip version.
|
||||||
|
// However this is not compatible with the single contactable address over each version in ENR.
|
||||||
|
// Because of this, it's important to test this is disallowed.
|
||||||
|
const V4_ADDR1: &str = "127.0.0.1";
|
||||||
|
const V4_ADDR2: &str = "0.0.0.0";
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some(V4_ADDR1))
|
||||||
|
.flag("listen-address", Some(V4_ADDR2))
|
||||||
|
.run_with_zero_port();
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn network_listen_address_flag_wrong_double_v6_value_config() {
|
||||||
|
// It's actually possible to listen over multiple sockets in libp2p over the same ip version.
|
||||||
|
// However this is not compatible with the single contactable address over each version in ENR.
|
||||||
|
// Because of this, it's important to test this is disallowed.
|
||||||
|
const V6_ADDR1: &str = "::3";
|
||||||
|
const V6_ADDR2: &str = "::1";
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some(V6_ADDR1))
|
||||||
|
.flag("listen-address", Some(V6_ADDR2))
|
||||||
|
.run_with_zero_port();
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_port_flag_over_ipv4() {
|
||||||
|
let port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("port", Some(port.to_string().as_str()))
|
.flag("port", Some(port.to_string().as_str()))
|
||||||
.run()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.libp2p_port, port);
|
assert_eq!(
|
||||||
assert_eq!(config.network.discovery_port, port);
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v4()
|
||||||
|
.map(|listen_addr| (listen_addr.udp_port, listen_addr.tcp_port)),
|
||||||
|
Some((port, port))
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn network_port_and_discovery_port_flags() {
|
fn network_port_flag_over_ipv6() {
|
||||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
let port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
let port2 = unused_udp_port().expect("Unable to find unused port.");
|
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("port", Some(port1.to_string().as_str()))
|
.flag("listen-address", Some("::1"))
|
||||||
.flag("discovery-port", Some(port2.to_string().as_str()))
|
.flag("port", Some(port.to_string().as_str()))
|
||||||
.run()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.libp2p_port, port1);
|
assert_eq!(
|
||||||
assert_eq!(config.network.discovery_port, port2);
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v6()
|
||||||
|
.map(|listen_addr| (listen_addr.udp_port, listen_addr.tcp_port)),
|
||||||
|
Some((port, port))
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_port_and_discovery_port_flags_over_ipv4() {
|
||||||
|
let tcp4_port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
|
let udp4_port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||||
|
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v4()
|
||||||
|
.map(|listen_addr| (listen_addr.tcp_port, listen_addr.udp_port)),
|
||||||
|
Some((tcp4_port, udp4_port))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_port_and_discovery_port_flags_over_ipv6() {
|
||||||
|
let tcp6_port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
let udp6_port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some("::1"))
|
||||||
|
.flag("port", Some(tcp6_port.to_string().as_str()))
|
||||||
|
.flag("discovery-port", Some(udp6_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v6()
|
||||||
|
.map(|listen_addr| (listen_addr.tcp_port, listen_addr.udp_port)),
|
||||||
|
Some((tcp6_port, udp6_port))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn network_port_and_discovery_port_flags_over_ipv4_and_ipv6() {
|
||||||
|
let tcp4_port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
|
let udp4_port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
let tcp6_port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
let udp6_port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("listen-address", Some("::1"))
|
||||||
|
.flag("listen-address", Some("127.0.0.1"))
|
||||||
|
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||||
|
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||||
|
.flag("port6", Some(tcp6_port.to_string().as_str()))
|
||||||
|
.flag("discovery-port6", Some(udp6_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v4()
|
||||||
|
.map(|listen_addr| (listen_addr.tcp_port, listen_addr.udp_port)),
|
||||||
|
Some((tcp4_port, udp4_port))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
config
|
||||||
|
.network
|
||||||
|
.listen_addrs()
|
||||||
|
.v6()
|
||||||
|
.map(|listen_addr| (listen_addr.tcp_port, listen_addr.udp_port)),
|
||||||
|
Some((tcp6_port, udp6_port))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn disable_discovery_flag() {
|
fn disable_discovery_flag() {
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
@ -986,7 +1137,6 @@ fn zero_ports_flag() {
|
|||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.enr_address, None);
|
|
||||||
assert_eq!(config.http_api.listen_port, 0);
|
assert_eq!(config.http_api.listen_port, 0);
|
||||||
assert_eq!(config.http_metrics.listen_port, 0);
|
assert_eq!(config.http_metrics.listen_port, 0);
|
||||||
});
|
});
|
||||||
@ -1003,67 +1153,171 @@ fn network_load_flag() {
|
|||||||
|
|
||||||
// Tests for ENR flags.
|
// Tests for ENR flags.
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_udp_port_flags() {
|
fn enr_udp_port_flag() {
|
||||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.enr_udp_port, Some(port)));
|
.with_config(|config| assert_eq!(config.network.enr_udp4_port, Some(port)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_tcp_port_flags() {
|
fn enr_tcp_port_flag() {
|
||||||
let port = unused_tcp_port().expect("Unable to find unused port.");
|
let port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-tcp-port", Some(port.to_string().as_str()))
|
.flag("enr-tcp-port", Some(port.to_string().as_str()))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| assert_eq!(config.network.enr_tcp_port, Some(port)));
|
.with_config(|config| assert_eq!(config.network.enr_tcp4_port, Some(port)));
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_match_flag() {
|
fn enr_udp6_port_flag() {
|
||||||
let addr = "127.0.0.2".parse::<IpAddr>().unwrap();
|
let port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
let port1 = unused_udp_port().expect("Unable to find unused port.");
|
CommandLineTest::new()
|
||||||
let port2 = unused_udp_port().expect("Unable to find unused port.");
|
.flag("enr-udp6-port", Some(port.to_string().as_str()))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| assert_eq!(config.network.enr_udp6_port, Some(port)));
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_tcp6_port_flag() {
|
||||||
|
let port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-tcp6-port", Some(port.to_string().as_str()))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| assert_eq!(config.network.enr_tcp6_port, Some(port)));
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_match_flag_over_ipv4() {
|
||||||
|
let addr = "127.0.0.2".parse::<Ipv4Addr>().unwrap();
|
||||||
|
let udp4_port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
let tcp4_port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-match", None)
|
.flag("enr-match", None)
|
||||||
.flag("listen-address", Some("127.0.0.2"))
|
.flag("listen-address", Some("127.0.0.2"))
|
||||||
.flag("discovery-port", Some(port1.to_string().as_str()))
|
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||||
.flag("port", Some(port2.to_string().as_str()))
|
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||||
.run()
|
.run()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.listen_address, addr);
|
assert_eq!(
|
||||||
assert_eq!(config.network.enr_address, Some(addr));
|
config.network.listen_addrs().v4().map(|listen_addr| (
|
||||||
assert_eq!(config.network.discovery_port, port1);
|
listen_addr.addr,
|
||||||
assert_eq!(config.network.enr_udp_port, Some(port1));
|
listen_addr.udp_port,
|
||||||
|
listen_addr.tcp_port
|
||||||
|
)),
|
||||||
|
Some((addr, udp4_port, tcp4_port))
|
||||||
|
);
|
||||||
|
assert_eq!(config.network.enr_address, (Some(addr), None));
|
||||||
|
assert_eq!(config.network.enr_udp4_port, Some(udp4_port));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_address_flag() {
|
fn enr_match_flag_over_ipv6() {
|
||||||
let addr = "192.167.1.1".parse::<IpAddr>().unwrap();
|
const ADDR: &str = "::1";
|
||||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
let addr = ADDR.parse::<Ipv6Addr>().unwrap();
|
||||||
|
let udp6_port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
|
let tcp6_port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-match", None)
|
||||||
|
.flag("listen-address", Some(ADDR))
|
||||||
|
.flag("discovery-port", Some(udp6_port.to_string().as_str()))
|
||||||
|
.flag("port", Some(tcp6_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v6().map(|listen_addr| (
|
||||||
|
listen_addr.addr,
|
||||||
|
listen_addr.udp_port,
|
||||||
|
listen_addr.tcp_port
|
||||||
|
)),
|
||||||
|
Some((addr, udp6_port, tcp6_port))
|
||||||
|
);
|
||||||
|
assert_eq!(config.network.enr_address, (None, Some(addr)));
|
||||||
|
assert_eq!(config.network.enr_udp6_port, Some(udp6_port));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_match_flag_over_ipv4_and_ipv6() {
|
||||||
|
const IPV6_ADDR: &str = "::1";
|
||||||
|
let ipv6_addr = IPV6_ADDR.parse::<Ipv6Addr>().unwrap();
|
||||||
|
let udp6_port = unused_udp6_port().expect("Unable to find unused port.");
|
||||||
|
let tcp6_port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||||
|
const IPV4_ADDR: &str = "127.0.0.1";
|
||||||
|
let ipv4_addr = IPV4_ADDR.parse::<Ipv4Addr>().unwrap();
|
||||||
|
let udp4_port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
let tcp4_port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-match", None)
|
||||||
|
.flag("listen-address", Some(IPV4_ADDR))
|
||||||
|
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||||
|
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||||
|
.flag("listen-address", Some(IPV6_ADDR))
|
||||||
|
.flag("discovery-port6", Some(udp6_port.to_string().as_str()))
|
||||||
|
.flag("port6", Some(tcp6_port.to_string().as_str()))
|
||||||
|
.run()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v6().map(|listen_addr| (
|
||||||
|
listen_addr.addr,
|
||||||
|
listen_addr.udp_port,
|
||||||
|
listen_addr.tcp_port
|
||||||
|
)),
|
||||||
|
Some((ipv6_addr, udp6_port, tcp6_port))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
config.network.listen_addrs().v4().map(|listen_addr| (
|
||||||
|
listen_addr.addr,
|
||||||
|
listen_addr.udp_port,
|
||||||
|
listen_addr.tcp_port
|
||||||
|
)),
|
||||||
|
Some((ipv4_addr, udp4_port, tcp4_port))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
config.network.enr_address,
|
||||||
|
(Some(ipv4_addr), Some(ipv6_addr))
|
||||||
|
);
|
||||||
|
assert_eq!(config.network.enr_udp6_port, Some(udp6_port));
|
||||||
|
assert_eq!(config.network.enr_udp4_port, Some(udp4_port));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_address_flag_with_ipv4() {
|
||||||
|
let addr = "192.167.1.1".parse::<Ipv4Addr>().unwrap();
|
||||||
|
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-address", Some("192.167.1.1"))
|
.flag("enr-address", Some("192.167.1.1"))
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert_eq!(config.network.enr_address, Some(addr));
|
assert_eq!(config.network.enr_address, (Some(addr), None));
|
||||||
assert_eq!(config.network.enr_udp_port, Some(port));
|
assert_eq!(config.network.enr_udp4_port, Some(port));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn enr_address_flag_with_ipv6() {
|
||||||
|
let addr = "192.167.1.1".parse::<Ipv4Addr>().unwrap();
|
||||||
|
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
|
CommandLineTest::new()
|
||||||
|
.flag("enr-address", Some("192.167.1.1"))
|
||||||
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
|
.run_with_zero_port()
|
||||||
|
.with_config(|config| {
|
||||||
|
assert_eq!(config.network.enr_address, (Some(addr), None));
|
||||||
|
assert_eq!(config.network.enr_udp4_port, Some(port));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_address_dns_flag() {
|
fn enr_address_dns_flag() {
|
||||||
let addr = "127.0.0.1".parse::<IpAddr>().unwrap();
|
let addr = Ipv4Addr::LOCALHOST;
|
||||||
let ipv6addr = "::1".parse::<IpAddr>().unwrap();
|
let ipv6addr = Ipv6Addr::LOCALHOST;
|
||||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-address", Some("localhost"))
|
.flag("enr-address", Some("localhost"))
|
||||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||||
.run_with_zero_port()
|
.run_with_zero_port()
|
||||||
.with_config(|config| {
|
.with_config(|config| {
|
||||||
assert!(
|
assert!(
|
||||||
config.network.enr_address == Some(addr)
|
config.network.enr_address.0 == Some(addr)
|
||||||
|| config.network.enr_address == Some(ipv6addr)
|
|| config.network.enr_address.1 == Some(ipv6addr)
|
||||||
);
|
);
|
||||||
assert_eq!(config.network.enr_udp_port, Some(port));
|
assert_eq!(config.network.enr_udp4_port, Some(port));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -1100,8 +1354,8 @@ fn http_address_ipv6_flag() {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn http_port_flag() {
|
fn http_port_flag() {
|
||||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
let port1 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
let port2 = unused_tcp_port().expect("Unable to find unused port.");
|
let port2 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("http-port", Some(port1.to_string().as_str()))
|
.flag("http-port", Some(port1.to_string().as_str()))
|
||||||
.flag("port", Some(port2.to_string().as_str()))
|
.flag("port", Some(port2.to_string().as_str()))
|
||||||
@ -1215,8 +1469,8 @@ fn metrics_address_ipv6_flag() {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn metrics_port_flag() {
|
fn metrics_port_flag() {
|
||||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
let port1 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
let port2 = unused_tcp_port().expect("Unable to find unused port.");
|
let port2 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("metrics", None)
|
.flag("metrics", None)
|
||||||
.flag("metrics-port", Some(port1.to_string().as_str()))
|
.flag("metrics-port", Some(port1.to_string().as_str()))
|
||||||
|
@ -12,7 +12,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_udp_port;
|
use unused_port::unused_udp4_port;
|
||||||
|
|
||||||
const IP_ADDRESS: &str = "192.168.2.108";
|
const IP_ADDRESS: &str = "192.168.2.108";
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ fn enr_address_arg() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn port_flag() {
|
fn port_flag() {
|
||||||
let port = unused_udp_port().unwrap();
|
let port = unused_udp4_port().unwrap();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("port", Some(port.to_string().as_str()))
|
.flag("port", Some(port.to_string().as_str()))
|
||||||
.run_with_ip()
|
.run_with_ip()
|
||||||
@ -122,7 +122,7 @@ fn boot_nodes_flag() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn enr_port_flag() {
|
fn enr_port_flag() {
|
||||||
let port = unused_udp_port().unwrap();
|
let port = unused_udp4_port().unwrap();
|
||||||
CommandLineTest::new()
|
CommandLineTest::new()
|
||||||
.flag("enr-port", Some(port.to_string().as_str()))
|
.flag("enr-port", Some(port.to_string().as_str()))
|
||||||
.run_with_ip()
|
.run_with_ip()
|
||||||
|
@ -3,7 +3,7 @@ use std::io::prelude::*;
|
|||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::process::{Child, Command, Stdio};
|
use std::process::{Child, Command, Stdio};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
use web3::{transports::Http, Transport, Web3};
|
use web3::{transports::Http, Transport, Web3};
|
||||||
|
|
||||||
/// How long we will wait for ganache to indicate that it is ready.
|
/// How long we will wait for ganache to indicate that it is ready.
|
||||||
@ -65,7 +65,7 @@ impl GanacheInstance {
|
|||||||
/// Start a new `ganache` process, waiting until it indicates that it is ready to accept
|
/// Start a new `ganache` process, waiting until it indicates that it is ready to accept
|
||||||
/// RPC connections.
|
/// RPC connections.
|
||||||
pub fn new(chain_id: u64) -> Result<Self, String> {
|
pub fn new(chain_id: u64) -> Result<Self, String> {
|
||||||
let port = unused_tcp_port()?;
|
let port = unused_tcp4_port()?;
|
||||||
let binary = match cfg!(windows) {
|
let binary = match cfg!(windows) {
|
||||||
true => "ganache.cmd",
|
true => "ganache.cmd",
|
||||||
false => "ganache",
|
false => "ganache",
|
||||||
@ -97,7 +97,7 @@ impl GanacheInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fork(&self) -> Result<Self, String> {
|
pub fn fork(&self) -> Result<Self, String> {
|
||||||
let port = unused_tcp_port()?;
|
let port = unused_tcp4_port()?;
|
||||||
let binary = match cfg!(windows) {
|
let binary = match cfg!(windows) {
|
||||||
true => "ganache.cmd",
|
true => "ganache.cmd",
|
||||||
false => "ganache",
|
false => "ganache",
|
||||||
|
@ -4,7 +4,7 @@ use sensitive_url::SensitiveUrl;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Child;
|
use std::process::Child;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
|
|
||||||
pub const KEYSTORE_PASSWORD: &str = "testpwd";
|
pub const KEYSTORE_PASSWORD: &str = "testpwd";
|
||||||
pub const ACCOUNT1: &str = "7b8C3a386C0eea54693fFB0DA17373ffC9228139";
|
pub const ACCOUNT1: &str = "7b8C3a386C0eea54693fFB0DA17373ffC9228139";
|
||||||
@ -50,8 +50,8 @@ impl<E: GenericExecutionEngine> ExecutionEngine<E> {
|
|||||||
pub fn new(engine: E) -> Self {
|
pub fn new(engine: E) -> Self {
|
||||||
let datadir = E::init_datadir();
|
let datadir = E::init_datadir();
|
||||||
let jwt_secret_path = datadir.path().join(DEFAULT_JWT_FILE);
|
let jwt_secret_path = datadir.path().join(DEFAULT_JWT_FILE);
|
||||||
let http_port = unused_tcp_port().unwrap();
|
let http_port = unused_tcp4_port().unwrap();
|
||||||
let http_auth_port = unused_tcp_port().unwrap();
|
let http_auth_port = unused_tcp4_port().unwrap();
|
||||||
let child = E::start_client(&datadir, http_port, http_auth_port, jwt_secret_path);
|
let child = E::start_client(&datadir, http_port, http_auth_port, jwt_secret_path);
|
||||||
let provider = Provider::<Http>::try_from(format!("http://localhost:{}", http_port))
|
let provider = Provider::<Http>::try_from(format!("http://localhost:{}", http_port))
|
||||||
.expect("failed to instantiate ethers provider");
|
.expect("failed to instantiate ethers provider");
|
||||||
|
@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::process::{Child, Command, Output};
|
use std::process::{Child, Command, Output};
|
||||||
use std::{env, fs::File};
|
use std::{env, fs::File};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
|
|
||||||
const GETH_BRANCH: &str = "master";
|
const GETH_BRANCH: &str = "master";
|
||||||
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";
|
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";
|
||||||
@ -83,7 +83,7 @@ impl GenericExecutionEngine for GethEngine {
|
|||||||
http_auth_port: u16,
|
http_auth_port: u16,
|
||||||
jwt_secret_path: PathBuf,
|
jwt_secret_path: PathBuf,
|
||||||
) -> Child {
|
) -> Child {
|
||||||
let network_port = unused_tcp_port().unwrap();
|
let network_port = unused_tcp4_port().unwrap();
|
||||||
|
|
||||||
Command::new(Self::binary_path())
|
Command::new(Self::binary_path())
|
||||||
.arg("--datadir")
|
.arg("--datadir")
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#![recursion_limit = "1024"]
|
|
||||||
/// This binary runs integration tests between Lighthouse and execution engines.
|
/// This binary runs integration tests between Lighthouse and execution engines.
|
||||||
///
|
///
|
||||||
/// It will first attempt to build any supported integration clients, then it will run tests.
|
/// It will first attempt to build any supported integration clients, then it will run tests.
|
||||||
|
@ -6,7 +6,7 @@ use std::fs::File;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Child, Command, Output};
|
use std::process::{Child, Command, Output};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp4_port;
|
||||||
|
|
||||||
/// We've pinned the Nethermind version since our method of using the `master` branch to
|
/// We've pinned the Nethermind version since our method of using the `master` branch to
|
||||||
/// find the latest tag isn't working. It appears Nethermind don't always tag on `master`.
|
/// find the latest tag isn't working. It appears Nethermind don't always tag on `master`.
|
||||||
@ -88,7 +88,7 @@ impl GenericExecutionEngine for NethermindEngine {
|
|||||||
http_auth_port: u16,
|
http_auth_port: u16,
|
||||||
jwt_secret_path: PathBuf,
|
jwt_secret_path: PathBuf,
|
||||||
) -> Child {
|
) -> Child {
|
||||||
let network_port = unused_tcp_port().unwrap();
|
let network_port = unused_tcp4_port().unwrap();
|
||||||
let genesis_json_path = datadir.path().join("genesis.json");
|
let genesis_json_path = datadir.path().join("genesis.json");
|
||||||
|
|
||||||
Command::new(Self::binary_path())
|
Command::new(Self::binary_path())
|
||||||
|
@ -89,8 +89,9 @@ pub fn testing_client_config() -> ClientConfig {
|
|||||||
let mut client_config = ClientConfig::default();
|
let mut client_config = ClientConfig::default();
|
||||||
|
|
||||||
// Setting ports to `0` means that the OS will choose some available port.
|
// Setting ports to `0` means that the OS will choose some available port.
|
||||||
client_config.network.libp2p_port = 0;
|
client_config
|
||||||
client_config.network.discovery_port = 0;
|
.network
|
||||||
|
.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, 0, 0);
|
||||||
client_config.network.upnp_enabled = false;
|
client_config.network.upnp_enabled = false;
|
||||||
client_config.http_api.enabled = true;
|
client_config.http_api.enabled = true;
|
||||||
client_config.http_api.listen_port = 0;
|
client_config.http_api.listen_port = 0;
|
||||||
|
@ -13,7 +13,7 @@ use node_test_rig::{
|
|||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use sensitive_url::SensitiveUrl;
|
use sensitive_url::SensitiveUrl;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::Ipv4Addr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use types::{Epoch, EthSpec, MinimalEthSpec};
|
use types::{Epoch, EthSpec, MinimalEthSpec};
|
||||||
@ -149,7 +149,7 @@ pub fn run_eth1_sim(matches: &ArgMatches) -> Result<(), String> {
|
|||||||
beacon_config.eth1.chain_id = Eth1Id::from(chain_id);
|
beacon_config.eth1.chain_id = Eth1Id::from(chain_id);
|
||||||
beacon_config.network.target_peers = node_count - 1;
|
beacon_config.network.target_peers = node_count - 1;
|
||||||
|
|
||||||
beacon_config.network.enr_address = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
|
beacon_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None);
|
||||||
|
|
||||||
if post_merge_sim {
|
if post_merge_sim {
|
||||||
let el_config = execution_layer::Config {
|
let el_config = execution_layer::Config {
|
||||||
|
@ -58,10 +58,13 @@ impl<E: EthSpec> LocalNetwork<E> {
|
|||||||
context: RuntimeContext<E>,
|
context: RuntimeContext<E>,
|
||||||
mut beacon_config: ClientConfig,
|
mut beacon_config: ClientConfig,
|
||||||
) -> Result<Self, String> {
|
) -> Result<Self, String> {
|
||||||
beacon_config.network.discovery_port = BOOTNODE_PORT;
|
beacon_config.network.set_ipv4_listening_address(
|
||||||
beacon_config.network.libp2p_port = BOOTNODE_PORT;
|
std::net::Ipv4Addr::UNSPECIFIED,
|
||||||
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT);
|
BOOTNODE_PORT,
|
||||||
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT);
|
BOOTNODE_PORT,
|
||||||
|
);
|
||||||
|
beacon_config.network.enr_udp4_port = Some(BOOTNODE_PORT);
|
||||||
|
beacon_config.network.enr_tcp4_port = Some(BOOTNODE_PORT);
|
||||||
beacon_config.network.discv5_config.table_filter = |_| true;
|
beacon_config.network.discv5_config.table_filter = |_| true;
|
||||||
|
|
||||||
let execution_node = if let Some(el_config) = &mut beacon_config.execution_layer {
|
let execution_node = if let Some(el_config) = &mut beacon_config.execution_layer {
|
||||||
@ -132,10 +135,13 @@ impl<E: EthSpec> LocalNetwork<E> {
|
|||||||
.enr()
|
.enr()
|
||||||
.expect("bootnode must have a network"),
|
.expect("bootnode must have a network"),
|
||||||
);
|
);
|
||||||
beacon_config.network.discovery_port = BOOTNODE_PORT + count;
|
beacon_config.network.set_ipv4_listening_address(
|
||||||
beacon_config.network.libp2p_port = BOOTNODE_PORT + count;
|
std::net::Ipv4Addr::UNSPECIFIED,
|
||||||
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT + count);
|
BOOTNODE_PORT + count,
|
||||||
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT + count);
|
BOOTNODE_PORT + count,
|
||||||
|
);
|
||||||
|
beacon_config.network.enr_udp4_port = Some(BOOTNODE_PORT + count);
|
||||||
|
beacon_config.network.enr_tcp4_port = Some(BOOTNODE_PORT + count);
|
||||||
beacon_config.network.discv5_config.table_filter = |_| true;
|
beacon_config.network.discv5_config.table_filter = |_| true;
|
||||||
}
|
}
|
||||||
if let Some(el_config) = &mut beacon_config.execution_layer {
|
if let Some(el_config) = &mut beacon_config.execution_layer {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#![recursion_limit = "256"]
|
|
||||||
|
|
||||||
//! This crate provides a simluation that creates `n` beacon node and validator clients, each with
|
//! This crate provides a simluation that creates `n` beacon node and validator clients, each with
|
||||||
//! `v` validators. A deposit contract is deployed at the start of the simulation using a local
|
//! `v` validators. A deposit contract is deployed at the start of the simulation using a local
|
||||||
//! `ganache` instance (you must have `ganache` installed and avaliable on your path). All
|
//! `ganache` instance (you must have `ganache` installed and avaliable on your path). All
|
||||||
|
@ -7,7 +7,7 @@ use node_test_rig::{
|
|||||||
};
|
};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::Ipv4Addr;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use types::{Epoch, EthSpec, MainnetEthSpec};
|
use types::{Epoch, EthSpec, MainnetEthSpec};
|
||||||
@ -91,7 +91,7 @@ pub fn run_no_eth1_sim(matches: &ArgMatches) -> Result<(), String> {
|
|||||||
beacon_config.dummy_eth1_backend = true;
|
beacon_config.dummy_eth1_backend = true;
|
||||||
beacon_config.sync_eth1_chain = true;
|
beacon_config.sync_eth1_chain = true;
|
||||||
|
|
||||||
beacon_config.network.enr_address = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
|
beacon_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None);
|
||||||
|
|
||||||
let main_future = async {
|
let main_future = async {
|
||||||
let network = LocalNetwork::new(context.clone(), beacon_config.clone()).await?;
|
let network = LocalNetwork::new(context.clone(), beacon_config.clone()).await?;
|
||||||
|
@ -8,7 +8,7 @@ use node_test_rig::{
|
|||||||
};
|
};
|
||||||
use node_test_rig::{testing_validator_config, ClientConfig};
|
use node_test_rig::{testing_validator_config, ClientConfig};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::Ipv4Addr;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
use types::{Epoch, EthSpec};
|
use types::{Epoch, EthSpec};
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ fn syncing_sim(
|
|||||||
|
|
||||||
beacon_config.http_api.allow_sync_stalled = true;
|
beacon_config.http_api.allow_sync_stalled = true;
|
||||||
|
|
||||||
beacon_config.network.enr_address = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
|
beacon_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None);
|
||||||
|
|
||||||
// Generate the directories and keystores required for the validator clients.
|
// Generate the directories and keystores required for the validator clients.
|
||||||
let validator_indices = (0..num_validators).collect::<Vec<_>>();
|
let validator_indices = (0..num_validators).collect::<Vec<_>>();
|
||||||
|
Loading…
Reference in New Issue
Block a user