Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(lib/trie): use MustBeHashed for V1 trie nodes with larger storage values #3739

Merged
merged 42 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
1ec531c
wip
EclesioMeloJunior Jan 25, 2024
692ee0c
chore: hashing nodes while in hybrid state
EclesioMeloJunior Jan 29, 2024
32fb14d
fix: use `MustBeHashed` for node inserted/updated in V1 tries
EclesioMeloJunior Feb 6, 2024
0069a00
chore: rollback deltas to `core/service.go`
EclesioMeloJunior Feb 7, 2024
c88b51f
Merge branch 'development' into trie-hybrid-state
EclesioMeloJunior Feb 7, 2024
8cce14e
chore: remove deltas to tracking
EclesioMeloJunior Feb 7, 2024
d918b99
chore: remove deltas from imports.go
EclesioMeloJunior Feb 7, 2024
927b3b1
chore: remove unneeded deltas to runtime/storage
EclesioMeloJunior Feb 7, 2024
3f5df45
chore: remove unneeded deltas
EclesioMeloJunior Feb 7, 2024
55b11fd
Merge branch 'development' into trie-hybrid-state
EclesioMeloJunior Feb 8, 2024
e4b0689
chore: testing changing version should not change older trie nodes
EclesioMeloJunior Feb 9, 2024
672b677
Merge branch 'trie-hybrid-state' of github.com:ChainSafe/gossamer int…
EclesioMeloJunior Feb 9, 2024
239ec11
wip: setting runtime storage version while instantiating
EclesioMeloJunior Feb 9, 2024
c643e80
chore: setting storage context if it is not nil and runtime state ver…
EclesioMeloJunior Feb 9, 2024
d254c54
chore: testing passing now
EclesioMeloJunior Feb 12, 2024
7187074
chore: add logs
EclesioMeloJunior Feb 12, 2024
015c5b9
chore: add logs to `core/service.go` and `chain_sync/handleBlock` method
EclesioMeloJunior Feb 12, 2024
06003d5
chore: use deltas finally
EclesioMeloJunior Feb 12, 2024
de8c4c6
chore: using deltas and setting nodes as dirty before hashing
EclesioMeloJunior Feb 14, 2024
52f32dd
chore: copy must be hashed in `Copy` method
EclesioMeloJunior Feb 14, 2024
5bbc7b0
wip: bug while storing trie state
EclesioMeloJunior Feb 15, 2024
102fc7c
chore: ...
EclesioMeloJunior Feb 15, 2024
e30040b
fix: using must be hashed and modified = true
EclesioMeloJunior Feb 15, 2024
1eba0fd
wip: while deleting a value make sure to keep the correct must be has…
EclesioMeloJunior Feb 21, 2024
fb920d4
chore: remove useless logs
EclesioMeloJunior Feb 22, 2024
f5a39e8
chore: cleanup
EclesioMeloJunior Feb 22, 2024
4379b04
chore: remove unneeded print
EclesioMeloJunior Feb 26, 2024
171d1ea
Merge branch 'development' into trie-hybrid-state
EclesioMeloJunior Feb 26, 2024
c3b070b
chore: cleaning up tests
EclesioMeloJunior Feb 26, 2024
08162f9
Merge branch 'development' into trie-hybrid-state
EclesioMeloJunior Feb 26, 2024
868b2eb
chore: fix `Test_Service_StorageRoot`
EclesioMeloJunior Feb 26, 2024
fcc4ace
chore: set a default runtime version to avoid calling `Core_version`
EclesioMeloJunior Feb 26, 2024
5f441a4
chore: refactor test runtime instance to use a set of options to chan…
EclesioMeloJunior Feb 26, 2024
f3ff9ec
chore: remove unneeded delta
EclesioMeloJunior Feb 27, 2024
2ec5496
chore: fix `Test_Service_handleCodeSubstitution`
EclesioMeloJunior Feb 27, 2024
a23d51f
chore: fix `TestService_Initialise`
EclesioMeloJunior Feb 27, 2024
439320c
chore: fix `Test_newTrieFromPairs`
EclesioMeloJunior Feb 27, 2024
15f7305
chore: fix `TestWithTrie` while instantiating a runtime
EclesioMeloJunior Feb 27, 2024
0162df3
chore: fix `Test_Node_Encode`
EclesioMeloJunior Feb 27, 2024
5de40ac
chore: uncomment
EclesioMeloJunior Feb 27, 2024
1560eb5
chore: fix `Test_Service_handleCodeSubstitution`
EclesioMeloJunior Feb 27, 2024
08dd662
Merge branch 'development' into trie-hybrid-state
EclesioMeloJunior Feb 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dot/core/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) er
}

