From 8b4bc39e5dd040d2bca3f06f7cec25d66ffef33a Mon Sep 17 00:00:00 2001
From: TBC Dev <48684072+tbcd@users.noreply.github.com>
Date: Tue, 23 Nov 2021 02:40:57 +0800
Subject: [PATCH] Fix atomic peer height update (#3019)

---
 cmd/sentry/download/sentry.go | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go
index b8f4ceb385..3d75743239 100644
--- a/cmd/sentry/download/sentry.go
+++ b/cmd/sentry/download/sentry.go
@@ -71,8 +71,15 @@ func (pi *PeerInfo) AddDeadline(deadline time.Time) {
 func (pi *PeerInfo) Height() uint64 {
 	return atomic.LoadUint64(&pi.height)
 }
-func (pi *PeerInfo) SetHeight(h uint64) {
-	atomic.StoreUint64(&pi.height, h)
+
+// SetIncreasedHeight atomically updates PeerInfo.height only if newHeight is higher
+func (pi *PeerInfo) SetIncreasedHeight(newHeight uint64) {
+	for {
+		oldHeight := atomic.LoadUint64(&pi.height)
+		if oldHeight >= newHeight || atomic.CompareAndSwapUint64(&pi.height, oldHeight, newHeight) {
+			break
+		}
+	}
 }
 
 // ClearDeadlines goes through the deadlines of
@@ -626,9 +633,7 @@ func (ss *SentryServerImpl) PenalizePeer(_ context.Context, req *proto_sentry.Pe
 func (ss *SentryServerImpl) PeerMinBlock(_ context.Context, req *proto_sentry.PeerMinBlockRequest) (*emptypb.Empty, error) {
 	peerID := ConvertH256ToPeerID(req.PeerId)
 	if peerInfo := ss.getPeer(peerID); peerInfo != nil {
-		if req.MinBlock > peerInfo.Height() {
-			peerInfo.SetHeight(req.MinBlock)
-		}
+		peerInfo.SetIncreasedHeight(req.MinBlock)
 	}
 	return &emptypb.Empty{}, nil
 }
-- 
GitLab