Skip to content

Commit 012ffc0

Browse files
authored
Merge pull request #73 from bnb-chain/develop
chore: prepare for release v0.0.7
2 parents 6316e5c + 88080cf commit 012ffc0

20 files changed

Lines changed: 428 additions & 182 deletions

File tree

crates/engine/tree/src/tree/metrics.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ pub(crate) struct EngineMetrics {
155155
pub(crate) block_insert_total_duration: Histogram,
156156
/// Block insert throughput in mgas/s
157157
pub(crate) block_insert_mgasps: Gauge,
158+
/// Block insertion delay: the difference between current timestamp and block header timestamp (in nanoseconds)
159+
pub(crate) block_insert_timestamp_delay: Histogram,
158160
}
159161

160162
/// Metrics for non-execution related block validation.

crates/engine/tree/src/tree/mod.rs

Lines changed: 121 additions & 99 deletions
Large diffs are not rendered by default.

crates/net/eth-wire-types/src/broadcast.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{EthMessage, EthVersion, NetworkPrimitives};
44
use alloc::{sync::Arc, vec::Vec};
55
use alloy_primitives::{
66
map::{HashMap, HashSet},
7-
Bytes, TxHash, B256, U128,
7+
Bytes, TxHash, B256, U128, U256,
88
};
99
use alloy_rlp::{
1010
Decodable, Encodable, RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper,
@@ -73,6 +73,9 @@ pub trait NewBlockPayload:
7373

7474
/// Returns a reference to the block.
7575
fn block(&self) -> &Self::Block;
76+
77+
/// Returns the total difficulty if available
78+
fn td(&self) -> Option<U256>;
7679
}
7780

7881
/// A new block with the current total difficulty, which includes the difficulty of the returned
@@ -93,6 +96,10 @@ impl<B: Block + 'static> NewBlockPayload for NewBlock<B> {
9396
fn block(&self) -> &Self::Block {
9497
&self.block
9598
}
99+
100+
fn td(&self) -> Option<U256> {
101+
Some(U256::from(self.td))
102+
}
96103
}
97104

98105
generate_tests!(#[rlp, 25] NewBlock<reth_ethereum_primitives::Block>, EthNewBlockTests);

crates/net/network-api/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub mod noop;
2323
pub mod test_utils;
2424
use test_utils::PeersHandleProvider;
2525

26+
use alloy_primitives::{B256, U256};
2627
pub use alloy_rpc_types_admin::EthProtocolInfo;
2728
pub use reth_network_p2p::{BlockClient, HeadersClient};
2829
pub use reth_network_types::{PeerKind, Reputation, ReputationChangeKind};
@@ -238,12 +239,18 @@ pub struct PeerInfo {
238239
pub direction: Direction,
239240
/// The negotiated eth version.
240241
pub eth_version: EthVersion,
241-
/// The Status message the peer sent for the `eth` handshake
242+
/// The Status message the peer sent for the `eth` handshake (snapshot at connection time)
242243
pub status: Arc<UnifiedStatus>,
243244
/// The timestamp when the session to that peer has been established.
244245
pub session_established: Instant,
245246
/// The peer's connection kind
246247
pub kind: PeerKind,
248+
/// Real-time tracked best block hash of the peer
249+
pub best_hash: B256,
250+
/// Real-time tracked best block number of the peer
251+
pub best_number: Option<u64>,
252+
/// Real-time tracked total difficulty of the peer (None in PoS)
253+
pub best_td: Option<U256>,
247254
}
248255

249256
/// The direction of the connection.

crates/net/network-types/src/peers/config.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88
};
99

1010
use reth_net_banlist::BanList;
11-
use reth_network_peers::{NodeRecord, TrustedPeer};
11+
use reth_network_peers::{NodeRecord, PeerId, TrustedPeer};
1212
use tracing::info;
1313