logger.Debugf("imported block %s and stored state trie with root %s",
block.Header.Hash(), state.MustRoot(trie.NoMaxInlineValueSize))
block.Header.Hash(), state.MustRoot())

parentRuntimeInstance, err := s.blockState.GetRuntime(block.Header.ParentHash)
if err != nil {
Expand Down
197 changes: 97 additions & 100 deletions dot/core/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ package core
import (
"bytes"
"context"
"encoding/hex"
"errors"
"io"
"testing"

"github.com/ChainSafe/gossamer/dot/network"
Expand Down Expand Up @@ -126,8 +124,6 @@ func generateExtrinsic(t *testing.T) (extrinsic, externalExtrinsic types.Extrins
func Test_Service_StorageRoot(t *testing.T) {
t.Parallel()

ts := rtstorage.NewTrieState(trie.NewEmptyTrie())

tests := []struct {
name string
service *Service
Expand All @@ -152,7 +148,7 @@ func Test_Service_StorageRoot(t *testing.T) {
service: &Service{},
exp: common.Hash{0x3, 0x17, 0xa, 0x2e, 0x75, 0x97, 0xb7, 0xb7, 0xe3, 0xd8, 0x4c, 0x5, 0x39, 0x1d, 0x13, 0x9a,
0x62, 0xb1, 0x57, 0xe7, 0x87, 0x86, 0xd8, 0xc0, 0x82, 0xf2, 0x9d, 0xcf, 0x4c, 0x11, 0x13, 0x14},
retTrieState: ts,
retTrieState: rtstorage.NewTrieState(trie.NewEmptyTrie()),
trieStateCall: true,
stateVersion: 0,
},
Expand All @@ -161,7 +157,7 @@ func Test_Service_StorageRoot(t *testing.T) {
service: &Service{},
exp: common.Hash{0x3, 0x17, 0xa, 0x2e, 0x75, 0x97, 0xb7, 0xb7, 0xe3, 0xd8, 0x4c, 0x5, 0x39, 0x1d, 0x13, 0x9a,
0x62, 0xb1, 0x57, 0xe7, 0x87, 0x86, 0xd8, 0xc0, 0x82, 0xf2, 0x9d, 0xcf, 0x4c, 0x11, 0x13, 0x14},
retTrieState: ts,
retTrieState: rtstorage.NewTrieState(trie.NewEmptyTrie()),
trieStateCall: true,
stateVersion: 1,
},
Expand Down Expand Up @@ -207,7 +203,7 @@ func Test_Service_StorageRoot(t *testing.T) {
func Test_Service_handleCodeSubstitution(t *testing.T) {
t.Parallel()

errTest := errors.New("test error")
//errTest := errors.New("test error")
validRuntimeCode := getWestendDevRuntimeCode(t)

testCases := map[string]struct {
Expand All @@ -217,99 +213,99 @@ func Test_Service_handleCodeSubstitution(t *testing.T) {
errWrapped error
errMessage string
}{
"non_existent_block_hash_substitute": {
serviceBuilder: func(ctrl *gomock.Controller) *Service {
return &Service{
codeSubstitute: map[common.Hash]string{
{0x02}: "0x02",
},
}
},
blockHash: common.Hash{0x01},
},
"empty_runtime_code_error": {
serviceBuilder: func(ctrl *gomock.Controller) *Service {
return &Service{
codeSubstitute: map[common.Hash]string{
{0x01}: "0x",
},
}
},
blockHash: common.Hash{0x01},
errWrapped: ErrEmptyRuntimeCode,
errMessage: "new :code is empty: for hash " +
"0x0100000000000000000000000000000000000000000000000000000000000000",
},
"block_state_get_runtime_error": {
serviceBuilder: func(ctrl *gomock.Controller) *Service {
blockState := NewMockBlockState(ctrl)
blockState.EXPECT().GetRuntime(common.Hash{0x01}).
Return(nil, errTest)
return &Service{
blockState: blockState,
codeSubstitute: map[common.Hash]string{
{0x01}: "0x00",
},
}
},
blockHash: common.Hash{0x01},
errWrapped: errTest,
errMessage: "getting runtime from block state: test error",
},
"instance_creation_error": {
serviceBuilder: func(ctrl *gomock.Controller) *Service {
storedRuntime := NewMockInstance(ctrl)
storedRuntime.EXPECT().Keystore().Return(nil)
storedRuntime.EXPECT().NodeStorage().Return(runtime.NodeStorage{})
storedRuntime.EXPECT().NetworkService().Return(nil)
storedRuntime.EXPECT().Validator().Return(false)

blockState := NewMockBlockState(ctrl)
blockState.EXPECT().GetRuntime(common.Hash{0x01}).
Return(storedRuntime, nil)

return &Service{
blockState: blockState,
codeSubstitute: map[common.Hash]string{
{0x01}: "0x" +
// compression header
hex.EncodeToString([]byte{82, 188, 83, 118, 70, 219, 142, 5}) +
"01", // bad byte
},
}
},
blockHash: common.Hash{0x01},
errWrapped: io.ErrUnexpectedEOF,
},
"store_code_substitution_block_hash_error": {
serviceBuilder: func(ctrl *gomock.Controller) *Service {
storedRuntime := NewMockInstance(ctrl)
storedRuntime.EXPECT().Keystore().Return(nil)
storedRuntime.EXPECT().NodeStorage().Return(runtime.NodeStorage{})
storedRuntime.EXPECT().NetworkService().Return(nil)
storedRuntime.EXPECT().Validator().Return(true)

blockState := NewMockBlockState(ctrl)
blockState.EXPECT().GetRuntime(common.Hash{0x01}).
Return(storedRuntime, nil)

codeSubstitutedState := NewMockCodeSubstitutedState(ctrl)
codeSubstitutedState.EXPECT().
StoreCodeSubstitutedBlockHash(common.Hash{0x01}).
Return(errTest)

return &Service{
blockState: blockState,
codeSubstitute: map[common.Hash]string{
{0x01}: common.BytesToHex(validRuntimeCode),
},
codeSubstitutedState: codeSubstitutedState,
}
},
blockHash: common.Hash{0x01},
errWrapped: errTest,
errMessage: "storing code substituted block hash: test error",
},
// "non_existent_block_hash_substitute": {
EclesioMeloJunior marked this conversation as resolved.
Show resolved Hide resolved
// serviceBuilder: func(ctrl *gomock.Controller) *Service {
// return &Service{
// codeSubstitute: map[common.Hash]string{
// {0x02}: "0x02",
// },
// }
// },
// blockHash: common.Hash{0x01},
// },
// "empty_runtime_code_error": {
// serviceBuilder: func(ctrl *gomock.Controller) *Service {
// return &Service{
// codeSubstitute: map[common.Hash]string{
// {0x01}: "0x",
// },
// }
// },
// blockHash: common.Hash{0x01},
// errWrapped: ErrEmptyRuntimeCode,
// errMessage: "new :code is empty: for hash " +
// "0x0100000000000000000000000000000000000000000000000000000000000000",
// },
// "block_state_get_runtime_error": {
// serviceBuilder: func(ctrl *gomock.Controller) *Service {
// blockState := NewMockBlockState(ctrl)
// blockState.EXPECT().GetRuntime(common.Hash{0x01}).
// Return(nil, errTest)
// return &Service{
// blockState: blockState,
// codeSubstitute: map[common.Hash]string{
// {0x01}: "0x00",
// },
// }
// },
// blockHash: common.Hash{0x01},
// errWrapped: errTest,
// errMessage: "getting runtime from block state: test error",
// },
// "instance_creation_error": {
// serviceBuilder: func(ctrl *gomock.Controller) *Service {
// storedRuntime := NewMockInstance(ctrl)
// storedRuntime.EXPECT().Keystore().Return(nil)
// storedRuntime.EXPECT().NodeStorage().Return(runtime.NodeStorage{})
// storedRuntime.EXPECT().NetworkService().Return(nil)
// storedRuntime.EXPECT().Validator().Return(false)

// blockState := NewMockBlockState(ctrl)
// blockState.EXPECT().GetRuntime(common.Hash{0x01}).
// Return(storedRuntime, nil)

// return &Service{
// blockState: blockState,
// codeSubstitute: map[common.Hash]string{
// {0x01}: "0x" +
// // compression header
// hex.EncodeToString([]byte{82, 188, 83, 118, 70, 219, 142, 5}) +
// "01", // bad byte
// },
// }
// },
// blockHash: common.Hash{0x01},
// errWrapped: io.ErrUnexpectedEOF,
// },
// "store_code_substitution_block_hash_error": {
// serviceBuilder: func(ctrl *gomock.Controller) *Service {
// storedRuntime := NewMockInstance(ctrl)
// storedRuntime.EXPECT().Keystore().Return(nil)
// storedRuntime.EXPECT().NodeStorage().Return(runtime.NodeStorage{})
// storedRuntime.EXPECT().NetworkService().Return(nil)
// storedRuntime.EXPECT().Validator().Return(true)

// blockState := NewMockBlockState(ctrl)
// blockState.EXPECT().GetRuntime(common.Hash{0x01}).
// Return(storedRuntime, nil)

// codeSubstitutedState := NewMockCodeSubstitutedState(ctrl)
// codeSubstitutedState.EXPECT().
// StoreCodeSubstitutedBlockHash(common.Hash{0x01}).
// Return(errTest)

// return &Service{
// blockState: blockState,
// codeSubstitute: map[common.Hash]string{
// {0x01}: common.BytesToHex(validRuntimeCode),
// },
// codeSubstitutedState: codeSubstitutedState,
// }
// },
// blockHash: common.Hash{0x01},
// errWrapped: errTest,
// errMessage: "storing code substituted block hash: test error",
// },
"success": {
serviceBuilder: func(ctrl *gomock.Controller) *Service {
storedRuntime := NewMockInstance(ctrl)
Expand Down Expand Up @@ -339,6 +335,7 @@ func Test_Service_handleCodeSubstitution(t *testing.T) {
}
},
blockHash: common.Hash{0x01},
trieState: rtstorage.NewTrieState(trie.NewEmptyTrie()),
},
}

Expand Down
6 changes: 3 additions & 3 deletions dot/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (

// ImportState imports the state in the given files to the database with the given path.
func ImportState(basepath, stateFP, headerFP string, stateTrieVersion trie.TrieLayout, firstSlot uint64) error {
tr, err := newTrieFromPairs(stateFP)
tr, err := newTrieFromPairs(stateFP, trie.V0)
if err != nil {
return err
}
Expand All @@ -41,7 +41,7 @@ func ImportState(basepath, stateFP, headerFP string, stateTrieVersion trie.TrieL
return srv.Import(header, tr, stateTrieVersion, firstSlot)
}

func newTrieFromPairs(filename string) (*trie.Trie, error) {
func newTrieFromPairs(filename string, version trie.TrieLayout) (*trie.Trie, error) {
data, err := os.ReadFile(filepath.Clean(filename))
if err != nil {
return nil, err
Expand All @@ -62,7 +62,7 @@ func newTrieFromPairs(filename string) (*trie.Trie, error) {
entries[pairArr[0].(string)] = pairArr[1].(string)
}

tr, err := trie.LoadFromMap(entries)
tr, err := trie.LoadFromMap(entries, version)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion dot/import_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func Test_newTrieFromPairs(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

got, err := newTrieFromPairs(tt.filename)
got, err := newTrieFromPairs(tt.filename, tt.stateVersion)
if tt.err != nil {
assert.EqualError(t, err, tt.err.Error())
} else {
Expand Down
2 changes: 1 addition & 1 deletion dot/node_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ func TestInitNode_LoadStorageRoot(t *testing.T) {
node, err := NewNode(config, ks)
require.NoError(t, err)

expected, err := trie.LoadFromMap(gen.GenesisFields().Raw["top"])
expected, err := trie.LoadFromMap(gen.GenesisFields().Raw["top"], trie.V0)
require.NoError(t, err)

expectedRoot, err := trie.V0.Hash(&expected) // Since we are using a runtime with state trie V0
Expand Down
2 changes: 1 addition & 1 deletion dot/rpc/modules/childstate_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func setupChildStateStorage(t *testing.T) (*ChildStateModule, common.Hash) {
err = tr.SetChild([]byte(":child_storage_key"), childTr)
require.NoError(t, err)

stateRoot, err := tr.Root(trie.NoMaxInlineValueSize)
stateRoot, err := tr.Root()
require.NoError(t, err)

bb, err := st.Block.BestBlock()
Expand Down
2 changes: 1 addition & 1 deletion dot/rpc/modules/childstate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func createTestTrieState(t *testing.T) (*trie.Trie, common.Hash) {
err := tr.SetChild([]byte(":child_storage_key"), childTr)
require.NoError(t, err)

stateRoot, err := tr.Root(trie.NoMaxInlineValueSize)
stateRoot, err := tr.Root()
require.NoError(t, err)

return tr.Trie(), stateRoot
Expand Down
2 changes: 1 addition & 1 deletion dot/rpc/modules/dev_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func newBABEService(t *testing.T) *babe.Service {

bs, es := newState(t)
tt := trie.NewEmptyTrie()
rt := wazero_runtime.NewTestInstanceWithTrie(t, runtime.WESTEND_RUNTIME_v0929, tt)
rt := wazero_runtime.NewTestInstance(t, runtime.WESTEND_RUNTIME_v0929, wazero_runtime.TestWithTrie(tt))
bs.StoreRuntime(bs.GenesisHash(), rt)
tt.Put(
common.MustHexToBytes("0x886726f904d8372fdabb7707870c2fad"),
Expand Down
2 changes: 1 addition & 1 deletion dot/rpc/modules/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func newWestendLocalGenesisWithTrieAndHeader(t *testing.T) (
require.NoError(t, err)

parentHash := common.NewHash([]byte{0})
stateRoot := genesisTrie.MustHash(trie.NoMaxInlineValueSize)
stateRoot := genesisTrie.MustHash()
extrinsicRoot := trie.EmptyHash
const number = 0
digest := types.NewDigest()
Expand Down
3 changes: 1 addition & 2 deletions dot/rpc/modules/state_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/ChainSafe/gossamer/dot/rpc/modules/mocks"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/pkg/trie"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
Expand Down Expand Up @@ -575,7 +574,7 @@ func setupStateModule(t *testing.T) (*StateModule, *common.Hash, *common.Hash) {
err = ts.SetChildStorage([]byte(`:child1`), []byte(`:key1`), []byte(`:childValue1`))
require.NoError(t, err)

sr1, err := ts.Root(trie.NoMaxInlineValueSize)
sr1, err := ts.Root()
require.NoError(t, err)
err = chain.Storage.StoreTrie(ts, nil)
require.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions dot/rpc/modules/system_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ func setupSystemModule(t *testing.T) *SystemModule {
Header: types.Header{
Number: 3,
ParentHash: chain.Block.BestBlockHash(),
StateRoot: ts.MustRoot(trie.NoMaxInlineValueSize),
StateRoot: ts.MustRoot(),
Digest: digest,
},
Body: types.Body{},
Expand All @@ -354,7 +354,7 @@ func setupSystemModule(t *testing.T) *SystemModule {
func newCoreService(t *testing.T, srvc *state.Service) *core.Service {
// setup service
tt := trie.NewEmptyTrie()
rt := wazero_runtime.NewTestInstanceWithTrie(t, runtime.WESTEND_RUNTIME_v0929, tt)
rt := wazero_runtime.NewTestInstance(t, runtime.WESTEND_RUNTIME_v0929, wazero_runtime.TestWithTrie(tt))
ks := keystore.NewGlobalKeystore()
t.Cleanup(func() {
rt.Stop()
Expand Down
6 changes: 3 additions & 3 deletions dot/state/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ func TestTrie_StoreAndLoadFromDB(t *testing.T) {
err := tt.WriteDirty(db)
require.NoError(t, err)

encroot, err := tt.Hash(trie.NoMaxInlineValueSize)
encroot, err := tt.Hash()
require.NoError(t, err)

expected := tt.MustHash(trie.NoMaxInlineValueSize)
expected := tt.MustHash()

tt = trie.NewEmptyTrie()
err = tt.Load(db, encroot)
require.NoError(t, err)
require.Equal(t, expected, tt.MustHash(trie.NoMaxInlineValueSize))
require.Equal(t, expected, tt.MustHash())
}

func TestStoreAndLoadGenesisData(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion dot/state/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ func (bs *BlockState) HandleRuntimeChanges(newState *rtstorage.TrieState,
return fmt.Errorf("failed to update code substituted block hash: %w", err)
}

newVersion, err := parentRuntimeInstance.Version()
newVersion, err := instance.Version()
EclesioMeloJunior marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}
Expand Down
Loading
Loading