@@ -100,11 +100,16 @@ type conn struct {
100100 // version stores the negotiated eth protocol version (e.g., 68 or 69).
101101 version uint
102102
103- // latestBlockHash and latestBlockNumber track the most recent block
104- // information received from this peer via NewBlock, NewBlockHashes,
105- // or BlockRangeUpdate messages. Uses ds.Locked for thread-safe API access.
106- latestBlockHash * ds.Locked [common.Hash ]
107- latestBlockNumber * ds.Locked [uint64 ]
103+ // latestBlock tracks the most recent block information received from this
104+ // peer via NewBlock, NewBlockHashes, or BlockRangeUpdate messages.
105+ // Hash and number are combined in a single struct to ensure consistency.
106+ latestBlock * ds.Locked [latestBlock ]
107+ }
108+
109+ // latestBlock holds the hash and number of the latest block from a peer.
110+ type latestBlock struct {
111+ Hash common.Hash
112+ Number uint64
108113}
109114
110115// EthProtocolOptions is the options used when creating a new eth protocol.
@@ -162,8 +167,7 @@ func NewEthProtocol(version uint, opts EthProtocolOptions) ethp2p.Protocol {
162167 blockAnnounce : make (chan eth.NewBlockHashesPacket , maxQueuedBlockAnns ),
163168 closeCh : make (chan struct {}),
164169 version : version ,
165- latestBlockHash : & ds.Locked [common.Hash ]{},
166- latestBlockNumber : & ds.Locked [uint64 ]{},
170+ latestBlock : & ds.Locked [latestBlock ]{},
167171 }
168172
169173 // Ensure cleanup happens on any exit path (including statusExchange failure)
@@ -440,11 +444,13 @@ func (c *conn) handleBlockRangeUpdate(msg ethp2p.Msg) error {
440444 Hex ("hash" , packet .LatestBlockHash [:]).
441445 Msg ("Received BlockRangeUpdate" )
442446
443- // Update latest block info from the range update (thread-safe for API access)
444- if packet .LatestBlock > c .latestBlockNumber .Get () {
445- c .latestBlockHash .Set (packet .LatestBlockHash )
446- c .latestBlockNumber .Set (packet .LatestBlock )
447- }
447+ // Update latest block info atomically if this block is newer
448+ c .latestBlock .Update (func (curr latestBlock ) (latestBlock , bool ) {
449+ if packet .LatestBlock > curr .Number {
450+ return latestBlock {Hash : packet .LatestBlockHash , Number : packet .LatestBlock }, true
451+ }
452+ return curr , false
453+ })
448454
449455 return nil
450456}
@@ -543,11 +549,13 @@ func (c *conn) handleNewBlockHashes(ctx context.Context, msg ethp2p.Msg) error {
543549 for _ , entry := range packet {
544550 hash := entry .Hash
545551
546- // Update latest block info if this block is newer (thread-safe for API access)
547- if entry .Number > c .latestBlockNumber .Get () {
548- c .latestBlockHash .Set (hash )
549- c .latestBlockNumber .Set (entry .Number )
550- }
552+ // Update latest block info atomically if this block is newer
553+ c .latestBlock .Update (func (current latestBlock ) (latestBlock , bool ) {
554+ if entry .Number > current .Number {
555+ return latestBlock {Hash : hash , Number : entry .Number }, true
556+ }
557+ return current , false
558+ })
551559
552560 // Mark as known from this peer
553561 c .addKnownBlock (hash )
@@ -1123,9 +1131,14 @@ func (c *conn) handleNewBlock(ctx context.Context, msg ethp2p.Msg) error {
11231131
11241132 c .countMsgReceived (packet .Name (), 1 )
11251133
1126- // Update latest block info for this peer (thread-safe for API access)
1127- c .latestBlockHash .Set (hash )
1128- c .latestBlockNumber .Set (packet .Block .Number ().Uint64 ())
1134+ // Update latest block info atomically if this block is newer
1135+ blockNum := packet .Block .Number ().Uint64 ()
1136+ c .latestBlock .Update (func (current latestBlock ) (latestBlock , bool ) {
1137+ if blockNum > current .Number {
1138+ return latestBlock {Hash : hash , Number : blockNum }, true
1139+ }
1140+ return current , false
1141+ })
11291142
11301143 // Mark block as known from this peer
11311144 c .addKnownBlock (hash )
0 commit comments