1414
use crate::{BackoffKind, ReputationChangeWeights};
@@ -166,6 +166,9 @@ pub struct PeersConfig {
166166
/// This acts as an IP based rate limit.
167167
#[cfg_attr(feature = "serde", serde(default, with = "humantime_serde"))]
168168
pub incoming_ip_throttle_duration: Duration,
169+
170+
/// The node ids of the proxyed nodes.
171+
pub proxyed_node_ids: Vec<PeerId>,
169172
}
170173

171174
impl Default for PeersConfig {
@@ -184,6 +187,7 @@ impl Default for PeersConfig {
184187
basic_nodes: Default::default(),
185188
max_backoff_count: 5,
186189
incoming_ip_throttle_duration: INBOUND_IP_THROTTLE_DURATION,
190+
proxyed_node_ids: Vec::new(),
187191
}
188192
}
189193
}

crates/net/network/src/config.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ pub struct NetworkConfigBuilder<N: NetworkPrimitives = EthNetworkPrimitives> {
220220
/// The Ethereum P2P handshake, see also:
221221
/// <https://github.com/ethereum/devp2p/blob/master/rlpx.md#initial-handshake>.
222222
handshake: Arc<dyn EthRlpxHandshake>,
223+
/// The node ids of the proxyed nodes.
224+
proxyed_node_ids: Vec<PeerId>,
223225
}
224226

225227
impl NetworkConfigBuilder<EthNetworkPrimitives> {
@@ -260,6 +262,7 @@ impl<N: NetworkPrimitives> NetworkConfigBuilder<N> {
260262
transactions_manager_config: Default::default(),
261263
nat: None,
262264
handshake: Arc::new(EthHandshake::default()),
265+
proxyed_node_ids: Vec::new(),
263266
}
264267
}
265268

@@ -467,6 +470,14 @@ impl<N: NetworkPrimitives> NetworkConfigBuilder<N> {
467470
self.boot_nodes.iter()
468471
}
469472

