From f0fbb2d8ffe6543f23695e648e532f3746612d7d Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 18 Jun 2020 21:35:17 +0300 Subject: [PATCH] core: prevent panic on forced exit If we're to close the Blockchain while it's storing a block this might happen: panic: assignment to entry in nil map goroutine 63 [running]: github.com/nspcc-dev/neo-go/pkg/core/storage.(*MemoryStore).put(...) /home/rik/dev/neo-go/pkg/core/storage/memory_store.go:53 github.com/nspcc-dev/neo-go/pkg/core/storage.(*MemCachedStore).Persist(0xc000673a40, 0x0, 0x0, 0x0) /home/rik/dev/neo-go/pkg/core/storage/memcached_store.go:118 +0x245 github.com/nspcc-dev/neo-go/pkg/core/dao.(*Simple).Persist(0xc003dbdcc0, 0xc003b18900, 0xc002505538, 0xc001c510e0) /home/rik/dev/neo-go/pkg/core/dao/dao.go:543 +0x2e github.com/nspcc-dev/neo-go/pkg/core/dao.(*Cached).Persist(0xc003b189c0, 0xc000240000, 0x0, 0x0) /home/rik/dev/neo-go/pkg/core/dao/cacheddao.go:169 +0x756 github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).storeBlock(0xc0001f4000, 0xc003611040, 0x0, 0x10) /home/rik/dev/neo-go/pkg/core/blockchain.go:647 +0xfa2 github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).AddBlock(0xc0001f4000, 0xc003611040, 0x0, 0x0) /home/rik/dev/neo-go/pkg/core/blockchain.go:447 +0xee github.com/nspcc-dev/neo-go/pkg/network.(*blockQueue).run(0xc0006f4120) /home/rik/dev/neo-go/pkg/network/blockqueue.go:48 +0x158 created by github.com/nspcc-dev/neo-go/pkg/network.(*Server).Start /home/rik/dev/neo-go/pkg/network/server.go:179 +0x2b5 --- pkg/core/blockchain.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 2bb20863d..c4e7b631f 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -408,8 +408,12 @@ func (bc *Blockchain) notificationDispatcher() { // Close stops Blockchain's internal loop, syncs changes to persistent storage // and closes it. The Blockchain is no longer functional after the call to Close. func (bc *Blockchain) Close() { + // If there is a block addition in progress, wait for it to finish and + // don't allow new ones. + bc.addLock.Lock() close(bc.stopCh) <-bc.runToExitCh + bc.addLock.Unlock() } // AddBlock accepts successive block for the Blockchain, verifies it and