Skip to content

Commit

Permalink
Merge pull request #939 from iotaledger/fix/tiebreaker
Browse files Browse the repository at this point in the history
Fix: Tiebreaker for chains with equal weight
  • Loading branch information
alexsporn authored Apr 26, 2024
2 parents a8e457c + 0570f4d commit f405e3c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
17 changes: 17 additions & 0 deletions pkg/protocol/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type Chain struct {
// ParentChain contains the chain that this chain forked from.
ParentChain reactive.Variable[*Chain]

// DivergencePointVerified contains a flag that indicates whether the divergence point of this chain is verified.
DivergencePointVerified reactive.Event

// ChildChains contains the set of all chains that forked from this chain.
ChildChains reactive.Set[*Chain]

Expand Down Expand Up @@ -75,6 +78,7 @@ func newChain(chains *Chains) *Chain {
c := &Chain{
ForkingPoint: reactive.NewVariable[*Commitment](),
ParentChain: reactive.NewVariable[*Chain](),
DivergencePointVerified: reactive.NewEvent(),
ChildChains: reactive.NewSet[*Chain](),
LatestCommitment: reactive.NewVariable[*Commitment](),
LatestAttestedCommitment: reactive.NewVariable[*Commitment](),
Expand Down Expand Up @@ -232,6 +236,8 @@ func (c *Chain) initDerivedProperties() (shutdown func()) {
c.deriveShouldEvict(forkingPoint, parentChain),
)
}),

c.deriveDivergencePointVerified(forkingPoint),
)
}),
),
Expand Down Expand Up @@ -290,6 +296,17 @@ func (c *Chain) deriveChildChains(child *Chain) (teardown func()) {
return
}

// deriveDivergencePointVerified defines how a chain determines whether its divergence point is verified.
func (c *Chain) deriveDivergencePointVerified(forkingPoint *Commitment) (shutdown func()) {
return lo.Batch(
c.DivergencePointVerified.InheritFrom(forkingPoint.IsRoot),

forkingPoint.Parent.WithNonEmptyValue(func(parentOfForkingPoint *Commitment) (teardown func()) {
return c.DivergencePointVerified.InheritFrom(parentOfForkingPoint.IsVerified)
}),
)
}

// deriveParentChain defines how a chain determines its parent chain from its forking point (it inherits the Chain from
// the parent commitment of the forking point or nil if either of them is still unknown).
func (c *Chain) deriveParentChain(forkingPoint *Commitment) (shutdown func()) {
Expand Down
30 changes: 13 additions & 17 deletions pkg/protocol/chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,13 +323,7 @@ func (c *Chains) initChainSwitching() (shutdown func()) {

return lo.BatchReverse(
c.HeaviestClaimedCandidate.WithNonEmptyValue(func(heaviestClaimedCandidate *Chain) (shutdown func()) {
return heaviestClaimedCandidate.ForkingPoint.WithNonEmptyValue(func(forkingPoint *Commitment) (teardown func()) {
return forkingPoint.Parent.WithNonEmptyValue(func(parentOfForkingPoint *Commitment) (teardown func()) {
return parentOfForkingPoint.IsVerified.WithNonEmptyValue(func(_ bool) (teardown func()) {
return heaviestClaimedCandidate.RequestAttestations.ToggleValue(true)
})
})
})
return heaviestClaimedCandidate.RequestAttestations.ToggleValue(true)
}),

c.HeaviestAttestedCandidate.OnUpdate(func(_ *Chain, heaviestAttestedCandidate *Chain) {
Expand All @@ -351,19 +345,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.DivergencePointVerified.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)
})
}
})
})
}

Expand Down

0 comments on commit f405e3c

Please sign in to comment.