473+
/// Sets the proxied peer IDs.
474+
///
475+
/// These peer IDs will be treated specially in the network layer.
476+
pub fn proxied_peers(mut self, peer_ids: Vec<PeerId>) -> Self {
477+
self.proxyed_node_ids = peer_ids;
478+
self
479+
}
480+
470481
/// Disable the DNS discovery.
471482
pub fn disable_dns_discovery(mut self) -> Self {
472483
self.dns_discovery_config = None;
@@ -606,6 +617,7 @@ impl<N: NetworkPrimitives> NetworkConfigBuilder<N> {
606617
transactions_manager_config,
607618
nat,
608619
handshake,
620+
proxyed_node_ids,
609621
} = self;
610622

611623
let head = head.unwrap_or_else(|| Head {
@@ -651,6 +663,10 @@ impl<N: NetworkPrimitives> NetworkConfigBuilder<N> {
651663
}
652664
}
653665

666+
// Set proxyed_node_ids in peers_config
667+
let mut peers_config = peers_config.unwrap_or_default();
668+
peers_config.proxyed_node_ids = proxyed_node_ids;
669+
654670
NetworkConfig {
655671
client,
656672
secret_key,
@@ -660,7 +676,7 @@ impl<N: NetworkPrimitives> NetworkConfigBuilder<N> {
660676
discovery_v5_config: discovery_v5_builder.map(|builder| builder.build()),
661677
discovery_v4_addr: discovery_addr.unwrap_or(DEFAULT_DISCOVERY_ADDRESS),
662678
listener_addr,
663-
peers_config: peers_config.unwrap_or_default(),
679+
peers_config,
664680
sessions_config: sessions_config.unwrap_or_default(),
665681
chain_id,
666682
block_import: block_import.unwrap_or_else(|| Box::<ProofOfStakeBlockImport>::default()),

crates/net/network/src/fetch/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ impl<N: NetworkPrimitives> StateFetcher<N> {
126126
false
127127
}
128128

129+
/// Gets the peer's best block number
130+
pub(crate) fn get_peer_best_number(&self, peer_id: &PeerId) -> Option<u64> {
131+
self.peers.get(peer_id).map(|peer| peer.best_number)
132+
}
133+
129134
/// Invoked when an active session is about to be disconnected.
130135
pub(crate) fn on_pending_disconnect(&mut self, peer_id: &PeerId) {
131136
if let Some(peer) = self.peers.get_mut(peer_id) {

crates/net/network/src/manager.rs

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,17 @@ impl<N: NetworkPrimitives> NetworkManager<N> {
605605
}
606606
PeerMessage::NewBlock(block) => {
607607
self.within_pow_or_disconnect(peer_id, move |this| {
608-
this.swarm.state_mut().on_new_block(peer_id, block.hash);
608+
// Extract TD from the NewBlock message
609+
let td = block.td();
610+
611+
// Update the session's current TD (important for BSC and other chains)
612+
if let Some(session) = this.swarm.sessions().active_sessions().get(&peer_id) {
613+
session.update_td(td);
614+
}
615+
616+
// Update NetworkState's ActivePeer TD
617+
this.swarm.state_mut().on_new_block_with_td(peer_id, block.hash, td);
618+
609619
// start block import process
610620
this.block_import.on_new_block(peer_id, NewBlockEvent::Block(block));
611621
});
@@ -641,13 +651,15 @@ impl<N: NetworkPrimitives> NetworkManager<N> {
641651
NetworkHandleMessage::DiscoveryListener(tx) => {
642652
self.swarm.state_mut().discovery_mut().add_listener(tx);
643653
}
644-
NetworkHandleMessage::AnnounceBlock(block, hash) => {
654+
NetworkHandleMessage::AnnounceBlock(block, hash, total_difficulty) => {
645655
if self.handle.mode().is_stake() {
646656
// See [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#devp2p)
647657
warn!(target: "net", "Peer performed block propagation, but it is not supported in proof of stake (EIP-3675)");
648-
return
658+
return;
649659
}
650-
let msg = NewBlockMessage { hash, block: Arc::new(block) };
660+
// Include the total_difficulty when announcing our own block
661+
// This is essential for BSC and other chains that rely on TD
662+
let msg = NewBlockMessage { hash, block: Arc::new(block), td: total_difficulty };
651663
self.swarm.state_mut().announce_new_block(msg);
652664
}
653665
NetworkHandleMessage::EthRequest { peer_id, request } => {
@@ -989,11 +1001,20 @@ impl<N: NetworkPrimitives> NetworkManager<N> {
9891001
.active_sessions()
9901002
.iter()
9911003
.filter_map(|(&peer_id, session)| {
992-
self.swarm
993-
.state()
994-
.peers()
995-
.peer_by_id(peer_id)
996-
.map(|(record, kind)| session.peer_info(&record, kind))
1004+
let (record, kind) = self.swarm.state().peers().peer_by_id(peer_id)?;
1005+
1006+
// Get real-time block info from NetworkState
1007+
let (best_hash, best_number, best_td) =
1008+
self.swarm.state().get_peer_best_block(&peer_id).unwrap_or_else(|| {
1009+
// Fallback to status from handshake if no real-time data
1010+
(
1011+
session.status.blockhash,
1012+
session.status.latest_block,
1013+
session.status.total_difficulty,
1014+
)
1015+
});
1016+
1017+
Some(session.peer_info(&record, kind, best_hash, best_number, best_td))
9971018
})
9981019
.collect()
9991020
}
@@ -1002,13 +1023,21 @@ impl<N: NetworkPrimitives> NetworkManager<N> {
10021023
///
10031024
/// Returns `None` if there's no active session to the peer.
10041025
fn get_peer_info_by_id(&self, peer_id: PeerId) -> Option<PeerInfo> {
1005-
self.swarm.sessions().active_sessions().get(&peer_id).and_then(|session| {
1006-
self.swarm
1007-
.state()
1008-
.peers()
1009-
.peer_by_id(peer_id)
1010-
.map(|(record, kind)| session.peer_info(&record, kind))
1011-
})
1026+
let session = self.swarm.sessions().active_sessions().get(&peer_id)?;
1027+
let (record, kind) = self.swarm.state().peers().peer_by_id(peer_id)?;
1028+
1029+
// Get real-time block info from NetworkState
1030+
let (best_hash, best_number, best_td) =
1031+
self.swarm.state().get_peer_best_block(&peer_id).unwrap_or_else(|| {
1032+
// Fallback to status from handshake if no real-time data
1033+
(
1034+
session.status.blockhash,
1035+
session.status.latest_block,
1036+
session.status.total_difficulty,
1037+
)
1038+
});
1039+
1040+
Some(session.peer_info(&record, kind, best_hash, best_number, best_td))
10121041
}
10131042

10141043
/// Returns [`PeerInfo`] for a given peers.
@@ -1142,7 +1171,7 @@ impl<N: NetworkPrimitives> Future for NetworkManager<N> {
11421171
if maybe_more_handle_messages || maybe_more_swarm_events {
11431172
// make sure we're woken up again
11441173
cx.waker().wake_by_ref();
1145-
return Poll::Pending
1174+
return Poll::Pending;
11461175
}
11471176

11481177
this.update_poll_metrics(start, poll_durations);

crates/net/network/src/message.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pub struct NewBlockMessage<P = NewBlock<reth_ethereum_primitives::Block>> {
3030
pub hash: B256,
3131
/// Raw received message
3232
pub block: Arc<P>,
33+
/// Total difficulty (extracted from the NewBlock message for BSC and other chains)
34+
pub td: Option<alloy_primitives::U256>,
3335
}
3436

3537
// === impl NewBlockMessage ===
@@ -39,6 +41,11 @@ impl<P: NewBlockPayload> NewBlockMessage<P> {
3941
pub fn number(&self) -> u64 {
4042
self.block.block().header().number()
4143
}
44+
45+
/// Returns the total difficulty if available
46+
pub fn td(&self) -> Option<alloy_primitives::U256> {
47+
self.td
48+
}
4249
}
4350

4451
/// All Bi-directional eth-message variants that can be sent to a session or received from a

crates/net/network/src/network.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,15 @@ impl<N: NetworkPrimitives> NetworkHandle<N> {
116116
/// Caution: in `PoS` this is a noop because new blocks are no longer announced over devp2p.
117117
/// Instead they are sent to the node by CL and can be requested over devp2p.
118118
/// Broadcasting new blocks is considered a protocol violation.
119-
pub fn announce_block(&self, block: N::NewBlockPayload, hash: B256) {
120-
self.send_message(NetworkHandleMessage::AnnounceBlock(block, hash))
119+
///
120+
/// For BSC and other PoW-based chains, the total_difficulty parameter is essential.
121+
pub fn announce_block(
122+
&self,
123+
block: N::NewBlockPayload,
124+
hash: B256,
125+
total_difficulty: Option<alloy_primitives::U256>,
126+
) {
127+
self.send_message(NetworkHandleMessage::AnnounceBlock(block, hash, total_difficulty))
121128
}
122129

123130
/// Sends a [`PeerRequest`] to the given peer's session.
@@ -395,7 +402,7 @@ impl<N: NetworkPrimitives> SyncStateProvider for NetworkHandle<N> {
395402
// used to guard the txpool
396403
fn is_initially_syncing(&self) -> bool {
397404
if self.inner.initial_sync_done.load(Ordering::Relaxed) {
398-
return false
405+
return false;
399406
}
400407
self.inner.is_syncing.load(Ordering::Relaxed)
401408
}
@@ -484,7 +491,7 @@ pub(crate) enum NetworkHandleMessage<N: NetworkPrimitives = EthNetworkPrimitives
484491
/// Disconnects a connection to a peer if it exists, optionally providing a disconnect reason.
485492
DisconnectPeer(PeerId, Option<DisconnectReason>),
486493
/// Broadcasts an event to announce a new block to all nodes.
487-
AnnounceBlock(N::NewBlockPayload, B256),
494+
AnnounceBlock(N::NewBlockPayload, B256, Option<alloy_primitives::U256>),
488495
/// Sends a list of transactions to the given peer.
489496
SendTransaction {
490497
/// The ID of the peer to which the transactions are sent.

0 commit comments

Comments
 (0)