Skip to content

Commit ecbf7ab

Browse files
committed
fix: address race condition during EuclidV2 header chain verification
1 parent 0b6f8f1 commit ecbf7ab

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

consensus/wrapper/consensus.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,31 @@ func (ue *UpgradableEngine) VerifyHeader(chain consensus.ChainHeaderReader, head
5959
return ue.chooseEngine(header.Time).VerifyHeader(chain, header, seal)
6060
}
6161

62+
func waitForHeader(chain consensus.ChainHeaderReader, header *types.Header) {
63+
hash, number := header.Hash(), header.Number.Uint64()
64+
65+
// poll every 2 seconds, should succeed after a few tries
66+
ticker := time.NewTicker(2 * time.Second)
67+
defer ticker.Stop()
68+
69+
// we give up after 2 minutes
70+
timeout := time.After(120 * time.Second)
71+
72+
for {
73+
select {
74+
case <-ticker.C:
75+
// try reading from chain, if the header is present then we are ready
76+
if h := chain.GetHeader(hash, number); h != nil {
77+
return
78+
}
79+
80+
case <-timeout:
81+
log.Warn("Unable to find last pre-EuclidV2 header in chain", "hash", hash.Hex(), "number", number)
82+
return
83+
}
84+
}
85+
}
86+
6287
// VerifyHeaders verifies a batch of headers concurrently. In our use-case,
6388
// headers can only be all system, all clique, or start with clique and then switch once to system.
6489
func (ue *UpgradableEngine) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
@@ -124,10 +149,10 @@ func (ue *UpgradableEngine) VerifyHeaders(chain consensus.ChainHeaderReader, hea
124149
}
125150
}
126151

127-
// Not sure why we need this here, but without this we get err="unknown ancestor"
128-
// at the 1st Euclid block. It seems that `VerifyHeaders` start processing the next
129-
// header before the previous one was written into `chain`.
130-
time.Sleep(2 * time.Second)
152+
// `VerifyHeader` will try to call `chain.GetHeader`, which will race with `InsertHeaderChain`.
153+
// This might result in "unknown ancestor" header validation error.
154+
// This should be temporary, so we solve this by waiting here.
155+
waitForHeader(chain, cliqueHeaders[len(cliqueHeaders)-1])
131156

132157
// Verify system contract headers.
133158
log.Info("Start EuclidV2 transition verification in SystemContract section", "startBlockNumber", systemHeaders[0].Number, "endBlockNumber", systemHeaders[len(systemHeaders)-1].Number)

params/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
const (
2525
VersionMajor = 5 // Major version component of the current release
2626
VersionMinor = 8 // Minor version component of the current release
27-
VersionPatch = 45 // Patch version component of the current release
27+
VersionPatch = 46 // Patch version component of the current release
2828
VersionMeta = "mainnet" // Version metadata to append to the version string
2929
)
3030

0 commit comments

Comments
 (0)