mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-28 18:23:38 +00:00
decouple eth2 from store and lighthouse_network (#6680)
- #6452 (partially) Remove dependencies on `store` and `lighthouse_network` from `eth2`. This was achieved as follows: - depend on `enr` and `multiaddr` directly instead of using `lighthouse_network`'s reexports. - make `lighthouse_network` responsible for converting between API and internal types. - in two cases, remove complex internal types and use the generic `serde_json::Value` instead - this is not ideal, but should be fine for now, as this affects two internal non-spec endpoints which are meant for debugging, unstable, and subject to change without notice anyway. Inspired by #6679. The alternative is to move all relevant types to `eth2` or `types` instead - what do you think?
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use crate::{BeaconChain, BeaconChainError, BeaconChainTypes};
|
||||
use eth2::lighthouse::attestation_rewards::{IdealAttestationRewards, TotalAttestationRewards};
|
||||
use eth2::lighthouse::StandardAttestationRewards;
|
||||
use eth2::types::ValidatorId;
|
||||
use eth2::types::{
|
||||
IdealAttestationRewards, StandardAttestationRewards, TotalAttestationRewards, ValidatorId,
|
||||
};
|
||||
use safe_arith::SafeArith;
|
||||
use serde_utils::quoted_u64::Quoted;
|
||||
use state_processing::common::base::{self, SqrtTotalActiveBalance};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{BeaconChain, BeaconChainError, BeaconChainTypes, StateSkipConfig};
|
||||
use attesting_indices_base::get_attesting_indices;
|
||||
use eth2::lighthouse::StandardBlockReward;
|
||||
use eth2::types::StandardBlockReward;
|
||||
use safe_arith::SafeArith;
|
||||
use state_processing::common::attesting_indices_base;
|
||||
use state_processing::{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{BeaconChain, BeaconChainError, BeaconChainTypes};
|
||||
|
||||
use eth2::lighthouse::SyncCommitteeReward;
|
||||
use eth2::types::SyncCommitteeReward;
|
||||
use safe_arith::SafeArith;
|
||||
use state_processing::per_block_processing::altair::sync_committee::compute_sync_aggregate_rewards;
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -9,9 +9,7 @@ use beacon_chain::{
|
||||
types::{Epoch, EthSpec, Keypair, MinimalEthSpec},
|
||||
BlockError, ChainConfig, StateSkipConfig, WhenSlotSkipped,
|
||||
};
|
||||
use eth2::lighthouse::attestation_rewards::TotalAttestationRewards;
|
||||
use eth2::lighthouse::StandardAttestationRewards;
|
||||
use eth2::types::ValidatorId;
|
||||
use eth2::types::{StandardAttestationRewards, TotalAttestationRewards, ValidatorId};
|
||||
use state_processing::{BlockReplayError, BlockReplayer};
|
||||
use std::array::IntoIter;
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -12,7 +12,6 @@ arc-swap = "1.6.0"
|
||||
builder_client = { path = "../builder_client" }
|
||||
bytes = { workspace = true }
|
||||
eth2 = { workspace = true }
|
||||
eth2_network_config = { workspace = true }
|
||||
ethereum_serde_utils = { workspace = true }
|
||||
ethereum_ssz = { workspace = true }
|
||||
ethers-core = { workspace = true }
|
||||
|
||||
@@ -50,7 +50,6 @@ warp_utils = { workspace = true }
|
||||
[dev-dependencies]
|
||||
genesis = { workspace = true }
|
||||
proto_array = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
[[test]]
|
||||
name = "bn_http_api_tests"
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
use beacon_chain::store::metadata::CURRENT_SCHEMA_VERSION;
|
||||
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
||||
use eth2::lighthouse::DatabaseInfo;
|
||||
use serde::Serialize;
|
||||
use std::sync::Arc;
|
||||
use store::{AnchorInfo, BlobInfo, Split, StoreConfig};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct DatabaseInfo {
|
||||
pub schema_version: u64,
|
||||
pub config: StoreConfig,
|
||||
pub split: Split,
|
||||
pub anchor: AnchorInfo,
|
||||
pub blob_info: BlobInfo,
|
||||
}
|
||||
|
||||
pub fn info<T: BeaconChainTypes>(
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
|
||||
@@ -16,6 +16,7 @@ mod builder_states;
|
||||
mod database;
|
||||
mod light_client;
|
||||
mod metrics;
|
||||
mod peer;
|
||||
mod produce_block;
|
||||
mod proposer_duties;
|
||||
mod publish_attestations;
|
||||
@@ -3022,15 +3023,13 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
};
|
||||
|
||||
// the eth2 API spec implies only peers we have been connected to at some point should be included.
|
||||
if let Some(dir) = peer_info.connection_direction().as_ref() {
|
||||
if let Some(&dir) = peer_info.connection_direction() {
|
||||
return Ok(api_types::GenericResponse::from(api_types::PeerData {
|
||||
peer_id: peer_id.to_string(),
|
||||
enr: peer_info.enr().map(|enr| enr.to_base64()),
|
||||
last_seen_p2p_address: address,
|
||||
direction: api_types::PeerDirection::from_connection_direction(dir),
|
||||
state: api_types::PeerState::from_peer_connection_status(
|
||||
peer_info.connection_status(),
|
||||
),
|
||||
direction: dir.into(),
|
||||
state: peer_info.connection_status().clone().into(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -3071,12 +3070,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
};
|
||||
|
||||
// the eth2 API spec implies only peers we have been connected to at some point should be included.
|
||||
if let Some(dir) = peer_info.connection_direction() {
|
||||
let direction =
|
||||
api_types::PeerDirection::from_connection_direction(dir);
|
||||
let state = api_types::PeerState::from_peer_connection_status(
|
||||
peer_info.connection_status(),
|
||||
);
|
||||
if let Some(&dir) = peer_info.connection_direction() {
|
||||
let direction = dir.into();
|
||||
let state = peer_info.connection_status().clone().into();
|
||||
|
||||
let state_matches = query.state.as_ref().is_none_or(|states| {
|
||||
states.iter().any(|state_param| *state_param == state)
|
||||
@@ -3128,9 +3124,8 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.read()
|
||||
.peers()
|
||||
.for_each(|(_, peer_info)| {
|
||||
let state = api_types::PeerState::from_peer_connection_status(
|
||||
peer_info.connection_status(),
|
||||
);
|
||||
let state =
|
||||
api_types::PeerState::from(peer_info.connection_status().clone());
|
||||
match state {
|
||||
api_types::PeerState::Connected => connected += 1,
|
||||
api_types::PeerState::Connecting => connecting += 1,
|
||||
@@ -4089,7 +4084,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.peers
|
||||
.read()
|
||||
.peers()
|
||||
.map(|(peer_id, peer_info)| eth2::lighthouse::Peer {
|
||||
.map(|(peer_id, peer_info)| peer::Peer {
|
||||
peer_id: peer_id.to_string(),
|
||||
peer_info: peer_info.clone(),
|
||||
})
|
||||
@@ -4109,15 +4104,14 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
|task_spawner: TaskSpawner<T::EthSpec>,
|
||||
network_globals: Arc<NetworkGlobals<T::EthSpec>>| {
|
||||
task_spawner.blocking_json_task(Priority::P1, move || {
|
||||
Ok(network_globals
|
||||
.peers
|
||||
.read()
|
||||
.connected_peers()
|
||||
.map(|(peer_id, peer_info)| eth2::lighthouse::Peer {
|
||||
let mut peers = vec![];
|
||||
for (peer_id, peer_info) in network_globals.peers.read().connected_peers() {
|
||||
peers.push(peer::Peer {
|
||||
peer_id: peer_id.to_string(),
|
||||
peer_info: peer_info.clone(),
|
||||
})
|
||||
.collect::<Vec<_>>())
|
||||
});
|
||||
}
|
||||
Ok(peers)
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
13
beacon_node/http_api/src/peer.rs
Normal file
13
beacon_node/http_api/src/peer.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
use lighthouse_network::PeerInfo;
|
||||
use serde::Serialize;
|
||||
use types::EthSpec;
|
||||
|
||||
/// Information returned by `peers` and `connected_peers`.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(bound = "E: EthSpec")]
|
||||
pub(crate) struct Peer<E: EthSpec> {
|
||||
/// The Peer's ID
|
||||
pub peer_id: String,
|
||||
/// The PeerInfo associated with the peer.
|
||||
pub peer_info: PeerInfo<E>,
|
||||
}
|
||||
@@ -2,7 +2,7 @@ use crate::sync_committee_rewards::get_state_before_applying_block;
|
||||
use crate::BlockId;
|
||||
use crate::ExecutionOptimistic;
|
||||
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
||||
use eth2::lighthouse::StandardBlockReward;
|
||||
use eth2::types::StandardBlockReward;
|
||||
use std::sync::Arc;
|
||||
use warp_utils::reject::unhandled_error;
|
||||
/// The difference between block_rewards and beacon_block_rewards is the later returns block
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::{BlockId, ExecutionOptimistic};
|
||||
use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes};
|
||||
use eth2::lighthouse::SyncCommitteeReward;
|
||||
use eth2::types::ValidatorId;
|
||||
use eth2::types::{SyncCommitteeReward, ValidatorId};
|
||||
use state_processing::BlockReplayer;
|
||||
use std::sync::Arc;
|
||||
use tracing::debug;
|
||||
|
||||
@@ -5686,19 +5686,6 @@ impl ApiTester {
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn test_get_lighthouse_database_info(self) -> Self {
|
||||
let info = self.client.get_lighthouse_database_info().await.unwrap();
|
||||
|
||||
assert_eq!(info.anchor, self.chain.store.get_anchor_info());
|
||||
assert_eq!(info.split, self.chain.store.get_split_info());
|
||||
assert_eq!(
|
||||
info.schema_version,
|
||||
store::metadata::CURRENT_SCHEMA_VERSION.as_u64()
|
||||
);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn test_post_lighthouse_database_reconstruct(self) -> Self {
|
||||
let response = self
|
||||
.client
|
||||
@@ -7254,8 +7241,6 @@ async fn lighthouse_endpoints() {
|
||||
.await
|
||||
.test_get_lighthouse_staking()
|
||||
.await
|
||||
.test_get_lighthouse_database_info()
|
||||
.await
|
||||
.test_post_lighthouse_database_reconstruct()
|
||||
.await
|
||||
.test_post_lighthouse_liveness()
|
||||
|
||||
@@ -13,6 +13,7 @@ directory = { workspace = true }
|
||||
dirs = { workspace = true }
|
||||
discv5 = { workspace = true }
|
||||
either = { workspace = true }
|
||||
eth2 = { workspace = true }
|
||||
ethereum_ssz = { workspace = true }
|
||||
ethereum_ssz_derive = { workspace = true }
|
||||
fnv = { workspace = true }
|
||||
|
||||
@@ -4,6 +4,7 @@ use super::sync_status::SyncStatus;
|
||||
use crate::discovery::Eth2Enr;
|
||||
use crate::{rpc::MetaData, types::Subnet};
|
||||
use discv5::Enr;
|
||||
use eth2::types::{PeerDirection, PeerState};
|
||||
use libp2p::core::multiaddr::{Multiaddr, Protocol};
|
||||
use serde::{
|
||||
ser::{SerializeStruct, Serializer},
|
||||
@@ -522,7 +523,7 @@ impl<E: EthSpec> PeerInfo<E> {
|
||||
}
|
||||
|
||||
/// Connection Direction of connection.
|
||||
#[derive(Debug, Clone, Serialize, AsRefStr)]
|
||||
#[derive(Debug, Clone, Copy, Serialize, AsRefStr)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum ConnectionDirection {
|
||||
/// The connection was established by a peer dialing us.
|
||||
@@ -531,6 +532,15 @@ pub enum ConnectionDirection {
|
||||
Outgoing,
|
||||
}
|
||||
|
||||
impl From<ConnectionDirection> for PeerDirection {
|
||||
fn from(direction: ConnectionDirection) -> Self {
|
||||
match direction {
|
||||
ConnectionDirection::Incoming => PeerDirection::Inbound,
|
||||
ConnectionDirection::Outgoing => PeerDirection::Outbound,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Connection Status of the peer.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub enum PeerConnectionStatus {
|
||||
@@ -624,3 +634,14 @@ impl Serialize for PeerConnectionStatus {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PeerConnectionStatus> for PeerState {
|
||||
fn from(status: PeerConnectionStatus) -> Self {
|
||||
match status {
|
||||
Connected { .. } => PeerState::Connected,
|
||||
Dialing { .. } => PeerState::Connecting,
|
||||
Disconnecting { .. } => PeerState::Disconnecting,
|
||||
Disconnected { .. } | Banned { .. } | Unknown => PeerState::Disconnected,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
mod globals;
|
||||
mod pubsub;
|
||||
mod subnet;
|
||||
mod sync_state;
|
||||
mod topics;
|
||||
|
||||
use types::{BitVector, EthSpec};
|
||||
@@ -11,10 +10,10 @@ pub type EnrSyncCommitteeBitfield<E> = BitVector<<E as EthSpec>::SyncCommitteeSu
|
||||
|
||||
pub type Enr = discv5::enr::Enr<discv5::enr::CombinedKey>;
|
||||
|
||||
pub use eth2::lighthouse::sync_state::{BackFillState, SyncState};
|
||||
pub use globals::NetworkGlobals;
|
||||
pub use pubsub::{PubsubMessage, SnappyTransform};
|
||||
pub use subnet::{Subnet, SubnetDiscovery};
|
||||
pub use sync_state::{BackFillState, SyncState};
|
||||
pub use topics::{
|
||||
all_topics_at_fork, core_topics_to_subscribe, is_fork_non_core_topic, subnet_from_topic_hash,
|
||||
GossipEncoding, GossipKind, GossipTopic, TopicConfig,
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use types::Slot;
|
||||
|
||||
/// The current state of the node.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum SyncState {
|
||||
/// The node is performing a long-range (batch) sync over a finalized chain.
|
||||
/// In this state, parent lookups are disabled.
|
||||
SyncingFinalized { start_slot: Slot, target_slot: Slot },
|
||||
/// The node is performing a long-range (batch) sync over one or many head chains.
|
||||
/// In this state parent lookups are disabled.
|
||||
SyncingHead { start_slot: Slot, target_slot: Slot },
|
||||
/// The node is undertaking a backfill sync. This occurs when a user has specified a trusted
|
||||
/// state. The node first syncs "forward" by downloading blocks up to the current head as
|
||||
/// specified by its peers. Once completed, the node enters this sync state and attempts to
|
||||
/// download all required historical blocks.
|
||||
BackFillSyncing { completed: usize, remaining: usize },
|
||||
/// The node has completed syncing a finalized chain and is in the process of re-evaluating
|
||||
/// which sync state to progress to.
|
||||
SyncTransition,
|
||||
/// The node is up to date with all known peers and is connected to at least one
|
||||
/// fully synced peer. In this state, parent lookups are enabled.
|
||||
Synced,
|
||||
/// No useful peers are connected. Long-range sync's cannot proceed and we have no useful
|
||||
/// peers to download parents for. More peers need to be connected before we can proceed.
|
||||
Stalled,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
/// The state of the backfill sync.
|
||||
pub enum BackFillState {
|
||||
/// The sync is partially completed and currently paused.
|
||||
Paused,
|
||||
/// We are currently backfilling.
|
||||
Syncing,
|
||||
/// A backfill sync has completed.
|
||||
Completed,
|
||||
/// Too many failed attempts at backfilling. Consider it failed.
|
||||
Failed,
|
||||
}
|
||||
|
||||
impl PartialEq for SyncState {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
matches!(
|
||||
(self, other),
|
||||
(
|
||||
SyncState::SyncingFinalized { .. },
|
||||
SyncState::SyncingFinalized { .. }
|
||||
) | (SyncState::SyncingHead { .. }, SyncState::SyncingHead { .. })
|
||||
| (SyncState::Synced, SyncState::Synced)
|
||||
| (SyncState::Stalled, SyncState::Stalled)
|
||||
| (SyncState::SyncTransition, SyncState::SyncTransition)
|
||||
| (
|
||||
SyncState::BackFillSyncing { .. },
|
||||
SyncState::BackFillSyncing { .. }
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl SyncState {
|
||||
/// Returns a boolean indicating the node is currently performing a long-range sync.
|
||||
pub fn is_syncing(&self) -> bool {
|
||||
match self {
|
||||
SyncState::SyncingFinalized { .. } => true,
|
||||
SyncState::SyncingHead { .. } => true,
|
||||
SyncState::SyncTransition => true,
|
||||
// Backfill doesn't effect any logic, we consider this state, not syncing.
|
||||
SyncState::BackFillSyncing { .. } => false,
|
||||
SyncState::Synced => false,
|
||||
SyncState::Stalled => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_syncing_finalized(&self) -> bool {
|
||||
match self {
|
||||
SyncState::SyncingFinalized { .. } => true,
|
||||
SyncState::SyncingHead { .. } => false,
|
||||
SyncState::SyncTransition => false,
|
||||
SyncState::BackFillSyncing { .. } => false,
|
||||
SyncState::Synced => false,
|
||||
SyncState::Stalled => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the node is synced.
|
||||
///
|
||||
/// NOTE: We consider the node synced if it is fetching old historical blocks.
|
||||
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 {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
SyncState::SyncingFinalized { .. } => write!(f, "Syncing Finalized Chain"),
|
||||
SyncState::SyncingHead { .. } => write!(f, "Syncing Head Chain"),
|
||||
SyncState::Synced { .. } => write!(f, "Synced"),
|
||||
SyncState::Stalled { .. } => write!(f, "Stalled"),
|
||||
SyncState::SyncTransition => write!(f, "Evaluating known peers"),
|
||||
SyncState::BackFillSyncing { .. } => write!(f, "Syncing Historical Blocks"),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user