From bda5f5e1622d148ad38dc00e5713e2afc0b02625 Mon Sep 17 00:00:00 2001 From: Piotr Macek <4007944+piotrm50@users.noreply.github.com> Date: Tue, 2 Apr 2024 08:55:57 +0200 Subject: [PATCH] Fix a deadlock during warpsync and publishing commitment. --- pkg/protocol/commitments.go | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/pkg/protocol/commitments.go b/pkg/protocol/commitments.go index 8828e7c23..793564248 100644 --- a/pkg/protocol/commitments.go +++ b/pkg/protocol/commitments.go @@ -141,25 +141,28 @@ func (c *Commitments) initRequester() (shutdown func()) { // publishRootCommitment publishes the root commitment of the main engine. func (c *Commitments) publishRootCommitment(mainChain *Chain, mainEngine *engine.Engine) func() { return mainEngine.RootCommitment.OnUpdate(func(_ *model.Commitment, rootCommitment *model.Commitment) { - publishedCommitment, published, err := c.publishCommitment(rootCommitment) - if err != nil { - c.LogError("failed to publish new root commitment", "id", rootCommitment.ID(), "error", err) + // Use workerpool to avoid a deadlock when + c.workerPool.Submit(func() { + publishedCommitment, published, err := c.publishCommitment(rootCommitment) + if err != nil { + c.LogError("failed to publish new root commitment", "id", rootCommitment.ID(), "error", err) - return - } + return + } - publishedCommitment.IsRoot.Set(true) - if published { - publishedCommitment.Chain.Set(mainChain) - } + publishedCommitment.IsRoot.Set(true) + if published { + publishedCommitment.Chain.Set(mainChain) + } - // Update the forking point of a chain only if the root is empty or root belongs to the main chain or the published commitment is on the main chain. - // to avoid updating ForkingPoint of the new mainChain into the past. - if c.Root.Get() == nil || c.Root.Get().Chain.Get() == mainChain || publishedCommitment.Chain.Get() == mainChain { - mainChain.ForkingPoint.Set(publishedCommitment) - } + // Update the forking point of a chain only if the root is empty or root belongs to the main chain or the published commitment is on the main chain. + // to avoid updating ForkingPoint of the new mainChain into the past. + if c.Root.Get() == nil || c.Root.Get().Chain.Get() == mainChain || publishedCommitment.Chain.Get() == mainChain { + mainChain.ForkingPoint.Set(publishedCommitment) + } - c.Root.Set(publishedCommitment) + c.Root.Set(publishedCommitment) + }) }) }