mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore(net): deny unused and cleanup (#289)
This commit is contained in:
@ -24,11 +24,11 @@ pub struct Discovery {
|
|||||||
/// Local ENR of the discovery service.
|
/// Local ENR of the discovery service.
|
||||||
local_enr: NodeRecord,
|
local_enr: NodeRecord,
|
||||||
/// Handler to interact with the Discovery v4 service
|
/// Handler to interact with the Discovery v4 service
|
||||||
discv4: Discv4,
|
_discv4: Discv4,
|
||||||
/// All KAD table updates from the discv4 service.
|
/// All KAD table updates from the discv4 service.
|
||||||
discv4_updates: ReceiverStream<TableUpdate>,
|
discv4_updates: ReceiverStream<TableUpdate>,
|
||||||
/// The initial config for the discv4 service
|
/// The initial config for the discv4 service
|
||||||
dsicv4_config: Discv4Config,
|
_dsicv4_config: Discv4Config,
|
||||||
/// Events buffered until polled.
|
/// Events buffered until polled.
|
||||||
queued_events: VecDeque<DiscoveryEvent>,
|
queued_events: VecDeque<DiscoveryEvent>,
|
||||||
/// The handle to the spawned discv4 service
|
/// The handle to the spawned discv4 service
|
||||||
@ -57,9 +57,9 @@ impl Discovery {
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
local_enr,
|
local_enr,
|
||||||
discv4,
|
_discv4: discv4,
|
||||||
discv4_updates,
|
discv4_updates,
|
||||||
dsicv4_config,
|
_dsicv4_config: dsicv4_config,
|
||||||
_discv4_service,
|
_discv4_service,
|
||||||
discovered_nodes: Default::default(),
|
discovered_nodes: Default::default(),
|
||||||
queued_events: Default::default(),
|
queued_events: Default::default(),
|
||||||
@ -71,23 +71,6 @@ impl Discovery {
|
|||||||
self.local_enr.id
|
self.local_enr.id
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Manually adds an address to the set.
|
|
||||||
///
|
|
||||||
/// This has the same effect as adding node discovered via network gossip.
|
|
||||||
pub(crate) fn add_node_address(&mut self, peer_id: PeerId, addr: SocketAddr) {
|
|
||||||
self.on_discv4_update(TableUpdate::Added(NodeRecord {
|
|
||||||
address: addr.ip(),
|
|
||||||
tcp_port: addr.port(),
|
|
||||||
udp_port: addr.port(),
|
|
||||||
id: peer_id,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns all nodes we know exist in the network.
|
|
||||||
pub fn nodes(&mut self) -> &HashMap<PeerId, SocketAddr> {
|
|
||||||
&self.discovered_nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_discv4_update(&mut self, update: TableUpdate) {
|
fn on_discv4_update(&mut self, update: TableUpdate) {
|
||||||
match update {
|
match update {
|
||||||
TableUpdate::Added(node) => {
|
TableUpdate::Added(node) => {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::message::BlockRequest;
|
use crate::message::BlockRequest;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use reth_eth_wire::{BlockBody, GetBlockBodies};
|
use reth_eth_wire::{BlockBody, GetBlockBodies, GetBlockHeaders};
|
||||||
use reth_interfaces::p2p::{
|
use reth_interfaces::p2p::{
|
||||||
error::{RequestError, RequestResult},
|
error::{RequestError, RequestResult},
|
||||||
headers::client::HeadersRequest,
|
headers::client::HeadersRequest,
|
||||||
@ -161,18 +161,15 @@ impl StateFetcher {
|
|||||||
|
|
||||||
match req {
|
match req {
|
||||||
DownloadRequest::GetBlockHeaders { request, response } => {
|
DownloadRequest::GetBlockHeaders { request, response } => {
|
||||||
let inflight = Request { request, response };
|
let inflight = Request { request: request.clone(), response };
|
||||||
self.inflight_headers_requests.insert(peer_id, inflight);
|
self.inflight_headers_requests.insert(peer_id, inflight);
|
||||||
|
let HeadersRequest { start, limit, reverse } = request;
|
||||||
unimplemented!("unify start types");
|
BlockRequest::GetBlockHeaders(GetBlockHeaders {
|
||||||
|
start_block: start,
|
||||||
// BlockRequest::GetBlockHeaders(GetBlockHeaders {
|
limit,
|
||||||
// // TODO: this should be converted
|
skip: 0,
|
||||||
// start_block: BlockHashOrNumber::Number(0),
|
reverse,
|
||||||
// limit: request.limit,
|
})
|
||||||
// skip: 0,
|
|
||||||
// reverse: request.reverse,
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
DownloadRequest::GetBlockBodies { request, response } => {
|
DownloadRequest::GetBlockBodies { request, response } => {
|
||||||
let inflight = Request { request: request.clone(), response };
|
let inflight = Request { request: request.clone(), response };
|
||||||
@ -307,9 +304,12 @@ impl PeerState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request that waits for a response from the network so it can send it back through the response
|
/// A request that waits for a response from the network, so it can send it back through the
|
||||||
/// channel.
|
/// response channel.
|
||||||
struct Request<Req, Resp> {
|
struct Request<Req, Resp> {
|
||||||
|
/// The issued request object
|
||||||
|
/// TODO: this can be attached to the response in error case
|
||||||
|
#[allow(unused)]
|
||||||
request: Req,
|
request: Req,
|
||||||
response: oneshot::Sender<Resp>,
|
response: oneshot::Sender<Resp>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,6 @@
|
|||||||
no_crate_inject,
|
no_crate_inject,
|
||||||
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
|
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
|
||||||
))]
|
))]
|
||||||
// TODO remove later
|
|
||||||
#![allow(dead_code, clippy::too_many_arguments)]
|
|
||||||
|
|
||||||
//! reth P2P networking.
|
//! reth P2P networking.
|
||||||
//!
|
//!
|
||||||
@ -25,11 +23,11 @@ mod listener;
|
|||||||
mod manager;
|
mod manager;
|
||||||
mod message;
|
mod message;
|
||||||
mod network;
|
mod network;
|
||||||
mod peers;
|
pub mod peers;
|
||||||
mod session;
|
mod session;
|
||||||
mod state;
|
mod state;
|
||||||
mod swarm;
|
mod swarm;
|
||||||
mod transactions;
|
pub mod transactions;
|
||||||
|
|
||||||
pub use config::NetworkConfig;
|
pub use config::NetworkConfig;
|
||||||
pub use fetch::FetchClient;
|
pub use fetch::FetchClient;
|
||||||
|
|||||||
@ -23,11 +23,12 @@ use crate::{
|
|||||||
listener::ConnectionListener,
|
listener::ConnectionListener,
|
||||||
message::{NewBlockMessage, PeerMessage, PeerRequest, PeerRequestSender},
|
message::{NewBlockMessage, PeerMessage, PeerRequest, PeerRequestSender},
|
||||||
network::{NetworkHandle, NetworkHandleMessage},
|
network::{NetworkHandle, NetworkHandleMessage},
|
||||||
peers::{PeersManager, ReputationChangeKind},
|
peers::{PeersHandle, PeersManager, ReputationChangeKind},
|
||||||
session::SessionManager,
|
session::SessionManager,
|
||||||
state::NetworkState,
|
state::NetworkState,
|
||||||
swarm::{Swarm, SwarmEvent},
|
swarm::{Swarm, SwarmEvent},
|
||||||
transactions::NetworkTransactionEvent,
|
transactions::NetworkTransactionEvent,
|
||||||
|
FetchClient,
|
||||||
};
|
};
|
||||||
use futures::{Future, StreamExt};
|
use futures::{Future, StreamExt};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
@ -36,7 +37,7 @@ use reth_eth_wire::{
|
|||||||
DisconnectReason,
|
DisconnectReason,
|
||||||
};
|
};
|
||||||
use reth_interfaces::provider::BlockProvider;
|
use reth_interfaces::provider::BlockProvider;
|
||||||
use reth_primitives::PeerId;
|
use reth_primitives::{PeerId, H256};
|
||||||
use std::{
|
use std::{
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
@ -48,7 +49,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
use tracing::{error, trace};
|
use tracing::{error, trace, warn};
|
||||||
|
|
||||||
/// Manages the _entire_ state of the network.
|
/// Manages the _entire_ state of the network.
|
||||||
///
|
///
|
||||||
@ -84,8 +85,6 @@ pub struct NetworkManager<C> {
|
|||||||
from_handle_rx: UnboundedReceiverStream<NetworkHandleMessage>,
|
from_handle_rx: UnboundedReceiverStream<NetworkHandleMessage>,
|
||||||
/// Handles block imports according to the `eth` protocol.
|
/// Handles block imports according to the `eth` protocol.
|
||||||
block_import: Box<dyn BlockImport>,
|
block_import: Box<dyn BlockImport>,
|
||||||
/// The address of this node that listens for incoming connections.
|
|
||||||
listener_address: Arc<Mutex<SocketAddr>>,
|
|
||||||
/// All listeners for [`Network`] events.
|
/// All listeners for [`Network`] events.
|
||||||
event_listeners: NetworkEventListeners,
|
event_listeners: NetworkEventListeners,
|
||||||
/// Sender half to send events to the [`TransactionsManager`] task, if configured.
|
/// Sender half to send events to the [`TransactionsManager`] task, if configured.
|
||||||
@ -142,7 +141,7 @@ where
|
|||||||
let num_active_peers = Arc::new(AtomicUsize::new(0));
|
let num_active_peers = Arc::new(AtomicUsize::new(0));
|
||||||
let handle = NetworkHandle::new(
|
let handle = NetworkHandle::new(
|
||||||
Arc::clone(&num_active_peers),
|
Arc::clone(&num_active_peers),
|
||||||
Arc::clone(&listener_address),
|
listener_address,
|
||||||
to_manager_tx,
|
to_manager_tx,
|
||||||
local_peer_id,
|
local_peer_id,
|
||||||
peers_handle,
|
peers_handle,
|
||||||
@ -154,7 +153,6 @@ where
|
|||||||
handle,
|
handle,
|
||||||
from_handle_rx: UnboundedReceiverStream::new(from_handle_rx),
|
from_handle_rx: UnboundedReceiverStream::new(from_handle_rx),
|
||||||
block_import,
|
block_import,
|
||||||
listener_address,
|
|
||||||
event_listeners: Default::default(),
|
event_listeners: Default::default(),
|
||||||
to_transactions: None,
|
to_transactions: None,
|
||||||
num_active_peers,
|
num_active_peers,
|
||||||
@ -171,6 +169,11 @@ where
|
|||||||
self.swarm.listener().local_address()
|
self.swarm.listener().local_address()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the configured genesis hash
|
||||||
|
pub fn genesis_hash(&self) -> H256 {
|
||||||
|
self.swarm.state().genesis_hash()
|
||||||
|
}
|
||||||
|
|
||||||
/// How many peers we're currently connected to.
|
/// How many peers we're currently connected to.
|
||||||
pub fn num_connected_peers(&self) -> usize {
|
pub fn num_connected_peers(&self) -> usize {
|
||||||
self.swarm.state().num_connected_peers()
|
self.swarm.state().num_connected_peers()
|
||||||
@ -188,6 +191,20 @@ where
|
|||||||
&self.handle
|
&self.handle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a new [`PeersHandle`] that can be cloned and shared.
|
||||||
|
///
|
||||||
|
/// The [`PeersHandle`] can be used to interact with the network's peer set.
|
||||||
|
pub fn peers_handle(&self) -> PeersHandle {
|
||||||
|
self.swarm.state().peers().handle()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [`FetchClient`] that can be cloned and shared.
|
||||||
|
///
|
||||||
|
/// The [`FetchClient`] is the entrypoint for sending requests to the network.
|
||||||
|
pub fn fetch_client(&self) -> FetchClient {
|
||||||
|
self.swarm.state().fetch_client()
|
||||||
|
}
|
||||||
|
|
||||||
/// Event hook for an unexpected message from the peer.
|
/// Event hook for an unexpected message from the peer.
|
||||||
fn on_invalid_message(
|
fn on_invalid_message(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -302,7 +319,9 @@ where
|
|||||||
PeerMessage::SendTransactions(_) => {
|
PeerMessage::SendTransactions(_) => {
|
||||||
unreachable!("Not emitted by session")
|
unreachable!("Not emitted by session")
|
||||||
}
|
}
|
||||||
PeerMessage::Other(_) => {}
|
PeerMessage::Other(other) => {
|
||||||
|
error!(target : "net", message_id=%other.id, "Ignoring unsupported message");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,6 +358,9 @@ where
|
|||||||
NetworkHandleMessage::ReputationChange(peer_id, kind) => {
|
NetworkHandleMessage::ReputationChange(peer_id, kind) => {
|
||||||
self.swarm.state_mut().peers_mut().apply_reputation_change(&peer_id, kind);
|
self.swarm.state_mut().peers_mut().apply_reputation_change(&peer_id, kind);
|
||||||
}
|
}
|
||||||
|
NetworkHandleMessage::FetchClient(tx) => {
|
||||||
|
let _ = tx.send(self.fetch_client());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -387,11 +409,11 @@ where
|
|||||||
SwarmEvent::TcpListenerError(err) => {
|
SwarmEvent::TcpListenerError(err) => {
|
||||||
trace!(target : "net", ?err, "TCP connection error.");
|
trace!(target : "net", ?err, "TCP connection error.");
|
||||||
}
|
}
|
||||||
SwarmEvent::IncomingTcpConnection { remote_addr, .. } => {
|
SwarmEvent::IncomingTcpConnection { remote_addr, session_id } => {
|
||||||
trace!(target : "net",?remote_addr, "Incoming connection");
|
trace!(target : "net", ?session_id, ?remote_addr, "Incoming connection");
|
||||||
}
|
}
|
||||||
SwarmEvent::OutgoingTcpConnection { remote_addr } => {
|
SwarmEvent::OutgoingTcpConnection { remote_addr, peer_id } => {
|
||||||
trace!(target : "net", ?remote_addr,"Starting outbound connection.");
|
trace!(target : "net", ?remote_addr, ?peer_id, "Starting outbound connection.");
|
||||||
}
|
}
|
||||||
SwarmEvent::SessionEstablished {
|
SwarmEvent::SessionEstablished {
|
||||||
peer_id,
|
peer_id,
|
||||||
@ -410,7 +432,10 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
if direction.is_incoming() {
|
if direction.is_incoming() {
|
||||||
this.swarm.state_mut().peers_mut().on_active_session(peer_id, remote_addr);
|
this.swarm
|
||||||
|
.state_mut()
|
||||||
|
.peers_mut()
|
||||||
|
.on_active_inbound_session(peer_id, remote_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.event_listeners.send(NetworkEvent::SessionEstablished {
|
this.event_listeners.send(NetworkEvent::SessionEstablished {
|
||||||
@ -440,14 +465,36 @@ where
|
|||||||
|
|
||||||
this.event_listeners.send(NetworkEvent::SessionClosed { peer_id });
|
this.event_listeners.send(NetworkEvent::SessionClosed { peer_id });
|
||||||
}
|
}
|
||||||
SwarmEvent::IncomingPendingSessionClosed { .. } => {}
|
SwarmEvent::IncomingPendingSessionClosed { remote_addr, error } => {
|
||||||
SwarmEvent::OutgoingPendingSessionClosed { peer_id, .. } => {
|
warn!(
|
||||||
|
target : "net",
|
||||||
|
?remote_addr,
|
||||||
|
?error,
|
||||||
|
"Incoming pending session failed"
|
||||||
|
);
|
||||||
|
this.swarm.state_mut().peers_mut().on_closed_incoming_pending_session()
|
||||||
|
}
|
||||||
|
SwarmEvent::OutgoingPendingSessionClosed { remote_addr, peer_id, error } => {
|
||||||
|
warn!(
|
||||||
|
target : "net",
|
||||||
|
?remote_addr,
|
||||||
|
?peer_id,
|
||||||
|
?error,
|
||||||
|
"Outgoing pending session failed"
|
||||||
|
);
|
||||||
this.swarm
|
this.swarm
|
||||||
.state_mut()
|
.state_mut()
|
||||||
.peers_mut()
|
.peers_mut()
|
||||||
.apply_reputation_change(&peer_id, ReputationChangeKind::FailedToConnect);
|
.apply_reputation_change(&peer_id, ReputationChangeKind::FailedToConnect);
|
||||||
}
|
}
|
||||||
SwarmEvent::OutgoingConnectionError { peer_id, .. } => {
|
SwarmEvent::OutgoingConnectionError { remote_addr, peer_id, error } => {
|
||||||
|
warn!(
|
||||||
|
target : "net",
|
||||||
|
?remote_addr,
|
||||||
|
?peer_id,
|
||||||
|
?error,
|
||||||
|
"Outgoing connection error"
|
||||||
|
);
|
||||||
this.swarm
|
this.swarm
|
||||||
.state_mut()
|
.state_mut()
|
||||||
.peers_mut()
|
.peers_mut()
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use reth_eth_wire::{
|
use reth_eth_wire::{
|
||||||
capability::CapabilityMessage, message::RequestPair, BlockBodies, BlockBody, BlockHeaders,
|
capability::RawCapabilityMessage, message::RequestPair, BlockBodies, BlockBody, BlockHeaders,
|
||||||
EthMessage, GetBlockBodies, GetBlockHeaders, GetNodeData, GetPooledTransactions, GetReceipts,
|
EthMessage, GetBlockBodies, GetBlockHeaders, GetNodeData, GetPooledTransactions, GetReceipts,
|
||||||
NewBlock, NewBlockHashes, NewPooledTransactionHashes, NodeData, PooledTransactions, Receipts,
|
NewBlock, NewBlockHashes, NewPooledTransactionHashes, NodeData, PooledTransactions, Receipts,
|
||||||
SharedTransactions, Transactions,
|
SharedTransactions, Transactions,
|
||||||
@ -53,7 +53,8 @@ pub enum PeerMessage {
|
|||||||
/// All `eth` request variants.
|
/// All `eth` request variants.
|
||||||
EthRequest(PeerRequest),
|
EthRequest(PeerRequest),
|
||||||
/// Other than eth namespace message
|
/// Other than eth namespace message
|
||||||
Other(CapabilityMessage),
|
#[allow(unused)]
|
||||||
|
Other(RawCapabilityMessage),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request Variants that only target block related data.
|
/// Request Variants that only target block related data.
|
||||||
@ -65,32 +66,6 @@ pub enum BlockRequest {
|
|||||||
GetBlockBodies(GetBlockBodies),
|
GetBlockBodies(GetBlockBodies),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// All Request variants of an [`EthMessage`]
|
|
||||||
///
|
|
||||||
/// Note: These variants come without a request ID, as it's expected that the peer session will
|
|
||||||
/// manage those
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
#[allow(missing_docs)]
|
|
||||||
#[allow(clippy::enum_variant_names)]
|
|
||||||
pub enum EthRequest {
|
|
||||||
GetBlockHeaders(GetBlockHeaders),
|
|
||||||
GetBlockBodies(GetBlockBodies),
|
|
||||||
GetPooledTransactions(GetPooledTransactions),
|
|
||||||
GetNodeData(GetNodeData),
|
|
||||||
GetReceipts(GetReceipts),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Corresponding Response variants for [`EthRequest`]
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
#[allow(missing_docs)]
|
|
||||||
pub enum EthResponse {
|
|
||||||
BlockHeaders(BlockHeaders),
|
|
||||||
BlockBodies(BlockBodies),
|
|
||||||
PooledTransactions(PooledTransactions),
|
|
||||||
NodeData(NodeData),
|
|
||||||
Receipts(Receipts),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Protocol related request messages that expect a response
|
/// Protocol related request messages that expect a response
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[allow(clippy::enum_variant_names)]
|
#[allow(clippy::enum_variant_names)]
|
||||||
@ -265,6 +240,7 @@ impl PeerResponseResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether this result is an error.
|
/// Returns whether this result is an error.
|
||||||
|
#[allow(unused)]
|
||||||
pub fn is_err(&self) -> bool {
|
pub fn is_err(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
PeerResponseResult::BlockHeaders(res) => res.is_err(),
|
PeerResponseResult::BlockHeaders(res) => res.is_err(),
|
||||||
@ -292,4 +268,9 @@ impl PeerRequestSender {
|
|||||||
pub fn try_send(&self, req: PeerRequest) -> Result<(), TrySendError<PeerRequest>> {
|
pub fn try_send(&self, req: PeerRequest) -> Result<(), TrySendError<PeerRequest>> {
|
||||||
self.to_session_tx.try_send(req)
|
self.to_session_tx.try_send(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the peer id of the remote peer.
|
||||||
|
pub fn peer_id(&self) -> &PeerId {
|
||||||
|
&self.peer_id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::{
|
|||||||
manager::NetworkEvent,
|
manager::NetworkEvent,
|
||||||
message::PeerRequest,
|
message::PeerRequest,
|
||||||
peers::{PeersHandle, ReputationChangeKind},
|
peers::{PeersHandle, ReputationChangeKind},
|
||||||
|
FetchClient,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use reth_eth_wire::{NewBlock, NewPooledTransactionHashes, SharedTransactions};
|
use reth_eth_wire::{NewBlock, NewPooledTransactionHashes, SharedTransactions};
|
||||||
@ -14,7 +15,7 @@ use std::{
|
|||||||
Arc,
|
Arc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use tokio::sync::{mpsc, mpsc::UnboundedSender};
|
use tokio::sync::{mpsc, mpsc::UnboundedSender, oneshot};
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
|
|
||||||
/// A _shareable_ network frontend. Used to interact with the network.
|
/// A _shareable_ network frontend. Used to interact with the network.
|
||||||
@ -64,6 +65,13 @@ impl NetworkHandle {
|
|||||||
&self.inner.local_peer_id
|
&self.inner.local_peer_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the [`PeersHandle`] that can be cloned and shared.
|
||||||
|
///
|
||||||
|
/// The [`PeersHandle`] can be used to interact with the network's peer set.
|
||||||
|
pub fn peers_handle(&self) -> &PeersHandle {
|
||||||
|
&self.inner.peers
|
||||||
|
}
|
||||||
|
|
||||||
fn manager(&self) -> &UnboundedSender<NetworkHandleMessage> {
|
fn manager(&self) -> &UnboundedSender<NetworkHandleMessage> {
|
||||||
&self.inner.to_manager_tx
|
&self.inner.to_manager_tx
|
||||||
}
|
}
|
||||||
@ -75,6 +83,15 @@ impl NetworkHandle {
|
|||||||
UnboundedReceiverStream::new(rx)
|
UnboundedReceiverStream::new(rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a new [`FetchClient`] that can be cloned and shared.
|
||||||
|
///
|
||||||
|
/// The [`FetchClient`] is the entrypoint for sending requests to the network.
|
||||||
|
pub async fn fetch_client(&self) -> Result<FetchClient, oneshot::error::RecvError> {
|
||||||
|
let (tx, rx) = oneshot::channel();
|
||||||
|
let _ = self.manager().send(NetworkHandleMessage::FetchClient(tx));
|
||||||
|
rx.await
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the mode of the network, either pow, or pos
|
/// Returns the mode of the network, either pow, or pos
|
||||||
pub fn mode(&self) -> &NetworkMode {
|
pub fn mode(&self) -> &NetworkMode {
|
||||||
&self.inner.network_mode
|
&self.inner.network_mode
|
||||||
@ -85,6 +102,13 @@ impl NetworkHandle {
|
|||||||
let _ = self.inner.to_manager_tx.send(msg);
|
let _ = self.inner.to_manager_tx.send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Announce a block over devp2p
|
||||||
|
///
|
||||||
|
/// Caution: in PoS this is a noop, since new block propagation will happen over devp2p
|
||||||
|
pub fn announce_block(&self, block: NewBlock, hash: H256) {
|
||||||
|
self.send_message(NetworkHandleMessage::AnnounceBlock(block, hash))
|
||||||
|
}
|
||||||
|
|
||||||
/// Sends a message to the [`NetworkManager`] to add a peer to the known set
|
/// Sends a message to the [`NetworkManager`] to add a peer to the known set
|
||||||
pub fn add_peer(&self, peer: PeerId, addr: SocketAddr) {
|
pub fn add_peer(&self, peer: PeerId, addr: SocketAddr) {
|
||||||
let _ = self.inner.to_manager_tx.send(NetworkHandleMessage::AddPeerAddress(peer, addr));
|
let _ = self.inner.to_manager_tx.send(NetworkHandleMessage::AddPeerAddress(peer, addr));
|
||||||
@ -154,4 +178,6 @@ pub(crate) enum NetworkHandleMessage {
|
|||||||
},
|
},
|
||||||
/// Apply a reputation change to the given peer.
|
/// Apply a reputation change to the given peer.
|
||||||
ReputationChange(PeerId, ReputationChangeKind),
|
ReputationChange(PeerId, ReputationChangeKind),
|
||||||
|
/// Returns the client that can be used to interact with the network.
|
||||||
|
FetchClient(oneshot::Sender<FetchClient>),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,13 +90,32 @@ impl PeersManager {
|
|||||||
PeersHandle { manager_tx: self.manager_tx.clone() }
|
PeersHandle { manager_tx: self.manager_tx.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Invoked when a new _incoming_ tcp connection is accepted.
|
||||||
|
///
|
||||||
|
/// Returns an Err with the configured limit with the number of accepted incoming connections
|
||||||
|
/// exceeded the configured limit.
|
||||||
|
pub(crate) fn on_inbound_pending_session(&mut self) -> Result<(), usize> {
|
||||||
|
if !self.connection_info.has_in_capacity() {
|
||||||
|
return Err(self.connection_info.max_inbound)
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep track of new connection
|
||||||
|
self.connection_info.inc_in();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when a pending session was closed.
|
||||||
|
pub(crate) fn on_closed_incoming_pending_session(&mut self) {
|
||||||
|
self.connection_info.decr_in()
|
||||||
|
}
|
||||||
|
|
||||||
/// Called when a new _incoming_ active session was established to the given peer.
|
/// Called when a new _incoming_ active session was established to the given peer.
|
||||||
///
|
///
|
||||||
/// This will update the state of the peer if not yet tracked.
|
/// This will update the state of the peer if not yet tracked.
|
||||||
///
|
///
|
||||||
/// If the reputation of the peer is below the `BANNED_REPUTATION` threshold, a disconnect will
|
/// If the reputation of the peer is below the `BANNED_REPUTATION` threshold, a disconnect will
|
||||||
/// be scheduled.
|
/// be scheduled.
|
||||||
pub(crate) fn on_active_session(&mut self, peer_id: PeerId, addr: SocketAddr) {
|
pub(crate) fn on_active_inbound_session(&mut self, peer_id: PeerId, addr: SocketAddr) {
|
||||||
match self.peers.entry(peer_id) {
|
match self.peers.entry(peer_id) {
|
||||||
Entry::Occupied(mut entry) => {
|
Entry::Occupied(mut entry) => {
|
||||||
let value = entry.get_mut();
|
let value = entry.get_mut();
|
||||||
@ -110,9 +129,6 @@ impl PeersManager {
|
|||||||
entry.insert(Peer::with_state(addr, PeerConnectionState::In));
|
entry.insert(Peer::with_state(addr, PeerConnectionState::In));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep track of new connection
|
|
||||||
self.connection_info.inc_in();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the corresponding reputation change to the given peer
|
/// Apply the corresponding reputation change to the given peer
|
||||||
@ -282,6 +298,11 @@ impl ConnectionInfo {
|
|||||||
self.num_outbound < self.max_outbound
|
self.num_outbound < self.max_outbound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if there's still capacity for a new incoming connection.
|
||||||
|
fn has_in_capacity(&self) -> bool {
|
||||||
|
self.num_inbound < self.max_inbound
|
||||||
|
}
|
||||||
|
|
||||||
fn decr_state(&mut self, state: PeerConnectionState) {
|
fn decr_state(&mut self, state: PeerConnectionState) {
|
||||||
match state {
|
match state {
|
||||||
PeerConnectionState::Idle => {}
|
PeerConnectionState::Idle => {}
|
||||||
|
|||||||
@ -106,16 +106,6 @@ pub(crate) struct ReputationChange(Reputation);
|
|||||||
// === impl ReputationChange ===
|
// === impl ReputationChange ===
|
||||||
|
|
||||||
impl ReputationChange {
|
impl ReputationChange {
|
||||||
/// Apply no reputation change.
|
|
||||||
pub(crate) const fn none() -> Self {
|
|
||||||
Self(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reputation change for a peer that dropped the connection.
|
|
||||||
pub(crate) const fn dropped() -> Self {
|
|
||||||
Self(REMOTE_DISCONNECT_REPUTATION_CHANGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper type for easier conversion
|
/// Helper type for easier conversion
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn as_i32(self) -> Reputation {
|
pub(crate) fn as_i32(self) -> Reputation {
|
||||||
|
|||||||
@ -42,6 +42,7 @@ use tracing::{error, warn};
|
|||||||
/// - incoming commands from the [`SessionsManager`]
|
/// - incoming commands from the [`SessionsManager`]
|
||||||
/// - incoming requests via the request channel
|
/// - incoming requests via the request channel
|
||||||
/// - responses for handled ETH requests received from the remote peer.
|
/// - responses for handled ETH requests received from the remote peer.
|
||||||
|
#[allow(unused)]
|
||||||
pub(crate) struct ActiveSession {
|
pub(crate) struct ActiveSession {
|
||||||
/// Keeps track of request ids.
|
/// Keeps track of request ids.
|
||||||
pub(crate) next_id: u64,
|
pub(crate) next_id: u64,
|
||||||
@ -216,7 +217,9 @@ impl ActiveSession {
|
|||||||
PeerMessage::ReceivedTransaction(_) => {
|
PeerMessage::ReceivedTransaction(_) => {
|
||||||
unreachable!("Not emitted by network")
|
unreachable!("Not emitted by network")
|
||||||
}
|
}
|
||||||
PeerMessage::Other(_) => {}
|
PeerMessage::Other(other) => {
|
||||||
|
error!(target : "net::session", message_id=%other.id, "Ignoring unsupported message");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,6 +435,7 @@ pub(crate) struct ReceivedRequest {
|
|||||||
/// Receiver half of the channel that's supposed to receive the proper response.
|
/// Receiver half of the channel that's supposed to receive the proper response.
|
||||||
rx: PeerResponse,
|
rx: PeerResponse,
|
||||||
/// Timestamp when we read this msg from the wire.
|
/// Timestamp when we read this msg from the wire.
|
||||||
|
#[allow(unused)]
|
||||||
received: Instant,
|
received: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,6 +467,7 @@ impl From<EthBroadcastMessage> for OutgoingMessage {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
#![allow(dead_code)]
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::session::{
|
use crate::session::{
|
||||||
config::REQUEST_TIMEOUT, handle::PendingSessionEvent, start_pending_incoming_session,
|
config::REQUEST_TIMEOUT, handle::PendingSessionEvent, start_pending_incoming_session,
|
||||||
|
|||||||
@ -155,6 +155,7 @@ impl SessionCounter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
pub(crate) fn ensure_pending_outbound(&self) -> Result<(), ExceedsSessionLimit> {
|
pub(crate) fn ensure_pending_outbound(&self) -> Result<(), ExceedsSessionLimit> {
|
||||||
Self::ensure(self.pending_outbound, self.limits.max_pending_outbound)
|
Self::ensure(self.pending_outbound, self.limits.max_pending_outbound)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ use tokio::{
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct PendingSessionHandle {
|
pub(crate) struct PendingSessionHandle {
|
||||||
/// Can be used to tell the session to disconnect the connection/abort the handshake process.
|
/// Can be used to tell the session to disconnect the connection/abort the handshake process.
|
||||||
pub(crate) disconnect_tx: oneshot::Sender<()>,
|
pub(crate) _disconnect_tx: oneshot::Sender<()>,
|
||||||
/// The direction of the session
|
/// The direction of the session
|
||||||
pub(crate) direction: Direction,
|
pub(crate) direction: Direction,
|
||||||
}
|
}
|
||||||
@ -33,6 +33,7 @@ pub(crate) struct PendingSessionHandle {
|
|||||||
/// Within an active session that supports the `Ethereum Wire Protocol `, three high-level tasks can
|
/// Within an active session that supports the `Ethereum Wire Protocol `, three high-level tasks can
|
||||||
/// be performed: chain synchronization, block propagation and transaction exchange.
|
/// be performed: chain synchronization, block propagation and transaction exchange.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(unused)]
|
||||||
pub(crate) struct ActiveSessionHandle {
|
pub(crate) struct ActiveSessionHandle {
|
||||||
/// The direction of the session
|
/// The direction of the session
|
||||||
pub(crate) direction: Direction,
|
pub(crate) direction: Direction,
|
||||||
@ -65,8 +66,6 @@ impl ActiveSessionHandle {
|
|||||||
/// A session starts with a `Handshake`, followed by a `Hello` message which
|
/// A session starts with a `Handshake`, followed by a `Hello` message which
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum PendingSessionEvent {
|
pub(crate) enum PendingSessionEvent {
|
||||||
/// Initial handshake step was successful <https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/rlpx.md#initial-handshake>
|
|
||||||
SuccessfulHandshake { remote_addr: SocketAddr, session_id: SessionId },
|
|
||||||
/// Represents a successful `Hello` and `Status` exchange: <https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/rlpx.md#hello-0x00>
|
/// Represents a successful `Hello` and `Status` exchange: <https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/rlpx.md#hello-0x00>
|
||||||
Established {
|
Established {
|
||||||
session_id: SessionId,
|
session_id: SessionId,
|
||||||
@ -134,6 +133,7 @@ pub(crate) enum ActiveSessionMessage {
|
|||||||
message: PeerMessage,
|
message: PeerMessage,
|
||||||
},
|
},
|
||||||
/// Received a message that does not match the announced capabilities of the peer.
|
/// Received a message that does not match the announced capabilities of the peer.
|
||||||
|
#[allow(unused)]
|
||||||
InvalidMessage {
|
InvalidMessage {
|
||||||
/// Identifier of the remote peer.
|
/// Identifier of the remote peer.
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
|
|||||||
@ -43,6 +43,7 @@ mod config;
|
|||||||
mod handle;
|
mod handle;
|
||||||
use crate::session::config::SessionCounter;
|
use crate::session::config::SessionCounter;
|
||||||
pub use config::SessionsConfig;
|
pub use config::SessionsConfig;
|
||||||
|
use reth_ecies::util::pk2id;
|
||||||
|
|
||||||
/// Internal identifier for active sessions.
|
/// Internal identifier for active sessions.
|
||||||
#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Eq, Hash)]
|
||||||
@ -59,8 +60,6 @@ pub(crate) struct SessionManager {
|
|||||||
request_timeout: Duration,
|
request_timeout: Duration,
|
||||||
/// The secret key used for authenticating sessions.
|
/// The secret key used for authenticating sessions.
|
||||||
secret_key: SecretKey,
|
secret_key: SecretKey,
|
||||||
/// The node id of node
|
|
||||||
peer_id: PeerId,
|
|
||||||
/// The `Status` message to send to peers.
|
/// The `Status` message to send to peers.
|
||||||
status: Status,
|
status: Status,
|
||||||
/// THe `Hello` message to send to peers.
|
/// THe `Hello` message to send to peers.
|
||||||
@ -105,7 +104,7 @@ impl SessionManager {
|
|||||||
let (active_session_tx, active_session_rx) = mpsc::channel(config.session_event_buffer);
|
let (active_session_tx, active_session_rx) = mpsc::channel(config.session_event_buffer);
|
||||||
|
|
||||||
let pk = secret_key.public_key(SECP256K1);
|
let pk = secret_key.public_key(SECP256K1);
|
||||||
let peer_id = PeerId::from_slice(&pk.serialize_uncompressed()[1..]);
|
let peer_id = pk2id(&pk);
|
||||||
|
|
||||||
// TODO: make sure this is the right place to put these builders - maybe per-Network rather
|
// TODO: make sure this is the right place to put these builders - maybe per-Network rather
|
||||||
// than per-Session?
|
// than per-Session?
|
||||||
@ -118,7 +117,6 @@ impl SessionManager {
|
|||||||
counter: SessionCounter::new(config.limits),
|
counter: SessionCounter::new(config.limits),
|
||||||
request_timeout: config.request_timeout,
|
request_timeout: config.request_timeout,
|
||||||
secret_key,
|
secret_key,
|
||||||
peer_id,
|
|
||||||
status,
|
status,
|
||||||
hello,
|
hello,
|
||||||
fork_filter,
|
fork_filter,
|
||||||
@ -181,7 +179,8 @@ impl SessionManager {
|
|||||||
self.fork_filter.clone(),
|
self.fork_filter.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let handle = PendingSessionHandle { disconnect_tx, direction: Direction::Incoming };
|
let handle =
|
||||||
|
PendingSessionHandle { _disconnect_tx: disconnect_tx, direction: Direction::Incoming };
|
||||||
self.pending_sessions.insert(session_id, handle);
|
self.pending_sessions.insert(session_id, handle);
|
||||||
self.counter.inc_pending_inbound();
|
self.counter.inc_pending_inbound();
|
||||||
Ok(session_id)
|
Ok(session_id)
|
||||||
@ -204,8 +203,10 @@ impl SessionManager {
|
|||||||
self.fork_filter.clone(),
|
self.fork_filter.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let handle =
|
let handle = PendingSessionHandle {
|
||||||
PendingSessionHandle { disconnect_tx, direction: Direction::Outgoing(remote_peer_id) };
|
_disconnect_tx: disconnect_tx,
|
||||||
|
direction: Direction::Outgoing(remote_peer_id),
|
||||||
|
};
|
||||||
self.pending_sessions.insert(session_id, handle);
|
self.pending_sessions.insert(session_id, handle);
|
||||||
self.counter.inc_pending_outbound();
|
self.counter.inc_pending_outbound();
|
||||||
}
|
}
|
||||||
@ -289,21 +290,12 @@ impl SessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Poll the pending session event stream
|
// Poll the pending session event stream
|
||||||
loop {
|
|
||||||
let event = match self.pending_session_rx.poll_next_unpin(cx) {
|
let event = match self.pending_session_rx.poll_next_unpin(cx) {
|
||||||
Poll::Pending => break,
|
Poll::Pending => return Poll::Pending,
|
||||||
Poll::Ready(None) => unreachable!("Manager holds both channel halves."),
|
Poll::Ready(None) => unreachable!("Manager holds both channel halves."),
|
||||||
Poll::Ready(Some(event)) => event,
|
Poll::Ready(Some(event)) => event,
|
||||||
};
|
};
|
||||||
match event {
|
return match event {
|
||||||
PendingSessionEvent::SuccessfulHandshake { remote_addr, session_id } => {
|
|
||||||
trace!(
|
|
||||||
target : "net::session",
|
|
||||||
?session_id,
|
|
||||||
?remote_addr,
|
|
||||||
"successful handshake"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
PendingSessionEvent::Established {
|
PendingSessionEvent::Established {
|
||||||
session_id,
|
session_id,
|
||||||
remote_addr,
|
remote_addr,
|
||||||
@ -316,8 +308,7 @@ impl SessionManager {
|
|||||||
// move from pending to established.
|
// move from pending to established.
|
||||||
self.remove_pending_session(&session_id);
|
self.remove_pending_session(&session_id);
|
||||||
|
|
||||||
let (commands_to_session, commands_rx) =
|
let (commands_to_session, commands_rx) = mpsc::channel(self.session_command_buffer);
|
||||||
mpsc::channel(self.session_command_buffer);
|
|
||||||
|
|
||||||
let (to_session_tx, messages_rx) = mpsc::channel(self.session_command_buffer);
|
let (to_session_tx, messages_rx) = mpsc::channel(self.session_command_buffer);
|
||||||
|
|
||||||
@ -354,7 +345,7 @@ impl SessionManager {
|
|||||||
self.active_sessions.insert(peer_id, handle);
|
self.active_sessions.insert(peer_id, handle);
|
||||||
self.counter.inc_active(&direction);
|
self.counter.inc_active(&direction);
|
||||||
|
|
||||||
return Poll::Ready(SessionEvent::SessionEstablished {
|
Poll::Ready(SessionEvent::SessionEstablished {
|
||||||
peer_id,
|
peer_id,
|
||||||
remote_addr,
|
remote_addr,
|
||||||
capabilities,
|
capabilities,
|
||||||
@ -371,7 +362,7 @@ impl SessionManager {
|
|||||||
"disconnected pending session"
|
"disconnected pending session"
|
||||||
);
|
);
|
||||||
self.remove_pending_session(&session_id);
|
self.remove_pending_session(&session_id);
|
||||||
return match direction {
|
match direction {
|
||||||
Direction::Incoming => {
|
Direction::Incoming => {
|
||||||
Poll::Ready(SessionEvent::IncomingPendingSessionClosed {
|
Poll::Ready(SessionEvent::IncomingPendingSessionClosed {
|
||||||
remote_addr,
|
remote_addr,
|
||||||
@ -402,18 +393,9 @@ impl SessionManager {
|
|||||||
"connection refused"
|
"connection refused"
|
||||||
);
|
);
|
||||||
self.remove_pending_session(&session_id);
|
self.remove_pending_session(&session_id);
|
||||||
return Poll::Ready(SessionEvent::OutgoingPendingSessionClosed {
|
Poll::Ready(SessionEvent::OutgoingConnectionError { remote_addr, peer_id, error })
|
||||||
remote_addr,
|
|
||||||
peer_id,
|
|
||||||
error: None,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
PendingSessionEvent::EciesAuthError {
|
PendingSessionEvent::EciesAuthError { remote_addr, session_id, error, direction } => {
|
||||||
remote_addr,
|
|
||||||
session_id,
|
|
||||||
error,
|
|
||||||
direction,
|
|
||||||
} => {
|
|
||||||
self.remove_pending_session(&session_id);
|
self.remove_pending_session(&session_id);
|
||||||
warn!(
|
warn!(
|
||||||
target : "net::session",
|
target : "net::session",
|
||||||
@ -423,7 +405,7 @@ impl SessionManager {
|
|||||||
"ecies auth failed"
|
"ecies auth failed"
|
||||||
);
|
);
|
||||||
self.remove_pending_session(&session_id);
|
self.remove_pending_session(&session_id);
|
||||||
return match direction {
|
match direction {
|
||||||
Direction::Incoming => {
|
Direction::Incoming => {
|
||||||
Poll::Ready(SessionEvent::IncomingPendingSessionClosed {
|
Poll::Ready(SessionEvent::IncomingPendingSessionClosed {
|
||||||
remote_addr,
|
remote_addr,
|
||||||
@ -441,9 +423,6 @@ impl SessionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Events produced by the [`SessionManager`]
|
/// Events produced by the [`SessionManager`]
|
||||||
@ -501,6 +480,22 @@ pub(crate) enum SessionEvent {
|
|||||||
Disconnected { peer_id: PeerId, remote_addr: SocketAddr },
|
Disconnected { peer_id: PeerId, remote_addr: SocketAddr },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The direction of the connection.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub(crate) enum Direction {
|
||||||
|
/// Incoming connection.
|
||||||
|
Incoming,
|
||||||
|
/// Outgoing connection to a specific node.
|
||||||
|
Outgoing(PeerId),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Direction {
|
||||||
|
/// Returns `true` if this an incoming connection.
|
||||||
|
pub(crate) fn is_incoming(&self) -> bool {
|
||||||
|
matches!(self, Direction::Incoming)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The error thrown when the max configured limit has been reached and no more connections are
|
/// The error thrown when the max configured limit has been reached and no more connections are
|
||||||
/// accepted.
|
/// accepted.
|
||||||
#[derive(Debug, Clone, thiserror::Error)]
|
#[derive(Debug, Clone, thiserror::Error)]
|
||||||
@ -510,6 +505,7 @@ pub struct ExceedsSessionLimit(pub(crate) u32);
|
|||||||
/// Starts the authentication process for a connection initiated by a remote peer.
|
/// Starts the authentication process for a connection initiated by a remote peer.
|
||||||
///
|
///
|
||||||
/// This will wait for the _incoming_ handshake request and answer it.
|
/// This will wait for the _incoming_ handshake request and answer it.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) async fn start_pending_incoming_session(
|
pub(crate) async fn start_pending_incoming_session(
|
||||||
disconnect_rx: oneshot::Receiver<()>,
|
disconnect_rx: oneshot::Receiver<()>,
|
||||||
session_id: SessionId,
|
session_id: SessionId,
|
||||||
@ -538,6 +534,7 @@ pub(crate) async fn start_pending_incoming_session(
|
|||||||
|
|
||||||
/// Starts the authentication process for a connection initiated by a remote peer.
|
/// Starts the authentication process for a connection initiated by a remote peer.
|
||||||
#[instrument(skip_all, fields(%remote_addr, peer_id), target = "net")]
|
#[instrument(skip_all, fields(%remote_addr, peer_id), target = "net")]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn start_pending_outbound_session(
|
async fn start_pending_outbound_session(
|
||||||
disconnect_rx: oneshot::Receiver<()>,
|
disconnect_rx: oneshot::Receiver<()>,
|
||||||
events: mpsc::Sender<PendingSessionEvent>,
|
events: mpsc::Sender<PendingSessionEvent>,
|
||||||
@ -578,23 +575,8 @@ async fn start_pending_outbound_session(
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The direction of the connection.
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub(crate) enum Direction {
|
|
||||||
/// Incoming connection.
|
|
||||||
Incoming,
|
|
||||||
/// Outgoing connection to a specific node.
|
|
||||||
Outgoing(PeerId),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Direction {
|
|
||||||
/// Returns `true` if this an incoming connection.
|
|
||||||
pub(crate) fn is_incoming(&self) -> bool {
|
|
||||||
matches!(self, Direction::Incoming)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Authenticates a session
|
/// Authenticates a session
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn authenticate(
|
async fn authenticate(
|
||||||
disconnect_rx: oneshot::Receiver<()>,
|
disconnect_rx: oneshot::Receiver<()>,
|
||||||
events: mpsc::Sender<PendingSessionEvent>,
|
events: mpsc::Sender<PendingSessionEvent>,
|
||||||
@ -672,6 +654,7 @@ async fn authenticate(
|
|||||||
/// Authenticate the stream via handshake
|
/// Authenticate the stream via handshake
|
||||||
///
|
///
|
||||||
/// On Success return the authenticated stream as [`PendingSessionEvent`]
|
/// On Success return the authenticated stream as [`PendingSessionEvent`]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn authenticate_stream(
|
async fn authenticate_stream(
|
||||||
stream: UnauthedP2PStream<ECIESStream<TcpStream>>,
|
stream: UnauthedP2PStream<ECIESStream<TcpStream>>,
|
||||||
session_id: SessionId,
|
session_id: SessionId,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use crate::{
|
|||||||
PeerResponseResult,
|
PeerResponseResult,
|
||||||
},
|
},
|
||||||
peers::{PeerAction, PeersManager},
|
peers::{PeerAction, PeersManager},
|
||||||
|
FetchClient,
|
||||||
};
|
};
|
||||||
use reth_eth_wire::{
|
use reth_eth_wire::{
|
||||||
capability::Capabilities, BlockHashNumber, DisconnectReason, NewBlockHashes, Status,
|
capability::Capabilities, BlockHashNumber, DisconnectReason, NewBlockHashes, Status,
|
||||||
@ -85,6 +86,21 @@ where
|
|||||||
&mut self.peers_manager
|
&mut self.peers_manager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns access to the [`PeersManager`]
|
||||||
|
pub(crate) fn peers(&self) -> &PeersManager {
|
||||||
|
&self.peers_manager
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [`FetchClient`]
|
||||||
|
pub(crate) fn fetch_client(&self) -> FetchClient {
|
||||||
|
self.state_fetcher.client()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// How many peers we're currently connected to.
|
||||||
|
pub fn genesis_hash(&self) -> H256 {
|
||||||
|
self.genesis_hash
|
||||||
|
}
|
||||||
|
|
||||||
/// How many peers we're currently connected to.
|
/// How many peers we're currently connected to.
|
||||||
pub fn num_connected_peers(&self) -> usize {
|
pub fn num_connected_peers(&self) -> usize {
|
||||||
self.connected_peers.len()
|
self.connected_peers.len()
|
||||||
@ -381,10 +397,11 @@ where
|
|||||||
/// Tracks the state of a Peer.
|
/// Tracks the state of a Peer.
|
||||||
///
|
///
|
||||||
/// For example known blocks,so we can decide what to announce.
|
/// For example known blocks,so we can decide what to announce.
|
||||||
pub struct ConnectedPeer {
|
pub(crate) struct ConnectedPeer {
|
||||||
/// Best block of the peer.
|
/// Best block of the peer.
|
||||||
pub(crate) best_hash: H256,
|
pub(crate) best_hash: H256,
|
||||||
/// The capabilities of the connected peer.
|
/// The capabilities of the connected peer.
|
||||||
|
#[allow(unused)]
|
||||||
pub(crate) capabilities: Arc<Capabilities>,
|
pub(crate) capabilities: Arc<Capabilities>,
|
||||||
/// A communication channel directly to the session task.
|
/// A communication channel directly to the session task.
|
||||||
pub(crate) request_tx: PeerRequestSender,
|
pub(crate) request_tx: PeerRequestSender,
|
||||||
|
|||||||
@ -19,7 +19,7 @@ use std::{
|
|||||||
sync::Arc,
|
sync::Arc,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
use tracing::warn;
|
use tracing::{trace, warn};
|
||||||
|
|
||||||
/// Contains the connectivity related state of the network.
|
/// Contains the connectivity related state of the network.
|
||||||
///
|
///
|
||||||
@ -99,6 +99,7 @@ where
|
|||||||
pub(crate) fn listener(&self) -> &ConnectionListener {
|
pub(crate) fn listener(&self) -> &ConnectionListener {
|
||||||
&self.incoming
|
&self.incoming
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable access to the [`SessionManager`].
|
/// Mutable access to the [`SessionManager`].
|
||||||
pub(crate) fn sessions_mut(&mut self) -> &mut SessionManager {
|
pub(crate) fn sessions_mut(&mut self) -> &mut SessionManager {
|
||||||
&mut self.sessions
|
&mut self.sessions
|
||||||
@ -171,12 +172,19 @@ where
|
|||||||
return Some(SwarmEvent::TcpListenerClosed { remote_addr: address })
|
return Some(SwarmEvent::TcpListenerClosed { remote_addr: address })
|
||||||
}
|
}
|
||||||
ListenerEvent::Incoming { stream, remote_addr } => {
|
ListenerEvent::Incoming { stream, remote_addr } => {
|
||||||
|
if let Err(limit) = self.state_mut().peers_mut().on_inbound_pending_session() {
|
||||||
|
// We currently don't have additional capacity to establish a session from an
|
||||||
|
// incoming connection, so we drop the connection.
|
||||||
|
trace!(target: "net", %limit, ?remote_addr, "Exceeded incoming connection limit; dropping connection");
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
match self.sessions.on_incoming(stream, remote_addr) {
|
match self.sessions.on_incoming(stream, remote_addr) {
|
||||||
Ok(session_id) => {
|
Ok(session_id) => {
|
||||||
return Some(SwarmEvent::IncomingTcpConnection { session_id, remote_addr })
|
return Some(SwarmEvent::IncomingTcpConnection { session_id, remote_addr })
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(?err, "Incoming connection rejected");
|
warn!(target: "net", ?err, "Incoming connection rejected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,7 +196,8 @@ where
|
|||||||
fn on_state_action(&mut self, event: StateAction) -> Option<SwarmEvent> {
|
fn on_state_action(&mut self, event: StateAction) -> Option<SwarmEvent> {
|
||||||
match event {
|
match event {
|
||||||
StateAction::Connect { remote_addr, peer_id } => {
|
StateAction::Connect { remote_addr, peer_id } => {
|
||||||
self.sessions.dial_outbound(remote_addr, peer_id);
|
self.dial_outbound(remote_addr, peer_id);
|
||||||
|
return Some(SwarmEvent::OutgoingTcpConnection { remote_addr, peer_id })
|
||||||
}
|
}
|
||||||
StateAction::Disconnect { peer_id, reason } => {
|
StateAction::Disconnect { peer_id, reason } => {
|
||||||
self.sessions.disconnect(peer_id, reason);
|
self.sessions.disconnect(peer_id, reason);
|
||||||
@ -301,6 +310,7 @@ pub(crate) enum SwarmEvent {
|
|||||||
/// An outbound connection is initiated.
|
/// An outbound connection is initiated.
|
||||||
OutgoingTcpConnection {
|
OutgoingTcpConnection {
|
||||||
/// Address of the remote peer.
|
/// Address of the remote peer.
|
||||||
|
peer_id: PeerId,
|
||||||
remote_addr: SocketAddr,
|
remote_addr: SocketAddr,
|
||||||
},
|
},
|
||||||
SessionEstablished {
|
SessionEstablished {
|
||||||
|
|||||||
@ -43,6 +43,19 @@ pub struct TransactionsHandle {
|
|||||||
manager_tx: mpsc::UnboundedSender<TransactionsCommand>,
|
manager_tx: mpsc::UnboundedSender<TransactionsCommand>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === impl TransactionsHandle ===
|
||||||
|
|
||||||
|
impl TransactionsHandle {
|
||||||
|
fn send(&self, cmd: TransactionsCommand) {
|
||||||
|
let _ = self.manager_tx.send(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Manually propagate the transaction that belongs to the hash.
|
||||||
|
pub fn propagate(&self, hash: TxHash) {
|
||||||
|
self.send(TransactionsCommand::PropagateHash(hash))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Manages transactions on top of the p2p network.
|
/// Manages transactions on top of the p2p network.
|
||||||
///
|
///
|
||||||
/// This can be spawned to another task and is supposed to be run as background service while
|
/// This can be spawned to another task and is supposed to be run as background service while
|
||||||
@ -248,6 +261,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handles a command received from a detached [`TransactionsHandle`]
|
||||||
|
fn on_command(&mut self, cmd: TransactionsCommand) {
|
||||||
|
match cmd {
|
||||||
|
TransactionsCommand::PropagateHash(hash) => {
|
||||||
|
self.on_new_transactions(std::iter::once(hash))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Handles a received event related to common network events.
|
/// Handles a received event related to common network events.
|
||||||
fn on_network_event(&mut self, event: NetworkEvent) {
|
fn on_network_event(&mut self, event: NetworkEvent) {
|
||||||
match event {
|
match event {
|
||||||
@ -355,6 +377,11 @@ where
|
|||||||
this.on_network_event(event);
|
this.on_network_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drain network/peer related events
|
||||||
|
while let Poll::Ready(Some(cmd)) = this.command_rx.poll_next_unpin(cx) {
|
||||||
|
this.on_command(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
// drain incoming transaction events
|
// drain incoming transaction events
|
||||||
while let Poll::Ready(Some(event)) = this.transaction_events.poll_next_unpin(cx) {
|
while let Poll::Ready(Some(event)) = this.transaction_events.poll_next_unpin(cx) {
|
||||||
this.on_network_tx_event(event);
|
this.on_network_tx_event(event);
|
||||||
@ -424,11 +451,12 @@ struct Peer {
|
|||||||
|
|
||||||
/// Commands to send to the [`TransactionManager`]
|
/// Commands to send to the [`TransactionManager`]
|
||||||
enum TransactionsCommand {
|
enum TransactionsCommand {
|
||||||
Propagate(H256),
|
PropagateHash(H256),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// All events related to transactions emitted by the network
|
/// All events related to transactions emitted by the network.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(missing_docs)]
|
||||||
pub enum NetworkTransactionEvent {
|
pub enum NetworkTransactionEvent {
|
||||||
/// Received list of transactions to the given peer.
|
/// Received list of transactions to the given peer.
|
||||||
IncomingTransactions { peer_id: PeerId, msg: Transactions },
|
IncomingTransactions { peer_id: PeerId, msg: Transactions },
|
||||||
|
|||||||
Reference in New Issue
Block a user