Skip to content

Commit

Permalink
core: fix restoring chain with StateRootInHeader = true
Browse files Browse the repository at this point in the history
Close #3597

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
  • Loading branch information
AliceInHunterland committed Nov 22, 2024
1 parent cdbc026 commit 5fec492
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 3 deletions.
72 changes: 72 additions & 0 deletions pkg/core/blockchain_core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import (
"github.com/nspcc-dev/neo-go/internal/testchain"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/chaindump"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util"
Expand Down Expand Up @@ -414,3 +416,73 @@ func TestNewBlockchain_InitHardforks(t *testing.T) {
}, bc.GetConfig().Hardforks)
})
}

type nopCloserStorage struct {
storage.Store
}

func (nopCloserStorage) Close() error {
return nil
}

func TestBlockchainRestoreStateRootInHeader(t *testing.T) {
bc := newTestChainWithCustomCfg(t, func(c *config.Config) {
c.ProtocolConfiguration.StateRootInHeader = true
})
require.NoError(t, bc.AddBlock(bc.newBlock()))
require.NoError(t, bc.AddBlock(bc.newBlock()))
require.NoError(t, bc.AddBlock(bc.newBlock()))

w := io.NewBufBinWriter()
require.NoError(t, chaindump.Dump(bc, w.BinWriter, 0, 4))
require.NoError(t, w.Err)

data := w.Bytes()
fcfg := func(c *config.Config) { c.ProtocolConfiguration.StateRootInHeader = true }
initChain := func(st storage.Store) *Blockchain {
chain := initTestChain(t, st, fcfg)
go chain.Run()
return chain
}

t.Run("empty MemoryStore", func(t *testing.T) {
bc := initChain(storage.NewMemoryStore())
r := io.NewBinReaderFromBuf(data)
require.NoError(t, chaindump.Restore(bc, r, 0, 4, nil))
bc.Close()
})
t.Run("not empty MemoryStore, one block", func(t *testing.T) {
st := nopCloserStorage{Store: storage.NewMemoryStore()}

bc := initChain(st)
r := io.NewBinReaderFromBuf(data)
require.NoError(t, chaindump.Restore(bc, r, 0, 1, nil))
expected := bc.stateRoot.CurrentLocalStateRoot()
bc.Close()

bc = initChain(st)
actual := bc.stateRoot.CurrentLocalStateRoot()
require.Equal(t, expected, actual)
r = io.NewBinReaderFromBuf(data)
require.NoError(t, chaindump.Restore(bc, r, 1, 1, nil))
bc.Close()
})

t.Run("not empty MemoryStore, multiple blocks", func(t *testing.T) {
st := nopCloserStorage{Store: storage.NewMemoryStore()}
{
bc := initChain(st)
r := io.NewBinReaderFromBuf(data)
require.NoError(t, chaindump.Restore(bc, r, 0, 2, nil))
expected := bc.stateRoot.CurrentLocalStateRoot()
bc.Close()

bc = initChain(st)
actual := bc.stateRoot.CurrentLocalStateRoot()
require.Equal(t, expected, actual)
r = io.NewBinReaderFromBuf(data)
require.NoError(t, chaindump.Restore(bc, r, 2, 1, nil))
bc.Close()
}
})
}
8 changes: 5 additions & 3 deletions pkg/core/stateroot/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,15 @@ func (s *Module) Init(height uint32) error {
updateStateHeightMetric(h)
}

if height == 0 {
if s.mpt == nil {
s.mpt = mpt.NewTrie(nil, s.mode, s.Store)
s.currentLocal.Store(util.Uint256{})
return nil
}
r, err := s.getStateRoot(makeStateRootKey(height))
if err != nil {
if height == 0 {
s.currentLocal.Store(util.Uint256{})
return nil
}
return err
}
s.currentLocal.Store(r.Root)
Expand Down

0 comments on commit 5fec492

Please sign in to comment.