Improve single-node testnet support and Arc NetworkConfig/ChainSpec (#6396)

* Arc ChainSpec and NetworkConfig

* Fix release tests

* Fix lint

* Merge remote-tracking branch 'origin/unstable' into single-node-testnet
This commit is contained in:
Michael Sproul
2024-09-24 10:16:18 +10:00
committed by GitHub
parent d84df5799c
commit 1447eeb40b
66 changed files with 340 additions and 250 deletions

View File

@@ -1215,10 +1215,11 @@ mod tests {
}
async fn build_discovery() -> Discovery<E> {
let spec = ChainSpec::default();
let spec = Arc::new(ChainSpec::default());
let keypair = secp256k1::Keypair::generate();
let mut config = NetworkConfig::default();
config.set_listening_addr(crate::ListenAddress::unused_v4_ports());
let config = Arc::new(config);
let enr_key: CombinedKey = CombinedKey::from_secp256k1(&keypair);
let enr: Enr = build_enr::<E>(&enr_key, &config, &EnrForkId::default(), &spec).unwrap();
let log = build_log(slog::Level::Debug, false);
@@ -1232,6 +1233,7 @@ mod tests {
vec![],
false,
&log,
config.clone(),
spec.clone(),
);
let keypair = keypair.into();

View File

@@ -4,9 +4,7 @@ use crate::discovery::enr_ext::EnrExt;
use crate::discovery::peer_id_to_node_id;
use crate::rpc::{GoodbyeReason, MetaData, Protocol, RPCError, RPCResponseErrorCode};
use crate::service::TARGET_SUBNET_PEERS;
use crate::{error, metrics, Gossipsub};
use crate::{NetworkGlobals, PeerId};
use crate::{Subnet, SubnetDiscovery};
use crate::{error, metrics, Gossipsub, NetworkGlobals, PeerId, Subnet, SubnetDiscovery};
use delay_map::HashSetDelay;
use discv5::Enr;
use libp2p::identify::Info as IdentifyInfo;
@@ -1452,6 +1450,7 @@ enum ConnectingType {
#[cfg(test)]
mod tests {
use super::*;
use crate::NetworkConfig;
use slog::{o, Drain};
use types::MainnetEthSpec as E;
@@ -1468,15 +1467,7 @@ mod tests {
}
async fn build_peer_manager(target_peer_count: usize) -> PeerManager<E> {
let config = config::Config {
target_peer_count,
discovery_enabled: false,
..Default::default()
};
let log = build_log(slog::Level::Debug, false);
let spec = E::default_spec();
let globals = NetworkGlobals::new_test_globals(vec![], &log, spec);
PeerManager::new(config, Arc::new(globals), &log).unwrap()
build_peer_manager_with_trusted_peers(vec![], target_peer_count).await
}
async fn build_peer_manager_with_trusted_peers(
@@ -1488,9 +1479,13 @@ mod tests {
discovery_enabled: false,
..Default::default()
};
let network_config = Arc::new(NetworkConfig {
target_peers: target_peer_count,
..Default::default()
});
let log = build_log(slog::Level::Debug, false);
let spec = E::default_spec();
let globals = NetworkGlobals::new_test_globals(trusted_peers, &log, spec);
let spec = Arc::new(E::default_spec());
let globals = NetworkGlobals::new_test_globals(trusted_peers, &log, network_config, spec);
PeerManager::new(config, Arc::new(globals), &log).unwrap()
}

View File

@@ -166,7 +166,7 @@ impl<E: EthSpec> Network<E> {
&config,
&ctx.enr_fork_id,
&log,
ctx.chain_spec,
&ctx.chain_spec,
)?;
// Construct the metadata
let custody_subnet_count = if ctx.chain_spec.is_peer_das_scheduled() {
@@ -186,6 +186,7 @@ impl<E: EthSpec> Network<E> {
trusted_peers,
config.disable_peer_scoring,
&log,
config.clone(),
ctx.chain_spec.clone(),
);
Arc::new(globals)
@@ -209,7 +210,7 @@ impl<E: EthSpec> Network<E> {
E::slots_per_epoch(),
);
let score_settings = PeerScoreSettings::new(ctx.chain_spec, gs_config.mesh_n());
let score_settings = PeerScoreSettings::new(&ctx.chain_spec, gs_config.mesh_n());
let gossip_cache = {
let slot_duration = std::time::Duration::from_secs(ctx.chain_spec.seconds_per_slot);
@@ -346,7 +347,7 @@ impl<E: EthSpec> Network<E> {
&config,
network_globals.clone(),
&log,
ctx.chain_spec,
&ctx.chain_spec,
)
.await?;
// start searching for peers

View File

@@ -30,10 +30,10 @@ pub const MAX_CONNECTIONS_PER_PEER: u32 = 1;
pub const METADATA_FILENAME: &str = "metadata";
pub struct Context<'a> {
pub config: &'a NetworkConfig,
pub config: Arc<NetworkConfig>,
pub enr_fork_id: EnrForkId,
pub fork_context: Arc<ForkContext>,
pub chain_spec: &'a ChainSpec,
pub chain_spec: Arc<ChainSpec>,
pub libp2p_registry: Option<&'a mut Registry>,
}

View File

@@ -2,12 +2,11 @@
use crate::peer_manager::peerdb::PeerDB;
use crate::rpc::{MetaData, MetaDataV3};
use crate::types::{BackFillState, SyncState};
use crate::Client;
use crate::EnrExt;
use crate::{Enr, GossipTopic, Multiaddr, PeerId};
use crate::{Client, Enr, EnrExt, GossipTopic, Multiaddr, NetworkConfig, PeerId};
use itertools::Itertools;
use parking_lot::RwLock;
use std::collections::HashSet;
use std::sync::Arc;
use types::{ChainSpec, ColumnIndex, DataColumnSubnetId, EthSpec};
pub struct NetworkGlobals<E: EthSpec> {
@@ -30,7 +29,10 @@ pub struct NetworkGlobals<E: EthSpec> {
/// The computed custody subnets and columns is stored to avoid re-computing.
pub custody_subnets: Vec<DataColumnSubnetId>,
pub custody_columns: Vec<ColumnIndex>,
pub spec: ChainSpec,
/// Network-related configuration. Immutable after initialization.
pub config: Arc<NetworkConfig>,
/// Ethereum chain configuration. Immutable after initialization.
pub spec: Arc<ChainSpec>,
}
impl<E: EthSpec> NetworkGlobals<E> {
@@ -40,7 +42,8 @@ impl<E: EthSpec> NetworkGlobals<E> {
trusted_peers: Vec<PeerId>,
disable_peer_scoring: bool,
log: &slog::Logger,
spec: ChainSpec,
config: Arc<NetworkConfig>,
spec: Arc<ChainSpec>,
) -> Self {
let (custody_subnets, custody_columns) = if spec.is_peer_das_scheduled() {
let custody_subnet_count = local_metadata
@@ -75,6 +78,7 @@ impl<E: EthSpec> NetworkGlobals<E> {
backfill_state: RwLock::new(BackFillState::NotRequired),
custody_subnets,
custody_columns,
config,
spec,
}
}
@@ -160,7 +164,8 @@ impl<E: EthSpec> NetworkGlobals<E> {
pub fn new_test_globals(
trusted_peers: Vec<PeerId>,
log: &slog::Logger,
spec: ChainSpec,
config: Arc<NetworkConfig>,
spec: Arc<ChainSpec>,
) -> NetworkGlobals<E> {
let metadata = MetaData::V3(MetaDataV3 {
seq_number: 0,
@@ -168,20 +173,21 @@ impl<E: EthSpec> NetworkGlobals<E> {
syncnets: Default::default(),
custody_subnet_count: spec.custody_requirement,
});
Self::new_test_globals_with_metadata(trusted_peers, metadata, log, spec)
Self::new_test_globals_with_metadata(trusted_peers, metadata, log, config, spec)
}
pub(crate) fn new_test_globals_with_metadata(
trusted_peers: Vec<PeerId>,
metadata: MetaData<E>,
log: &slog::Logger,
spec: ChainSpec,
config: Arc<NetworkConfig>,
spec: Arc<ChainSpec>,
) -> NetworkGlobals<E> {
use crate::CombinedKeyExt;
let keypair = libp2p::identity::secp256k1::Keypair::generate();
let enr_key: discv5::enr::CombinedKey = discv5::enr::CombinedKey::from_secp256k1(&keypair);
let enr = discv5::enr::Enr::builder().build(&enr_key).unwrap();
NetworkGlobals::new(enr, metadata, trusted_peers, false, log, spec)
NetworkGlobals::new(enr, metadata, trusted_peers, false, log, config, spec)
}
}
@@ -198,9 +204,15 @@ mod test {
let custody_subnet_count = spec.data_column_sidecar_subnet_count / 2;
let metadata = get_metadata(custody_subnet_count);
let config = Arc::new(NetworkConfig::default());
let globals =
NetworkGlobals::<E>::new_test_globals_with_metadata(vec![], metadata, &log, spec);
let globals = NetworkGlobals::<E>::new_test_globals_with_metadata(
vec![],
metadata,
&log,
config,
Arc::new(spec),
);
assert_eq!(globals.custody_subnets.len(), custody_subnet_count as usize);
}
@@ -213,9 +225,15 @@ mod test {
let custody_subnet_count = spec.data_column_sidecar_subnet_count / 2;
let custody_columns_count = spec.number_of_columns / 2;
let metadata = get_metadata(custody_subnet_count);
let config = Arc::new(NetworkConfig::default());
let globals =
NetworkGlobals::<E>::new_test_globals_with_metadata(vec![], metadata, &log, spec);
let globals = NetworkGlobals::<E>::new_test_globals_with_metadata(
vec![],
metadata,
&log,
config,
Arc::new(spec),
);
assert_eq!(globals.custody_columns.len(), custody_columns_count);
}

View File

@@ -91,6 +91,14 @@ impl SyncState {
pub fn is_synced(&self) -> bool {
matches!(self, SyncState::Synced | SyncState::BackFillSyncing { .. })
}
/// Returns true if the node is *stalled*, i.e. has no synced peers.
///
/// Usually this state is treated as unsynced, except in some places where we make an exception
/// for single-node testnets where having 0 peers is desired.
pub fn is_stalled(&self) -> bool {
matches!(self, SyncState::Stalled)
}
}
impl std::fmt::Display for SyncState {