From 82fc88d19ff7ace26d9a2c24d91ef9986ee55ded Mon Sep 17 00:00:00 2001
From: Luca Moser <moser.luca@gmail.com>
Date: Sun, 28 Jun 2020 16:51:32 +0200
Subject: [PATCH] Fixes some small bugs in the sync plugin (#571)

* fix incorrect usage of timer instead of ticker

* only add anchor points with newer issuance times

* adds before time boundary
---
 plugins/sync/plugin.go | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/plugins/sync/plugin.go b/plugins/sync/plugin.go
index b44f9d21..d29842dd 100644
--- a/plugins/sync/plugin.go
+++ b/plugins/sync/plugin.go
@@ -39,6 +39,12 @@ const (
 	// CfgSyncDesyncedIfNoMessageAfterSec defines the time period in which new messages must be received and if not
 	// the node is marked as desynced.
 	CfgSyncDesyncedIfNoMessageAfterSec = "sync.desyncedIfNoMessagesAfterSec"
+
+	// defines the max. divergence a potential new anchor point's issuance time can have
+	// from the current issuance threshold. say the current threshold is at 1000, the boundary at 10,
+	// we allow a new potential anchor point's issuance time to be within >=990 / 10 seconds older
+	// than the current threshold.
+	issuanceThresholdBeforeTimeBoundary = 20 * time.Second
 )
 
 func init() {
@@ -218,7 +224,7 @@ func monitorForSynchronization() {
 		defer messagelayer.Tangle().Events.MessageSolid.Detach(checkAnchorPointSolidityClosure)
 
 		cleanupDelta := config.Node().GetDuration(CfgSyncAnchorPointsCleanupAfterSec) * time.Second
-		ticker := time.NewTimer(config.Node().GetDuration(CfgSyncAnchorPointsCleanupIntervalSec) * time.Second)
+		ticker := time.NewTicker(config.Node().GetDuration(CfgSyncAnchorPointsCleanupIntervalSec) * time.Second)
 		defer ticker.Stop()
 		for {
 			select {
@@ -263,9 +269,11 @@ func initAnchorPoint(anchorPoints *anchorpoints, msg *message.Message) *message.
 		return nil
 	}
 
-	// add a new anchor point
+	// add a new anchor point if its issuance time is newer than any other anchor point
 	id := msg.Id()
-	anchorPoints.add(id)
+	if !anchorPoints.add(id, msg.IssuingTime()) {
+		return nil
+	}
 	return &id
 }
 
@@ -312,11 +320,22 @@ type anchorpoints struct {
 	wanted int
 	// how many anchor points have been solidified.
 	solidified int
+	// holds the highest issuance time of any message which was an anchor point.
+	// this is used to determine whether further attached messages should become an
+	// anchor point by matching their issuance time against this time.
+	issuanceTimeThreshold time.Time
 }
 
-// adds the given message to the anchor points set.
-func (ap *anchorpoints) add(id message.Id) {
+// adds the given message to the anchor points set if its issuance time is newer than
+// any other existing anchor point's.
+func (ap *anchorpoints) add(id message.Id, issuanceTime time.Time) bool {
+	if !ap.issuanceTimeThreshold.IsZero() &&
+		ap.issuanceTimeThreshold.Add(-issuanceThresholdBeforeTimeBoundary).After(issuanceTime) {
+		return false
+	}
 	ap.ids[id] = time.Now()
+	ap.issuanceTimeThreshold = issuanceTime
+	return true
 }
 
 func (ap *anchorpoints) has(id message.Id) bool {
-- 
GitLab