@@ -10,9 +10,11 @@ import (
10
10
11
11
"github.com/iotaledger/hive.go/core/generics/event"
12
12
"github.com/iotaledger/hive.go/core/generics/lo"
13
+ "github.com/iotaledger/hive.go/core/generics/shrinkingmap"
13
14
"github.com/iotaledger/hive.go/core/logger"
14
15
15
16
"github.com/iotaledger/goshimmer/packages/core/conflictdag"
17
+ "github.com/iotaledger/goshimmer/packages/core/mana"
16
18
"github.com/iotaledger/goshimmer/packages/node/clock"
17
19
18
20
"github.com/iotaledger/goshimmer/packages/core/epoch"
@@ -35,7 +37,7 @@ type Manager struct {
35
37
epochCommitmentFactoryMutex sync.RWMutex
36
38
bootstrapMutex sync.RWMutex
37
39
options * ManagerOptions
38
- pendingConflictsCounters map [epoch.Index ] uint64
40
+ pendingConflictsCounters * shrinkingmap. ShrinkingMap [epoch.Index , uint64 ]
39
41
log * logger.Logger
40
42
Events * Events
41
43
bootstrapped bool
@@ -55,7 +57,7 @@ func NewManager(epochCommitmentFactory *EpochCommitmentFactory, t *tangleold.Tan
55
57
new = & Manager {
56
58
tangle : t ,
57
59
epochCommitmentFactory : epochCommitmentFactory ,
58
- pendingConflictsCounters : make ( map [epoch.Index ] uint64 ),
60
+ pendingConflictsCounters : shrinkingmap . New [epoch.Index , uint64 ]( ),
59
61
log : options .Log ,
60
62
options : options ,
61
63
Events : & Events {
@@ -66,7 +68,7 @@ func NewManager(epochCommitmentFactory *EpochCommitmentFactory, t *tangleold.Tan
66
68
UTXOTreeInserted : event .New [* UTXOUpdatedEvent ](),
67
69
UTXOTreeRemoved : event .New [* UTXOUpdatedEvent ](),
68
70
EpochCommittable : event .New [* EpochCommittableEvent ](),
69
- ManaVectorUpdate : event .New [* ManaVectorUpdateEvent ](),
71
+ ManaVectorUpdate : event .New [* mana. ManaVectorUpdateEvent ](),
70
72
Bootstrapped : event .New [* BootstrappedEvent ](),
71
73
SyncRange : event .New [* SyncRangeEvent ](),
72
74
ActivityTreeInserted : event .New [* ActivityTreeUpdatedEvent ](),
@@ -172,7 +174,7 @@ func (m *Manager) LoadOutputsWithMetadata(outputsWithMetadatas []*ledger.OutputW
172
174
}
173
175
}
174
176
175
- // LoadEpochDiffs updates the state tree from a given snapshot .
177
+ // LoadEpochDiff loads an epoch diff .
176
178
func (m * Manager ) LoadEpochDiff (epochDiff * ledger.EpochDiff ) {
177
179
m .epochCommitmentFactoryMutex .Lock ()
178
180
defer m .epochCommitmentFactoryMutex .Unlock ()
@@ -328,8 +330,6 @@ func (m *Manager) OnBlockStored(block *tangleold.Block) {
328
330
latestCommittableEI := lo .PanicOnErr (m .epochCommitmentFactory .storage .latestCommittableEpochIndex ())
329
331
epochDeltaSeconds := time .Duration (int64 (blockEI - latestCommittableEI )* epoch .Duration ) * time .Second
330
332
331
- m .log .Debugf ("block committing to epoch %d stored, latest committable epoch is %d" , blockEI , latestCommittableEI )
332
-
333
333
// If we are too far behind, we will warpsync
334
334
if epochDeltaSeconds > m .options .BootstrapWindow {
335
335
m .Events .SyncRange .Trigger (& SyncRangeEvent {
@@ -451,7 +451,7 @@ func (m *Manager) OnConflictAccepted(conflictID utxo.TransactionID) {
451
451
}
452
452
453
453
// OnConflictConfirmed is the handler for conflict confirmed event.
454
- func (m * Manager ) onConflictAccepted (conflictID utxo.TransactionID ) ([]* EpochCommittableEvent , []* ManaVectorUpdateEvent ) {
454
+ func (m * Manager ) onConflictAccepted (conflictID utxo.TransactionID ) ([]* EpochCommittableEvent , []* mana. ManaVectorUpdateEvent ) {
455
455
m .epochCommitmentFactoryMutex .Lock ()
456
456
defer m .epochCommitmentFactoryMutex .Unlock ()
457
457
@@ -485,7 +485,7 @@ func (m *Manager) OnConflictRejected(conflictID utxo.TransactionID) {
485
485
}
486
486
487
487
// OnConflictRejected is the handler for conflict created event.
488
- func (m * Manager ) onConflictRejected (conflictID utxo.TransactionID ) ([]* EpochCommittableEvent , []* ManaVectorUpdateEvent ) {
488
+ func (m * Manager ) onConflictRejected (conflictID utxo.TransactionID ) ([]* EpochCommittableEvent , []* mana. ManaVectorUpdateEvent ) {
489
489
m .epochCommitmentFactoryMutex .Lock ()
490
490
defer m .epochCommitmentFactoryMutex .Unlock ()
491
491
@@ -505,7 +505,7 @@ func (m *Manager) OnAcceptanceTimeUpdated(newTime time.Time) {
505
505
}
506
506
507
507
// OnAcceptanceTimeUpdated is the handler for time updated event and returns events to be triggered.
508
- func (m * Manager ) onAcceptanceTimeUpdated (newTime time.Time ) ([]* EpochCommittableEvent , []* ManaVectorUpdateEvent ) {
508
+ func (m * Manager ) onAcceptanceTimeUpdated (newTime time.Time ) ([]* EpochCommittableEvent , []* mana. ManaVectorUpdateEvent ) {
509
509
m .epochCommitmentFactoryMutex .Lock ()
510
510
defer m .epochCommitmentFactoryMutex .Unlock ()
511
511
@@ -532,21 +532,14 @@ func (m *Manager) PendingConflictsCountAll() (pendingConflicts map[epoch.Index]u
532
532
m .epochCommitmentFactoryMutex .RLock ()
533
533
defer m .epochCommitmentFactoryMutex .RUnlock ()
534
534
535
- pendingConflicts = make (map [epoch.Index ]uint64 , len ( m .pendingConflictsCounters ))
536
- for k , v := range m . pendingConflictsCounters {
535
+ pendingConflicts = make (map [epoch.Index ]uint64 , m .pendingConflictsCounters . Size ( ))
536
+ m . pendingConflictsCounters . ForEach ( func ( k epoch. Index , v uint64 ) bool {
537
537
pendingConflicts [k ] = v
538
- }
538
+ return true
539
+ })
539
540
return pendingConflicts
540
541
}
541
542
542
- // GetEpochDiff returns the epoch diff of an epoch.
543
- func (m * Manager ) GetEpochDiff (ei epoch.Index ) (spent []* ledger.OutputWithMetadata , created []* ledger.OutputWithMetadata ) {
544
- m .epochCommitmentFactoryMutex .Lock ()
545
- defer m .epochCommitmentFactoryMutex .Unlock ()
546
- spent , created = m .epochCommitmentFactory .loadDiffUTXOs (ei )
547
- return
548
- }
549
-
550
543
// Bootstrapped returns the current value of pendingConflictsCount per epoch.
551
544
func (m * Manager ) Bootstrapped () bool {
552
545
m .bootstrapMutex .RLock ()
@@ -563,16 +556,20 @@ func (m *Manager) Shutdown() {
563
556
m .epochCommitmentFactory .storage .shutdown ()
564
557
}
565
558
566
- func (m * Manager ) decreasePendingConflictCounter (ei epoch.Index ) ([]* EpochCommittableEvent , []* ManaVectorUpdateEvent ) {
567
- m .pendingConflictsCounters [ei ]--
568
- if m .pendingConflictsCounters [ei ] == 0 {
559
+ func (m * Manager ) decreasePendingConflictCounter (ei epoch.Index ) ([]* EpochCommittableEvent , []* mana.ManaVectorUpdateEvent ) {
560
+ count , _ := m .pendingConflictsCounters .Get (ei )
561
+ count --
562
+ m .pendingConflictsCounters .Set (ei , count )
563
+ if count == 0 {
569
564
return m .moveLatestCommittableEpoch (ei )
570
565
}
571
566
return nil , nil
572
567
}
573
568
574
569
func (m * Manager ) increasePendingConflictCounter (ei epoch.Index ) {
575
- m .pendingConflictsCounters [ei ]++
570
+ count , _ := m .pendingConflictsCounters .Get (ei )
571
+ count ++
572
+ m .pendingConflictsCounters .Set (ei , count )
576
573
}
577
574
578
575
func (m * Manager ) includeTransactionInEpoch (txID utxo.TransactionID , ei epoch.Index , spent , created []* ledger.OutputWithMetadata ) (err error ) {
@@ -611,7 +608,7 @@ func (m *Manager) allPastConflictsAreResolved(ei epoch.Index) (conflictsResolved
611
608
}
612
609
// epoch is not committable if there are any not resolved conflicts in this and past epochs
613
610
for index := lastEI ; index <= ei ; index ++ {
614
- if m .pendingConflictsCounters [ index ] != 0 {
611
+ if count , _ := m .pendingConflictsCounters . Get ( index ); count != 0 {
615
612
return false
616
613
}
617
614
}
@@ -675,21 +672,31 @@ func (m *Manager) resolveOutputs(tx utxo.Transaction) (spentOutputsWithMetadata,
675
672
return
676
673
}
677
674
678
- func (m * Manager ) manaVectorUpdate (ei epoch.Index ) (event * ManaVectorUpdateEvent ) {
679
- return & ManaVectorUpdateEvent {
680
- EI : ei ,
675
+ func (m * Manager ) manaVectorUpdate (ei epoch.Index ) (event * mana.ManaVectorUpdateEvent ) {
676
+ manaEpoch := ei - epoch .Index (m .options .ManaEpochDelay )
677
+ spent := []* ledger.OutputWithMetadata {}
678
+ created := []* ledger.OutputWithMetadata {}
679
+
680
+ if manaEpoch > 0 {
681
+ spent , created = m .epochCommitmentFactory .loadDiffUTXOs (manaEpoch )
682
+ }
683
+
684
+ return & mana.ManaVectorUpdateEvent {
685
+ EI : ei ,
686
+ Spent : spent ,
687
+ Created : created ,
681
688
}
682
689
}
683
690
684
- func (m * Manager ) moveLatestCommittableEpoch (currentEpoch epoch.Index ) ([]* EpochCommittableEvent , []* ManaVectorUpdateEvent ) {
691
+ func (m * Manager ) moveLatestCommittableEpoch (currentEpoch epoch.Index ) ([]* EpochCommittableEvent , []* mana. ManaVectorUpdateEvent ) {
685
692
latestCommittable , err := m .epochCommitmentFactory .storage .latestCommittableEpochIndex ()
686
693
if err != nil {
687
694
m .log .Errorf ("could not obtain last committed epoch index: %v" , err )
688
695
return nil , nil
689
696
}
690
697
691
698
epochCommittableEvents := make ([]* EpochCommittableEvent , 0 )
692
- manaVectorUpdateEvents := make ([]* ManaVectorUpdateEvent , 0 )
699
+ manaVectorUpdateEvents := make ([]* mana. ManaVectorUpdateEvent , 0 )
693
700
for ei := latestCommittable + 1 ; ei <= currentEpoch ; ei ++ {
694
701
if ! m .isCommittable (ei ) {
695
702
break
@@ -715,11 +722,14 @@ func (m *Manager) moveLatestCommittableEpoch(currentEpoch epoch.Index) ([]*Epoch
715
722
if manaVectorUpdateEvent := m .manaVectorUpdate (ei ); manaVectorUpdateEvent != nil {
716
723
manaVectorUpdateEvents = append (manaVectorUpdateEvents , manaVectorUpdateEvent )
717
724
}
725
+
726
+ // We do not need to track pending conflicts for a committed epoch anymore.
727
+ m .pendingConflictsCounters .Delete (ei )
718
728
}
719
729
return epochCommittableEvents , manaVectorUpdateEvents
720
730
}
721
731
722
- func (m * Manager ) triggerEpochEvents (epochCommittableEvents []* EpochCommittableEvent , manaVectorUpdateEvents []* ManaVectorUpdateEvent ) {
732
+ func (m * Manager ) triggerEpochEvents (epochCommittableEvents []* EpochCommittableEvent , manaVectorUpdateEvents []* mana. ManaVectorUpdateEvent ) {
723
733
for _ , epochCommittableEvent := range epochCommittableEvents {
724
734
m .Events .EpochCommittable .Trigger (epochCommittableEvent )
725
735
}
@@ -755,6 +765,15 @@ type ManagerOptions struct {
755
765
MinCommittableEpochAge time.Duration
756
766
BootstrapWindow time.Duration
757
767
Log * logger.Logger
768
+ ManaEpochDelay uint
769
+ }
770
+
771
+ // ManaEpochDelay specifies how many epochs the consensus mana booking is delayed with respect to the latest committable
772
+ // epoch.
773
+ func ManaEpochDelay (manaEpochDelay uint ) ManagerOption {
774
+ return func (options * ManagerOptions ) {
775
+ options .ManaEpochDelay = manaEpochDelay
776
+ }
758
777
}
759
778
760
779
// MinCommittableEpochAge specifies how old an epoch has to be for it to be committable.
0 commit comments