mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 12:46:44 +00:00
engine_v2, params: fix unsynchronized reads of V2.CurrentConfig, close XFN-53 (#1642)
This commit is contained in:
parent
3d707cf8b1
commit
013646403c
5 changed files with 31 additions and 14 deletions
|
|
@ -142,14 +142,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
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
@ -254,10 +255,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
|
||||
|
|
|
|||
|
|
@ -302,7 +302,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 {
|
||||
log.Warn("[OnCountdownTimeout] timeout sync threadhold reached, send syncInfo message")
|
||||
syncInfo := x.getSyncInfo()
|
||||
x.broadcastToBftChannel(syncInfo)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package engine_v2
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
|
|
|
|||
|
|
@ -494,8 +494,8 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
|
|||
}
|
||||
|
||||
// GetBlockReceipts returns the block receipts for the given block hash or number or tag.
|
||||
func (api *PublicBlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) {
|
||||
block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash)
|
||||
func (s *PublicBlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) {
|
||||
block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -493,7 +493,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
|
||||
}
|
||||
|
||||
|
|
@ -538,18 +538,32 @@ func (v *V2) UpdateConfig(round uint64) {
|
|||
v.CurrentConfig = v.AllConfigs[index]
|
||||
}
|
||||
|
||||
func (v *V2) Config(round uint64) *V2Config {
|
||||
// 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
|
||||
|
||||
//find the right config
|
||||
for i := range v.configIndex {
|
||||
if v.configIndex[i] <= configRound {
|
||||
index = v.configIndex[i]
|
||||
for i := range v2.configIndex {
|
||||
if v2.configIndex[i] <= configRound {
|
||||
index = v2.configIndex[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
return v.AllConfigs[index]
|
||||
return v2.AllConfigs[index]
|
||||
}
|
||||
|
||||
func (v *V2) BuildConfigIndex() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue