)
const (
- logModule = "blockproposer"
- timeProportionDenominator = 3
+ logModule = "blockproposer"
+ warnTimeNum = 2
+ warnTimeDenom = 5
+ criticalTimeNum = 4
+ criticalTimeDenom = 5
)
// BlockProposer propose several block in specified time range
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
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()
}
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{
}
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
}
b.gasLeft = gasLeft
tempTxs = []*types.Tx{}
- if b.isTimeout() {
+ if b.getTimeoutStatus() == timeoutCritical {
break
}
}
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
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) {