From 3e2e5f3494a7230ef72a4dd5d13f6e8371871627 Mon Sep 17 00:00:00 2001 From: Hans Moog <3293976+hmoog@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:58:46 +0200 Subject: [PATCH] Fix: Tiebreaker for chains with equal weight --- pkg/protocol/chain.go | 15 +++++++++++++++ pkg/protocol/chains.go | 22 ++++++++++++---------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/pkg/protocol/chain.go b/pkg/protocol/chain.go index 5639c7392..d8190ec96 100644 --- a/pkg/protocol/chain.go +++ b/pkg/protocol/chain.go @@ -54,6 +54,9 @@ type Chain struct { // Engine contains the engine instance that is used to process blocks for this chain. Engine reactive.Variable[*engine.Engine] + // IsSolid contains a flag that indicates whether this chain is solid (has a connection to the root). + IsSolid reactive.Event + // IsEvicted contains a flag that indicates whether this chain was evicted. IsEvicted reactive.Event @@ -86,6 +89,7 @@ func newChain(chains *Chains) *Chain { StartEngine: reactive.NewVariable[bool](), Engine: reactive.NewVariable[*engine.Engine](), IsEvicted: reactive.NewEvent(), + IsSolid: reactive.NewEvent(), shouldEvict: reactive.NewEvent(), chains: chains, @@ -230,6 +234,8 @@ func (c *Chain) initDerivedProperties() (shutdown func()) { parentChain.deriveChildChains(c), c.deriveShouldEvict(forkingPoint, parentChain), + + c.deriveIsSolid(forkingPoint, parentChain), ) }), ) @@ -264,6 +270,15 @@ func (c *Chain) deriveShouldEvict(forkingPoint *Commitment, parentChain *Chain) return } +// deriveIsSolid defines how a chain determines whether it is solid (has a connection to the root). +func (c *Chain) deriveIsSolid(forkingPoint *Commitment, parentChain *Chain) (shutdown func()) { + if parentChain != nil { + return c.IsSolid.InheritFrom(parentChain.IsSolid) + } + + return c.IsSolid.InheritFrom(forkingPoint.IsRoot) +} + // deriveWarpSyncMode defines how a chain determines whether it is in warp sync mode or not. func (c *Chain) deriveWarpSyncMode(engine *engine.Engine) func() { return c.WarpSyncMode.DeriveValueFrom(reactive.NewDerivedVariable4(func(warpSyncMode bool, engineInitialized bool, latestSyncedSlot iotago.SlotIndex, latestSeenSlot iotago.SlotIndex, outOfSyncThreshold iotago.SlotIndex) bool { diff --git a/pkg/protocol/chains.go b/pkg/protocol/chains.go index 89da80693..a874c5d76 100644 --- a/pkg/protocol/chains.go +++ b/pkg/protocol/chains.go @@ -351,19 +351,21 @@ func (c *Chains) initChainSwitching() (shutdown func()) { func (c *Chains) trackHeaviestCandidates(chain *Chain) (teardown func()) { return chain.LatestCommitment.OnUpdate(func(_ *Commitment, latestCommitment *Commitment) { - targetSlot := latestCommitment.ID().Index() + chain.IsSolid.OnTrigger(func() { + targetSlot := latestCommitment.ID().Index() - if evictionEvent := c.protocol.EvictionEvent(targetSlot); !evictionEvent.WasTriggered() { - c.HeaviestClaimedCandidate.registerCommitment(targetSlot, latestCommitment, evictionEvent) + if evictionEvent := c.protocol.EvictionEvent(targetSlot); !evictionEvent.WasTriggered() { + c.HeaviestClaimedCandidate.registerCommitment(targetSlot, latestCommitment, evictionEvent) - latestCommitment.IsAttested.OnTrigger(func() { - c.HeaviestAttestedCandidate.registerCommitment(targetSlot, latestCommitment, evictionEvent) - }) + latestCommitment.IsAttested.OnTrigger(func() { + c.HeaviestAttestedCandidate.registerCommitment(targetSlot, latestCommitment, evictionEvent) + }) - latestCommitment.IsVerified.OnTrigger(func() { - c.HeaviestVerifiedCandidate.registerCommitment(targetSlot, latestCommitment, evictionEvent) - }) - } + latestCommitment.IsVerified.OnTrigger(func() { + c.HeaviestVerifiedCandidate.registerCommitment(targetSlot, latestCommitment, evictionEvent) + }) + } + }) }) }