From fe55edda0f1d155875e3ed75ad8551c11f6fba67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Thu, 23 May 2024 10:26:11 +0300 Subject: [PATCH] consensus/clique: fix race condition (#24957) (#766) --- consensus/clique/clique.go | 18 ++++++++++++------ params/version.go | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 6830ad1d83f9..8c0505f760de 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -181,7 +181,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 @@ -509,9 +509,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 { @@ -528,10 +527,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 { @@ -670,7 +673,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 { diff --git a/params/version.go b/params/version.go index 10c2108ed287..404665739804 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 3 // Minor version component of the current release - VersionPatch = 19 // Patch version component of the current release + VersionPatch = 20 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string )