Skip to content

Commit

Permalink
Merge pull request #940 from iotaledger/fix/lazyinit
Browse files Browse the repository at this point in the history
Fix: Prevent spawning of unnecessary chains
  • Loading branch information
alexsporn authored Apr 26, 2024
2 parents f405e3c + e60e764 commit 849071e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 16 deletions.
24 changes: 12 additions & 12 deletions pkg/protocol/commitment.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ type Commitment struct {

// NewCommitment creates a new Commitment from the given model.Commitment.
func newCommitment(commitments *Commitments, model *model.Commitment) *Commitment {
c := &Commitment{
return &Commitment{
Commitment: model,
Parent: reactive.NewVariable[*Commitment](),
Children: reactive.NewSet[*Commitment](),
Expand All @@ -116,16 +116,8 @@ func newCommitment(commitments *Commitments, model *model.Commitment) *Commitmen
ReplayDroppedBlocks: reactive.NewVariable[bool](),
IsEvicted: reactive.NewEvent(),
commitments: commitments,
Logger: commitments.NewChildLogger(fmt.Sprintf("Slot%d.", model.Slot()), true),
}

shutdown := lo.BatchReverse(
c.initLogger(),
c.initDerivedProperties(),
)

c.IsEvicted.OnTrigger(shutdown)

return c
}

// TargetEngine returns the engine that is responsible for booking the blocks of this Commitment.
Expand Down Expand Up @@ -203,10 +195,18 @@ func (c *Commitment) Less(other *Commitment) bool {
}
}

// initBehavior initializes the behavior of this Commitment by setting up the relations between its properties.
func (c *Commitment) initBehavior() {
shutdown := lo.BatchReverse(
c.initLogger(),
c.initDerivedProperties(),
)

c.IsEvicted.OnTrigger(shutdown)
}

// initLogger initializes the Logger of this Commitment.
func (c *Commitment) initLogger() (shutdown func()) {
c.Logger = c.commitments.NewChildLogger(fmt.Sprintf("Slot%d.", c.Slot()), true)

return lo.BatchReverse(
c.Parent.LogUpdates(c, log.LevelTrace, "Parent", (*Commitment).LogName),
c.MainChild.LogUpdates(c, log.LevelTrace, "MainChild", (*Commitment).LogName),
Expand Down
18 changes: 14 additions & 4 deletions pkg/protocol/commitments.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,26 +187,31 @@ func (c *Commitments) publishEngineCommitments(chain *Chain, engine *engine.Engi
}

// publish the commitment
publishedCommitment, _, err := c.publishCommitment(commitment)
publishedCommitment, published, err := c.publishCommitment(commitment, true)
if err != nil {
c.LogError("failed to publish commitment from engine", "engine", engine.LogName(), "commitment", commitment, "err", err)

return
}

// force the chain before initializing the behavior to prevent the creation of unnecessary chains
publishedCommitment.forceChain(chain)
if published {
publishedCommitment.initBehavior()
}

// mark it as produced by ourselves and force it to be on the right chain (in case our chain produced a
// different commitment than the one we erroneously expected it to be - we always trust our engine most).
publishedCommitment.AttestedWeight.Set(publishedCommitment.Weight.Get())
publishedCommitment.IsVerified.Set(true)
publishedCommitment.forceChain(chain)
}
})
}

// publishCommitment publishes the given commitment and returns the singleton Commitment instance that is used to
// represent it in our data structure (together with a boolean that indicates if we were the first goroutine to publish
// the commitment).
func (c *Commitments) publishCommitment(commitment *model.Commitment) (publishedCommitment *Commitment, published bool, err error) {
func (c *Commitments) publishCommitment(commitment *model.Commitment, initManually ...bool) (publishedCommitment *Commitment, published bool, err error) {
// retrieve promise and abort if it was already rejected
cachedRequest := c.cachedRequest(commitment.ID())
if cachedRequest.WasRejected() {
Expand All @@ -215,9 +220,14 @@ func (c *Commitments) publishCommitment(commitment *model.Commitment) (published

// otherwise try to publish it and determine if we were the goroutine that published it
cachedRequest.ResolveDynamically(func() *Commitment {
publishedCommitment = newCommitment(c, commitment)
published = true

return newCommitment(c, commitment)
if !lo.First(initManually) {
publishedCommitment.initBehavior()
}

return publishedCommitment
})

return cachedRequest.Result(), published, nil
Expand Down

0 comments on commit 849071e

Please sign in to comment.