mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
engine_v2, params: fix unsynchronized reads of V2.CurrentConfig, close XFN-53 (#1642)
This commit is contained in:
parent
33c09226ba
commit
5a26279c1c
3 changed files with 23 additions and 7 deletions
|
|
@ -150,14 +150,15 @@ func (x *XDPoS_v2) UpdateParams(header *types.Header) {
|
|||
x.config.V2.UpdateConfig(uint64(round))
|
||||
|
||||
// Setup timeoutTimer
|
||||
duration := time.Duration(x.config.V2.CurrentConfig.TimeoutPeriod) * time.Second
|
||||
err = x.timeoutWorker.SetParams(duration, x.config.V2.CurrentConfig.ExpTimeoutConfig.Base, x.config.V2.CurrentConfig.ExpTimeoutConfig.MaxExponent)
|
||||
currentConfig := x.config.V2.GetCurrentConfig()
|
||||
duration := time.Duration(currentConfig.TimeoutPeriod) * time.Second
|
||||
err = x.timeoutWorker.SetParams(duration, currentConfig.ExpTimeoutConfig.Base, currentConfig.ExpTimeoutConfig.MaxExponent)
|
||||
if err != nil {
|
||||
log.Error("[UpdateParams] set params failed", "err", err)
|
||||
}
|
||||
// avoid deadlock
|
||||
go func() {
|
||||
x.minePeriodCh <- x.config.V2.CurrentConfig.MinePeriod
|
||||
x.minePeriodCh <- currentConfig.MinePeriod
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
@ -261,10 +262,11 @@ func (x *XDPoS_v2) initial(chain consensus.ChainReader, header *types.Header) er
|
|||
}
|
||||
|
||||
// Initial timeout
|
||||
log.Warn("[initial] miner wait period", "period", x.config.V2.CurrentConfig.MinePeriod)
|
||||
currentConfig := x.config.V2.GetCurrentConfig()
|
||||
log.Warn("[initial] miner wait period", "period", currentConfig.MinePeriod)
|
||||
// avoid deadlock
|
||||
go func() {
|
||||
x.minePeriodCh <- x.config.V2.CurrentConfig.MinePeriod
|
||||
x.minePeriodCh <- currentConfig.MinePeriod
|
||||
}()
|
||||
|
||||
// Kick-off the countdown timer
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ func (x *XDPoS_v2) OnCountdownTimeout(time time.Time, chain interface{}) error {
|
|||
}
|
||||
|
||||
x.timeoutCount++
|
||||
if x.timeoutCount%x.config.V2.CurrentConfig.TimeoutSyncThreshold == 0 {
|
||||
if x.timeoutCount%x.config.V2.GetCurrentConfig().TimeoutSyncThreshold == 0 {
|
||||
syncInfo := x.getSyncInfo()
|
||||
log.Info("[OnCountdownTimeout] Timeout sync threshold reached, send syncInfo message", "QC round", syncInfo.HighestQuorumCert.ProposedBlockInfo.Round, "QC num", syncInfo.HighestQuorumCert.ProposedBlockInfo.Number, "QC sigs", len(syncInfo.HighestQuorumCert.Signatures), "TC round", syncInfo.HighestTimeoutCert.Round, "TC sigs", len(syncInfo.HighestTimeoutCert.Signatures))
|
||||
x.broadcastToBftChannel(syncInfo)
|
||||
|
|
|
|||
|
|
@ -560,7 +560,7 @@ func (v2 *V2) Description(indent int) string {
|
|||
banner += fmt.Sprintf("%s- SwitchEpoch: %v\n", prefix, v2.SwitchEpoch)
|
||||
banner += fmt.Sprintf("%s- SwitchBlock: %v\n", prefix, v2.SwitchBlock)
|
||||
banner += fmt.Sprintf("%s- SkipV2Validation: %v\n", prefix, v2.SkipV2Validation)
|
||||
banner += fmt.Sprintf("%s- %s", prefix, v2.CurrentConfig.Description("CurrentConfig", indent+2))
|
||||
banner += fmt.Sprintf("%s- %s", prefix, v2.GetCurrentConfig().Description("CurrentConfig", indent+2))
|
||||
return banner
|
||||
}
|
||||
|
||||
|
|
@ -625,6 +625,20 @@ func (v2 *V2) UpdateConfig(round uint64) {
|
|||
v2.CurrentConfig = v2.AllConfigs[index]
|
||||
}
|
||||
|
||||
// GetCurrentConfig returns a opy of the current config, it assumes v2 is not nil
|
||||
func (v2 *V2) GetCurrentConfig() *V2Config {
|
||||
v2.lock.RLock()
|
||||
defer v2.lock.RUnlock()
|
||||
|
||||
if v2.CurrentConfig == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// avoid CurrentConfig is changed by other goroutines
|
||||
cpyConfig := *v2.CurrentConfig
|
||||
return &cpyConfig
|
||||
}
|
||||
|
||||
func (v2 *V2) Config(round uint64) *V2Config {
|
||||
configRound := round
|
||||
var index uint64
|
||||
|
|
|
|||
Loading…
Reference in a new issue