From 731be8dcae888b50d8eb99c7298a5e918c052555 Mon Sep 17 00:00:00 2001 From: Hans Moog <3293976+hmoog@users.noreply.github.com> Date: Tue, 7 Nov 2023 04:10:35 +0100 Subject: [PATCH] Feat: added Reset of TipManager and TipSelection --- .../engine/tipmanager/v1/tipmanager.go | 15 ++++---- .../engine/tipselection/v1/tip_selection.go | 34 ++++++++++++++++++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/pkg/protocol/engine/tipmanager/v1/tipmanager.go b/pkg/protocol/engine/tipmanager/v1/tipmanager.go index 57afb93a7..635a3a36c 100644 --- a/pkg/protocol/engine/tipmanager/v1/tipmanager.go +++ b/pkg/protocol/engine/tipmanager/v1/tipmanager.go @@ -42,13 +42,11 @@ type TipManager struct { // New creates a new TipManager. func New(blockRetriever func(blockID iotago.BlockID) (block *blocks.Block, exists bool)) *TipManager { t := &TipManager{ - retrieveBlock: blockRetriever, - tipMetadataStorage: shrinkingmap.New[iotago.SlotIndex, *shrinkingmap.ShrinkingMap[iotago.BlockID, *TipMetadata]](), - strongTipSet: randommap.New[iotago.BlockID, *TipMetadata](), - weakTipSet: randommap.New[iotago.BlockID, *TipMetadata](), - blockAdded: event.New1[tipmanager.TipMetadata](), + retrieveBlock: blockRetriever, + blockAdded: event.New1[tipmanager.TipMetadata](), } + t.Reset() t.TriggerConstructed() t.TriggerInitialized() @@ -105,7 +103,12 @@ func (t *TipManager) Evict(slot iotago.SlotIndex) { // Reset resets the component to a clean state as if it was created at the last commitment. func (t *TipManager) Reset() { - // TODO: reset tip metadata storage + t.evictionMutex.Lock() + defer t.evictionMutex.Unlock() + + t.tipMetadataStorage = shrinkingmap.New[iotago.SlotIndex, *shrinkingmap.ShrinkingMap[iotago.BlockID, *TipMetadata]]() + t.strongTipSet = randommap.New[iotago.BlockID, *TipMetadata]() + t.weakTipSet = randommap.New[iotago.BlockID, *TipMetadata]() } // Shutdown marks the TipManager as shutdown. diff --git a/pkg/protocol/engine/tipselection/v1/tip_selection.go b/pkg/protocol/engine/tipselection/v1/tip_selection.go index a46ea0a5b..4c39c7e8a 100644 --- a/pkg/protocol/engine/tipselection/v1/tip_selection.go +++ b/pkg/protocol/engine/tipselection/v1/tip_selection.go @@ -9,6 +9,7 @@ import ( "github.com/iotaledger/hive.go/lo" "github.com/iotaledger/hive.go/runtime/module" "github.com/iotaledger/hive.go/runtime/options" + "github.com/iotaledger/hive.go/runtime/syncutils" "github.com/iotaledger/hive.go/runtime/timed" "github.com/iotaledger/iota-core/pkg/model" "github.com/iotaledger/iota-core/pkg/protocol/engine/blocks" @@ -55,6 +56,12 @@ type TipSelection struct { // optMaxWeakReferences contains the maximum number of weak references that are allowed. optMaxWeakReferences int + // livenessThresholdQueueMutex is used to synchronize access to the liveness threshold queue. + livenessThresholdQueueMutex syncutils.RWMutex + + // acceptanceTimeMutex is used to synchronize access to the acceptance time. + acceptanceTimeMutex syncutils.RWMutex + // Module embeds the required methods of the module.Interface. module.Module } @@ -139,12 +146,16 @@ func (t *TipSelection) SelectTips(amount int) (references model.ParentReferences // SetAcceptanceTime updates the acceptance time of the TipSelection. func (t *TipSelection) SetAcceptanceTime(acceptanceTime time.Time) (previousValue time.Time) { + t.acceptanceTimeMutex.RLock() + defer t.acceptanceTimeMutex.RUnlock() + return t.acceptanceTime.Set(acceptanceTime) } // Reset resets the component to a clean state as if it was created at the last commitment. func (t *TipSelection) Reset() { - // TODO: reset acceptance time and liveness threshold queue + t.resetAcceptanceTime() + t.resetLivenessThresholdQueue() } // Shutdown triggers the shutdown of the TipSelection. @@ -235,6 +246,9 @@ func (t *TipSelection) isValidWeakTip(block *blocks.Block) bool { // triggerLivenessThreshold triggers the liveness threshold for all tips that have reached the given threshold. func (t *TipSelection) triggerLivenessThreshold(threshold time.Time) { + t.livenessThresholdQueueMutex.RLock() + defer t.livenessThresholdQueueMutex.RUnlock() + for _, tip := range t.livenessThresholdQueue.PopUntil(threshold) { if dynamicLivenessThreshold := tip.Block().IssuingTime().Add(t.livenessThreshold(tip)); dynamicLivenessThreshold.After(threshold) { t.livenessThresholdQueue.Push(tip, dynamicLivenessThreshold) @@ -244,6 +258,24 @@ func (t *TipSelection) triggerLivenessThreshold(threshold time.Time) { } } +func (t *TipSelection) resetLivenessThresholdQueue() { + t.livenessThresholdQueueMutex.Lock() + defer t.livenessThresholdQueueMutex.Unlock() + + t.livenessThresholdQueue = timed.NewPriorityQueue[tipmanager.TipMetadata](true) +} + +func (t *TipSelection) resetAcceptanceTime() { + t.acceptanceTimeMutex.Lock() + defer t.acceptanceTimeMutex.Unlock() + + t.acceptanceTime = reactive.NewVariable[time.Time](monotonicallyIncreasing) + + t.acceptanceTime.OnUpdate(func(_, acceptanceTime time.Time) { + t.triggerLivenessThreshold(acceptanceTime) + }) +} + // WithMaxStrongParents is an option for the TipSelection that allows to configure the maximum number of strong parents. func WithMaxStrongParents(maxStrongParents int) options.Option[TipSelection] { return func(tipManager *TipSelection) {