From de51742a8f9d4473e9b4a2c7429073b7470ed8e2 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Tue, 15 Nov 2022 11:21:33 +0800 Subject: [PATCH 1/7] Add ddos protection to txpool due to real attack --- chain/params.go | 1 + server/server.go | 1 + txpool/txpool.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/chain/params.go b/chain/params.go index cf6bca31dc..9676e20dab 100644 --- a/chain/params.go +++ b/chain/params.go @@ -11,6 +11,7 @@ type Params struct { Engine map[string]interface{} `json:"engine"` BlockGasTarget uint64 `json:"blockGasTarget"` BlackList []string `json:"blackList,omitempty"` + DDOSPretection bool `json:"ddosPretection,omitempty"` } func (p *Params) GetEngine() string { diff --git a/server/server.go b/server/server.go index 94302d9651..b3ad438ae2 100644 --- a/server/server.go +++ b/server/server.go @@ -281,6 +281,7 @@ func NewServer(config *Config) (*Server, error) { PruneTickSeconds: m.config.PruneTickSeconds, PromoteOutdateSeconds: m.config.PromoteOutdateSeconds, BlackList: blackList, + DDOSPretection: m.config.Chain.Params.DDOSPretection, }, ) if err != nil { diff --git a/txpool/txpool.go b/txpool/txpool.go index 9bde3da7db..ceb1a41e2f 100644 --- a/txpool/txpool.go +++ b/txpool/txpool.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "math/big" + "sync" "time" "github.com/dogechain-lab/dogechain/blockchain" @@ -24,6 +25,11 @@ const ( topicNameV1 = "txpool/0.1" ) +const ( + _ddosReduceCount = 10 // contract ddos count reduction + _ddosReduceDuration = 10 * time.Minute // trigger for ddos count reduction +) + // errors var ( ErrIntrinsicGas = errors.New("intrinsic gas too low") @@ -40,6 +46,7 @@ var ( ErrOversizedData = errors.New("oversized data") ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") ErrBlackList = errors.New("address in blacklist") + ErrContractDDOSList = errors.New("contract in ddos list") ) // indicates origin of a transaction @@ -83,6 +90,7 @@ type Config struct { PruneTickSeconds uint64 PromoteOutdateSeconds uint64 BlackList []types.Address + DDOSPretection bool } /* All requests are passed to the main loop @@ -184,6 +192,10 @@ type TxPool struct { // some very bad guys whose txs should never be included blacklist map[types.Address]struct{} + // drop all those ddos contract transactions + ddosPretection bool + ddosReductionTicker *time.Ticker + ddosContracts sync.Map } // NewTxPool returns a new pool for processing incoming transactions. @@ -226,6 +238,7 @@ func NewTxPool( priceLimit: config.PriceLimit, pruneTick: time.Second * time.Duration(pruneTickSeconds), promoteOutdateDuration: time.Second * time.Duration(promoteOutdateSeconds), + ddosPretection: config.DDOSPretection, } pool.SetSealing(config.Sealing) // sealing flag @@ -284,6 +297,7 @@ func (p *TxPool) Start() { p.metrics.SetDefaultValue(0) p.pruneAccountTicker = time.NewTicker(p.pruneTick) + p.ddosReductionTicker = time.NewTicker(_ddosReduceDuration) go func() { for { @@ -302,6 +316,10 @@ func (p *TxPool) Start() { if ok { // readable go p.pruneStaleAccounts() } + case _, ok := <-p.ddosReductionTicker.C: + if ok { + go p.reduceDDOSCounts() + } } } }() @@ -514,6 +532,9 @@ func (p *TxPool) ResetWithHeaders(headers ...*types.Header) { // process the txs in the event // to make sure the pool is up-to-date p.processEvent(e) + + // reduce ddos count + p.reduceDDOSCounts() } // processEvent collects the latest nonces for each account containted @@ -666,11 +687,56 @@ func (p *TxPool) validateTx(tx *types.Transaction) error { return nil } +func (p *TxPool) IsDDOSTx(tx *types.Transaction) bool { + if !p.ddosPretection || tx.To == nil { + return false + } + + count, exists := p.ddosContracts.Load(*tx.To) + //nolint:forcetypeassert + if exists && count.(int) > 0 { + return true + } + + return false +} + +func (p *TxPool) MarkDDOSTx(tx *types.Transaction, count int) { + if !p.ddosPretection || tx.To == nil { + return + } + + // update its ddos count + old, _ := p.ddosContracts.Load(*tx.To) + oldCount, _ := old.(int) + p.ddosContracts.Store(*tx.To, oldCount+count) +} + +// reduceDDOSCounts reduces might-be misunderstanding of ddos attack +func (p *TxPool) reduceDDOSCounts() { + p.ddosContracts.Range(func(key, value interface{}) bool { + count, _ := value.(int) + + count -= _ddosReduceCount + if count < 0 { + count = 0 + } + + p.ddosContracts.Store(key, count) + + return true + }) +} + // addTx is the main entry point to the pool // for all new transactions. If the call is // successful, an account is created for this address // (only once) and an enqueueRequest is signaled. func (p *TxPool) addTx(origin txOrigin, tx *types.Transaction) error { + if p.IsDDOSTx(tx) { + return ErrContractDDOSList + } + // get the hash already from the very beginning p.logger.Debug("add tx", "origin", origin.String(), From 9a8a5f12a4835c40973bc3f18fb758119e2229fc Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Tue, 15 Nov 2022 12:10:02 +0800 Subject: [PATCH 2/7] Use ddos threshold to those marked contract transactions --- txpool/txpool.go | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/txpool/txpool.go b/txpool/txpool.go index ceb1a41e2f..eaf1184b8f 100644 --- a/txpool/txpool.go +++ b/txpool/txpool.go @@ -26,8 +26,9 @@ const ( ) const ( - _ddosReduceCount = 10 // contract ddos count reduction - _ddosReduceDuration = 10 * time.Minute // trigger for ddos count reduction + _ddosThreshold = 3 // >= 3/minute is a ddos attack + _ddosReduceCount = 5 // contract ddos count reduction + _ddosReduceDuration = 1 * time.Minute // trigger for ddos count reduction ) // errors @@ -192,10 +193,10 @@ type TxPool struct { // some very bad guys whose txs should never be included blacklist map[types.Address]struct{} - // drop all those ddos contract transactions - ddosPretection bool - ddosReductionTicker *time.Ticker - ddosContracts sync.Map + // ddos protection fields + ddosPretection bool // enable ddos protection + ddosReductionTicker *time.Ticker // ddos reduction ticker for releasing from imprisonment + ddosContracts sync.Map // ddos contract caching } // NewTxPool returns a new pool for processing incoming transactions. @@ -327,6 +328,7 @@ func (p *TxPool) Start() { // Close shuts down the pool's main loop. func (p *TxPool) Close() { + p.ddosReductionTicker.Stop() p.pruneAccountTicker.Stop() p.eventManager.Close() // stop @@ -532,9 +534,6 @@ func (p *TxPool) ResetWithHeaders(headers ...*types.Header) { // process the txs in the event // to make sure the pool is up-to-date p.processEvent(e) - - // reduce ddos count - p.reduceDDOSCounts() } // processEvent collects the latest nonces for each account containted @@ -687,6 +686,7 @@ func (p *TxPool) validateTx(tx *types.Transaction) error { return nil } +// IsDDOSTx returns whether a contract transaction marks as ddos attack func (p *TxPool) IsDDOSTx(tx *types.Transaction) bool { if !p.ddosPretection || tx.To == nil { return false @@ -694,22 +694,24 @@ func (p *TxPool) IsDDOSTx(tx *types.Transaction) bool { count, exists := p.ddosContracts.Load(*tx.To) //nolint:forcetypeassert - if exists && count.(int) > 0 { + if exists && count.(int) > _ddosThreshold { return true } return false } -func (p *TxPool) MarkDDOSTx(tx *types.Transaction, count int) { +// MarkDDOSTx marks resource consuming transaction as a might-be attack +func (p *TxPool) MarkDDOSTx(tx *types.Transaction) { if !p.ddosPretection || tx.To == nil { return } // update its ddos count - old, _ := p.ddosContracts.Load(*tx.To) - oldCount, _ := old.(int) - p.ddosContracts.Store(*tx.To, oldCount+count) + v, _ := p.ddosContracts.Load(*tx.To) + count, _ := v.(int) + count++ + p.ddosContracts.Store(*tx.To, count) } // reduceDDOSCounts reduces might-be misunderstanding of ddos attack From 30ab6e149db51ca4fb189b3a324e62f06ca47c2f Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Tue, 15 Nov 2022 14:23:27 +0800 Subject: [PATCH 3/7] Banish contract transactions due to ddos attack instead of resource exhaustring --- consensus/ibft/hooks.go | 1 - consensus/ibft/ibft.go | 100 +++++++++++++++++++++------------------- txpool/txpool.go | 13 ++++++ 3 files changed, 65 insertions(+), 49 deletions(-) diff --git a/consensus/ibft/hooks.go b/consensus/ibft/hooks.go index 758e1c15f4..aeb3b5e8d3 100644 --- a/consensus/ibft/hooks.go +++ b/consensus/ibft/hooks.go @@ -9,7 +9,6 @@ import ( const ( KeyType = "type" KeyEpochSize = "epochSize" - KeyBanishAbnormalContract = "banishAbnormalContract" ) // Define the type of the IBFT consensus diff --git a/consensus/ibft/ibft.go b/consensus/ibft/ibft.go index 0ac614b4aa..899e8ded20 100644 --- a/consensus/ibft/ibft.go +++ b/consensus/ibft/ibft.go @@ -31,8 +31,9 @@ import ( ) const ( - DefaultEpochSize = 100000 - DefaultBanishAbnormalContract = false // banish abnormal contract whose execution consumes too much time. + DefaultEpochSize = 100000 + // banish abnormal contract whose execution consumes too much time + DefaultBanishAbnormalContract = false ) var ( @@ -54,7 +55,13 @@ type blockchainInterface interface { CalculateGasLimit(number uint64) (uint64, error) } +type ddosProtectionInterface interface { + IsDDOSTx(tx *types.Transaction) bool + MarkDDOSTx(tx *types.Transaction) +} + type txPoolInterface interface { + ddosProtectionInterface Drop(tx *types.Transaction) DemoteAllPromoted(tx *types.Transaction, correctNonce uint64) ResetWithHeaders(headers ...*types.Header) @@ -116,9 +123,9 @@ type Ibft struct { // Dynamic References for signing and validating currentTxSigner crypto.TxSigner // Tx Signer at current sequence currentValidators validator.Validators // Validator set at current sequence - // for banishing some exhausting contracts - banishAbnormalContract bool - exhaustingContracts map[types.Address]struct{} + // Recording resource exhausting contracts + // but would not banish it until it became a real ddos attack + exhaustingContracts map[types.Address]struct{} } // runHook runs a specified hook if it is present in the hook map @@ -170,36 +177,23 @@ func Factory( } } - var banishAbnormalContract bool - if definedBanish, ok := params.Config.Config[KeyBanishAbnormalContract]; !ok { - banishAbnormalContract = DefaultBanishAbnormalContract - } else { - banish, ok := definedBanish.(bool) - if !ok { - return nil, errors.New("banishAbnormalContract invalid type assertion") - } - - banishAbnormalContract = banish - } - p := &Ibft{ - logger: params.Logger.Named("ibft"), - config: params.Config, - Grpc: params.Grpc, - blockchain: params.Blockchain, - executor: params.Executor, - closeCh: make(chan struct{}), - isClosed: atomic.NewBool(false), - txpool: params.Txpool, - state: ¤tstate.CurrentState{}, - network: params.Network, - epochSize: epochSize, - sealing: params.Seal, - metrics: params.Metrics, - secretsManager: params.SecretsManager, - blockTime: time.Duration(params.BlockTime) * time.Second, - banishAbnormalContract: banishAbnormalContract, - exhaustingContracts: make(map[types.Address]struct{}), + logger: params.Logger.Named("ibft"), + config: params.Config, + Grpc: params.Grpc, + blockchain: params.Blockchain, + executor: params.Executor, + closeCh: make(chan struct{}), + isClosed: atomic.NewBool(false), + txpool: params.Txpool, + state: ¤tstate.CurrentState{}, + network: params.Network, + epochSize: epochSize, + sealing: params.Seal, + metrics: params.Metrics, + secretsManager: params.SecretsManager, + blockTime: time.Duration(params.BlockTime) * time.Second, + exhaustingContracts: make(map[types.Address]struct{}), } // Initialize the mechanism @@ -936,12 +930,18 @@ func (i *Ibft) writeTransactions( break } - if i.shouldBanishTx(tx) { - i.logger.Info("banish some exausting contract and drop all sender transactions", + if i.shouldMarkLongConsumingTx(tx) { + // count attack + i.countDDOSAttack(tx) + } + + if i.txpool.IsDDOSTx(tx) { + i.logger.Info("drop ddos attack contract transactions", "address", tx.To, "from", tx.From, ) + // drop tx shouldDropTxs = append(shouldDropTxs, tx) continue @@ -963,7 +963,8 @@ func (i *Ibft) writeTransactions( begin := time.Now() // for duration calculation if err := transition.Write(tx); err != nil { - i.banishLongTimeConsumingTx(tx, begin) + // mark long time consuming contract to prevent ddos attack + i.markLongTimeConsumingContract(tx, begin) i.logger.Debug("write transaction failed", "hash", tx.Hash, "from", tx.From, "nonce", tx.Nonce, "err", err) @@ -1006,7 +1007,8 @@ func (i *Ibft) writeTransactions( // no errors, go on priceTxs.Shift() - i.banishLongTimeConsumingTx(tx, begin) + // mark long time consuming contract to prevent ddos attack + i.markLongTimeConsumingContract(tx, begin) includedTransactions = append(includedTransactions, tx) } @@ -1024,34 +1026,36 @@ func (i *Ibft) shouldTerminate(terminalTime time.Time) bool { return time.Now().After(terminalTime) } -func (i *Ibft) shouldBanishTx(tx *types.Transaction) bool { - if !i.banishAbnormalContract || tx.To == nil { +func (i *Ibft) shouldMarkLongConsumingTx(tx *types.Transaction) bool { + if tx.To == nil { return false } - // if tx send to some banish contract, drop it - _, shouldBanish := i.exhaustingContracts[*tx.To] + _, exists := i.exhaustingContracts[*tx.To] + + return exists +} - return shouldBanish +func (i *Ibft) countDDOSAttack(tx *types.Transaction) { + i.txpool.MarkDDOSTx(tx) } -func (i *Ibft) banishLongTimeConsumingTx(tx *types.Transaction, begin time.Time) { +func (i *Ibft) markLongTimeConsumingContract(tx *types.Transaction, begin time.Time) { duration := time.Since(begin).Milliseconds() - if duration < i.blockTime.Milliseconds() || - tx.To == nil { // long contract creation is tolerable + // long contract creation is tolerable, long time execution is not tolerable + if tx.To == nil || duration < i.blockTime.Milliseconds() { return } // banish the contract i.exhaustingContracts[*tx.To] = struct{}{} - i.logger.Info("banish contract who consumes too many CPU time", + i.logger.Info("mark contract who consumes too many CPU or I/O time", "duration", duration, "from", tx.From, "to", tx.To, "gasPrice", tx.GasPrice, "gas", tx.Gas, - "len", len(tx.Input), ) } diff --git a/txpool/txpool.go b/txpool/txpool.go index eaf1184b8f..4087768422 100644 --- a/txpool/txpool.go +++ b/txpool/txpool.go @@ -712,12 +712,20 @@ func (p *TxPool) MarkDDOSTx(tx *types.Transaction) { count, _ := v.(int) count++ p.ddosContracts.Store(*tx.To, count) + + p.logger.Debug("increase ddos contract transaction count", + "address", tx.To, + "count", count, + ) } // reduceDDOSCounts reduces might-be misunderstanding of ddos attack func (p *TxPool) reduceDDOSCounts() { p.ddosContracts.Range(func(key, value interface{}) bool { count, _ := value.(int) + if count <= 0 { + return true + } count -= _ddosReduceCount if count < 0 { @@ -726,6 +734,11 @@ func (p *TxPool) reduceDDOSCounts() { p.ddosContracts.Store(key, count) + p.logger.Debug("decrease ddos contract transaction count", + "address", key, + "count", count, + ) + return true }) } From 4a0d3a5bd8686d8555a3c7a8628b21de2fd2ebfa Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Tue, 15 Nov 2022 14:23:51 +0800 Subject: [PATCH 4/7] Fix test case error --- consensus/ibft/ibft_test.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/consensus/ibft/ibft_test.go b/consensus/ibft/ibft_test.go index 02ade275c1..ad0b91943a 100644 --- a/consensus/ibft/ibft_test.go +++ b/consensus/ibft/ibft_test.go @@ -1044,6 +1044,7 @@ type mockTxPool struct { nonceDecreased map[*types.Transaction]bool resetWithHeaderCalled bool resetWithHeadersParam []*types.Header + ddosContracts map[types.Address]bool } func newMockTxPool(txs []*types.Transaction) *mockTxPool { @@ -1088,6 +1089,20 @@ func (p *mockTxPool) Pending() map[types.Address][]*types.Transaction { return txs } +func (p *mockTxPool) IsDDOSTx(tx *types.Transaction) bool { + if tx.To == nil { + return false + } + + _, exists := p.ddosContracts[*tx.To] + + return exists +} + +func (p *mockTxPool) MarkDDOSTx(tx *types.Transaction) { + p.ddosContracts[*tx.To] = true +} + type mockTransition struct { failReceiptsWritten []*types.Transaction shouldDroppedTransactions []*types.Transaction @@ -1792,7 +1807,7 @@ func Test_increaseHeaderGasIfNeeded(t *testing.T) { assert.Equal(t, uint64(155000), header.GasLimit) } -func Test_shouldBanishTx(t *testing.T) { +func Test_shouldMarkLongConsumingTx(t *testing.T) { mockTx := &types.Transaction{ Nonce: 0, GasPrice: big.NewInt(1000), @@ -1804,13 +1819,12 @@ func Test_shouldBanishTx(t *testing.T) { } i := newMockIbft(t, []string{"A", "B", "C", "D"}, "A") - i.Ibft.banishAbnormalContract = true i.Ibft.exhaustingContracts[addr2] = struct{}{} - assert.True(t, i.shouldBanishTx(mockTx)) + assert.True(t, i.shouldMarkLongConsumingTx(mockTx)) } -func Test_banishLongTimeConsumingTx(t *testing.T) { +func Test_markLongTimeConsumingContract(t *testing.T) { mockTx := &types.Transaction{ Nonce: 0, GasPrice: big.NewInt(1000), @@ -1822,12 +1836,11 @@ func Test_banishLongTimeConsumingTx(t *testing.T) { } i := newMockIbft(t, []string{"A", "B", "C", "D"}, "A") - i.Ibft.banishAbnormalContract = true // make sure begin time out what we set begin := time.Now().Add(-1*i.blockTime - 1) - i.banishLongTimeConsumingTx(mockTx, begin) + i.markLongTimeConsumingContract(mockTx, begin) assert.Equal( t, From 159069ef722c4f00d3de154dc16b80b9b74aaef6 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Tue, 15 Nov 2022 14:33:21 +0800 Subject: [PATCH 5/7] Fix typo --- consensus/ibft/ibft.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/ibft/ibft.go b/consensus/ibft/ibft.go index 899e8ded20..179424789d 100644 --- a/consensus/ibft/ibft.go +++ b/consensus/ibft/ibft.go @@ -936,7 +936,7 @@ func (i *Ibft) writeTransactions( } if i.txpool.IsDDOSTx(tx) { - i.logger.Info("drop ddos attack contract transactions", + i.logger.Info("drop ddos attack contract transaction", "address", tx.To, "from", tx.From, ) From ea73353f27de61dea5c61d527d866ba2e36cd6c0 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Tue, 15 Nov 2022 14:55:02 +0800 Subject: [PATCH 6/7] Refactor system transactions writing --- consensus/ibft/ibft.go | 117 ++++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 37 deletions(-) diff --git a/consensus/ibft/ibft.go b/consensus/ibft/ibft.go index 179424789d..e0c610c3be 100644 --- a/consensus/ibft/ibft.go +++ b/consensus/ibft/ibft.go @@ -708,47 +708,12 @@ func (i *Ibft) buildBlock(snap *Snapshot, parent *types.Header) (*types.Block, e // insert system transactions at last to ensure it works if i.shouldWriteSystemTransactions(header.Number) { - txn := transition.Txn() - - // make slash tx if needed - if i.currentRound() > 0 { - // only punish the first validator - lastBlockProposer, _ := ecrecoverFromHeader(parent) - - needPunished := i.state.CalcNeedPunished(i.currentRound(), lastBlockProposer) - if len(needPunished) > 0 { - tx, err := i.makeTransitionSlashTx(txn, header.Number, needPunished[0]) - if err != nil { - return nil, err - } - - // system transaction, increase gas limit if needed - increaseHeaderGasIfNeeded(transition, header, tx) - - // execute slash tx - if err := transition.Write(tx); err != nil { - return nil, err - } - - txs = append(txs, tx) - } - } - - // make deposit tx - tx, err := i.makeTransitionDepositTx(transition.Txn(), header.Number) + systemTxs, err := i.writeSystemTxs(transition, parent, header) if err != nil { return nil, err } - // system transaction, increase gas limit if needed - increaseHeaderGasIfNeeded(transition, header, tx) - - // execute deposit tx - if err := transition.Write(tx); err != nil { - return nil, err - } - - txs = append(txs, tx) + txs = append(txs, systemTxs...) } if err := i.PreStateCommit(header, transition); err != nil { @@ -798,6 +763,84 @@ func (i *Ibft) buildBlock(snap *Snapshot, parent *types.Header) (*types.Block, e return block, nil } +func (i *Ibft) writeSystemSlashTx( + transition *state.Transition, + parent, header *types.Header, +) (*types.Transaction, error) { + if i.currentRound() == 0 { + // no need slashing + return nil, nil + } + + // only punish the first validator + lastBlockProposer, _ := ecrecoverFromHeader(parent) + + needPunished := i.state.CalcNeedPunished(i.currentRound(), lastBlockProposer) + if len(needPunished) == 0 { + // it shouldn't be, but we still need to prevent overwhelming + return nil, nil + } + + tx, err := i.makeTransitionSlashTx(transition.Txn(), header.Number, needPunished[0]) + if err != nil { + return nil, err + } + + // system transaction, increase gas limit if needed + increaseHeaderGasIfNeeded(transition, header, tx) + + // execute slash tx + if err := transition.Write(tx); err != nil { + return nil, err + } + + return tx, nil +} + +func (i *Ibft) writeSystemDepositTx( + transition *state.Transition, + header *types.Header, +) (*types.Transaction, error) { + // make deposit tx + tx, err := i.makeTransitionDepositTx(transition.Txn(), header.Number) + if err != nil { + return nil, err + } + + // system transaction, increase gas limit if needed + increaseHeaderGasIfNeeded(transition, header, tx) + + // execute deposit tx + if err := transition.Write(tx); err != nil { + return nil, err + } + + return tx, nil +} + +func (i *Ibft) writeSystemTxs( + transition *state.Transition, + parent, header *types.Header, +) (txs []*types.Transaction, err error) { + // slash transaction + slashTx, err := i.writeSystemSlashTx(transition, parent, header) + if err != nil { + return nil, err + } else if slashTx != nil { + txs = append(txs, slashTx) + } + + // deposit transaction + depositTx, err := i.writeSystemDepositTx(transition, header) + if err != nil { + return nil, err + } + + txs = append(txs, depositTx) + + return txs, nil +} + func increaseHeaderGasIfNeeded(transition *state.Transition, header *types.Header, tx *types.Transaction) { if transition.TotalGas()+tx.Gas <= header.GasLimit { return From 1c852d1feda80ee2dccb3185af068855c7931dce Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Tue, 15 Nov 2022 16:49:41 +0800 Subject: [PATCH 7/7] Fix lint error --- consensus/ibft/hooks.go | 4 ++-- consensus/ibft/ibft.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/consensus/ibft/hooks.go b/consensus/ibft/hooks.go index aeb3b5e8d3..fbdde60c3a 100644 --- a/consensus/ibft/hooks.go +++ b/consensus/ibft/hooks.go @@ -7,8 +7,8 @@ import ( ) const ( - KeyType = "type" - KeyEpochSize = "epochSize" + KeyType = "type" + KeyEpochSize = "epochSize" ) // Define the type of the IBFT consensus diff --git a/consensus/ibft/ibft.go b/consensus/ibft/ibft.go index e0c610c3be..59af8c8bf8 100644 --- a/consensus/ibft/ibft.go +++ b/consensus/ibft/ibft.go @@ -1602,6 +1602,7 @@ func (i *Ibft) runRoundChangeState() { for i.getState() == currentstate.RoundChangeState { // timeout should update every time it enters a new round timeout := i.state.MessageTimeout() + msg, ok := i.getNextMessage(timeout) if !ok { // closing