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
This commit is contained in:
Roman Khimov 2022-04-22 14:45:37 +03:00
parent 887fe0634d
commit 53423b7c37

View file

@ -105,10 +105,13 @@ func (bq *blockQueue) run() {
func (bq *blockQueue) putBlock(block *block.Block) error { func (bq *blockQueue) putBlock(block *block.Block) error {
h := bq.chain.BlockHeight() h := bq.chain.BlockHeight()
bq.queueLock.Lock() bq.queueLock.Lock()
defer bq.queueLock.Unlock()
if bq.discarded.Load() {
return nil
}
if block.Index <= h || h+blockCacheSize < block.Index { if block.Index <= h || h+blockCacheSize < block.Index {
// can easily happen when fetching the same blocks from // can easily happen when fetching the same blocks from
// different peers, thus not considered as error // different peers, thus not considered as error
bq.queueLock.Unlock()
return nil return nil
} }
pos := indexToPosition(block.Index) pos := indexToPosition(block.Index)
@ -122,7 +125,6 @@ func (bq *blockQueue) putBlock(block *block.Block) error {
} }
} }
l := bq.len l := bq.len
bq.queueLock.Unlock()
// update metrics // update metrics
updateBlockQueueLenMetric(l) updateBlockQueueLenMetric(l)
select { select {
@ -142,8 +144,8 @@ func (bq *blockQueue) lastQueued() uint32 {
func (bq *blockQueue) discard() { func (bq *blockQueue) discard() {
if bq.discarded.CAS(false, true) { if bq.discarded.CAS(false, true) {
close(bq.checkBlocks)
bq.queueLock.Lock() bq.queueLock.Lock()
close(bq.checkBlocks)
// Technically we could bq.queue = nil, but this would cost // Technically we could bq.queue = nil, but this would cost
// another if in run(). // another if in run().
for i := 0; i < len(bq.queue); i++ { for i := 0; i < len(bq.queue); i++ {