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
This commit is contained in:
Roman Khimov 2020-06-18 21:35:17 +03:00
parent bbe174ee4a
commit f0fbb2d8ff

View file

@ -408,8 +408,12 @@ func (bc *Blockchain) notificationDispatcher() {
// Close stops Blockchain's internal loop, syncs changes to persistent storage // 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. // and closes it. The Blockchain is no longer functional after the call to Close.
func (bc *Blockchain) 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) close(bc.stopCh)
<-bc.runToExitCh <-bc.runToExitCh
bc.addLock.Unlock()
} }
// AddBlock accepts successive block for the Blockchain, verifies it and // AddBlock accepts successive block for the Blockchain, verifies it and