diff --git a/go.sum b/go.sum index d8d261632..b4f79a7ff 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0= -github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/ethereum/go-ethereum v1.12.2 h1:eGHJ4ij7oyVqUQn48LBz3B7pvQ8sV0wGJiIE6gDq/6Y= github.com/ethereum/go-ethereum v1.12.2/go.mod h1:1cRAEV+rp/xX0zraSCBnu9Py3HQ+geRMj3HdR+k0wfI= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -268,8 +266,6 @@ github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20230817124507-83988a14d80d h1: github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20230817124507-83988a14d80d/go.mod h1:N4tN4g5vb3dcJU35U9o/CD/2G3DdxgXbJUUuSwDeBdE= github.com/iotaledger/hive.go/crypto v0.0.0-20230817124507-83988a14d80d h1:ggHDvRR/FN16iuKia5ZOSAL7DuoMDhHp70s4suxGS4U= github.com/iotaledger/hive.go/crypto v0.0.0-20230817124507-83988a14d80d/go.mod h1:dh01lKrdkIqN5O/NqNIW+IsbZFR/+Pst6rcLbVkhe9Q= -github.com/iotaledger/hive.go/ds v0.0.0-20230817124507-83988a14d80d h1:usox/ZLeIDMBs0vyxzxZ4gmqSAGtPEKHF7ss6A/5/R0= -github.com/iotaledger/hive.go/ds v0.0.0-20230817124507-83988a14d80d/go.mod h1:x6uTxewNdOkYUs/Pd123A98Qv8iIIl1UUoB8jmF7nfA= github.com/iotaledger/hive.go/ds v0.0.0-20230818002409-9755559b5ff6 h1:IkP9D1XcpdWiYCbQsql6ZRWlkakgYSCxHTAGthD0qAA= github.com/iotaledger/hive.go/ds v0.0.0-20230818002409-9755559b5ff6/go.mod h1:x6uTxewNdOkYUs/Pd123A98Qv8iIIl1UUoB8jmF7nfA= github.com/iotaledger/hive.go/ierrors v0.0.0-20230817124507-83988a14d80d h1:HvTox3m7aBI4c7iIOqPHFPEIbGh9nBg4plq+MguQy3E= @@ -643,8 +639,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230724220655-d98519c11495 h1:zKGKw2WlGb8oPoRGqQ2PT8g2YoCN1w/YbbQjHXCdUWE= -golang.org/x/exp v0.0.0-20230724220655-d98519c11495/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230810033253-352e893a4cad h1:g0bG7Z4uG+OgH2QDODnjp6ggkk1bJDsINcuWmJN1iJU= golang.org/x/exp v0.0.0-20230810033253-352e893a4cad/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.9.0 h1:QrzfX26snvCM20hIhBwuHI/ThTg18b/+kcKdXHvnR+g= golang.org/x/image v0.9.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0= diff --git a/pkg/protocol/chainmanagerv1/chain.go b/pkg/protocol/chainmanagerv1/chain.go index cf337dc66..14932b868 100644 --- a/pkg/protocol/chainmanagerv1/chain.go +++ b/pkg/protocol/chainmanagerv1/chain.go @@ -50,6 +50,7 @@ func NewChain(forkingPoint *CommitmentMetadata) *Chain { } c.forkingPoint.Set(forkingPoint) + c.latestCommitmentIndex.Set(forkingPoint.Index()) c.syncThreshold = reactive.NewDerivedVariable[iotago.SlotIndex](func(latestVerifiedCommitmentIndex iotago.SlotIndex) iotago.SlotIndex { return latestVerifiedCommitmentIndex + 1 + SyncWindow @@ -94,17 +95,22 @@ func (c *Chain) registerCommitment(commitment *CommitmentMetadata) { c.latestCommitmentIndex.Compute(func(latestCommitmentIndex iotago.SlotIndex) iotago.SlotIndex { c.commitments.Set(commitment.Index(), commitment) - return lo.Cond(latestCommitmentIndex > commitment.Index(), latestCommitmentIndex, commitment.Index()) + if latestCommitmentIndex > commitment.Index() { + return latestCommitmentIndex + } + + return commitment.Index() }) - unregisterCommitment := reactive.NewEvent() + unregistered := reactive.NewEvent() + unsubscribe := commitment.Chain().OnUpdate(func(_, newValue *Chain) { if newValue != c { - unregisterCommitment.Trigger() + unregistered.Trigger() } }) - unregisterCommitment.OnTrigger(func() { + unregistered.OnTrigger(func() { go unsubscribe() c.latestCommitmentIndex.Compute(func(latestCommitmentIndex iotago.SlotIndex) iotago.SlotIndex { diff --git a/pkg/protocol/chainmanagerv1/chainmanager.go b/pkg/protocol/chainmanagerv1/chainmanager.go index bafa4616e..793b8eb1f 100644 --- a/pkg/protocol/chainmanagerv1/chainmanager.go +++ b/pkg/protocol/chainmanagerv1/chainmanager.go @@ -23,7 +23,7 @@ type ChainManager struct { commitmentRequester *eventticker.EventTicker[iotago.SlotIndex, iotago.CommitmentID] - *SlotEviction + *EvictionState } func NewChainManager() *ChainManager { @@ -33,7 +33,7 @@ func NewChainManager() *ChainManager { cachedCommitments: shrinkingmap.New[iotago.CommitmentID, *promise.Promise[*CommitmentMetadata]](), commitmentRequester: eventticker.New[iotago.SlotIndex, iotago.CommitmentID](), - SlotEviction: NewSlotEviction(), + EvictionState: NewEvictionState(), } } @@ -95,7 +95,7 @@ func (c *ChainManager) setupCommitment(commitment *CommitmentMetadata, slotEvict } func (c *ChainManager) requestCommitment(id iotago.CommitmentID, index iotago.SlotIndex, requestIfMissing bool, optSuccessCallbacks ...func(metadata *CommitmentMetadata)) (commitmentRequest *promise.Promise[*CommitmentMetadata], requestCreated bool) { - slotEvicted := c.EvictedEvent(index) + slotEvicted := c.EvictionEvent(index) if slotEvicted.WasTriggered() { if rootCommitment := c.rootCommitment.Get(); rootCommitment != nil && id == rootCommitment.ID() { for _, successCallback := range optSuccessCallbacks { diff --git a/pkg/protocol/chainmanagerv1/eviction.go b/pkg/protocol/chainmanagerv1/eviction.go index e8a53485d..38122e5f3 100644 --- a/pkg/protocol/chainmanagerv1/eviction.go +++ b/pkg/protocol/chainmanagerv1/eviction.go @@ -3,64 +3,68 @@ package chainmanagerv1 import ( "github.com/iotaledger/hive.go/ds/reactive" "github.com/iotaledger/hive.go/ds/shrinkingmap" - iotago "github.com/iotaledger/iota.go/v4" ) -type SlotEviction struct { - evictionEvents *shrinkingmap.ShrinkingMap[iotago.SlotIndex, reactive.Event] +type EvictionState[Type SlotType] struct { + evictionEvents *shrinkingmap.ShrinkingMap[Type, reactive.Event] - lastEvictedSlotIndex reactive.Variable[iotago.SlotIndex] + lastEvictedSlotIndex reactive.Variable[Type] } -func NewSlotEviction() *SlotEviction { - return &SlotEviction{ - evictionEvents: shrinkingmap.New[iotago.SlotIndex, reactive.Event](), - lastEvictedSlotIndex: reactive.NewVariable[iotago.SlotIndex](), +func NewEvictionState[Type SlotType]() *EvictionState[Type] { + return &EvictionState[Type]{ + evictionEvents: shrinkingmap.New[Type, reactive.Event](), + lastEvictedSlotIndex: reactive.NewVariable[Type](), } } -func (c *SlotEviction) LastEvictedSlotIndex() reactive.Variable[iotago.SlotIndex] { +func (c *EvictionState[Type]) LastEvictedSlot() reactive.Variable[Type] { return c.lastEvictedSlotIndex } -func (c *SlotEviction) EvictedEvent(index iotago.SlotIndex) reactive.Event { - slotEvictedEvent := defaultTriggeredEvent +func (c *EvictionState[Type]) EvictionEvent(slot Type) reactive.Event { + evictionEvent := evictedSlotEvent - c.lastEvictedSlotIndex.Compute(func(lastEvictedSlotIndex iotago.SlotIndex) iotago.SlotIndex { - if index > lastEvictedSlotIndex { - slotEvictedEvent, _ = c.evictionEvents.GetOrCreate(index, reactive.NewEvent) + c.lastEvictedSlotIndex.Compute(func(lastEvictedSlotIndex Type) Type { + if slot > lastEvictedSlotIndex { + evictionEvent, _ = c.evictionEvents.GetOrCreate(slot, reactive.NewEvent) } - return lastEvictedSlotIndex }) - return slotEvictedEvent + return evictionEvent } -func (c *SlotEviction) Evict(slotIndex iotago.SlotIndex) { - slotEvictedEventsToTrigger := make([]reactive.Event, 0) +func (c *EvictionState[Type]) Evict(slot Type) { + for _, slotEvictedEvent := range c.evict(slot) { + slotEvictedEvent.Trigger() + } +} - c.lastEvictedSlotIndex.Compute(func(lastEvictedSlotIndex iotago.SlotIndex) iotago.SlotIndex { - if slotIndex <= lastEvictedSlotIndex { +func (c *EvictionState[Type]) evict(slot Type) (eventsToTrigger []reactive.Event) { + c.lastEvictedSlotIndex.Compute(func(lastEvictedSlotIndex Type) Type { + if slot <= lastEvictedSlotIndex { return lastEvictedSlotIndex } - for i := lastEvictedSlotIndex + 1; i <= slotIndex; i++ { + for i := lastEvictedSlotIndex + Type(1); i <= slot; i = i + Type(1) { if slotEvictedEvent, exists := c.evictionEvents.Get(i); exists { - slotEvictedEventsToTrigger = append(slotEvictedEventsToTrigger, slotEvictedEvent) + eventsToTrigger = append(eventsToTrigger, slotEvictedEvent) } } - return slotIndex + return slot }) - for _, slotEvictedEvent := range slotEvictedEventsToTrigger { - slotEvictedEvent.Trigger() - } + return eventsToTrigger +} + +type SlotType interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string } -var defaultTriggeredEvent = reactive.NewEvent() +var evictedSlotEvent = reactive.NewEvent() func init() { - defaultTriggeredEvent.Trigger() + evictedSlotEvent.Trigger() }