OSDN Git Service

timeout level
authorpaladz <453256728@qq.com>
Mon, 25 Nov 2019 02:56:33 +0000 (10:56 +0800)
committerpaladz <453256728@qq.com>
Mon, 25 Nov 2019 02:56:33 +0000 (10:56 +0800)
proposal/blockproposer/blockproposer.go
proposal/proposal.go

index 7b7c0c4..3bf2243 100644 (file)
@@ -16,8 +16,11 @@ import (
 )
 
 const (
-       logModule                 = "blockproposer"
-       timeProportionDenominator = 3
+       logModule         = "blockproposer"
+       warnTimeNum       = 2
+       warnTimeDenom     = 5
+       criticalTimeNum   = 4
+       criticalTimeDenom = 5
 )
 
 // BlockProposer propose several block in specified time range
@@ -75,8 +78,9 @@ func (b *BlockProposer) generateBlocks() {
                        continue
                }
 
-               timeoutDuration := time.Duration(consensus.ActiveNetParams.BlockTimeInterval/timeProportionDenominator) * time.Millisecond
-               block, err := proposal.NewBlockTemplate(b.chain, b.accountManager, nextBlockTime, timeoutDuration)
+               warnDuration := time.Duration(consensus.ActiveNetParams.BlockTimeInterval*warnTimeNum/warnTimeDenom) * time.Millisecond
+               criticalDuration := time.Duration(consensus.ActiveNetParams.BlockTimeInterval*criticalTimeNum/criticalTimeDenom) * time.Millisecond
+               block, err := proposal.NewBlockTemplate(b.chain, b.accountManager, nextBlockTime, warnDuration, criticalDuration)
                if err != nil {
                        log.WithFields(log.Fields{"module": logModule, "error": err}).Error("failed on create NewBlockTemplate")
                        continue
index c754412..622e1f1 100644 (file)
@@ -22,11 +22,15 @@ import (
 const (
        logModule     = "mining"
        batchApplyNum = 64
+
+       timeoutOk = iota + 1
+       timeoutWarn
+       timeoutCritical
 )
 
 // NewBlockTemplate returns a new block template that is ready to be solved
-func NewBlockTemplate(chain *protocol.Chain, accountManager *account.Manager, timestamp uint64, timeoutDuration time.Duration) (*types.Block, error) {
-       builder := newBlockBuilder(chain, accountManager, timestamp, timeoutDuration)
+func NewBlockTemplate(chain *protocol.Chain, accountManager *account.Manager, timestamp uint64, warnDuration, criticalDuration time.Duration) (*types.Block, error) {
+       builder := newBlockBuilder(chain, accountManager, timestamp, warnDuration, criticalDuration)
        return builder.build()
 }
 
@@ -38,12 +42,13 @@ type blockBuilder struct {
        txStatus *bc.TransactionStatus
        utxoView *state.UtxoViewpoint
 
-       timeoutCh   <-chan time.Time
-       gasLeft     int64
-       timeoutFlag bool
+       warnTimeoutCh     <-chan time.Time
+       criticalTimeoutCh <-chan time.Time
+       gasLeft           int64
+       timeoutStatus     uint8
 }
 
-func newBlockBuilder(chain *protocol.Chain, accountManager *account.Manager, timestamp uint64, timeoutDuration time.Duration) *blockBuilder {
+func newBlockBuilder(chain *protocol.Chain, accountManager *account.Manager, timestamp uint64, warnDuration, criticalDuration time.Duration) *blockBuilder {
        preBlockHeader := chain.BestBlockHeader()
        block := &types.Block{
                BlockHeader: types.BlockHeader{
@@ -57,13 +62,15 @@ func newBlockBuilder(chain *protocol.Chain, accountManager *account.Manager, tim
        }
 
        builder := &blockBuilder{
-               chain:          chain,
-               accountManager: accountManager,
-               block:          block,
-               txStatus:       bc.NewTransactionStatus(),
-               utxoView:       state.NewUtxoViewpoint(),
-               timeoutCh:      time.After(timeoutDuration),
-               gasLeft:        int64(consensus.ActiveNetParams.MaxBlockGas),
+               chain:             chain,
+               accountManager:    accountManager,
+               block:             block,
+               txStatus:          bc.NewTransactionStatus(),
+               utxoView:          state.NewUtxoViewpoint(),
+               warnTimeoutCh:     time.After(warnDuration),
+               criticalTimeoutCh: time.After(criticalDuration),
+               gasLeft:           int64(consensus.ActiveNetParams.MaxBlockGas),
+               timeoutStatus:     timeoutOk,
        }
        return builder
 }
@@ -111,7 +118,7 @@ func (b *blockBuilder) applyTransactions(txs []*types.Tx) error {
 
                b.gasLeft = gasLeft
                tempTxs = []*types.Tx{}
-               if b.isTimeout() {
+               if b.getTimeoutStatus() == timeoutCritical {
                        break
                }
        }
@@ -136,12 +143,16 @@ func (b *blockBuilder) applyTransactionFromSubProtocol() error {
                return err
        }
 
+       isTimeout := func() bool {
+               return b.getTimeoutStatus() > timeoutOk
+       }
+
        for i, p := range b.chain.SubProtocols() {
-               if b.gasLeft <= 0 || b.isTimeout() {
+               if b.gasLeft <= 0 || isTimeout() {
                        break
                }
 
-               subTxs, err := p.BeforeProposalBlock(b.block.Transactions, cp, b.block.Height, b.gasLeft, b.isTimeout)
+               subTxs, err := p.BeforeProposalBlock(b.block.Transactions, cp, b.block.Height, b.gasLeft, isTimeout)
                if err != nil {
                        log.WithFields(log.Fields{"module": logModule, "index": i, "error": err}).Error("failed on sub protocol txs package")
                        continue
@@ -207,17 +218,27 @@ func (b *blockBuilder) createCoinbaseTx() (*types.Tx, error) {
        return createCoinbaseTxByReward(b.accountManager, b.block.Height, rewards)
 }
 
-func (b *blockBuilder) isTimeout() bool {
-       if b.timeoutFlag {
-               return true
+func (b *blockBuilder) getTimeoutStatus() uint8 {
+       if b.timeoutStatus == timeoutCritical {
+               return b.timeoutStatus
+       }
+
+       select {
+       case <-b.criticalTimeoutCh:
+               b.timeoutStatus = timeoutCritical
+       default:
+       }
+
+       if b.timeoutStatus > timeoutOk {
+               return b.timeoutStatus
        }
 
        select {
-       case <-b.timeoutCh:
-               b.timeoutFlag = true
+       case <-b.warnTimeoutCh:
+               b.timeoutStatus = timeoutWarn
        default:
        }
-       return b.timeoutFlag
+       return b.timeoutStatus
 }
 
 func createCoinbaseTxByReward(accountManager *account.Manager, blockHeight uint64, rewards []state.CoinbaseReward) (tx *types.Tx, err error) {