Merge branch 'unstable' into eip4844
This commit is contained in:
commit
7f2e9b80bb
@ -201,6 +201,9 @@ pub enum ProduceBlockVerification {
|
||||
pub struct PrePayloadAttributes {
|
||||
pub proposer_index: u64,
|
||||
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
|
||||
@ -3975,16 +3978,21 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
proposer as u64
|
||||
};
|
||||
|
||||
// Get the `prev_randao` value.
|
||||
let prev_randao = if proposer_head == parent_block_root {
|
||||
cached_head.parent_random()
|
||||
// Get the `prev_randao` and parent block number.
|
||||
let head_block_number = cached_head.head_block_number()?;
|
||||
let (prev_randao, parent_block_number) = if proposer_head == parent_block_root {
|
||||
(
|
||||
cached_head.parent_random()?,
|
||||
head_block_number.saturating_sub(1),
|
||||
)
|
||||
} else {
|
||||
cached_head.head_random()
|
||||
}?;
|
||||
(cached_head.head_random()?, head_block_number)
|
||||
};
|
||||
|
||||
Ok(Some(PrePayloadAttributes {
|
||||
proposer_index,
|
||||
prev_randao,
|
||||
parent_block_number,
|
||||
}))
|
||||
}
|
||||
|
||||
@ -5059,6 +5067,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
proposal_slot: prepare_slot,
|
||||
proposer_index: proposer,
|
||||
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(),
|
||||
payload_attributes: payload_attributes.into(),
|
||||
},
|
||||
|
@ -167,6 +167,17 @@ impl<E: EthSpec> CachedHead<E> {
|
||||
.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.
|
||||
///
|
||||
/// 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
|
||||
.attestation_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "attestation")),
|
||||
.map(|count| log_count("attestation", count)),
|
||||
EventKind::Block(_) => self
|
||||
.block_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "block")),
|
||||
.map(|count| log_count("block", count)),
|
||||
EventKind::FinalizedCheckpoint(_) => self
|
||||
.finalized_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "finalized checkpoint")),
|
||||
.map(|count| log_count("finalized checkpoint", count)),
|
||||
EventKind::Head(_) => self
|
||||
.head_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "head")),
|
||||
.map(|count| log_count("head", count)),
|
||||
EventKind::VoluntaryExit(_) => self
|
||||
.exit_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "exit")),
|
||||
.map(|count| log_count("exit", count)),
|
||||
EventKind::ChainReorg(_) => self
|
||||
.chain_reorg_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "chain reorg")),
|
||||
.map(|count| log_count("chain reorg", count)),
|
||||
EventKind::ContributionAndProof(_) => self
|
||||
.contribution_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "contribution and proof")),
|
||||
.map(|count| log_count("contribution and proof", count)),
|
||||
EventKind::PayloadAttributes(_) => self
|
||||
.payload_attributes_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "payload attributes")),
|
||||
.map(|count| log_count("payload attributes", count)),
|
||||
EventKind::LateHead(_) => self
|
||||
.late_head
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "late head")),
|
||||
.map(|count| log_count("late head", count)),
|
||||
EventKind::BlockReward(_) => self
|
||||
.block_reward_tx
|
||||
.send(kind)
|
||||
.map(|count| log_count(count, "block reward")),
|
||||
.map(|count| log_count("block reward", count)),
|
||||
};
|
||||
if let Err(SendError(event)) = result {
|
||||
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_verification;
|
||||
mod attester_cache;
|
||||
|
@ -468,7 +468,7 @@ where
|
||||
builder_threshold: Option<u128>,
|
||||
) -> Self {
|
||||
// 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 spec = self.spec.clone().expect("cannot build without spec");
|
||||
|
@ -46,9 +46,18 @@ impl<T: BeaconChainTypes> Client<T> {
|
||||
self.http_metrics_listen_addr
|
||||
}
|
||||
|
||||
/// Returns the port of the client's libp2p stack, if it was started.
|
||||
pub fn libp2p_listen_port(&self) -> Option<u16> {
|
||||
self.network_globals.as_ref().map(|n| n.listen_port_tcp())
|
||||
/// Returns the ipv4 port of the client's libp2p stack, if it was started.
|
||||
pub fn libp2p_listen_ipv4_port(&self) -> Option<u16> {
|
||||
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.
|
||||
|
@ -57,7 +57,7 @@ use types::{
|
||||
|
||||
mod block_hash;
|
||||
mod engine_api;
|
||||
mod engines;
|
||||
pub mod engines;
|
||||
mod keccak;
|
||||
mod metrics;
|
||||
pub mod payload_cache;
|
||||
@ -342,6 +342,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
|
||||
.map_err(Error::InvalidJWTSecret)
|
||||
} else {
|
||||
// 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()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![recursion_limit = "1024"]
|
||||
//! This crate contains a HTTP server which serves the endpoints listed here:
|
||||
//!
|
||||
//! https://github.com/ethereum/beacon-APIs
|
||||
@ -71,7 +70,8 @@ use warp::Reply;
|
||||
use warp::{http::Response, Filter};
|
||||
use warp_utils::{
|
||||
query::multi_key_query,
|
||||
task::{blocking_json_task, blocking_task},
|
||||
task::{blocking_json_task, blocking_response_task},
|
||||
uor::UnifyingOrFilter,
|
||||
};
|
||||
|
||||
const API_PREFIX: &str = "eth";
|
||||
@ -1125,7 +1125,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
log: Logger| async move {
|
||||
publish_blocks::publish_block(None, block, chain, &network_tx, log)
|
||||
.await
|
||||
.map(|()| warp::reply())
|
||||
.map(|()| warp::reply().into_response())
|
||||
},
|
||||
);
|
||||
|
||||
@ -1145,7 +1145,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
log: Logger| async move {
|
||||
publish_blocks::publish_blinded_block(block, chain, &network_tx, log)
|
||||
.await
|
||||
.map(|()| warp::reply())
|
||||
.map(|()| warp::reply().into_response())
|
||||
},
|
||||
);
|
||||
|
||||
@ -1251,7 +1251,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
|block_id: BlockId,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
accept_header: Option<api_types::Accept>| {
|
||||
blocking_task(move || {
|
||||
blocking_response_task(move || {
|
||||
let (block, execution_optimistic) = block_id.blinded_block(&chain)?;
|
||||
let fork_name = block
|
||||
.fork_name(&chain.spec)
|
||||
@ -1763,7 +1763,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(eth1_service_filter.clone())
|
||||
.and_then(
|
||||
|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 => {
|
||||
let snapshot = eth1_service.get_deposit_snapshot();
|
||||
Ok(
|
||||
@ -1982,7 +1982,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
state_id: StateId,
|
||||
accept_header: Option<api_types::Accept>,
|
||||
chain: Arc<BeaconChain<T>>| {
|
||||
blocking_task(move || match accept_header {
|
||||
blocking_response_task(move || match accept_header {
|
||||
Some(api_types::Accept::Ssz) => {
|
||||
// We can ignore the optimistic status for the "fork" since it's a
|
||||
// specification constant that doesn't change across competing heads of the
|
||||
@ -1995,7 +1995,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.status(200)
|
||||
.header("Content-Type", "application/octet-stream")
|
||||
.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| {
|
||||
warp_utils::reject::custom_server_error(format!(
|
||||
"failed to create response: {}",
|
||||
@ -2158,7 +2160,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(warp::path::end())
|
||||
.and(network_globals.clone())
|
||||
.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::SyncingHead { .. }
|
||||
| SyncState::SyncTransition
|
||||
@ -2422,7 +2424,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.map_err(inconsistent_fork_rejection)?;
|
||||
|
||||
fork_versioned_response(endpoint_version, fork_name, block)
|
||||
.map(|response| warp::reply::json(&response))
|
||||
.map(|response| warp::reply::json(&response).into_response())
|
||||
},
|
||||
);
|
||||
|
||||
@ -2479,7 +2481,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
|
||||
// Pose as a V2 endpoint so we return the fork `version`.
|
||||
fork_versioned_response(V2, fork_name, block)
|
||||
.map(|response| warp::reply::json(&response))
|
||||
.map(|response| warp::reply::json(&response).into_response())
|
||||
},
|
||||
);
|
||||
|
||||
@ -2852,7 +2854,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
))
|
||||
})?;
|
||||
|
||||
Ok::<_, warp::reject::Rejection>(warp::reply::json(&()))
|
||||
Ok::<_, warp::reject::Rejection>(warp::reply::json(&()).into_response())
|
||||
},
|
||||
);
|
||||
|
||||
@ -2961,7 +2963,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
builder
|
||||
.post_builder_validators(&filtered_registration_data)
|
||||
.await
|
||||
.map(|resp| warp::reply::json(&resp))
|
||||
.map(|resp| warp::reply::json(&resp).into_response())
|
||||
.map_err(|e| {
|
||||
warn!(
|
||||
log,
|
||||
@ -3223,7 +3225,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(warp::path::end())
|
||||
.and(chain_filter.clone())
|
||||
.and_then(|chain: Arc<BeaconChain<T>>| {
|
||||
blocking_task(move || {
|
||||
blocking_response_task(move || {
|
||||
Ok::<_, warp::Rejection>(warp::reply::json(&api_types::GenericResponseRef::from(
|
||||
chain
|
||||
.canonical_head
|
||||
@ -3342,7 +3344,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(warp::path::end())
|
||||
.and(chain_filter.clone())
|
||||
.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.
|
||||
let (state, _execution_optimistic) = state_id.state(&chain)?;
|
||||
Response::builder()
|
||||
@ -3478,9 +3480,10 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(chain_filter.clone())
|
||||
.and_then(|chain: Arc<BeaconChain<T>>| async move {
|
||||
let merge_readiness = chain.check_merge_readiness().await;
|
||||
Ok::<_, warp::reject::Rejection>(warp::reply::json(&api_types::GenericResponse::from(
|
||||
merge_readiness,
|
||||
)))
|
||||
Ok::<_, warp::reject::Rejection>(
|
||||
warp::reply::json(&api_types::GenericResponse::from(merge_readiness))
|
||||
.into_response(),
|
||||
)
|
||||
});
|
||||
|
||||
// GET lighthouse/beacon/blobs_sidecars/{block_id}
|
||||
@ -3526,7 +3529,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and_then(
|
||||
|topics_res: Result<api_types::EventQuery, warp::Rejection>,
|
||||
chain: Arc<BeaconChain<T>>| {
|
||||
blocking_task(move || {
|
||||
blocking_response_task(move || {
|
||||
let topics = topics_res?;
|
||||
// for each topic subscribed spawn a new subscription
|
||||
let mut receivers = Vec::with_capacity(topics.topics.len());
|
||||
@ -3593,109 +3596,110 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
);
|
||||
|
||||
// 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()
|
||||
.and(
|
||||
get_beacon_genesis
|
||||
.boxed()
|
||||
.or(get_beacon_state_root.boxed())
|
||||
.or(get_beacon_state_fork.boxed())
|
||||
.or(get_beacon_state_finality_checkpoints.boxed())
|
||||
.or(get_beacon_state_validator_balances.boxed())
|
||||
.or(get_beacon_state_validators_id.boxed())
|
||||
.or(get_beacon_state_validators.boxed())
|
||||
.or(get_beacon_state_committees.boxed())
|
||||
.or(get_beacon_state_sync_committees.boxed())
|
||||
.or(get_beacon_state_randao.boxed())
|
||||
.or(get_beacon_headers.boxed())
|
||||
.or(get_beacon_headers_block_id.boxed())
|
||||
.or(get_beacon_block.boxed())
|
||||
.or(get_beacon_block_attestations.boxed())
|
||||
.or(get_beacon_blinded_block.boxed())
|
||||
.or(get_beacon_block_root.boxed())
|
||||
.or(get_beacon_pool_attestations.boxed())
|
||||
.or(get_beacon_pool_attester_slashings.boxed())
|
||||
.or(get_beacon_pool_proposer_slashings.boxed())
|
||||
.or(get_beacon_pool_voluntary_exits.boxed())
|
||||
.or(get_beacon_pool_bls_to_execution_changes.boxed())
|
||||
.or(get_beacon_deposit_snapshot.boxed())
|
||||
.or(get_beacon_rewards_blocks.boxed())
|
||||
.or(get_config_fork_schedule.boxed())
|
||||
.or(get_config_spec.boxed())
|
||||
.or(get_config_deposit_contract.boxed())
|
||||
.or(get_debug_beacon_states.boxed())
|
||||
.or(get_debug_beacon_heads.boxed())
|
||||
.or(get_node_identity.boxed())
|
||||
.or(get_node_version.boxed())
|
||||
.or(get_node_syncing.boxed())
|
||||
.or(get_node_health.boxed())
|
||||
.or(get_node_peers_by_id.boxed())
|
||||
.or(get_node_peers.boxed())
|
||||
.or(get_node_peer_count.boxed())
|
||||
.or(get_validator_duties_proposer.boxed())
|
||||
.or(get_validator_blocks.boxed())
|
||||
.or(get_validator_blinded_blocks.boxed())
|
||||
.or(get_validator_attestation_data.boxed())
|
||||
.or(get_validator_aggregate_attestation.boxed())
|
||||
.or(get_validator_sync_committee_contribution.boxed())
|
||||
.or(get_lighthouse_health.boxed())
|
||||
.or(get_lighthouse_ui_health.boxed())
|
||||
.or(get_lighthouse_ui_validator_count.boxed())
|
||||
.or(get_lighthouse_syncing.boxed())
|
||||
.or(get_lighthouse_nat.boxed())
|
||||
.or(get_lighthouse_peers.boxed())
|
||||
.or(get_lighthouse_peers_connected.boxed())
|
||||
.or(get_lighthouse_proto_array.boxed())
|
||||
.or(get_lighthouse_validator_inclusion_global.boxed())
|
||||
.or(get_lighthouse_validator_inclusion.boxed())
|
||||
.or(get_lighthouse_eth1_syncing.boxed())
|
||||
.or(get_lighthouse_eth1_block_cache.boxed())
|
||||
.or(get_lighthouse_eth1_deposit_cache.boxed())
|
||||
.or(get_lighthouse_beacon_states_ssz.boxed())
|
||||
.or(get_lighthouse_staking.boxed())
|
||||
.or(get_lighthouse_database_info.boxed())
|
||||
.or(get_lighthouse_block_rewards.boxed())
|
||||
.or(get_lighthouse_attestation_performance.boxed())
|
||||
.or(get_lighthouse_block_packing_efficiency.boxed())
|
||||
.or(get_lighthouse_merge_readiness.boxed())
|
||||
.or(get_lighthouse_blobs_sidecars.boxed())
|
||||
.or(get_events.boxed())
|
||||
.uor(get_beacon_state_root)
|
||||
.uor(get_beacon_state_fork)
|
||||
.uor(get_beacon_state_finality_checkpoints)
|
||||
.uor(get_beacon_state_validator_balances)
|
||||
.uor(get_beacon_state_validators_id)
|
||||
.uor(get_beacon_state_validators)
|
||||
.uor(get_beacon_state_committees)
|
||||
.uor(get_beacon_state_sync_committees)
|
||||
.uor(get_beacon_state_randao)
|
||||
.uor(get_beacon_headers)
|
||||
.uor(get_beacon_headers_block_id)
|
||||
.uor(get_beacon_block)
|
||||
.uor(get_beacon_block_attestations)
|
||||
.uor(get_beacon_blinded_block)
|
||||
.uor(get_beacon_block_root)
|
||||
.uor(get_beacon_pool_attestations)
|
||||
.uor(get_beacon_pool_attester_slashings)
|
||||
.uor(get_beacon_pool_proposer_slashings)
|
||||
.uor(get_beacon_pool_voluntary_exits)
|
||||
.uor(get_beacon_pool_bls_to_execution_changes)
|
||||
.uor(get_beacon_deposit_snapshot)
|
||||
.uor(get_beacon_rewards_blocks)
|
||||
.uor(get_config_fork_schedule)
|
||||
.uor(get_config_spec)
|
||||
.uor(get_config_deposit_contract)
|
||||
.uor(get_debug_beacon_states)
|
||||
.uor(get_debug_beacon_heads)
|
||||
.uor(get_node_identity)
|
||||
.uor(get_node_version)
|
||||
.uor(get_node_syncing)
|
||||
.uor(get_node_health)
|
||||
.uor(get_node_peers_by_id)
|
||||
.uor(get_node_peers)
|
||||
.uor(get_node_peer_count)
|
||||
.uor(get_validator_duties_proposer)
|
||||
.uor(get_validator_blocks)
|
||||
.uor(get_validator_blinded_blocks)
|
||||
.uor(get_validator_attestation_data)
|
||||
.uor(get_validator_aggregate_attestation)
|
||||
.uor(get_validator_sync_committee_contribution)
|
||||
.uor(get_lighthouse_health)
|
||||
.uor(get_lighthouse_ui_health)
|
||||
.uor(get_lighthouse_ui_validator_count)
|
||||
.uor(get_lighthouse_syncing)
|
||||
.uor(get_lighthouse_nat)
|
||||
.uor(get_lighthouse_peers)
|
||||
.uor(get_lighthouse_peers_connected)
|
||||
.uor(get_lighthouse_proto_array)
|
||||
.uor(get_lighthouse_validator_inclusion_global)
|
||||
.uor(get_lighthouse_validator_inclusion)
|
||||
.uor(get_lighthouse_eth1_syncing)
|
||||
.uor(get_lighthouse_eth1_block_cache)
|
||||
.uor(get_lighthouse_eth1_deposit_cache)
|
||||
.uor(get_lighthouse_beacon_states_ssz)
|
||||
.uor(get_lighthouse_staking)
|
||||
.uor(get_lighthouse_database_info)
|
||||
.uor(get_lighthouse_block_rewards)
|
||||
.uor(get_lighthouse_attestation_performance)
|
||||
.uor(get_lighthouse_block_packing_efficiency)
|
||||
.uor(get_lighthouse_merge_readiness)
|
||||
.uor(get_events)
|
||||
.recover(warp_utils::reject::handle_rejection),
|
||||
)
|
||||
.boxed()
|
||||
.or(warp::post().and(
|
||||
post_beacon_blocks
|
||||
.boxed()
|
||||
.or(post_beacon_blinded_blocks.boxed())
|
||||
.or(post_beacon_pool_attestations.boxed())
|
||||
.or(post_beacon_pool_attester_slashings.boxed())
|
||||
.or(post_beacon_pool_proposer_slashings.boxed())
|
||||
.or(post_beacon_pool_voluntary_exits.boxed())
|
||||
.or(post_beacon_pool_sync_committees.boxed())
|
||||
.or(post_beacon_pool_bls_to_execution_changes.boxed())
|
||||
.or(post_beacon_rewards_attestations.boxed())
|
||||
.or(post_beacon_rewards_sync_committee.boxed())
|
||||
.or(post_validator_duties_attester.boxed())
|
||||
.or(post_validator_duties_sync.boxed())
|
||||
.or(post_validator_aggregate_and_proofs.boxed())
|
||||
.or(post_validator_contribution_and_proofs.boxed())
|
||||
.or(post_validator_beacon_committee_subscriptions.boxed())
|
||||
.or(post_validator_sync_committee_subscriptions.boxed())
|
||||
.or(post_validator_prepare_beacon_proposer.boxed())
|
||||
.or(post_validator_register_validator.boxed())
|
||||
.or(post_lighthouse_liveness.boxed())
|
||||
.or(post_lighthouse_database_reconstruct.boxed())
|
||||
.or(post_lighthouse_database_historical_blocks.boxed())
|
||||
.or(post_lighthouse_block_rewards.boxed())
|
||||
.or(post_lighthouse_ui_validator_metrics.boxed())
|
||||
.or(post_lighthouse_ui_validator_info.boxed())
|
||||
.recover(warp_utils::reject::handle_rejection),
|
||||
))
|
||||
.uor(
|
||||
warp::post().and(
|
||||
post_beacon_blocks
|
||||
.uor(post_beacon_blinded_blocks)
|
||||
.uor(post_beacon_pool_attestations)
|
||||
.uor(post_beacon_pool_attester_slashings)
|
||||
.uor(post_beacon_pool_proposer_slashings)
|
||||
.uor(post_beacon_pool_voluntary_exits)
|
||||
.uor(post_beacon_pool_sync_committees)
|
||||
.uor(post_beacon_pool_bls_to_execution_changes)
|
||||
.uor(post_beacon_rewards_attestations)
|
||||
.uor(post_beacon_rewards_sync_committee)
|
||||
.uor(post_validator_duties_attester)
|
||||
.uor(post_validator_duties_sync)
|
||||
.uor(post_validator_aggregate_and_proofs)
|
||||
.uor(post_validator_contribution_and_proofs)
|
||||
.uor(post_validator_beacon_committee_subscriptions)
|
||||
.uor(post_validator_sync_committee_subscriptions)
|
||||
.uor(post_validator_prepare_beacon_proposer)
|
||||
.uor(post_validator_register_validator)
|
||||
.uor(post_lighthouse_liveness)
|
||||
.uor(post_lighthouse_database_reconstruct)
|
||||
.uor(post_lighthouse_database_historical_blocks)
|
||||
.uor(post_lighthouse_block_rewards)
|
||||
.uor(post_lighthouse_ui_validator_metrics)
|
||||
.uor(post_lighthouse_ui_validator_info)
|
||||
.recover(warp_utils::reject::handle_rejection),
|
||||
),
|
||||
)
|
||||
.recover(warp_utils::reject::handle_rejection)
|
||||
.with(slog_logging(log.clone()))
|
||||
.with(prometheus_metrics())
|
||||
// Add a `Server` header.
|
||||
.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_server: HttpServer = match config.tls_config {
|
||||
|
@ -4,7 +4,7 @@ use serde::Serialize;
|
||||
use types::{
|
||||
ExecutionOptimisticForkVersionedResponse, ForkName, ForkVersionedResponse, InconsistentFork,
|
||||
};
|
||||
use warp::reply::{self, Reply, WithHeader};
|
||||
use warp::reply::{self, Reply, Response};
|
||||
|
||||
pub const V1: EndpointVersion = EndpointVersion(1);
|
||||
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.
|
||||
pub fn add_consensus_version_header<T: Reply>(reply: T, fork_name: ForkName) -> WithHeader<T> {
|
||||
reply::with_header(reply, CONSENSUS_VERSION_HEADER, fork_name.to_string())
|
||||
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()).into_response()
|
||||
}
|
||||
|
||||
pub fn inconsistent_fork_rejection(error: InconsistentFork) -> warp::reject::Rejection {
|
||||
|
@ -127,7 +127,7 @@ pub async fn create_api_server<T: BeaconChainTypes>(
|
||||
log: Logger,
|
||||
) -> ApiServer<T::EthSpec, impl Future<Output = ()>> {
|
||||
// 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
|
||||
}
|
||||
|
||||
@ -148,8 +148,8 @@ pub async fn create_api_server_on_port<T: BeaconChainTypes>(
|
||||
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||
let network_globals = Arc::new(NetworkGlobals::new(
|
||||
enr.clone(),
|
||||
TCP_PORT,
|
||||
UDP_PORT,
|
||||
Some(TCP_PORT),
|
||||
None,
|
||||
meta_data,
|
||||
vec![],
|
||||
&log,
|
||||
|
@ -1,5 +1,4 @@
|
||||
#![cfg(not(debug_assertions))] // Tests are too slow in debug.
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
pub mod common;
|
||||
pub mod fork_tests;
|
||||
|
@ -112,7 +112,7 @@ impl ApiTester {
|
||||
pub async fn new_from_config(config: ApiTesterConfig) -> Self {
|
||||
// Get a random unused port
|
||||
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 harness = Arc::new(
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::listen_addr::{ListenAddr, ListenAddress};
|
||||
use crate::rpc::config::OutboundRateLimiterConfig;
|
||||
use crate::types::GossipKind;
|
||||
use crate::{Enr, PeerIdSerialized};
|
||||
@ -12,6 +13,7 @@ use libp2p::gossipsub::{
|
||||
use libp2p::Multiaddr;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@ -57,24 +59,24 @@ pub struct Config {
|
||||
/// Data directory where node's keyfile is stored
|
||||
pub network_dir: PathBuf,
|
||||
|
||||
/// IP address to listen on.
|
||||
pub listen_address: std::net::IpAddr,
|
||||
|
||||
/// The TCP port that libp2p listens on.
|
||||
pub libp2p_port: u16,
|
||||
|
||||
/// UDP port that discovery listens on.
|
||||
pub discovery_port: u16,
|
||||
/// IP addresses to listen on.
|
||||
listen_addresses: ListenAddress,
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
pub enr_udp_port: Option<u16>,
|
||||
/// The udp4 port to broadcast to peers in order to reach back for discovery.
|
||||
pub enr_udp4_port: Option<u16>,
|
||||
|
||||
/// The tcp port to broadcast to peers in order to reach back for libp2p services.
|
||||
pub enr_tcp_port: Option<u16>,
|
||||
/// The tcp4 port to broadcast to peers in order to reach back for libp2p services.
|
||||
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.
|
||||
pub target_peers: usize,
|
||||
@ -139,6 +141,105 @@ pub struct Config {
|
||||
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 {
|
||||
/// Generate a default network configuration.
|
||||
fn default() -> Self {
|
||||
@ -183,7 +284,7 @@ impl Default for Config {
|
||||
.filter_rate_limiter(filter_rate_limiter)
|
||||
.filter_max_bans_per_ip(Some(5))
|
||||
.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)))
|
||||
.ping_interval(Duration::from_secs(300))
|
||||
.build();
|
||||
@ -191,12 +292,16 @@ impl Default for Config {
|
||||
// NOTE: Some of these get overridden by the corresponding CLI default values.
|
||||
Config {
|
||||
network_dir,
|
||||
listen_address: "0.0.0.0".parse().expect("valid ip address"),
|
||||
libp2p_port: 9000,
|
||||
discovery_port: 9000,
|
||||
enr_address: None,
|
||||
enr_udp_port: None,
|
||||
enr_tcp_port: None,
|
||||
listen_addresses: ListenAddress::V4(ListenAddr {
|
||||
addr: Ipv4Addr::UNSPECIFIED,
|
||||
udp_port: 9000,
|
||||
tcp_port: 9000,
|
||||
}),
|
||||
enr_address: (None, None),
|
||||
enr_udp4_port: None,
|
||||
enr_tcp4_port: None,
|
||||
enr_udp6_port: None,
|
||||
enr_tcp6_port: None,
|
||||
target_peers: 50,
|
||||
gs_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()`
|
||||
/// function is not yet stable on IpAddr.
|
||||
#[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
|
||||
// globally routable addresses in the 192.0.0.0/24 range.
|
||||
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
|
||||
&& 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,
|
||||
) -> EnrBuilder<T> {
|
||||
let mut builder = EnrBuilder::new("v4");
|
||||
if let Some(enr_address) = config.enr_address {
|
||||
builder.ip(enr_address);
|
||||
let (maybe_ipv4_address, maybe_ipv6_address) = &config.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 {
|
||||
let tcp_port = config.enr_tcp_port.unwrap_or(config.libp2p_port);
|
||||
builder.tcp4(tcp_port);
|
||||
// If the ENR port is not set, and we are listening over that ip version, use the listening port instead.
|
||||
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
|
||||
}
|
||||
|
@ -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(),
|
||||
"ip4" => ?local_enr.ip4(), "udp4"=> ?local_enr.udp4(), "tcp4" => ?local_enr.tcp6()
|
||||
);
|
||||
|
||||
let listen_socket = SocketAddr::new(config.listen_address, config.discovery_port);
|
||||
let listen_socket = match config.listen_addrs() {
|
||||
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
|
||||
let enr_key: CombinedKey = CombinedKey::from_libp2p(local_key)?;
|
||||
@ -1015,14 +1020,27 @@ impl<TSpec: EthSpec> NetworkBehaviour for Discovery<TSpec> {
|
||||
*self.network_globals.local_enr.write() = enr;
|
||||
// A new UDP socket has been detected.
|
||||
// Build a multiaddr to report to libp2p
|
||||
let mut address = Multiaddr::from(socket_addr.ip());
|
||||
// NOTE: This doesn't actually track the external TCP port. More sophisticated NAT handling
|
||||
// should handle this.
|
||||
address.push(Protocol::Tcp(self.network_globals.listen_port_tcp()));
|
||||
return Poll::Ready(NBAction::ReportObservedAddr {
|
||||
address,
|
||||
score: AddressScore::Finite(1),
|
||||
});
|
||||
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
|
||||
// should handle this.
|
||||
return Poll::Ready(NBAction::ReportObservedAddr {
|
||||
address,
|
||||
score: AddressScore::Finite(1),
|
||||
});
|
||||
}
|
||||
}
|
||||
Discv5Event::EnrAdded { .. }
|
||||
| Discv5Event::TalkRequest(_)
|
||||
@ -1087,7 +1105,6 @@ mod tests {
|
||||
use enr::EnrBuilder;
|
||||
use slog::{o, Drain};
|
||||
use types::{BitVector, MinimalEthSpec, SubnetId};
|
||||
use unused_port::unused_udp_port;
|
||||
|
||||
type E = MinimalEthSpec;
|
||||
|
||||
@ -1105,17 +1122,15 @@ mod tests {
|
||||
|
||||
async fn build_discovery() -> Discovery<E> {
|
||||
let keypair = libp2p::identity::Keypair::generate_secp256k1();
|
||||
let config = NetworkConfig {
|
||||
discovery_port: unused_udp_port().unwrap(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut config = NetworkConfig::default();
|
||||
config.set_listening_addr(crate::ListenAddress::unused_v4_ports());
|
||||
let enr_key: CombinedKey = CombinedKey::from_libp2p(&keypair).unwrap();
|
||||
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default()).unwrap();
|
||||
let log = build_log(slog::Level::Debug, false);
|
||||
let globals = NetworkGlobals::new(
|
||||
enr,
|
||||
9000,
|
||||
9000,
|
||||
Some(9000),
|
||||
None,
|
||||
MetaData::V2(MetaDataV2 {
|
||||
seq_number: 0,
|
||||
attnets: Default::default(),
|
||||
|
@ -10,12 +10,14 @@ pub mod service;
|
||||
|
||||
#[allow(clippy::mutable_key_type)] // PeerId in hashmaps are no longer permitted by clippy
|
||||
pub mod discovery;
|
||||
pub mod listen_addr;
|
||||
pub mod metrics;
|
||||
pub mod peer_manager;
|
||||
pub mod rpc;
|
||||
pub mod types;
|
||||
|
||||
pub use config::gossip_max_size;
|
||||
pub use listen_addr::*;
|
||||
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
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 {
|
||||
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
|
||||
{
|
||||
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 globals = NetworkGlobals::new(
|
||||
enr,
|
||||
config.libp2p_port,
|
||||
config.discovery_port,
|
||||
config.listen_addrs().v4().map(|v4_addr| v4_addr.tcp_port),
|
||||
config.listen_addrs().v6().map(|v6_addr| v6_addr.tcp_port),
|
||||
meta_data,
|
||||
config
|
||||
.trusted_peers
|
||||
@ -390,36 +390,26 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
|
||||
async fn start(&mut self, config: &crate::NetworkConfig) -> error::Result<()> {
|
||||
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));
|
||||
let discovery_string = if config.disable_discovery {
|
||||
"None".into()
|
||||
} else {
|
||||
config.discovery_port.to_string()
|
||||
};
|
||||
debug!(self.log, "Attempting to open listening ports"; config.listen_addrs(), "discovery_enabled" => !config.disable_discovery);
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
match self.swarm.listen_on(listen_multiaddr.clone()) {
|
||||
Ok(_) => {
|
||||
let mut log_address = listen_multiaddr;
|
||||
log_address.push(MProtocol::P2p(enr.peer_id().into()));
|
||||
info!(self.log, "Listening established"; "address" => %log_address);
|
||||
}
|
||||
Err(err) => {
|
||||
crit!(
|
||||
self.log,
|
||||
"Unable to listen on libp2p address";
|
||||
"error" => ?err,
|
||||
"listen_multiaddr" => %listen_multiaddr,
|
||||
);
|
||||
return Err("Libp2p was unable to listen on the given listen address.".into());
|
||||
}
|
||||
};
|
||||
for listen_multiaddr in config.listen_addrs().tcp_addresses() {
|
||||
match self.swarm.listen_on(listen_multiaddr.clone()) {
|
||||
Ok(_) => {
|
||||
let mut log_address = listen_multiaddr;
|
||||
log_address.push(MProtocol::P2p(enr.peer_id().into()));
|
||||
info!(self.log, "Listening established"; "address" => %log_address);
|
||||
}
|
||||
Err(err) => {
|
||||
crit!(
|
||||
self.log,
|
||||
"Unable to listen on libp2p address";
|
||||
"error" => ?err,
|
||||
"listen_multiaddr" => %listen_multiaddr,
|
||||
);
|
||||
return Err("Libp2p was unable to listen on the given listen address.".into());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// helper closure for dialing peers
|
||||
let mut dial = |mut multiaddr: Multiaddr| {
|
||||
|
@ -7,7 +7,6 @@ use crate::EnrExt;
|
||||
use crate::{Enr, GossipTopic, Multiaddr, PeerId};
|
||||
use parking_lot::RwLock;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::atomic::{AtomicU16, Ordering};
|
||||
use types::EthSpec;
|
||||
|
||||
pub struct NetworkGlobals<TSpec: EthSpec> {
|
||||
@ -17,10 +16,10 @@ pub struct NetworkGlobals<TSpec: EthSpec> {
|
||||
pub peer_id: RwLock<PeerId>,
|
||||
/// Listening multiaddrs.
|
||||
pub listen_multiaddrs: RwLock<Vec<Multiaddr>>,
|
||||
/// The TCP port that the libp2p service is listening on
|
||||
pub listen_port_tcp: AtomicU16,
|
||||
/// The UDP port that the discovery service is listening on
|
||||
pub listen_port_udp: AtomicU16,
|
||||
/// The TCP port that the libp2p service is listening on over Ipv4.
|
||||
listen_port_tcp4: Option<u16>,
|
||||
/// The TCP port that the libp2p service is listening on over Ipv6.
|
||||
listen_port_tcp6: Option<u16>,
|
||||
/// The collection of known peers.
|
||||
pub peers: RwLock<PeerDB<TSpec>>,
|
||||
// The local meta data of our node.
|
||||
@ -36,8 +35,8 @@ pub struct NetworkGlobals<TSpec: EthSpec> {
|
||||
impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||
pub fn new(
|
||||
enr: Enr,
|
||||
tcp_port: u16,
|
||||
udp_port: u16,
|
||||
listen_port_tcp4: Option<u16>,
|
||||
listen_port_tcp6: Option<u16>,
|
||||
local_metadata: MetaData<TSpec>,
|
||||
trusted_peers: Vec<PeerId>,
|
||||
log: &slog::Logger,
|
||||
@ -46,8 +45,8 @@ impl<TSpec: EthSpec> NetworkGlobals<TSpec> {
|
||||
local_enr: RwLock::new(enr.clone()),
|
||||
peer_id: RwLock::new(enr.peer_id()),
|
||||
listen_multiaddrs: RwLock::new(Vec::new()),
|
||||
listen_port_tcp: AtomicU16::new(tcp_port),
|
||||
listen_port_udp: AtomicU16::new(udp_port),
|
||||
listen_port_tcp4,
|
||||
listen_port_tcp6,
|
||||
local_metadata: RwLock::new(local_metadata),
|
||||
peers: RwLock::new(PeerDB::new(trusted_peers, log)),
|
||||
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.
|
||||
pub fn listen_port_tcp(&self) -> u16 {
|
||||
self.listen_port_tcp.load(Ordering::Relaxed)
|
||||
pub fn listen_port_tcp4(&self) -> Option<u16> {
|
||||
self.listen_port_tcp4
|
||||
}
|
||||
|
||||
/// Returns the UDP discovery port that this node has been configured to listen on.
|
||||
pub fn listen_port_udp(&self) -> u16 {
|
||||
self.listen_port_udp.load(Ordering::Relaxed)
|
||||
pub fn listen_port_tcp6(&self) -> Option<u16> {
|
||||
self.listen_port_tcp6
|
||||
}
|
||||
|
||||
/// 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();
|
||||
NetworkGlobals::new(
|
||||
enr,
|
||||
9000,
|
||||
9000,
|
||||
Some(9000),
|
||||
None,
|
||||
MetaData::V2(MetaDataV2 {
|
||||
seq_number: 0,
|
||||
attnets: Default::default(),
|
||||
|
@ -13,7 +13,7 @@ use tokio::runtime::Runtime;
|
||||
use types::{
|
||||
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 ReqId = usize;
|
||||
@ -78,11 +78,9 @@ pub fn build_config(port: u16, mut boot_nodes: Vec<Enr>) -> NetworkConfig {
|
||||
.tempdir()
|
||||
.unwrap();
|
||||
|
||||
config.libp2p_port = port; // tcp port
|
||||
config.discovery_port = port; // udp port
|
||||
config.enr_tcp_port = Some(port);
|
||||
config.enr_udp_port = Some(port);
|
||||
config.enr_address = Some("127.0.0.1".parse().unwrap());
|
||||
config.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, port, port);
|
||||
config.enr_udp4_port = Some(port);
|
||||
config.enr_address = (Some(std::net::Ipv4Addr::LOCALHOST), None);
|
||||
config.boot_nodes_enr.append(&mut boot_nodes);
|
||||
config.network_dir = path.into_path();
|
||||
// Reduce gossipsub heartbeat parameters
|
||||
@ -100,7 +98,7 @@ pub async fn build_libp2p_instance(
|
||||
log: slog::Logger,
|
||||
fork_name: ForkName,
|
||||
) -> Libp2pInstance {
|
||||
let port = unused_tcp_port().unwrap();
|
||||
let port = unused_tcp4_port().unwrap();
|
||||
let config = build_config(port, boot_nodes);
|
||||
// launch libp2p service
|
||||
|
||||
|
@ -36,7 +36,6 @@ const SMALL_CHAIN: u64 = 2;
|
||||
const LONG_CHAIN: u64 = SLOTS_PER_EPOCH * 2;
|
||||
|
||||
const TCP_PORT: u16 = 42;
|
||||
const UDP_PORT: u16 = 42;
|
||||
const SEQ_NUMBER: u64 = 0;
|
||||
|
||||
/// The default time to wait for `BeaconProcessor` events.
|
||||
@ -177,8 +176,8 @@ impl TestRig {
|
||||
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||
let network_globals = Arc::new(NetworkGlobals::new(
|
||||
enr,
|
||||
TCP_PORT,
|
||||
UDP_PORT,
|
||||
Some(TCP_PORT),
|
||||
None,
|
||||
meta_data,
|
||||
vec![],
|
||||
&log,
|
||||
|
@ -20,13 +20,13 @@ pub struct UPnPConfig {
|
||||
disable_discovery: bool,
|
||||
}
|
||||
|
||||
impl From<&NetworkConfig> for UPnPConfig {
|
||||
fn from(config: &NetworkConfig) -> Self {
|
||||
UPnPConfig {
|
||||
tcp_port: config.libp2p_port,
|
||||
udp_port: config.discovery_port,
|
||||
impl UPnPConfig {
|
||||
pub fn from_config(config: &NetworkConfig) -> Option<Self> {
|
||||
config.listen_addrs().v4().map(|v4_addr| UPnPConfig {
|
||||
tcp_port: v4_addr.tcp_port,
|
||||
udp_port: v4_addr.udp_port,
|
||||
disable_discovery: config.disable_discovery,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,16 +228,21 @@ impl<T: BeaconChainTypes> NetworkService<T> {
|
||||
let (network_senders, network_recievers) = NetworkSenders::new();
|
||||
|
||||
// try and construct UPnP port mappings if required.
|
||||
let upnp_config = crate::nat::UPnPConfig::from(config);
|
||||
let upnp_log = network_log.new(o!("service" => "UPnP"));
|
||||
let upnp_network_send = network_senders.network_send();
|
||||
if config.upnp_enabled {
|
||||
executor.spawn_blocking(
|
||||
move || {
|
||||
crate::nat::construct_upnp_mappings(upnp_config, upnp_network_send, upnp_log)
|
||||
},
|
||||
"UPnP",
|
||||
);
|
||||
if let Some(upnp_config) = crate::nat::UPnPConfig::from_config(config) {
|
||||
let upnp_log = network_log.new(o!("service" => "UPnP"));
|
||||
let upnp_network_send = network_senders.network_send();
|
||||
if config.upnp_enabled {
|
||||
executor.spawn_blocking(
|
||||
move || {
|
||||
crate::nat::construct_upnp_mappings(
|
||||
upnp_config,
|
||||
upnp_network_send,
|
||||
upnp_log,
|
||||
)
|
||||
},
|
||||
"UPnP",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// get a reference to the beacon chain store
|
||||
|
@ -61,10 +61,9 @@ mod tests {
|
||||
);
|
||||
|
||||
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.libp2p_port = 21212;
|
||||
config.upnp_enabled = false;
|
||||
config.discovery_port = 21212;
|
||||
config.boot_nodes_enr = enrs.clone();
|
||||
runtime.block_on(async move {
|
||||
// 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")
|
||||
.long("listen-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")
|
||||
.takes_value(true)
|
||||
)
|
||||
@ -86,10 +95,21 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||
Arg::with_name("port")
|
||||
.long("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")
|
||||
.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::with_name("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`")
|
||||
.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::with_name("target-peers")
|
||||
.long("target-peers")
|
||||
@ -137,27 +166,49 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||
Arg::with_name("enr-udp-port")
|
||||
.long("enr-udp-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),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("enr-tcp-port")
|
||||
.long("enr-tcp-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.\
|
||||
The --port flag is used if this is not set.")
|
||||
.help("The TCP4 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. 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),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("enr-address")
|
||||
.long("enr-address")
|
||||
.value_name("ADDRESS")
|
||||
.help("The IP address/ DNS address to broadcast to other peers on how to reach this node. \
|
||||
If a DNS address is provided, the enr-address is set to the IP address it resolves to and \
|
||||
does not auto-update based on PONG responses in discovery. \
|
||||
Set this only if you are sure other nodes can connect to your local node on this address. \
|
||||
Discovery will automatically find your external address, if possible.")
|
||||
.help("The IP address/ DNS address to broadcast to other peers on how to reach \
|
||||
this node. If a DNS address is provided, the enr-address is set to the IP \
|
||||
address it resolves to and does not auto-update based on PONG responses in \
|
||||
discovery. Set this only if you are sure other nodes can connect to your \
|
||||
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")
|
||||
.multiple(true)
|
||||
.max_values(2)
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
@ -165,7 +216,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||
.short("e")
|
||||
.long("enr-match")
|
||||
.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::with_name("disable-enr-auto-update")
|
||||
|
@ -11,13 +11,13 @@ use environment::RuntimeContext;
|
||||
use execution_layer::DEFAULT_JWT_FILE;
|
||||
use genesis::Eth1Endpoint;
|
||||
use http_api::TlsConfig;
|
||||
use lighthouse_network::ListenAddress;
|
||||
use lighthouse_network::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSerialized};
|
||||
use sensitive_url::SensitiveUrl;
|
||||
use slog::{info, warn, Logger};
|
||||
use std::cmp;
|
||||
use std::cmp::max;
|
||||
use std::fmt::Debug;
|
||||
use std::fmt::Write;
|
||||
use std::fs;
|
||||
use std::net::Ipv6Addr;
|
||||
use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
|
||||
@ -25,7 +25,6 @@ use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
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.
|
||||
///
|
||||
@ -79,13 +78,7 @@ pub fn get_config<E: EthSpec>(
|
||||
|
||||
let data_dir_ref = client_config.data_dir().clone();
|
||||
|
||||
set_network_config(
|
||||
&mut client_config.network,
|
||||
cli_args,
|
||||
&data_dir_ref,
|
||||
log,
|
||||
false,
|
||||
)?;
|
||||
set_network_config(&mut client_config.network, cli_args, &data_dir_ref, log)?;
|
||||
|
||||
/*
|
||||
* Staking flag
|
||||
@ -441,13 +434,6 @@ pub fn get_config<E: EthSpec>(
|
||||
* Discovery address is set to localhost by default.
|
||||
*/
|
||||
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_metrics.listen_port = 0;
|
||||
}
|
||||
@ -798,13 +784,177 @@ pub fn get_config<E: EthSpec>(
|
||||
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(
|
||||
config: &mut NetworkConfig,
|
||||
cli_args: &ArgMatches,
|
||||
data_dir: &Path,
|
||||
log: &Logger,
|
||||
use_listening_port_as_enr_port_by_default: bool,
|
||||
) -> Result<(), String> {
|
||||
// If a network dir has been specified, override the `datadir` definition.
|
||||
if let Some(dir) = cli_args.value_of("network-dir") {
|
||||
@ -825,12 +975,7 @@ pub fn set_network_config(
|
||||
config.shutdown_after_sync = true;
|
||||
}
|
||||
|
||||
if let Some(listen_address_str) = cli_args.value_of("listen-address") {
|
||||
let listen_address = listen_address_str
|
||||
.parse()
|
||||
.map_err(|_| format!("Invalid listen address: {:?}", listen_address_str))?;
|
||||
config.listen_address = listen_address;
|
||||
}
|
||||
config.set_listening_addr(parse_listening_addresses(cli_args, log)?);
|
||||
|
||||
if let Some(target_peers_str) = cli_args.value_of("target-peers") {
|
||||
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))?;
|
||||
}
|
||||
|
||||
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") {
|
||||
let network_load = value
|
||||
.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") {
|
||||
config.enr_udp_port = Some(
|
||||
config.enr_udp4_port = Some(
|
||||
enr_udp_port_str
|
||||
.parse::<u16>()
|
||||
.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") {
|
||||
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
|
||||
.parse::<u16>()
|
||||
.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") {
|
||||
// Match the Ip and UDP port in the enr.
|
||||
|
||||
// set the enr address to localhost if the address is unspecified
|
||||
if config.listen_address == IpAddr::V4(Ipv4Addr::UNSPECIFIED) {
|
||||
config.enr_address = Some(IpAddr::V4(Ipv4Addr::LOCALHOST));
|
||||
} else if config.listen_address == IpAddr::V6(Ipv6Addr::UNSPECIFIED) {
|
||||
config.enr_address = Some(IpAddr::V6(Ipv6Addr::LOCALHOST));
|
||||
} else {
|
||||
config.enr_address = Some(config.listen_address);
|
||||
if let Some(ipv4_addr) = config.listen_addrs().v4().cloned() {
|
||||
let ipv4_enr_addr = if ipv4_addr.addr == Ipv4Addr::UNSPECIFIED {
|
||||
Ipv4Addr::LOCALHOST
|
||||
} else {
|
||||
ipv4_addr.addr
|
||||
};
|
||||
config.enr_address.0 = Some(ipv4_enr_addr);
|
||||
config.enr_udp4_port = Some(ipv4_addr.udp_port);
|
||||
}
|
||||
|
||||
if let Some(ipv6_addr) = config.listen_addrs().v6().cloned() {
|
||||
let ipv6_enr_addr = if ipv6_addr.addr == Ipv6Addr::UNSPECIFIED {
|
||||
Ipv6Addr::LOCALHOST
|
||||
} else {
|
||||
ipv6_addr.addr
|
||||
};
|
||||
config.enr_address.1 = Some(ipv6_enr_addr);
|
||||
config.enr_udp6_port = Some(ipv6_addr.udp_port);
|
||||
}
|
||||
config.enr_udp_port = Some(config.discovery_port);
|
||||
}
|
||||
|
||||
if let Some(enr_address) = cli_args.value_of("enr-address") {
|
||||
let resolved_addr = match enr_address.parse::<IpAddr>() {
|
||||
Ok(addr) => addr, // // Input is an IpAddr
|
||||
Err(_) => {
|
||||
let mut addr = enr_address.to_string();
|
||||
// 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
|
||||
// will make the node undiscoverable.
|
||||
if let Some(enr_udp_port) =
|
||||
config
|
||||
.enr_udp_port
|
||||
.or(if use_listening_port_as_enr_port_by_default {
|
||||
Some(config.discovery_port)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
{
|
||||
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(),
|
||||
);
|
||||
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(_) => {
|
||||
// Try to resolve the address
|
||||
|
||||
// NOTE: From checking the `to_socket_addrs` code I don't think the port
|
||||
// actually matters. Just use the udp port.
|
||||
|
||||
let port = match config.listen_addrs() {
|
||||
ListenAddress::V4(v4_addr) => v4_addr.udp_port,
|
||||
ListenAddress::V6(v6_addr) => v6_addr.udp_port,
|
||||
ListenAddress::DualStack(v4_addr, _v6_addr) => {
|
||||
// NOTE: slight preference for ipv4 that I don't think is of importance.
|
||||
v4_addr.udp_port
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// `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));
|
||||
};
|
||||
config.discv5_config.enr_update = false;
|
||||
resolved_addr
|
||||
}
|
||||
};
|
||||
config.enr_address = Some(resolved_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;
|
||||
}
|
||||
}
|
||||
|
||||
if cli_args.is_present("disable-enr-auto-update") {
|
||||
|
@ -1,5 +1,4 @@
|
||||
#![cfg(test)]
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
use beacon_chain::StateSkipConfig;
|
||||
use node_test_rig::{
|
||||
|
@ -53,6 +53,14 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||
.takes_value(true)
|
||||
.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::with_name("enable-enr-auto-update")
|
||||
.short("x")
|
||||
|
@ -1,7 +1,7 @@
|
||||
use beacon_node::{get_data_dir, set_network_config};
|
||||
use clap::ArgMatches;
|
||||
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::{enr::CombinedKey, Discv5Config, Enr};
|
||||
use lighthouse_network::{
|
||||
@ -57,12 +57,24 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
||||
|
||||
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.
|
||||
if !matches.is_present("enr-udp-port") {
|
||||
network_config.enr_udp_port = Some(network_config.discovery_port);
|
||||
}
|
||||
// Set the Enr UDP ports to the listening ports if not present.
|
||||
if let Some(listening_addr_v4) = network_config.listen_addrs().v4() {
|
||||
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.
|
||||
if !matches.is_present("enable-enr-auto-update") {
|
||||
@ -70,17 +82,29 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
||||
}
|
||||
|
||||
// the address to listen on
|
||||
let listen_socket =
|
||||
SocketAddr::new(network_config.listen_address, network_config.discovery_port);
|
||||
if listen_socket.is_ipv6() {
|
||||
// create ipv6 sockets and enable ipv4 mapped addresses.
|
||||
network_config.discv5_config.ip_mode = IpMode::Ip6 {
|
||||
enable_mapped_addresses: true,
|
||||
};
|
||||
} else {
|
||||
// Set explicitly as ipv4 otherwise
|
||||
network_config.discv5_config.ip_mode = IpMode::Ip4;
|
||||
}
|
||||
let listen_socket = match network_config.listen_addrs().clone() {
|
||||
lighthouse_network::ListenAddress::V4(v4_addr) => {
|
||||
// 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.
|
||||
network_config.discv5_config.ip_mode = IpMode::Ip6 {
|
||||
enable_mapped_addresses: true,
|
||||
};
|
||||
|
||||
v6_addr.udp_socket_addr()
|
||||
}
|
||||
};
|
||||
|
||||
let private_key = load_private_key(&network_config, &logger);
|
||||
let local_key = CombinedKey::from_libp2p(&private_key)?;
|
||||
@ -115,30 +139,8 @@ impl<T: EthSpec> BootNodeConfig<T> {
|
||||
// Build the local ENR
|
||||
|
||||
let mut local_enr = {
|
||||
let mut builder = EnrBuilder::new("v4");
|
||||
// Set the enr address if specified. Set also the port.
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let enable_tcp = false;
|
||||
let mut builder = create_enr_builder_from_config(&network_config, enable_tcp);
|
||||
// If we know of the ENR field, add it to the initial construction
|
||||
if let Some(enr_fork_bytes) = enr_fork {
|
||||
builder.add_value("eth2", enr_fork_bytes.as_slice());
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![recursion_limit = "256"]
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
@ -921,6 +921,8 @@ pub struct SseExtendedPayloadAttributesGeneric<T> {
|
||||
#[serde(with = "eth2_serde_utils::quoted_u64")]
|
||||
pub proposer_index: u64,
|
||||
pub parent_block_root: Hash256,
|
||||
#[serde(with = "eth2_serde_utils::quoted_u64")]
|
||||
pub parent_block_number: u64,
|
||||
pub parent_block_hash: ExecutionBlockHash,
|
||||
pub payload_attributes: T,
|
||||
}
|
||||
@ -958,6 +960,7 @@ impl ForkVersionDeserialize for SseExtendedPayloadAttributes {
|
||||
proposal_slot: helper.proposal_slot,
|
||||
proposer_index: helper.proposer_index,
|
||||
parent_block_root: helper.parent_block_root,
|
||||
parent_block_number: helper.parent_block_number,
|
||||
parent_block_hash: helper.parent_block_hash,
|
||||
payload_attributes: SsePayloadAttributes::deserialize_by_fork::<D>(
|
||||
helper.payload_attributes,
|
||||
|
@ -6,14 +6,30 @@ pub enum Transport {
|
||||
Udp,
|
||||
}
|
||||
|
||||
/// A convenience function for `unused_port(Transport::Tcp)`.
|
||||
pub fn unused_tcp_port() -> Result<u16, String> {
|
||||
unused_port(Transport::Tcp)
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum IpVersion {
|
||||
Ipv4,
|
||||
Ipv6,
|
||||
}
|
||||
|
||||
/// A convenience function for `unused_port(Transport::Tcp)`.
|
||||
pub fn unused_udp_port() -> Result<u16, String> {
|
||||
unused_port(Transport::Udp)
|
||||
/// A convenience wrapper over [`zero_port`].
|
||||
pub fn unused_tcp4_port() -> Result<u16, String> {
|
||||
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.
|
||||
@ -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
|
||||
/// 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.
|
||||
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 {
|
||||
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)
|
||||
})?;
|
||||
listener.local_addr().map_err(|e| {
|
||||
@ -40,7 +61,7 @@ pub fn unused_port(transport: Transport) -> Result<u16, String> {
|
||||
})?
|
||||
}
|
||||
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))?;
|
||||
socket.local_addr().map_err(|e| {
|
||||
format!(
|
||||
|
@ -6,3 +6,4 @@ pub mod metrics;
|
||||
pub mod query;
|
||||
pub mod reject;
|
||||
pub mod task;
|
||||
pub mod uor;
|
||||
|
@ -1,4 +1,5 @@
|
||||
use serde::Serialize;
|
||||
use warp::reply::{Reply, Response};
|
||||
|
||||
/// A convenience wrapper around `blocking_task`.
|
||||
pub async fn blocking_task<F, T>(func: F) -> Result<T, warp::Rejection>
|
||||
@ -8,16 +9,29 @@ where
|
||||
{
|
||||
tokio::task::spawn_blocking(func)
|
||||
.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.
|
||||
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
|
||||
F: FnOnce() -> Result<T, warp::Rejection> + Send + 'static,
|
||||
T: Serialize + Send + 'static,
|
||||
{
|
||||
blocking_task(func)
|
||||
.await
|
||||
.map(|resp| warp::reply::json(&resp))
|
||||
blocking_response_task(|| {
|
||||
let response = func()?;
|
||||
Ok(warp::reply::json(&response))
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
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,
|
||||
{
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
#![recursion_limit = "256"]
|
||||
//! Provides procedural derive macros for the `Encode` and `Decode` traits of the `eth2_ssz` crate.
|
||||
//!
|
||||
//! ## Attributes
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![recursion_limit = "256"]
|
||||
use darling::FromDeriveInput;
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
|
@ -1,6 +1,4 @@
|
||||
//! Ethereum 2.0 types
|
||||
// Required for big type-level numbers
|
||||
#![recursion_limit = "128"]
|
||||
// Clippy lint set up
|
||||
#![cfg_attr(
|
||||
not(test),
|
||||
|
@ -3,15 +3,14 @@ use lighthouse_network::{
|
||||
discovery::{build_enr, CombinedKey, CombinedKeyExt, Keypair, ENR_FILENAME},
|
||||
NetworkConfig, NETWORK_KEY_FILENAME,
|
||||
};
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::net::IpAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::{fs, net::Ipv4Addr};
|
||||
use types::{ChainSpec, EnrForkId, Epoch, EthSpec, Hash256};
|
||||
|
||||
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 tcp_port: u16 = clap_utils::parse_required(matches, "tcp-port")?;
|
||||
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 {
|
||||
enr_address: Some(ip),
|
||||
enr_udp_port: Some(udp_port),
|
||||
enr_tcp_port: Some(tcp_port),
|
||||
..Default::default()
|
||||
};
|
||||
let mut config = NetworkConfig::default();
|
||||
config.enr_address = (Some(ip), None);
|
||||
config.enr_udp4_port = Some(udp_port);
|
||||
config.enr_tcp6_port = Some(tcp_port);
|
||||
|
||||
let local_keypair = Keypair::generate_secp256k1();
|
||||
let enr_key = CombinedKey::from_libp2p(&local_keypair)?;
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
mod metrics;
|
||||
|
||||
use beacon_node::ProductionBeaconNode;
|
||||
|
@ -8,7 +8,7 @@ use eth1::Eth1Endpoint;
|
||||
use lighthouse_network::PeerId;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::net::IpAddr;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
@ -16,7 +16,7 @@ use std::string::ToString;
|
||||
use std::time::Duration;
|
||||
use tempfile::TempDir;
|
||||
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/";
|
||||
|
||||
@ -851,37 +851,188 @@ fn network_shutdown_after_sync_disabled_flag() {
|
||||
.with_config(|config| assert!(!config.network.shutdown_after_sync));
|
||||
}
|
||||
#[test]
|
||||
fn network_listen_address_flag() {
|
||||
let addr = "127.0.0.2".parse::<IpAddr>().unwrap();
|
||||
fn network_listen_address_flag_v4() {
|
||||
let addr = "127.0.0.2".parse::<Ipv4Addr>().unwrap();
|
||||
CommandLineTest::new()
|
||||
.flag("listen-address", Some("127.0.0.2"))
|
||||
.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]
|
||||
fn network_port_flag() {
|
||||
let port = unused_tcp_port().expect("Unable to find unused port.");
|
||||
fn network_listen_address_flag_v6() {
|
||||
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()
|
||||
.flag("port", Some(port.to_string().as_str()))
|
||||
.run()
|
||||
.with_config(|config| {
|
||||
assert_eq!(config.network.libp2p_port, port);
|
||||
assert_eq!(config.network.discovery_port, port);
|
||||
assert_eq!(
|
||||
config
|
||||
.network
|
||||
.listen_addrs()
|
||||
.v4()
|
||||
.map(|listen_addr| (listen_addr.udp_port, listen_addr.tcp_port)),
|
||||
Some((port, port))
|
||||
);
|
||||
});
|
||||
}
|
||||
#[test]
|
||||
fn network_port_and_discovery_port_flags() {
|
||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
||||
let port2 = unused_udp_port().expect("Unable to find unused port.");
|
||||
fn network_port_flag_over_ipv6() {
|
||||
let port = unused_tcp6_port().expect("Unable to find unused port.");
|
||||
CommandLineTest::new()
|
||||
.flag("port", Some(port1.to_string().as_str()))
|
||||
.flag("discovery-port", Some(port2.to_string().as_str()))
|
||||
.flag("listen-address", Some("::1"))
|
||||
.flag("port", Some(port.to_string().as_str()))
|
||||
.run()
|
||||
.with_config(|config| {
|
||||
assert_eq!(config.network.libp2p_port, port1);
|
||||
assert_eq!(config.network.discovery_port, port2);
|
||||
assert_eq!(
|
||||
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]
|
||||
fn disable_discovery_flag() {
|
||||
CommandLineTest::new()
|
||||
@ -986,7 +1137,6 @@ fn zero_ports_flag() {
|
||||
CommandLineTest::new()
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
assert_eq!(config.network.enr_address, None);
|
||||
assert_eq!(config.http_api.listen_port, 0);
|
||||
assert_eq!(config.http_metrics.listen_port, 0);
|
||||
});
|
||||
@ -1003,67 +1153,171 @@ fn network_load_flag() {
|
||||
|
||||
// Tests for ENR flags.
|
||||
#[test]
|
||||
fn enr_udp_port_flags() {
|
||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
||||
fn enr_udp_port_flag() {
|
||||
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||
CommandLineTest::new()
|
||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||
.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]
|
||||
fn enr_tcp_port_flags() {
|
||||
let port = unused_tcp_port().expect("Unable to find unused port.");
|
||||
fn enr_tcp_port_flag() {
|
||||
let port = unused_tcp4_port().expect("Unable to find unused port.");
|
||||
CommandLineTest::new()
|
||||
.flag("enr-tcp-port", Some(port.to_string().as_str()))
|
||||
.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]
|
||||
fn enr_match_flag() {
|
||||
let addr = "127.0.0.2".parse::<IpAddr>().unwrap();
|
||||
let port1 = unused_udp_port().expect("Unable to find unused port.");
|
||||
let port2 = unused_udp_port().expect("Unable to find unused port.");
|
||||
fn enr_udp6_port_flag() {
|
||||
let port = unused_udp6_port().expect("Unable to find unused port.");
|
||||
CommandLineTest::new()
|
||||
.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()
|
||||
.flag("enr-match", None)
|
||||
.flag("listen-address", Some("127.0.0.2"))
|
||||
.flag("discovery-port", Some(port1.to_string().as_str()))
|
||||
.flag("port", Some(port2.to_string().as_str()))
|
||||
.flag("discovery-port", Some(udp4_port.to_string().as_str()))
|
||||
.flag("port", Some(tcp4_port.to_string().as_str()))
|
||||
.run()
|
||||
.with_config(|config| {
|
||||
assert_eq!(config.network.listen_address, addr);
|
||||
assert_eq!(config.network.enr_address, Some(addr));
|
||||
assert_eq!(config.network.discovery_port, port1);
|
||||
assert_eq!(config.network.enr_udp_port, Some(port1));
|
||||
assert_eq!(
|
||||
config.network.listen_addrs().v4().map(|listen_addr| (
|
||||
listen_addr.addr,
|
||||
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]
|
||||
fn enr_address_flag() {
|
||||
let addr = "192.167.1.1".parse::<IpAddr>().unwrap();
|
||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
||||
fn enr_match_flag_over_ipv6() {
|
||||
const ADDR: &str = "::1";
|
||||
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()
|
||||
.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));
|
||||
assert_eq!(config.network.enr_udp_port, Some(port));
|
||||
assert_eq!(config.network.enr_address, (Some(addr), None));
|
||||
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]
|
||||
fn enr_address_dns_flag() {
|
||||
let addr = "127.0.0.1".parse::<IpAddr>().unwrap();
|
||||
let ipv6addr = "::1".parse::<IpAddr>().unwrap();
|
||||
let port = unused_udp_port().expect("Unable to find unused port.");
|
||||
let addr = Ipv4Addr::LOCALHOST;
|
||||
let ipv6addr = Ipv6Addr::LOCALHOST;
|
||||
let port = unused_udp4_port().expect("Unable to find unused port.");
|
||||
CommandLineTest::new()
|
||||
.flag("enr-address", Some("localhost"))
|
||||
.flag("enr-udp-port", Some(port.to_string().as_str()))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
assert!(
|
||||
config.network.enr_address == Some(addr)
|
||||
|| config.network.enr_address == Some(ipv6addr)
|
||||
config.network.enr_address.0 == Some(addr)
|
||||
|| 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]
|
||||
@ -1100,8 +1354,8 @@ fn http_address_ipv6_flag() {
|
||||
}
|
||||
#[test]
|
||||
fn http_port_flag() {
|
||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
||||
let port2 = unused_tcp_port().expect("Unable to find unused port.");
|
||||
let port1 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||
let port2 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||
CommandLineTest::new()
|
||||
.flag("http-port", Some(port1.to_string().as_str()))
|
||||
.flag("port", Some(port2.to_string().as_str()))
|
||||
@ -1215,8 +1469,8 @@ fn metrics_address_ipv6_flag() {
|
||||
}
|
||||
#[test]
|
||||
fn metrics_port_flag() {
|
||||
let port1 = unused_tcp_port().expect("Unable to find unused port.");
|
||||
let port2 = unused_tcp_port().expect("Unable to find unused port.");
|
||||
let port1 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||
let port2 = unused_tcp4_port().expect("Unable to find unused port.");
|
||||
CommandLineTest::new()
|
||||
.flag("metrics", None)
|
||||
.flag("metrics-port", Some(port1.to_string().as_str()))
|
||||
|
@ -12,7 +12,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use tempfile::TempDir;
|
||||
use unused_port::unused_udp_port;
|
||||
use unused_port::unused_udp4_port;
|
||||
|
||||
const IP_ADDRESS: &str = "192.168.2.108";
|
||||
|
||||
@ -62,7 +62,7 @@ fn enr_address_arg() {
|
||||
|
||||
#[test]
|
||||
fn port_flag() {
|
||||
let port = unused_udp_port().unwrap();
|
||||
let port = unused_udp4_port().unwrap();
|
||||
CommandLineTest::new()
|
||||
.flag("port", Some(port.to_string().as_str()))
|
||||
.run_with_ip()
|
||||
@ -122,7 +122,7 @@ fn boot_nodes_flag() {
|
||||
|
||||
#[test]
|
||||
fn enr_port_flag() {
|
||||
let port = unused_udp_port().unwrap();
|
||||
let port = unused_udp4_port().unwrap();
|
||||
CommandLineTest::new()
|
||||
.flag("enr-port", Some(port.to_string().as_str()))
|
||||
.run_with_ip()
|
||||
|
@ -3,7 +3,7 @@ use std::io::prelude::*;
|
||||
use std::io::BufReader;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::time::{Duration, Instant};
|
||||
use unused_port::unused_tcp_port;
|
||||
use unused_port::unused_tcp4_port;
|
||||
use web3::{transports::Http, Transport, Web3};
|
||||
|
||||
/// 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
|
||||
/// RPC connections.
|
||||
pub fn new(chain_id: u64) -> Result<Self, String> {
|
||||
let port = unused_tcp_port()?;
|
||||
let port = unused_tcp4_port()?;
|
||||
let binary = match cfg!(windows) {
|
||||
true => "ganache.cmd",
|
||||
false => "ganache",
|
||||
@ -97,7 +97,7 @@ impl GanacheInstance {
|
||||
}
|
||||
|
||||
pub fn fork(&self) -> Result<Self, String> {
|
||||
let port = unused_tcp_port()?;
|
||||
let port = unused_tcp4_port()?;
|
||||
let binary = match cfg!(windows) {
|
||||
true => "ganache.cmd",
|
||||
false => "ganache",
|
||||
|
@ -4,7 +4,7 @@ use sensitive_url::SensitiveUrl;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Child;
|
||||
use tempfile::TempDir;
|
||||
use unused_port::unused_tcp_port;
|
||||
use unused_port::unused_tcp4_port;
|
||||
|
||||
pub const KEYSTORE_PASSWORD: &str = "testpwd";
|
||||
pub const ACCOUNT1: &str = "7b8C3a386C0eea54693fFB0DA17373ffC9228139";
|
||||
@ -50,8 +50,8 @@ impl<E: GenericExecutionEngine> ExecutionEngine<E> {
|
||||
pub fn new(engine: E) -> Self {
|
||||
let datadir = E::init_datadir();
|
||||
let jwt_secret_path = datadir.path().join(DEFAULT_JWT_FILE);
|
||||
let http_port = unused_tcp_port().unwrap();
|
||||
let http_auth_port = unused_tcp_port().unwrap();
|
||||
let http_port = unused_tcp4_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 provider = Provider::<Http>::try_from(format!("http://localhost:{}", http_port))
|
||||
.expect("failed to instantiate ethers provider");
|
||||
|
@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::process::{Child, Command, Output};
|
||||
use std::{env, fs::File};
|
||||
use tempfile::TempDir;
|
||||
use unused_port::unused_tcp_port;
|
||||
use unused_port::unused_tcp4_port;
|
||||
|
||||
const GETH_BRANCH: &str = "master";
|
||||
const GETH_REPO_URL: &str = "https://github.com/ethereum/go-ethereum";
|
||||
@ -83,7 +83,7 @@ impl GenericExecutionEngine for GethEngine {
|
||||
http_auth_port: u16,
|
||||
jwt_secret_path: PathBuf,
|
||||
) -> Child {
|
||||
let network_port = unused_tcp_port().unwrap();
|
||||
let network_port = unused_tcp4_port().unwrap();
|
||||
|
||||
Command::new(Self::binary_path())
|
||||
.arg("--datadir")
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![recursion_limit = "1024"]
|
||||
/// 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.
|
||||
|
@ -6,7 +6,7 @@ use std::fs::File;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Child, Command, Output};
|
||||
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
|
||||
/// 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,
|
||||
jwt_secret_path: PathBuf,
|
||||
) -> Child {
|
||||
let network_port = unused_tcp_port().unwrap();
|
||||
let network_port = unused_tcp4_port().unwrap();
|
||||
let genesis_json_path = datadir.path().join("genesis.json");
|
||||
|
||||
Command::new(Self::binary_path())
|
||||
|
@ -89,8 +89,9 @@ pub fn testing_client_config() -> ClientConfig {
|
||||
let mut client_config = ClientConfig::default();
|
||||
|
||||
// Setting ports to `0` means that the OS will choose some available port.
|
||||
client_config.network.libp2p_port = 0;
|
||||
client_config.network.discovery_port = 0;
|
||||
client_config
|
||||
.network
|
||||
.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, 0, 0);
|
||||
client_config.network.upnp_enabled = false;
|
||||
client_config.http_api.enabled = true;
|
||||
client_config.http_api.listen_port = 0;
|
||||
|
@ -13,7 +13,7 @@ use node_test_rig::{
|
||||
use rayon::prelude::*;
|
||||
use sensitive_url::SensitiveUrl;
|
||||
use std::cmp::max;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::time::Duration;
|
||||
use tokio::time::sleep;
|
||||
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.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 {
|
||||
let el_config = execution_layer::Config {
|
||||
|
@ -58,10 +58,13 @@ impl<E: EthSpec> LocalNetwork<E> {
|
||||
context: RuntimeContext<E>,
|
||||
mut beacon_config: ClientConfig,
|
||||
) -> Result<Self, String> {
|
||||
beacon_config.network.discovery_port = BOOTNODE_PORT;
|
||||
beacon_config.network.libp2p_port = BOOTNODE_PORT;
|
||||
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT);
|
||||
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT);
|
||||
beacon_config.network.set_ipv4_listening_address(
|
||||
std::net::Ipv4Addr::UNSPECIFIED,
|
||||
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;
|
||||
|
||||
let execution_node = if let Some(el_config) = &mut beacon_config.execution_layer {
|
||||
@ -132,10 +135,13 @@ impl<E: EthSpec> LocalNetwork<E> {
|
||||
.enr()
|
||||
.expect("bootnode must have a network"),
|
||||
);
|
||||
beacon_config.network.discovery_port = BOOTNODE_PORT + count;
|
||||
beacon_config.network.libp2p_port = BOOTNODE_PORT + count;
|
||||
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT + count);
|
||||
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT + count);
|
||||
beacon_config.network.set_ipv4_listening_address(
|
||||
std::net::Ipv4Addr::UNSPECIFIED,
|
||||
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;
|
||||
}
|
||||
if let Some(el_config) = &mut beacon_config.execution_layer {
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
//! 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
|
||||
//! `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 std::cmp::max;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
use tokio::time::sleep;
|
||||
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.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 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 std::cmp::max;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
use types::{Epoch, EthSpec};
|
||||
|
||||
@ -95,7 +95,7 @@ fn syncing_sim(
|
||||
|
||||
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.
|
||||
let validator_indices = (0..num_validators).collect::<Vec<_>>();
|
||||
|
Loading…
Reference in New Issue
Block a user