diff --git a/pkg/network/blockqueue.go b/pkg/network/blockqueue.go index 179c468a1..a5bb92c42 100644 --- a/pkg/network/blockqueue.go +++ b/pkg/network/blockqueue.go @@ -15,6 +15,12 @@ type blockQueue struct { relayF func(*block.Block) } +const ( + // blockCacheSize is the amount of blocks above current height + // which are stored in queue. + blockCacheSize = 2000 +) + func newBlockQueue(capacity int, bc blockchainer.Blockchainer, log *zap.Logger, relayer func(*block.Block)) *blockQueue { if log == nil { return nil @@ -66,7 +72,8 @@ func (bq *blockQueue) run() { } func (bq *blockQueue) putBlock(block *block.Block) error { - if bq.chain.BlockHeight() >= block.Index { + h := bq.chain.BlockHeight() + if block.Index <= h || h+blockCacheSize < block.Index { // can easily happen when fetching the same blocks from // different peers, thus not considered as error return nil diff --git a/pkg/network/blockqueue_test.go b/pkg/network/blockqueue_test.go index 7141976cf..85382c526 100644 --- a/pkg/network/blockqueue_test.go +++ b/pkg/network/blockqueue_test.go @@ -31,6 +31,9 @@ func TestBlockQueue(t *testing.T) { // but they're still not put into the blockchain, because bq isn't running assert.Equal(t, uint32(0), chain.BlockHeight()) assert.Equal(t, 4, bq.length()) + // block with too big index is dropped + assert.NoError(t, bq.putBlock(&block.Block{Base: block.Base{Index: bq.chain.BlockHeight() + blockCacheSize + 1}})) + assert.Equal(t, 4, bq.length()) go bq.run() // run() is asynchronous, so we need some kind of timeout anyway and this is the simplest one for i := 0; i < 5; i++ {