From 1dac45bbbb1e3561cec65973cd503aea7156606c Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Thu, 10 Nov 2022 14:31:49 +0300 Subject: [PATCH] core: add ability to check whether blockchain is running --- pkg/core/blockchain.go | 5 +++++ pkg/core/blockchain_core_test.go | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 08bce558b..d913847b2 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -151,6 +151,8 @@ type Blockchain struct { // Stop synchronization mechanisms. stopCh chan struct{} runToExitCh chan struct{} + // isRunning denotes whether blockchain routines are currently running. + isRunning atomic.Value memPool *mempool.Pool @@ -302,6 +304,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L return nil, err } + bc.isRunning.Store(false) return bc, nil } @@ -658,6 +661,7 @@ func (bc *Blockchain) initializeNativeCache(blockHeight uint32, d *dao.Simple) e // Run runs chain loop, it needs to be run as goroutine and executing it is // critical for correct Blockchain operation. func (bc *Blockchain) Run() { + bc.isRunning.Store(true) persistTimer := time.NewTimer(persistInterval) defer func() { persistTimer.Stop() @@ -667,6 +671,7 @@ func (bc *Blockchain) Run() { if err := bc.dao.Store.Close(); err != nil { bc.log.Warn("failed to close db", zap.Error(err)) } + bc.isRunning.Store(false) close(bc.runToExitCh) }() go bc.notificationDispatcher() diff --git a/pkg/core/blockchain_core_test.go b/pkg/core/blockchain_core_test.go index 8ef59604e..c7f652a63 100644 --- a/pkg/core/blockchain_core_test.go +++ b/pkg/core/blockchain_core_test.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "strings" + "sync/atomic" "testing" "time" @@ -340,3 +341,20 @@ func TestBlockchain_BaseExecFeeBaseStoragePrice_Compat(t *testing.T) { check(t) }) } + +func TestBlockchain_IsRunning(t *testing.T) { + chain := initTestChain(t, nil, nil) + require.False(t, chain.isRunning.Load().(bool)) + oldPersisted := atomic.LoadUint32(&chain.persistedHeight) + + go chain.Run() + require.NoError(t, chain.AddBlock(chain.newBlock())) + require.Eventually(t, func() bool { + persisted := atomic.LoadUint32(&chain.persistedHeight) + return persisted > oldPersisted + }, 2*persistInterval, 100*time.Millisecond) + require.True(t, chain.isRunning.Load().(bool)) + + chain.Close() + require.False(t, chain.isRunning.Load().(bool)) +}