11package conflict
22
33import (
4+ "fmt"
5+ "math/rand"
46 "sync"
57 "sync/atomic"
68
79 "github.com/iotaledger/goshimmer/packages/protocol/engine/ledger/mempool/newconflictdag/weight"
810 "github.com/iotaledger/hive.go/ds/shrinkingmap"
11+ "github.com/iotaledger/hive.go/ds/types"
912 "github.com/iotaledger/hive.go/runtime/event"
1013 "github.com/iotaledger/hive.go/runtime/syncutils"
1114 "github.com/iotaledger/hive.go/stringify"
@@ -14,7 +17,7 @@ import (
1417// SortedSet is a set of Conflicts that is sorted by their weight.
1518type SortedSet [ConflictID , ResourceID IDType ] struct {
1619 // HeaviestPreferredMemberUpdated is triggered when the heaviest preferred member of the SortedSet changes.
17- HeaviestPreferredMemberUpdated * event.Event1 [* Conflict [ConflictID , ResourceID ]]
20+ HeaviestPreferredMemberUpdated * event.Event2 [* Conflict [ConflictID , ResourceID ], TriggerContext [ ConflictID ]]
1821
1922 // owner is the Conflict that owns this SortedSet.
2023 owner * Conflict [ConflictID , ResourceID ]
@@ -50,7 +53,7 @@ type SortedSet[ConflictID, ResourceID IDType] struct {
5053// NewSortedSet creates a new SortedSet that is owned by the given Conflict.
5154func NewSortedSet [ConflictID , ResourceID IDType ](owner * Conflict [ConflictID , ResourceID ]) * SortedSet [ConflictID , ResourceID ] {
5255 s := & SortedSet [ConflictID , ResourceID ]{
53- HeaviestPreferredMemberUpdated : event .New1 [* Conflict [ConflictID , ResourceID ]](),
56+ HeaviestPreferredMemberUpdated : event .New2 [* Conflict [ConflictID , ResourceID ], TriggerContext [ ConflictID ]](),
5457 owner : owner ,
5558 members : shrinkingmap .New [ConflictID , * sortedSetMember [ConflictID , ResourceID ]](),
5659 pendingWeightUpdates : shrinkingmap .New [ConflictID , * sortedSetMember [ConflictID , ResourceID ]](),
@@ -86,12 +89,6 @@ func (s *SortedSet[ConflictID, ResourceID]) Add(conflict *Conflict[ConflictID, R
8689 return
8790 }
8891
89- if conflict .IsPreferred () && newMember .Compare (s .heaviestPreferredMember ) == weight .Heavier {
90- s .heaviestPreferredMember = newMember
91-
92- s .HeaviestPreferredMemberUpdated .Trigger (conflict )
93- }
94-
9592 for currentMember := s .heaviestMember ; ; currentMember = currentMember .lighterMember {
9693 comparison := newMember .Compare (currentMember )
9794 if comparison == weight .Equal {
@@ -121,6 +118,12 @@ func (s *SortedSet[ConflictID, ResourceID]) Add(conflict *Conflict[ConflictID, R
121118 break
122119 }
123120 }
121+
122+ if conflict .IsPreferred () && newMember .Compare (s .heaviestPreferredMember ) == weight .Heavier {
123+ s .heaviestPreferredMember = newMember
124+
125+ s .HeaviestPreferredMemberUpdated .Trigger (conflict , NewTriggerContext (conflict .ID ()))
126+ }
124127}
125128
126129// ForEach iterates over all Conflicts of the SortedSet and calls the given callback for each of them.
@@ -151,6 +154,11 @@ func (s *SortedSet[ConflictID, ResourceID]) HeaviestConflict() *Conflict[Conflic
151154
152155// HeaviestPreferredConflict returns the heaviest preferred Conflict of the SortedSet.
153156func (s * SortedSet [ConflictID , ResourceID ]) HeaviestPreferredConflict () * Conflict [ConflictID , ResourceID ] {
157+ a := rand .Float64 ()
158+
159+ fmt .Println ("HeaviestPreferreConflict" , s .owner .ID (), a )
160+ defer fmt .Println ("unlocked HeaviestPreferreConflict" , s .owner .ID (), a )
161+
154162 s .mutex .RLock ()
155163 defer s .mutex .RUnlock ()
156164
@@ -192,14 +200,17 @@ func (s *SortedSet[ConflictID, ResourceID]) notifyPendingWeightUpdate(member *so
192200}
193201
194202// notifyPreferredInsteadUpdate notifies the SortedSet about a member that changed its preferred instead flag.
195- func (s * SortedSet [ConflictID , ResourceID ]) notifyPreferredInsteadUpdate (member * sortedSetMember [ConflictID , ResourceID ], preferred bool ) {
203+ func (s * SortedSet [ConflictID , ResourceID ]) notifyPreferredInsteadUpdate (member * sortedSetMember [ConflictID , ResourceID ], preferred bool , visitedConflicts TriggerContext [ConflictID ]) {
204+ fmt .Println ("Write-Lock" , s .owner .ID (), "notifyPreferredInsteadUpdate(" , member .ID (), "," , preferred , "," , visitedConflicts , ")" )
205+ defer fmt .Println ("Write-Unlock" , s .owner .ID (), "notifyPreferredInsteadUpdate(" , member .ID (), "," , preferred , "," , visitedConflicts , ")" )
206+
196207 s .mutex .Lock ()
197208 defer s .mutex .Unlock ()
198209
199210 if preferred {
200211 if member .Compare (s .heaviestPreferredMember ) == weight .Heavier {
201212 s .heaviestPreferredMember = member
202- s .HeaviestPreferredMemberUpdated .Trigger (member .Conflict )
213+ s .HeaviestPreferredMemberUpdated .Trigger (member .Conflict , visitedConflicts )
203214 }
204215
205216 return
@@ -215,7 +226,7 @@ func (s *SortedSet[ConflictID, ResourceID]) notifyPreferredInsteadUpdate(member
215226 }
216227
217228 s .heaviestPreferredMember = currentMember
218- s .HeaviestPreferredMemberUpdated .Trigger (currentMember .Conflict )
229+ s .HeaviestPreferredMemberUpdated .Trigger (currentMember .Conflict , visitedConflicts )
219230}
220231
221232// nextPendingWeightUpdate returns the next member that needs to be updated (or nil if the shutdown flag is set).
@@ -249,17 +260,21 @@ func (s *SortedSet[ConflictID, ResourceID]) fixMemberPositionWorker() {
249260
250261// fixMemberPosition fixes the position of the given member in the SortedSet.
251262func (s * SortedSet [ConflictID , ResourceID ]) fixMemberPosition (member * sortedSetMember [ConflictID , ResourceID ]) {
263+ fmt .Println ("Write-Lock" , s .owner .ID (), "fixMemberPosition(" , member .ID (), ")" )
264+ defer fmt .Println ("Write-Unlock" , s .owner .ID (), "fixMemberPosition(" , member .ID (), ")" )
265+
252266 s .mutex .Lock ()
253267 defer s .mutex .Unlock ()
254268
269+ preferredMember := s .preferredInstead (member )
270+
255271 // the member needs to be moved up in the list
256- memberIsPreferred := (member .Conflict == s .owner && member == s .heaviestPreferredMember ) || member .IsPreferred ()
257272 for currentMember := member .heavierMember ; currentMember != nil && currentMember .Compare (member ) == weight .Lighter ; currentMember = member .heavierMember {
258273 s .swapNeighbors (member , currentMember )
259274
260- if memberIsPreferred && currentMember == s . heaviestPreferredMember {
275+ if currentMember . ID () == preferredMember . ID () {
261276 s .heaviestPreferredMember = member
262- s .HeaviestPreferredMemberUpdated .Trigger (member .Conflict )
277+ s .HeaviestPreferredMemberUpdated .Trigger (member .Conflict , NewTriggerContext ( s . owner . ID ()) )
263278 }
264279 }
265280
@@ -268,15 +283,27 @@ func (s *SortedSet[ConflictID, ResourceID]) fixMemberPosition(member *sortedSetM
268283 for currentMember := member .lighterMember ; currentMember != nil && currentMember .Compare (member ) == weight .Heavier ; currentMember = member .lighterMember {
269284 s .swapNeighbors (currentMember , member )
270285
271- if memberIsHeaviestPreferred && currentMember . IsPreferred ( ) {
286+ if memberIsHeaviestPreferred && s . isPreferred ( currentMember ) {
272287 s .heaviestPreferredMember = currentMember
273- s .HeaviestPreferredMemberUpdated .Trigger (currentMember .Conflict )
288+ s .HeaviestPreferredMemberUpdated .Trigger (currentMember .Conflict , TriggerContext [ ConflictID ]{ s . owner . ID (): types . Void } )
274289
275290 memberIsHeaviestPreferred = false
276291 }
277292 }
278293}
279294
295+ func (s * SortedSet [ConflictID , ResourceID ]) preferredInstead (member * sortedSetMember [ConflictID , ResourceID ]) * Conflict [ConflictID , ResourceID ] {
296+ if member .Conflict == s .owner {
297+ return s .heaviestPreferredMember .Conflict
298+ }
299+
300+ return member .PreferredInstead ()
301+ }
302+
303+ func (s * SortedSet [ConflictID , ResourceID ]) isPreferred (member * sortedSetMember [ConflictID , ResourceID ]) bool {
304+ return s .preferredInstead (member ) == member .Conflict
305+ }
306+
280307// swapNeighbors swaps the given members in the SortedSet.
281308func (s * SortedSet [ConflictID , ResourceID ]) swapNeighbors (heavierMember , lighterMember * sortedSetMember [ConflictID , ResourceID ]) {
282309 if heavierMember .lighterMember != nil {
0 commit comments