From ea3dc859971b39ae2cdc7601c17f2a4badba4b78 Mon Sep 17 00:00:00 2001 From: GrapeS Date: Tue, 26 May 2026 12:32:18 +0800 Subject: [PATCH] feature: add fastforward hello message latency metric --- .../org/tron/common/prometheus/MetricKeys.java | 10 ++++++++++ .../tron/common/prometheus/MetricsHistogram.java | 2 ++ .../net/service/handshake/HandshakeService.java | 16 ++++++++++++++-- .../core/net/service/relay/RelayService.java | 16 ++++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/org/tron/common/prometheus/MetricKeys.java b/common/src/main/java/org/tron/common/prometheus/MetricKeys.java index d473dac2ccb..7e9dfa566b9 100644 --- a/common/src/main/java/org/tron/common/prometheus/MetricKeys.java +++ b/common/src/main/java/org/tron/common/prometheus/MetricKeys.java @@ -77,6 +77,16 @@ public static class Histogram { */ public static final String TX_FETCH_LATENCY = "tron:tx_fetch_latency_seconds"; + /** + * Handshake round-trip latency in seconds: from TCP connection + * establishment to {@code HelloMessage} fully processed. + *

Sampled only on the SR{@literal <->}FF handshake path — either + * the received {@code HelloMessage} carries a witness signature, or + * the remote peer is in {@code node.fastForward.nodes}. Regular + * FullNode handshakes are not sampled. + */ + public static final String HANDSHAKE_LATENCY = "tron:handshake_latency_seconds"; + private Histogram() { throw new IllegalStateException("Histogram"); } diff --git a/common/src/main/java/org/tron/common/prometheus/MetricsHistogram.java b/common/src/main/java/org/tron/common/prometheus/MetricsHistogram.java index d8adf7e18c2..d792372e177 100644 --- a/common/src/main/java/org/tron/common/prometheus/MetricsHistogram.java +++ b/common/src/main/java/org/tron/common/prometheus/MetricsHistogram.java @@ -50,6 +50,8 @@ public class MetricsHistogram { "receive block delay time, receiveTime - blockTime."); init(MetricKeys.Histogram.TX_FETCH_LATENCY, "fetch transaction latency: GET_DATA send to full TXS received round-trip."); + init(MetricKeys.Histogram.HANDSHAKE_LATENCY, + "handshake round-trip latency on the SR<->FF path."); init(MetricKeys.Histogram.BLOCK_TRANSACTION_COUNT, "Distribution of transaction counts per block.", diff --git a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java index 070a9f56406..2c61a557d63 100644 --- a/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java +++ b/framework/src/main/java/org/tron/core/net/service/handshake/HandshakeService.java @@ -4,6 +4,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.prometheus.MetricKeys; +import org.tron.common.prometheus.Metrics; import org.tron.common.utils.ByteArray; import org.tron.core.ChainBaseManager; import org.tron.core.ChainBaseManager.NodeType; @@ -15,6 +17,7 @@ import org.tron.core.net.service.effective.EffectiveCheckService; import org.tron.core.net.service.relay.RelayService; import org.tron.p2p.discover.Node; +import org.tron.protos.Protocol; import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") @@ -122,8 +125,17 @@ public void processHelloMessage(PeerConnection peer, HelloMessage msg) { peer.setHelloMessageReceive(msg); - peer.getChannel().updateAvgLatency( - System.currentTimeMillis() - peer.getChannel().getStartTime()); + long latencyMs = System.currentTimeMillis() - peer.getChannel().getStartTime(); + peer.getChannel().updateAvgLatency(latencyMs); + // Sample only the SR<->FF handshake path: + // - inbound: received hello carries a witness signature. + // - outbound: peer is in node.fastForward.nodes. + Protocol.HelloMessage hello = msg.getInstance(); + boolean signed = !hello.getSignature().isEmpty() || hello.hasPqAuthSig(); + if (signed || relayService.isFastForwardPeer(peer.getChannel())) { + Metrics.histogramObserve(MetricKeys.Histogram.HANDSHAKE_LATENCY, + latencyMs / Metrics.MILLISECONDS_PER_SECOND); + } PeerManager.sortPeers(); peer.onConnect(); } diff --git a/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java b/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java index f898cafdb49..a52f9f12470 100644 --- a/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java +++ b/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java @@ -121,6 +121,22 @@ public void close() { ExecutorServiceManager.shutdownAndAwaitTermination(executorService, esName); } + /** + * Whether the channel's remote peer is in {@code node.fastForward.nodes}. + */ + public boolean isFastForwardPeer(Channel channel) { + if (fastForwardNodes.isEmpty() || channel == null + || channel.getInetAddress() == null) { + return false; + } + for (InetSocketAddress ff : fastForwardNodes) { + if (channel.getInetAddress().equals(ff.getAddress())) { + return true; + } + } + return false; + } + public void fillHelloMessage(HelloMessage message, Channel channel) { if (!isActiveWitness()) { return;