mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
Merge branch 'master' into release-br-v2.4.3-beta1
This commit is contained in:
commit
383e2d5207
3 changed files with 47 additions and 24 deletions
|
|
@ -41,6 +41,7 @@ import (
|
||||||
const (
|
const (
|
||||||
ExtraFieldCheck = true
|
ExtraFieldCheck = true
|
||||||
SkipExtraFieldCheck = false
|
SkipExtraFieldCheck = false
|
||||||
|
newRoundChanSize = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func (x *XDPoS) SigHash(header *types.Header) (hash common.Hash) {
|
func (x *XDPoS) SigHash(header *types.Header) (hash common.Hash) {
|
||||||
|
|
@ -64,6 +65,8 @@ type XDPoS struct {
|
||||||
// Share Channel
|
// Share Channel
|
||||||
MinePeriodCh chan int // Miner wait Period Channel
|
MinePeriodCh chan int // Miner wait Period Channel
|
||||||
|
|
||||||
|
NewRoundCh chan types.Round // Miner use this channel to trigger worker to commitNewWork
|
||||||
|
|
||||||
// Trading and lending service
|
// Trading and lending service
|
||||||
GetXDCXService func() utils.TradingService
|
GetXDCXService func() utils.TradingService
|
||||||
GetLendingService func() utils.LendingService
|
GetLendingService func() utils.LendingService
|
||||||
|
|
@ -104,6 +107,7 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS {
|
||||||
log.Info("xdc config loading", "v2 config", config.V2)
|
log.Info("xdc config loading", "v2 config", config.V2)
|
||||||
|
|
||||||
minePeriodCh := make(chan int)
|
minePeriodCh := make(chan int)
|
||||||
|
newRoundCh := make(chan types.Round, newRoundChanSize)
|
||||||
|
|
||||||
// Allocate the snapshot caches and create the engine
|
// Allocate the snapshot caches and create the engine
|
||||||
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)
|
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)
|
||||||
|
|
@ -113,10 +117,11 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS {
|
||||||
db: db,
|
db: db,
|
||||||
|
|
||||||
MinePeriodCh: minePeriodCh,
|
MinePeriodCh: minePeriodCh,
|
||||||
|
NewRoundCh: newRoundCh,
|
||||||
|
|
||||||
signingTxsCache: signingTxsCache,
|
signingTxsCache: signingTxsCache,
|
||||||
EngineV1: engine_v1.New(chainConfig, db),
|
EngineV1: engine_v1.New(chainConfig, db),
|
||||||
EngineV2: engine_v2.New(chainConfig, db, minePeriodCh),
|
EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,6 +136,7 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS {
|
||||||
}
|
}
|
||||||
|
|
||||||
minePeriodCh := make(chan int)
|
minePeriodCh := make(chan int)
|
||||||
|
newRoundCh := make(chan types.Round, newRoundChanSize)
|
||||||
|
|
||||||
// Allocate the snapshot caches and create the engine
|
// Allocate the snapshot caches and create the engine
|
||||||
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)
|
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)
|
||||||
|
|
@ -140,13 +146,14 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS {
|
||||||
db: db,
|
db: db,
|
||||||
|
|
||||||
MinePeriodCh: minePeriodCh,
|
MinePeriodCh: minePeriodCh,
|
||||||
|
NewRoundCh: newRoundCh,
|
||||||
|
|
||||||
GetXDCXService: func() utils.TradingService { return nil },
|
GetXDCXService: func() utils.TradingService { return nil },
|
||||||
GetLendingService: func() utils.LendingService { return nil },
|
GetLendingService: func() utils.LendingService { return nil },
|
||||||
|
|
||||||
signingTxsCache: signingTxsCache,
|
signingTxsCache: signingTxsCache,
|
||||||
EngineV1: engine_v1.NewFaker(db, chainConfig),
|
EngineV1: engine_v1.NewFaker(db, chainConfig),
|
||||||
EngineV2: engine_v2.New(chainConfig, db, minePeriodCh),
|
EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh),
|
||||||
}
|
}
|
||||||
return fakeEngine
|
return fakeEngine
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ type XDPoS_v2 struct {
|
||||||
|
|
||||||
BroadcastCh chan interface{}
|
BroadcastCh chan interface{}
|
||||||
minePeriodCh chan int
|
minePeriodCh chan int
|
||||||
|
newRoundCh chan types.Round
|
||||||
|
|
||||||
timeoutWorker *countdown.CountdownTimer // Timer to generate broadcast timeout msg if threashold reached
|
timeoutWorker *countdown.CountdownTimer // Timer to generate broadcast timeout msg if threashold reached
|
||||||
timeoutCount int // number of timeout being sent
|
timeoutCount int // number of timeout being sent
|
||||||
|
|
@ -71,7 +72,7 @@ type XDPoS_v2 struct {
|
||||||
votePoolCollectionTime time.Time
|
votePoolCollectionTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan int) *XDPoS_v2 {
|
func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan int, newRoundCh chan types.Round) *XDPoS_v2 {
|
||||||
config := chainConfig.XDPoS
|
config := chainConfig.XDPoS
|
||||||
// Setup timeoutTimer
|
// Setup timeoutTimer
|
||||||
duration := time.Duration(config.V2.CurrentConfig.TimeoutPeriod) * time.Second
|
duration := time.Duration(config.V2.CurrentConfig.TimeoutPeriod) * time.Second
|
||||||
|
|
@ -100,6 +101,7 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan i
|
||||||
timeoutWorker: timeoutTimer,
|
timeoutWorker: timeoutTimer,
|
||||||
BroadcastCh: make(chan interface{}),
|
BroadcastCh: make(chan interface{}),
|
||||||
minePeriodCh: minePeriodCh,
|
minePeriodCh: minePeriodCh,
|
||||||
|
newRoundCh: newRoundCh,
|
||||||
|
|
||||||
round2epochBlockInfo: round2epochBlockInfo,
|
round2epochBlockInfo: round2epochBlockInfo,
|
||||||
|
|
||||||
|
|
@ -902,6 +904,7 @@ func (x *XDPoS_v2) processQC(blockChainReader consensus.ChainReader, incomingQuo
|
||||||
1. Set currentRound = QC round + 1 (or TC round +1)
|
1. Set currentRound = QC round + 1 (or TC round +1)
|
||||||
2. Reset timer
|
2. Reset timer
|
||||||
3. Reset vote and timeout Pools
|
3. Reset vote and timeout Pools
|
||||||
|
4. Send signal to miner
|
||||||
*/
|
*/
|
||||||
func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round types.Round) {
|
func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round types.Round) {
|
||||||
log.Info("[setNewRound] new round and reset pools and workers", "round", round)
|
log.Info("[setNewRound] new round and reset pools and workers", "round", round)
|
||||||
|
|
@ -911,6 +914,12 @@ func (x *XDPoS_v2) setNewRound(blockChainReader consensus.ChainReader, round typ
|
||||||
x.timeoutPool.Clear()
|
x.timeoutPool.Clear()
|
||||||
// don't need to clean vote pool, we have other process to clean and it's not good to clean here, some edge case may break
|
// don't need to clean vote pool, we have other process to clean and it's not good to clean here, some edge case may break
|
||||||
// for example round gets bump during collecting vote, so we have to keep vote.
|
// for example round gets bump during collecting vote, so we have to keep vote.
|
||||||
|
|
||||||
|
// send signal to newRoundCh, but if full don't send
|
||||||
|
select {
|
||||||
|
case x.newRoundCh <- round:
|
||||||
|
default:
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *XDPoS_v2) broadcastToBftChannel(msg interface{}) {
|
func (x *XDPoS_v2) broadcastToBftChannel(msg interface{}) {
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,9 @@ type worker struct {
|
||||||
chainHeadSub event.Subscription
|
chainHeadSub event.Subscription
|
||||||
chainSideCh chan core.ChainSideEvent
|
chainSideCh chan core.ChainSideEvent
|
||||||
chainSideSub event.Subscription
|
chainSideSub event.Subscription
|
||||||
wg sync.WaitGroup
|
resetCh chan time.Duration // Channel to request timer resets
|
||||||
|
|
||||||
|
wg sync.WaitGroup
|
||||||
|
|
||||||
agents map[Agent]struct{}
|
agents map[Agent]struct{}
|
||||||
recv chan *Result
|
recv chan *Result
|
||||||
|
|
@ -158,6 +160,7 @@ func newWorker(config *params.ChainConfig, engine consensus.Engine, coinbase com
|
||||||
txsCh: make(chan core.NewTxsEvent, txChanSize),
|
txsCh: make(chan core.NewTxsEvent, txChanSize),
|
||||||
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
|
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
|
||||||
chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize),
|
chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize),
|
||||||
|
resetCh: make(chan time.Duration, 1),
|
||||||
chainDb: eth.ChainDb(),
|
chainDb: eth.ChainDb(),
|
||||||
recv: make(chan *Result, resultQueueSize),
|
recv: make(chan *Result, resultQueueSize),
|
||||||
chain: eth.BlockChain(),
|
chain: eth.BlockChain(),
|
||||||
|
|
@ -273,6 +276,7 @@ func (self *worker) update() {
|
||||||
minePeriod := 2
|
minePeriod := 2
|
||||||
MinePeriodCh := self.engine.(*XDPoS.XDPoS).MinePeriodCh
|
MinePeriodCh := self.engine.(*XDPoS.XDPoS).MinePeriodCh
|
||||||
defer close(MinePeriodCh)
|
defer close(MinePeriodCh)
|
||||||
|
NewRoundCh := self.engine.(*XDPoS.XDPoS).NewRoundCh
|
||||||
|
|
||||||
timeout := time.NewTimer(time.Duration(minePeriod) * time.Second)
|
timeout := time.NewTimer(time.Duration(minePeriod) * time.Second)
|
||||||
c := make(chan struct{})
|
c := make(chan struct{})
|
||||||
|
|
@ -283,6 +287,16 @@ func (self *worker) update() {
|
||||||
for {
|
for {
|
||||||
// A real event arrived, process interesting content
|
// A real event arrived, process interesting content
|
||||||
select {
|
select {
|
||||||
|
case d := <-self.resetCh:
|
||||||
|
// Reset the timer to the new duration.
|
||||||
|
if !timeout.Stop() {
|
||||||
|
// Drain the timer channel if it had already expired.
|
||||||
|
select {
|
||||||
|
case <-timeout.C:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeout.Reset(d)
|
||||||
case <-timeout.C:
|
case <-timeout.C:
|
||||||
c <- struct{}{}
|
c <- struct{}{}
|
||||||
case <-finish:
|
case <-finish:
|
||||||
|
|
@ -291,26 +305,31 @@ func (self *worker) update() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
prevReset0TimeMillisec := int64(0)
|
|
||||||
// A real event arrived, process interesting content
|
// A real event arrived, process interesting content
|
||||||
select {
|
select {
|
||||||
case v := <-MinePeriodCh:
|
case v := <-MinePeriodCh:
|
||||||
log.Info("[worker] update wait period", "period", v)
|
log.Info("[worker] update wait period", "period", v)
|
||||||
minePeriod = v
|
minePeriod = v
|
||||||
timeout.Reset(time.Duration(minePeriod) * time.Second)
|
self.resetCh <- time.Duration(minePeriod) * time.Second
|
||||||
|
|
||||||
case <-c:
|
case <-c:
|
||||||
if atomic.LoadInt32(&self.mining) == 1 {
|
if atomic.LoadInt32(&self.mining) == 1 {
|
||||||
self.commitNewWork()
|
self.commitNewWork()
|
||||||
}
|
}
|
||||||
resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec)
|
resetTime := getResetTime(self.chain, minePeriod)
|
||||||
timeout.Reset(resetTime)
|
self.resetCh <- resetTime
|
||||||
|
|
||||||
// Handle ChainHeadEvent
|
// Handle ChainHeadEvent
|
||||||
case <-self.chainHeadCh:
|
case <-self.chainHeadCh:
|
||||||
self.commitNewWork()
|
self.commitNewWork()
|
||||||
resetTime := getResetTime(self.chain, minePeriod, &prevReset0TimeMillisec)
|
resetTime := getResetTime(self.chain, minePeriod)
|
||||||
timeout.Reset(resetTime)
|
self.resetCh <- resetTime
|
||||||
|
|
||||||
|
// Handle new round
|
||||||
|
case <-NewRoundCh:
|
||||||
|
self.commitNewWork()
|
||||||
|
resetTime := getResetTime(self.chain, minePeriod)
|
||||||
|
self.resetCh <- resetTime
|
||||||
|
|
||||||
// Handle ChainSideEvent
|
// Handle ChainSideEvent
|
||||||
case <-self.chainSideCh:
|
case <-self.chainSideCh:
|
||||||
|
|
@ -357,27 +376,15 @@ func (self *worker) update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getResetTime(chain *core.BlockChain, minePeriod int, prevReset0TimeMillisec *int64) time.Duration {
|
func getResetTime(chain *core.BlockChain, minePeriod int) time.Duration {
|
||||||
minePeriodDuration := time.Duration(minePeriod) * time.Second
|
minePeriodDuration := time.Duration(minePeriod) * time.Second
|
||||||
currentBlockTime := chain.CurrentBlock().Time().Int64()
|
currentBlockTime := chain.CurrentBlock().Time().Int64()
|
||||||
nowTime := time.Now().UnixMilli()
|
nowTime := time.Now().UnixMilli()
|
||||||
resetTime := time.Duration(currentBlockTime)*time.Second + minePeriodDuration - time.Duration(nowTime)*time.Millisecond
|
resetTime := time.Duration(currentBlockTime)*time.Second + minePeriodDuration - time.Duration(nowTime)*time.Millisecond
|
||||||
// in case the current block time is not very accurate
|
// in case the current block time is not very accurate
|
||||||
if resetTime > minePeriodDuration {
|
if resetTime > minePeriodDuration || resetTime <= 0 {
|
||||||
resetTime = minePeriodDuration
|
resetTime = minePeriodDuration
|
||||||
}
|
}
|
||||||
// in case the current block is too far in the past, the block time already is huge, we wait for mine period
|
|
||||||
if resetTime < 0 {
|
|
||||||
resetTime = minePeriodDuration
|
|
||||||
}
|
|
||||||
if resetTime == 0 {
|
|
||||||
if nowTime == *prevReset0TimeMillisec {
|
|
||||||
// in case it resets to 0 in one millisecond too many times, we wait for mine period
|
|
||||||
resetTime = minePeriodDuration
|
|
||||||
} else {
|
|
||||||
*prevReset0TimeMillisec = nowTime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Debug("[update] Miner worker timer reset", "resetMilliseconds", resetTime.Milliseconds(), "minePeriodSec", minePeriod, "currentBlockTimeSec", fmt.Sprintf("%d", currentBlockTime), "currentSystemTimeSec", fmt.Sprintf("%d.%03d", nowTime/1000, nowTime%1000))
|
log.Debug("[update] Miner worker timer reset", "resetMilliseconds", resetTime.Milliseconds(), "minePeriodSec", minePeriod, "currentBlockTimeSec", fmt.Sprintf("%d", currentBlockTime), "currentSystemTimeSec", fmt.Sprintf("%d.%03d", nowTime/1000, nowTime%1000))
|
||||||
return resetTime
|
return resetTime
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue