From 1f336149844588bd4cb50c99c4157fd5a190f12d Mon Sep 17 00:00:00 2001 From: Harry Kalodner Date: Wed, 25 May 2022 08:53:11 -0400 Subject: [PATCH 1/2] consensus/clique: remove race condition --- consensus/clique/clique.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 685186817d2d..21867c6b4d02 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -507,9 +507,8 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header if err != nil { return err } + c.lock.RLock() if number%c.config.Epoch != 0 { - c.lock.RLock() - // Gather all the proposals that make sense voting on addresses := make([]common.Address, 0, len(c.proposals)) for address, authorize := range c.proposals { @@ -526,10 +525,14 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header copy(header.Nonce[:], nonceDropVote) } } - c.lock.RUnlock() } + + // Copy signer protected by mutex to avoid race condition + signer := c.signer + c.lock.RUnlock() + // Set the correct difficulty - header.Difficulty = calcDifficulty(snap, c.signer) + header.Difficulty = calcDifficulty(snap, signer) // Ensure the extra data has all its components if len(header.Extra) < extraVanity { From 03595bf8a16fd0054c05879eb1fb4bab32114e00 Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Thu, 26 May 2022 11:10:22 +0800 Subject: [PATCH 2/2] consensus/clique: fix one more signer data race --- consensus/clique/clique.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 21867c6b4d02..950300f03486 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -180,7 +180,7 @@ type Clique struct { signer common.Address // Ethereum address of the signing key signFn SignerFn // Signer function to authorize hashes with - lock sync.RWMutex // Protects the signer fields + lock sync.RWMutex // Protects the signer and proposals fields // The fields below are for testing only fakeDiff bool // Skip difficulty verifications @@ -669,7 +669,10 @@ func (c *Clique) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, if err != nil { return nil } - return calcDifficulty(snap, c.signer) + c.lock.RLock() + signer := c.signer + c.lock.RUnlock() + return calcDifficulty(snap, signer) } func calcDifficulty(snap *Snapshot, signer common.Address) *big.Int {