Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.

Commit c62c95e

Browse files
authored
Merge pull request #630 from iotaledger/feat/metastability-breaker
Feat: Add metastability breaking mechanism
2 parents 95c0bc1 + 69963d1 commit c62c95e

File tree

14 files changed

+634
-147
lines changed

14 files changed

+634
-147
lines changed

pkg/protocol/attestations.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,11 @@ func (a *Attestations) initRequester() (shutdown func()) {
7878
unsubscribeFromTicker := lo.Batch(
7979
a.protocol.Commitments.WithElements(func(commitment *Commitment) (shutdown func()) {
8080
return commitment.RequestAttestations.WithNonEmptyValue(func(_ bool) (teardown func()) {
81-
if commitment.CumulativeWeight() == 0 {
82-
commitment.IsAttested.Set(true)
81+
if commitment.CumulativeWeight.Get() == 0 {
82+
// execute in worker pool since it can have long-running effects (e.g. chain switching)
83+
a.workerPool.Submit(func() {
84+
commitment.IsAttested.Set(true)
85+
})
8386

8487
return nil
8588
}
@@ -161,7 +164,10 @@ func (a *Attestations) processResponse(commitment *model.Commitment, attestation
161164
return
162165
}
163166

164-
if publishedCommitment.AttestedWeight.Compute(func(currentWeight uint64) uint64 {
167+
var wasAttested, attestationsUpdated bool
168+
publishedCommitment.AttestedWeight.Compute(func(currentWeight uint64) uint64 {
169+
wasAttested = currentWeight > 0
170+
165171
if !publishedCommitment.RequestAttestations.Get() {
166172
a.LogTrace("received attestations for previously attested commitment", "commitment", publishedCommitment.LogName())
167173

@@ -189,12 +195,14 @@ func (a *Attestations) processResponse(commitment *model.Commitment, attestation
189195
return currentWeight
190196
}
191197

192-
if actualWeight > currentWeight {
193-
a.LogDebug("received response", "commitment", publishedCommitment.LogName(), "fromPeer", from)
198+
if attestationsUpdated = actualWeight > currentWeight; attestationsUpdated {
199+
a.LogDebug("received response", "commitment", publishedCommitment.LogName(), "weight", actualWeight, "fromPeer", from)
194200
}
195201

196202
return actualWeight
197-
}) > 0 {
203+
})
204+
205+
if !wasAttested && attestationsUpdated {
198206
publishedCommitment.IsAttested.Set(true)
199207
}
200208
})

pkg/protocol/chain.go

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,6 @@ type Chain struct {
3333
// corresponding blocks in the Engine.
3434
LatestProducedCommitment reactive.Variable[*Commitment]
3535

36-
// ClaimedWeight contains the claimed weight of this chain which is derived from the cumulative weight of the
37-
// LatestCommitment.
38-
ClaimedWeight reactive.Variable[uint64]
39-
40-
// AttestedWeight contains the attested weight of this chain which is derived from the cumulative weight of all
41-
// attestations up to the LatestAttestedCommitment.
42-
AttestedWeight reactive.Variable[uint64]
43-
44-
// VerifiedWeight contains the verified weight of this chain which is derived from the cumulative weight of the
45-
// latest verified commitment.
46-
VerifiedWeight reactive.Variable[uint64]
47-
4836
// WarpSyncMode contains a flag that indicates whether this chain is in warp sync mode.
4937
WarpSyncMode reactive.Variable[bool]
5038

@@ -88,9 +76,6 @@ func newChain(chains *Chains) *Chain {
8876
LatestCommitment: reactive.NewVariable[*Commitment](),
8977
LatestAttestedCommitment: reactive.NewVariable[*Commitment](),
9078
LatestProducedCommitment: reactive.NewVariable[*Commitment](),
91-
ClaimedWeight: reactive.NewVariable[uint64](),
92-
AttestedWeight: reactive.NewVariable[uint64](),
93-
VerifiedWeight: reactive.NewVariable[uint64](),
9479
WarpSyncMode: reactive.NewVariable[bool]().Init(true),
9580
LatestSyncedSlot: reactive.NewVariable[iotago.SlotIndex](),
9681
OutOfSyncThreshold: reactive.NewVariable[iotago.SlotIndex](),
@@ -189,9 +174,6 @@ func (c *Chain) initLogger() (shutdown func()) {
189174
c.LatestSyncedSlot.LogUpdates(c, log.LevelTrace, "LatestSyncedSlot"),
190175
c.OutOfSyncThreshold.LogUpdates(c, log.LevelTrace, "OutOfSyncThreshold"),
191176
c.ForkingPoint.LogUpdates(c, log.LevelTrace, "ForkingPoint", (*Commitment).LogName),
192-
c.ClaimedWeight.LogUpdates(c, log.LevelTrace, "ClaimedWeight"),
193-
c.AttestedWeight.LogUpdates(c, log.LevelTrace, "AttestedWeight"),
194-
c.VerifiedWeight.LogUpdates(c, log.LevelTrace, "VerifiedWeight"),
195177
c.LatestCommitment.LogUpdates(c, log.LevelTrace, "LatestCommitment", (*Commitment).LogName),
196178
c.LatestAttestedCommitment.LogUpdates(c, log.LevelTrace, "LatestAttestedCommitment", (*Commitment).LogName),
197179
c.LatestProducedCommitment.LogUpdates(c, log.LevelDebug, "LatestProducedCommitment", (*Commitment).LogName),
@@ -207,9 +189,6 @@ func (c *Chain) initLogger() (shutdown func()) {
207189
// initDerivedProperties initializes the behavior of this chain by setting up the relations between its properties.
208190
func (c *Chain) initDerivedProperties() (shutdown func()) {
209191
return lo.Batch(
210-
c.deriveClaimedWeight(),
211-
c.deriveVerifiedWeight(),
212-
c.deriveLatestAttestedWeight(),
213192
c.deriveWarpSyncMode(),
214193

215194
c.ForkingPoint.WithValue(c.deriveParentChain),
@@ -231,39 +210,6 @@ func (c *Chain) deriveWarpSyncMode() func() {
231210
}, c.LatestSyncedSlot, c.chains.LatestSeenSlot, c.OutOfSyncThreshold, c.WarpSyncMode.Get()))
232211
}
233212

234-
// deriveClaimedWeight defines how a chain determines its claimed weight (by setting the cumulative weight of the
235-
// latest commitment).
236-
func (c *Chain) deriveClaimedWeight() (shutdown func()) {
237-
return c.ClaimedWeight.DeriveValueFrom(reactive.NewDerivedVariable(func(_ uint64, latestCommitment *Commitment) uint64 {
238-
if latestCommitment == nil {
239-
return 0
240-
}
241-
242-
return latestCommitment.CumulativeWeight()
243-
}, c.LatestCommitment))
244-
}
245-
246-
// deriveLatestAttestedWeight defines how a chain determines its attested weight (by inheriting the cumulative attested
247-
// weight of the latest attested commitment). It uses inheritance instead of simply setting the value as the cumulative
248-
// attested weight can change over time depending on the attestations that are received.
249-
func (c *Chain) deriveLatestAttestedWeight() func() {
250-
return c.LatestAttestedCommitment.WithNonEmptyValue(func(latestAttestedCommitment *Commitment) (shutdown func()) {
251-
return c.AttestedWeight.InheritFrom(latestAttestedCommitment.CumulativeAttestedWeight)
252-
})
253-
}
254-
255-
// deriveVerifiedWeight defines how a chain determines its verified weight (by setting the cumulative weight of the
256-
// latest produced commitment).
257-
func (c *Chain) deriveVerifiedWeight() func() {
258-
return c.VerifiedWeight.DeriveValueFrom(reactive.NewDerivedVariable(func(_ uint64, latestProducedCommitment *Commitment) uint64 {
259-
if latestProducedCommitment == nil {
260-
return 0
261-
}
262-
263-
return latestProducedCommitment.CumulativeWeight()
264-
}, c.LatestProducedCommitment))
265-
}
266-
267213
// deriveChildChains defines how a chain determines its ChildChains (by adding each child to the set).
268214
func (c *Chain) deriveChildChains(child *Chain) func() {
269215
c.ChildChains.Add(child)
@@ -353,21 +299,3 @@ func (c *Chain) dispatchBlockToSpawnedEngine(block *model.Block, src peer.ID) (d
353299

354300
return true
355301
}
356-
357-
// claimedWeight is a getter for the ClaimedWeight variable of this chain, which is internally used to be able to
358-
// "address" the variable across multiple chains in a generic way.
359-
func (c *Chain) claimedWeight() reactive.Variable[uint64] {
360-
return c.ClaimedWeight
361-
}
362-
363-
// verifiedWeight is a getter for the VerifiedWeight variable of this chain, which is internally used to be able to
364-
// "address" the variable across multiple chains in a generic way.
365-
func (c *Chain) verifiedWeight() reactive.Variable[uint64] {
366-
return c.VerifiedWeight
367-
}
368-
369-
// attestedWeight is a getter for the AttestedWeight variable of this chain, which is internally used to be able to
370-
// "address" the variable across multiple chains in a generic way.
371-
func (c *Chain) attestedWeight() reactive.Variable[uint64] {
372-
return c.AttestedWeight
373-
}

0 commit comments

Comments
 (0)