From 53423b7c3723e04e4c15f313f4327e7950a73e4b Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 22 Apr 2022 14:45:37 +0300 Subject: [PATCH] network: fix panic in blockqueue during shutdown panic: send on closed channel goroutine 116 [running]: github.com/nspcc-dev/neo-go/pkg/network.(*blockQueue).putBlock(0xc00011b650, 0xc01e371200) github.com/nspcc-dev/neo-go/pkg/network/blockqueue.go:129 +0x185 github.com/nspcc-dev/neo-go/pkg/network.(*Server).handleBlockCmd(0xc0002d3c00, {0xf69b7f?, 0xc001520010?}, 0xc02eb44000?) github.com/nspcc-dev/neo-go/pkg/network/server.go:607 +0x6f github.com/nspcc-dev/neo-go/pkg/network.(*Server).handleMessage(0xc0002d3c00, {0x121f4c8?, 0xc001528000?}, 0xc01e35cf80) github.com/nspcc-dev/neo-go/pkg/network/server.go:1160 +0x6c5 github.com/nspcc-dev/neo-go/pkg/network.(*TCPPeer).handleIncoming(0xc001528000) github.com/nspcc-dev/neo-go/pkg/network/tcp_peer.go:189 +0x98 created by github.com/nspcc-dev/neo-go/pkg/network.(*TCPPeer).handleConn github.com/nspcc-dev/neo-go/pkg/network/tcp_peer.go:164 +0xcf --- pkg/network/blockqueue.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/network/blockqueue.go b/pkg/network/blockqueue.go index f3437d912..992ea54c8 100644 --- a/pkg/network/blockqueue.go +++ b/pkg/network/blockqueue.go @@ -105,10 +105,13 @@ func (bq *blockQueue) run() { func (bq *blockQueue) putBlock(block *block.Block) error { h := bq.chain.BlockHeight() bq.queueLock.Lock() + defer bq.queueLock.Unlock() + if bq.discarded.Load() { + return nil + } if block.Index <= h || h+blockCacheSize < block.Index { // can easily happen when fetching the same blocks from // different peers, thus not considered as error - bq.queueLock.Unlock() return nil } pos := indexToPosition(block.Index) @@ -122,7 +125,6 @@ func (bq *blockQueue) putBlock(block *block.Block) error { } } l := bq.len - bq.queueLock.Unlock() // update metrics updateBlockQueueLenMetric(l) select { @@ -142,8 +144,8 @@ func (bq *blockQueue) lastQueued() uint32 { func (bq *blockQueue) discard() { if bq.discarded.CAS(false, true) { - close(bq.checkBlocks) bq.queueLock.Lock() + close(bq.checkBlocks) // Technically we could bq.queue = nil, but this would cost // another if in run(). for i := 0; i < len(bq.queue); i++ {