From 1ec531cbfb913d1b29743ecf12cead87961f3a74 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Thu, 25 Jan 2024 17:21:46 -0400 Subject: [PATCH 01/36] wip --- .gitignore | 2 + internal/trie/node/branch_encode.go | 3 +- internal/trie/node/copy.go | 7 +- internal/trie/node/encode.go | 10 ++- internal/trie/node/hash.go | 7 +- internal/trie/node/header.go | 2 +- internal/trie/tracking/deltas.go | 50 ++++++++++- internal/trie/tracking/deltas_test.go | 2 +- internal/trie/tracking/interfaces.go | 5 +- lib/runtime/storage/trie.go | 16 +++- lib/runtime/wazero/imports.go | 57 +++++++----- lib/runtime/wazero/instance.go | 2 + lib/runtime/wazero/instance_test.go | 124 ++++++++++++++++++++++++++ lib/trie/child_storage.go | 1 + lib/trie/interfaces.go | 12 ++- lib/trie/trie.go | 122 ++++++++++++++++++++++--- lib/trie/trie_test.go | 12 ++- 17 files changed, 372 insertions(+), 62 deletions(-) diff --git a/.gitignore b/.gitignore index d5d719704f..c685c55c63 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ tmp # node_modules used by polkadot.js/api tests tests/polkadotjs_test/node_modules !tests/polkadotjs_test/test/*.wasm + +*.json diff --git a/internal/trie/node/branch_encode.go b/internal/trie/node/branch_encode.go index d9b8e7b5a6..a3c73f714b 100644 --- a/internal/trie/node/branch_encode.go +++ b/internal/trie/node/branch_encode.go @@ -18,8 +18,7 @@ type encodingAsyncResult struct { err error } -func runEncodeChild(child *Node, index, maxInlineValue int, - results chan<- encodingAsyncResult, rateLimit <-chan struct{}) { +func runEncodeChild(child *Node, index, maxInlineValue int, results chan<- encodingAsyncResult, rateLimit <-chan struct{}) { buffer := bytes.NewBuffer(nil) err := encodeChild(child, maxInlineValue, buffer) diff --git a/internal/trie/node/copy.go b/internal/trie/node/copy.go index f622419456..156f072f0a 100644 --- a/internal/trie/node/copy.go +++ b/internal/trie/node/copy.go @@ -55,9 +55,10 @@ type CopySettings struct { // children as well. func (n *Node) Copy(settings CopySettings) *Node { cpy := &Node{ - Dirty: n.Dirty, - Generation: n.Generation, - Descendants: n.Descendants, + Dirty: n.Dirty, + Generation: n.Generation, + Descendants: n.Descendants, + IsHashedValue: n.IsHashedValue, } if n.Kind() == Branch { diff --git a/internal/trie/node/encode.go b/internal/trie/node/encode.go index 1e5810ea34..13d0a032ae 100644 --- a/internal/trie/node/encode.go +++ b/internal/trie/node/encode.go @@ -4,6 +4,7 @@ package node import ( + "bytes" "fmt" "github.com/ChainSafe/gossamer/internal/trie/codec" @@ -46,14 +47,17 @@ func (n *Node) Encode(buffer Buffer, maxInlineValue int) (err error) { // even if it is empty. Do not encode if the branch is without value. // Note leaves and branches with value cannot have a `nil` storage value. if n.StorageValue != nil { - if len(n.StorageValue) > maxInlineValue { + if len(n.StorageValue) > maxInlineValue && n.IsHashedValue { hashedValue, err := common.Blake2bHash(n.StorageValue) if err != nil { return fmt.Errorf("hashing storage value: %w", err) } - _, err = buffer.Write(hashedValue.ToBytes()) + + prefixedValueKey := bytes.Join([][]byte{n.PartialKey, hashedValue.ToBytes()}, nil) + encoder := scale.NewEncoder(buffer) + err = encoder.Encode(prefixedValueKey) if err != nil { - return fmt.Errorf("encoding hashed storage value: %w", err) + return fmt.Errorf("scale encoding storage value: %w", err) } } else { encoder := scale.NewEncoder(buffer) diff --git a/internal/trie/node/hash.go b/internal/trie/node/hash.go index 1dfbca098d..f721a6830f 100644 --- a/internal/trie/node/hash.go +++ b/internal/trie/node/hash.go @@ -71,9 +71,9 @@ func (n *Node) CalculateMerkleValue(maxInlineValue int) (merkleValue []byte, err // CalculateRootMerkleValue returns the Merkle value of the root node. func (n *Node) CalculateRootMerkleValue(maxInlineValue int) (merkleValue []byte, err error) { const rootMerkleValueLength = 32 - if !n.Dirty && len(n.MerkleValue) == rootMerkleValueLength { - return n.MerkleValue, nil - } + // if !n.Dirty && len(n.MerkleValue) == rootMerkleValueLength { + // return n.MerkleValue, nil + // } _, merkleValue, err = n.EncodeAndHashRoot(maxInlineValue) if err != nil { @@ -130,6 +130,7 @@ func (n *Node) EncodeAndHashRoot(maxInlineValue int) (encoding, merkleValue []by return nil, nil, fmt.Errorf("merkle value: %w", err) } merkleValue = merkleValueBuffer.Bytes() + fmt.Printf("caching merkle value using %v\n", maxInlineValue) n.MerkleValue = merkleValue // no need to copy return encoding, merkleValue, nil diff --git a/internal/trie/node/header.go b/internal/trie/node/header.go index 30f910be5e..cfc397fa35 100644 --- a/internal/trie/node/header.go +++ b/internal/trie/node/header.go @@ -21,7 +21,7 @@ func encodeHeader(node *Node, maxInlineValueSize int, writer io.Writer) (err err panic(fmt.Sprintf("partial key length is too big: %d", partialKeyLength)) } - isHashedValue := len(node.StorageValue) > maxInlineValueSize + isHashedValue := len(node.StorageValue) > maxInlineValueSize && node.IsHashedValue // Merge variant byte and partial key length together var nodeVariant variant diff --git a/internal/trie/tracking/deltas.go b/internal/trie/tracking/deltas.go index 4e80e37a20..87a28097a9 100644 --- a/internal/trie/tracking/deltas.go +++ b/internal/trie/tracking/deltas.go @@ -3,16 +3,25 @@ package tracking -import "github.com/ChainSafe/gossamer/lib/common" +import ( + "github.com/ChainSafe/gossamer/lib/common" +) + +type DeltaEntry struct { + Key []byte + Value []byte +} // Deltas tracks the trie deltas, for example deleted node hashes. type Deltas struct { + entries []DeltaEntry deletedNodeHashes map[common.Hash]struct{} } // New returns a new Deltas struct. func New() *Deltas { return &Deltas{ + entries: make([]DeltaEntry, 0), deletedNodeHashes: make(map[common.Hash]struct{}), } } @@ -22,6 +31,22 @@ func (d *Deltas) RecordDeleted(nodeHash common.Hash) { d.deletedNodeHashes[nodeHash] = struct{}{} } +// RecordUpdated records a node hash that was created or updated. +func (d *Deltas) RecordUpdated(key, value []byte) { + newEntry := DeltaEntry{ + Key: make([]byte, len(key)), + Value: make([]byte, len(value)), + } + + copy(newEntry.Key[:], key[:]) + copy(newEntry.Value[:], value[:]) + d.entries = append(d.entries, newEntry) +} + +func (d *Deltas) HasUpdated(partialKeyHash common.Hash) bool { + return false +} + // Deleted returns a set (map) of all the recorded deleted // node hashes. Note the map returned is not deep copied for // performance reasons and so it's not safe for mutation. @@ -29,12 +54,20 @@ func (d *Deltas) Deleted() (nodeHashes map[common.Hash]struct{}) { return d.deletedNodeHashes } +func (d *Deltas) Updated() []DeltaEntry { + return d.entries +} + // MergeWith merges the deltas given as argument in the receiving // deltas struct. -func (d *Deltas) MergeWith(deltas DeletedGetter) { +func (d *Deltas) MergeWith(deltas Getter) { for nodeHash := range deltas.Deleted() { d.RecordDeleted(nodeHash) } + + for _, deltaEntry := range deltas.Updated() { + d.RecordUpdated(deltaEntry.Key, deltaEntry.Value) + } } // DeepCopy returns a deep copy of the deltas. @@ -52,5 +85,18 @@ func (d *Deltas) DeepCopy() (deepCopy *Deltas) { } } + if len(d.entries) != 0 { + deepCopy.entries = make([]DeltaEntry, len(d.entries)) + for idx, deltaEntry := range d.entries { + newEntry := DeltaEntry{ + Key: make([]byte, len(deltaEntry.Key)), + Value: make([]byte, len(deltaEntry.Value)), + } + + copy(newEntry.Key[:], deltaEntry.Key[:]) + copy(newEntry.Value[:], deltaEntry.Value[:]) + deepCopy.entries[idx] = newEntry + } + } return deepCopy } diff --git a/internal/trie/tracking/deltas_test.go b/internal/trie/tracking/deltas_test.go index 3af891a943..5c77cfa8be 100644 --- a/internal/trie/tracking/deltas_test.go +++ b/internal/trie/tracking/deltas_test.go @@ -103,7 +103,7 @@ func Test_Deltas_MergeWith(t *testing.T) { testCases := map[string]struct { deltas Deltas - deltasArg DeletedGetter + deltasArg Getter expectedDeltas Deltas }{ "merge_empty_deltas": { diff --git a/internal/trie/tracking/interfaces.go b/internal/trie/tracking/interfaces.go index 0e4ea324fd..0f13399e94 100644 --- a/internal/trie/tracking/interfaces.go +++ b/internal/trie/tracking/interfaces.go @@ -5,7 +5,8 @@ package tracking import "github.com/ChainSafe/gossamer/lib/common" -// DeletedGetter gets deleted node hashes. -type DeletedGetter interface { +// Getter gets deleted node hashes. +type Getter interface { Deleted() (nodeHashes map[common.Hash]struct{}) + Updated() []DeltaEntry } diff --git a/lib/runtime/storage/trie.go b/lib/runtime/storage/trie.go index 7b76779f5e..cde6450e79 100644 --- a/lib/runtime/storage/trie.go +++ b/lib/runtime/storage/trie.go @@ -44,6 +44,8 @@ func (t *TrieState) StartTransaction() { t.mtx.Lock() defer t.mtx.Unlock() + fmt.Println("STARTING A TRANSACTION") + t.transactions.PushBack(t.getCurrentTrie().Snapshot()) } @@ -56,6 +58,8 @@ func (t *TrieState) RollbackTransaction() { panic("no transactions to rollback") } + fmt.Println("ROLLBACK A TRANSACTION") + t.transactions.Remove(t.transactions.Back()) } @@ -68,6 +72,7 @@ func (t *TrieState) CommitTransaction() { panic("no transactions to commit") } + fmt.Println("COMMITING A TRANSACTION") t.transactions.Back().Prev().Value = t.transactions.Remove(t.transactions.Back()) } @@ -100,12 +105,21 @@ func (t *TrieState) Get(key []byte) []byte { // MustRoot returns the trie's root hash. It panics if it fails to compute the root. func (t *TrieState) MustRoot(maxInlineValue int) common.Hash { + t.mtx.RLock() + defer t.mtx.RUnlock() + return t.getCurrentTrie().MustHash(maxInlineValue) } // Root returns the trie's root hash func (t *TrieState) Root(maxInlineValue int) (common.Hash, error) { - return t.getCurrentTrie().Hash(maxInlineValue) + t.mtx.RLock() + defer t.mtx.RUnlock() + + currentTrie := t.getCurrentTrie() + currentTrie.HashOnlyDeltas(maxInlineValue) + + return currentTrie.Hash(maxInlineValue) } // Has returns whether or not a key exists diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index 1fb3ae59fe..01b94df8f2 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -92,22 +92,23 @@ func ext_logging_log_version_1(ctx context.Context, m api.Module, level int32, t target := string(read(m, targetData)) msg := string(read(m, msgData)) - line := fmt.Sprintf("target=%s message=%s", target, msg) - - switch int(level) { - case 0: - logger.Critical(line) - case 1: - logger.Warn(line) - case 2: - logger.Info(line) - case 3: - logger.Debug(line) - case 4: - logger.Trace(line) - default: - logger.Errorf("level=%d target=%s message=%s", int(level), target, msg) - } + line := fmt.Sprintf("target=%s message=%s\n", target, msg) + fmt.Print(line) + + // switch int(level) { + // case 0: + // logger.Critical(line) + // case 1: + // logger.Warn(line) + // case 2: + // logger.Info(line) + // case 3: + // logger.Debug(line) + // case 4: + // logger.Trace(line) + // default: + // logger.Errorf("level=%d target=%s message=%s", int(level), target, msg) + // } } func ext_crypto_ed25519_generate_version_1( @@ -837,12 +838,16 @@ func ext_trie_blake2_256_ordered_root_version_2( data := read(m, dataSpan) + fmt.Printf("ext_trie_blake2_256_ordered_root_version_2 with pre parse: %v\n", version) + stateVersion, err := trie.ParseVersion(version) if err != nil { logger.Errorf("failed parsing state version: %s", err) return 0 } + fmt.Printf("ext_trie_blake2_256_ordered_root_version_2 with pos parse: %s\n", stateVersion.String()) + var values [][]byte err = scale.Unmarshal(data, &values) if err != nil { @@ -875,7 +880,7 @@ func ext_trie_blake2_256_ordered_root_version_2( return 0 } - logger.Debugf("root hash is %s", hash) + fmt.Printf("root hash is %s\n", hash) m.Memory().Write(ptr, hash[:]) return ptr } @@ -2053,7 +2058,7 @@ func ext_storage_clear_prefix_version_1(ctx context.Context, m api.Module, prefi storage := rtCtx.Storage prefix := read(m, prefixSpan) - logger.Debugf("prefix: 0x%x", prefix) + fmt.Printf("[ext_storage_clear_prefix_version_1] prefix: 0x%x\n", prefix) err := storage.ClearPrefix(prefix) if err != nil { @@ -2091,8 +2096,6 @@ func ext_storage_clear_prefix_version_2(ctx context.Context, m api.Module, prefi storage := rtCtx.Storage prefix := read(m, prefixSpan) - logger.Debugf("prefix: 0x%x", prefix) - limitBytes := read(m, lim) var limit []byte @@ -2108,12 +2111,16 @@ func ext_storage_clear_prefix_version_2(ctx context.Context, m api.Module, prefi } limitUint := binary.LittleEndian.Uint32(limit) + numRemoved, all, err := storage.ClearPrefixLimit(prefix, limitUint) if err != nil { logger.Errorf("failed to clear prefix limit: %s", err) panic(err) } + fmt.Printf("[ext_storage_clear_prefix_version_2] prefix: 0x%x, lim: %d, removed: %d, all: %v\n", + prefix, limitUint, numRemoved, all) + encBytes, err := toKillStorageResultEnum(all, numRemoved) if err != nil { logger.Errorf("failed to allocate memory: %s", err) @@ -2180,8 +2187,8 @@ func ext_storage_next_key_version_1(ctx context.Context, m api.Module, keySpan u key := read(m, keySpan) next := storage.NextKey(key) - logger.Debugf( - "key: 0x%x; next key 0x%x", + fmt.Printf( + "[ext_storage_next_key_version_1] key: 0x%x; next key 0x%x\n", key, next) var encodedOption []byte @@ -2266,19 +2273,23 @@ func ext_storage_root_version_2(ctx context.Context, m api.Module, version uint3 } storage := rtCtx.Storage + fmt.Printf("ext_storage_root_version_2 with pre parsed: %v\n", version) + stateVersion, err := trie.ParseVersion(version) if err != nil { logger.Errorf("failed parsing state version: %s", err) return mustWrite(m, rtCtx.Allocator, emptyByteVectorEncoded) } + fmt.Printf("ext_storage_root_version_2 with pos parsed: %s\n", stateVersion.String()) + root, err := storage.Root(stateVersion.MaxInlineValue()) if err != nil { logger.Errorf("failed to get storage root: %s", err) panic(err) } - logger.Debugf("root hash is: %s", root) + fmt.Printf("root v1 hash is: %s\n", root.String()) rootSpan, err := write(m, rtCtx.Allocator, root[:]) if err != nil { diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index 8a793691a9..42743ce9f4 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -511,6 +511,8 @@ func (in *Instance) version() error { //skipcq: RVV-B0001 return fmt.Errorf("decoding version: %w", err) } + fmt.Println("state version", version.StateVersion) + in.Context.Version = &version return nil diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index bc42235f01..5b3ab6eece 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -5,6 +5,8 @@ package wazero_runtime import ( _ "embed" + "fmt" + "strings" "bytes" "encoding/json" @@ -13,6 +15,7 @@ import ( "path/filepath" "testing" + "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" @@ -1276,3 +1279,124 @@ func TestInstance_GrandpaSubmitReportEquivocationUnsignedExtrinsic(t *testing.T) err = runtime.GrandpaSubmitReportEquivocationUnsignedExtrinsic(equivocationProof, opaqueKeyOwnershipProof) require.NoError(t, err) } + +func TestTrie(t *testing.T) { + tt := trie.NewEmptyTrie() + tt.Put([]byte("a"), make([]byte, 40)) + tt.Put([]byte("al"), make([]byte, 40)) + tt.Put([]byte("alfa"), make([]byte, 40)) + + hash, err := tt.Hash(trie.V0.MaxInlineValue()) + require.NoError(t, err) + + fmt.Printf("%s\n", hash.String()) // 0xdf1012a786cddcdfa4a8cf015e873677bc2e7a3c8b3579d9bae93117cbcfb7c1 + + tt = trie.NewEmptyTrie() + tt.Put([]byte("a"), make([]byte, 40)) + tt.Put([]byte("al"), make([]byte, 40)) + tt.Put([]byte("alfa"), make([]byte, 40)) + + hash, err = tt.Hash(trie.V1.MaxInlineValue()) + require.NoError(t, err) + + fmt.Printf("%s\n", hash.String()) // 0x99a5fee4d1d352a6e6530ce4c965d1063abe92e2a3327da07061c6730f221583 +} + +func TestDebugWestendBlock14576855(t *testing.T) { + wnd14576854StateTrie := newTrieFromRPC(t, "../test_data/14576854trie_state_data.json") + expectedStorageRootHash := common.MustHexToHash("0xedd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b") + require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) + + state := storage.NewTrieState(wnd14576854StateTrie) + cfg := Config{ + Storage: state, + LogLvl: log.Critical, + } + + instance, err := NewInstanceFromTrie(wnd14576854StateTrie, cfg) + require.NoError(t, err) + + blockResponseBytes, err := common.HexToBytes("0x0a91140a200283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4012a10240a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e1a0b280402000b6182c93586011abb11e522042d00400c0100000000b6a695e095d905fda4aa41746c0a0752cc3559eb00687d9a13c2a01745290573f6fa11cf3569c116e125d57ec15723653e8f4cda3ec481df1e0d2938f9c3f6880c0101000000740d6868002741aad034c5ffb5dcf31db78f2bb2eb1349bb02dc17d445e9f837914ec9394d52b6d6a3301fc7597de47bc2e48f6f3965999b4ea48fa5667aa4890c01020000002a0962f0b38163dfc2ed4f18727d530d49c05b4e8dbbd1b2c3af310956651277ed247263db04acedb2076ec99b516dff7598ba1f2d328006d4eb04e4c7e7028a0c0103000000f4a8ad3422500b05b5e91f1bae5db4aaa0d576f201ef8f39104764be34b9f229e3e123aec9f98fc9a64b3c4323428bbee3fb358474e2142f273fc3218cc9248c0c0104000000a6a5ee07dafbff4e52ae279f3149d35023751e61a4174c95e3a1afd56ca3365b939b7437f87bda45bfc052a0b0a71cd731296ed6d9edbc127a8e16cdeb52ff800c0105000000b0901765a119c80051f5000b3418b88f328a425b0fbd67aaa0f48acf6347903747cd681c8c4abd4fcb04f0748de2402a3da9ba59f6da9154e07b17e0c1154f890c01060000004cf0b4ec852a062a2cc599ac764a5bd6d6afb469326cfbf736ef0399d987de06ddf842c42f03c479d683aa7c511eb5ccc8f038192ff1fb8a1e1f234446efcb8c0c01070000004aad3d5f2f24ff187a06db9b87a2affa8ac0e219b02512dfd81549bccf62b8111e9961befb215d7e05d7f9ae14f2726098dd95f971e01daac6e720fde387f08c0c01080000004263728475b9e1e48f313e9e4d10cd9a1938d3bd3a80d48ed1418657d303643fac70ba80a6cdad37746e119eb280b668455d297e3b9113edc80ac6762536d18d0c01090000002a9aef1f1b91400ba0d52126b535393ffbfa60c531265efe2bf3dee09aa6f5453a14f3d94bc7f34f3b3d931d46f4726bc87e117a7baa93dd9bb1ac8a9d41da8e0c010a0000000606a0fbaf5f6ba57bc8276aa3e4ad587a1103563d8ea806ded26c8c751fa51dc3e69b4c1f016446cc711be1172a687ee2a5c52f2cb25b9255bf95c4b0fb57810c010b00000054ef1c2e69dd06552fef2b085c4afe5ea1bede23cb912aefb3eff3a3be820f3f1852e54001c15ba05d8b038e2b72207d94c94f8550b0f02fd8c7ee44bcf4df840c010c000000a6b9492a5bc58a4ca6f975c1c50f0c8f09f6b4e842a04a767867c11cc4910f1528efe6a26579981a7d82bda20cdc346fa805703d0aff9988a61ae63443a5008a0c010d000000ca13f5d6336bf7b54351c831d51c3d3aa37c9c1b806ed5715bb72c6a3206d25c893772dac586a3b3e3a616c637947d86119aa54ee4599c4dad23d4ff2f4e7b860c010e0000000e756428f4382e4e540c46a0ea60fdb094129e0d0be80fb7494498d7e714d832c57b158de81ca0f0df736f89035e7eb7449b609adf5c80ef751fb205acac0a800c010f000000820323f879134b5ca5bdcfa4f45a6089c1f5f198633ca8f841349e0e32a6032d20612506730aa5cf0141d56e156234540548164cf1cb6837d767a14d9d5dc18b04ea03000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e3468b0e01113f2c78d4b7b20efd4bdc38627c60bb4b840c8e7476e891b505d828eb016dba1703a583c3e64688bdf97e2bc29a8b6cb499a432d237a323b1412e90e2f769655c4651e3d298ecdc2a536cb89a3a3f31a0f6441a3ae4aa51c4741d32d1cd99206627a51c448c1dbf1f50009655c98b0c1326ae38420d9515cbbcf93ec8084285c48449903c919b164453fde3c5412badebcee765a01aa1b7a8fd503519283259d37c98ecab006af925b013b57a27fe56800cda5f5feec980cb110f87030f7913bfad164bd2dcff5556e48cf06bc28bb3f1ead5200be27d95adbcac624e714e61e9b3100565ae524c326102f8bc17bd3e9e73a185b8116a9e964e665c000000e902d1eb45830486f22485d977ff49349529742a039db30cb9da5fda419c6302bfa8b6ea0b005ff08f7e128ee3e8d263926c4f682842d2eb319b09f251540a815836db74761490734e7a9fd6e677f451d30e6fe142c52655c15db683a4931659c75ac85fbf6c080661757261204411530800000000056175726101015e53dd83b63d9a65ee2906fcbeb0719f9a7a7281513441e211f448efcdfd472a80fe4cb669fa22b8499961bea7643c3586fd16d26e220cb7e5a9da8a1d07ce8b00000000d66cde001401b0b5c1ee601faedc6101d132c793fcdae39737468c9c3dcc3c57fb5b4e2f14648b002685a67f4aeca1fef16795c2c2c352b5afd91a8fe346b7f278f2fce67b8602d23eb4ca1a20f459e1557a1ccc8976dcc686873f3499262e8cd38d0e6294a4340c1fa00bc26ec9a18df5b1b14d4b90bd3c75c5d35b6dff8eeca23976de2f288301d4fa4f3d94cb63c38ea719e64ae09cd7d6eb409d8d1bc21f1a00377fb30e4118e89dd2b4fba1a538819f4dc57e5cf76e80d953ef4c04ad81918b4d68b050db8f021aba632739c7993e789b4ae276b6c933e82a644d5442443224e9fb12d499e12a41a8b4deeb4ebe503842cf8cb680e84e0e4e6898bf62a3cf722262f654cec086029c38b051968569013dc5c2fbc93db0c4bb86a3f548dc5ddff363f32fbe7704682a5dabb9e9689ba820a5f68ac31a92613e0f760d4862c41f5d97edb22e378d8a141f007d63733ead4d8c05045abe1f10fca05ca02aa44c5aafb59135a841c09afeb3965ab37903edd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b5f6028c17d04a84ec8811461e52a44e489e67b01bfd421b1e25e002200ab433e080642414245b501030d0000008922a610000000002e1e6cadbc719c66a3a4193c2b577cce37eec5e041213ba010823a9b988da947f942254709d3786c37eebb54253f639584dd149883df229258a3ae02ee81860b5945c6ba5fb7990a0fb7ec0ff19c9d5ea8b7d613cfe7de3a8bcb4bdb8f6fed0f05424142450101266ba8cf6a2b5b86a3a1bda16be242d75b042a8dea21e57e0c265cdbc942612c9531ff2178a02871336d6e326d2a71bbb749c3dbc7e3a82ea1c2c0690a73ca8a") + require.NoError(t, err) + + blockResponse := new(network.BlockResponseMessage) + err = blockResponse.Decode(blockResponseBytes) + require.NoError(t, err) + + blockData := blockResponse.BlockData[0] + + block := &types.Block{ + Header: *blockData.Header, + Body: *blockData.Body, + } + + instance.version() + + _, err = instance.ExecuteBlock(block) + require.NoError(t, err) +} + +func TestDebugWestendBlock14576856(t *testing.T) { + wnd14576854StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") + expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") + require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) + + state := storage.NewTrieState(wnd14576854StateTrie) + cfg := Config{ + Storage: state, + LogLvl: log.Critical, + } + + instance, err := NewInstanceFromTrie(wnd14576854StateTrie, cfg) + require.NoError(t, err) + + blockResponseBytes, err := common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") + require.NoError(t, err) + + blockResponse := new(network.BlockResponseMessage) + err = blockResponse.Decode(blockResponseBytes) + require.NoError(t, err) + + blockData := blockResponse.BlockData[0] + + block := &types.Block{ + Header: *blockData.Header, + Body: *blockData.Body, + } + + instance.version() + + _, err = instance.ExecuteBlock(block) + require.NoError(t, err) +} + +func newTrieFromRPC(t *testing.T, filename string) *trie.Trie { + data, err := os.ReadFile(filename) + require.NoError(t, err) + + encodedTrieEntries := make([]string, 0) + err = json.Unmarshal(data, &encodedTrieEntries) + require.NoError(t, err) + + expectedPrefix := "0x3a6368696c645f73746f726167653a64656661756c743a" + + entries := make(map[string]string, len(encodedTrieEntries)) + for _, encodedEntry := range encodedTrieEntries { + bytesEncodedEntry := common.MustHexToBytes(encodedEntry) + entry := trie.Entry{} + err := scale.Unmarshal(bytesEncodedEntry, &entry) + require.NoError(t, err) + + key := common.BytesToHex(entry.Key) + if strings.HasPrefix(strings.ToLower(key), strings.ToLower(expectedPrefix)) { + fmt.Printf("%s\n", key) + panic("GOTCHA!") + } + + entries[key] = common.BytesToHex(entry.Value) + } + + tr, err := trie.LoadFromMap(entries) + require.NoError(t, err) + return &tr +} diff --git a/lib/trie/child_storage.go b/lib/trie/child_storage.go index 2f3cd008da..9acdae02b3 100644 --- a/lib/trie/child_storage.go +++ b/lib/trie/child_storage.go @@ -28,6 +28,7 @@ func (t *Trie) SetChild(keyToChild []byte, child *Trie) error { copy(key, ChildStorageKeyPrefix) copy(key[len(ChildStorageKeyPrefix):], keyToChild) + child.childTriePartialKey = key err = t.Put(key, childHash.ToBytes()) if err != nil { return fmt.Errorf("putting child trie root hash %s in trie: %w", childHash, err) diff --git a/lib/trie/interfaces.go b/lib/trie/interfaces.go index 452b46dbcc..6a7fa294dd 100644 --- a/lib/trie/interfaces.go +++ b/lib/trie/interfaces.go @@ -12,21 +12,19 @@ import ( // the last snapshot. type Deltas interface { DeltaMerger - DeltaDeletedGetter + tracking.Getter + DeltaRecorder + DeepCopy() (deepCopy *tracking.Deltas) } // DeltaMerger merges the given deltas into the current // deltas. type DeltaMerger interface { - MergeWith(deltas tracking.DeletedGetter) -} - -// DeltaDeletedGetter returns the deleted node hashes recorded so far. -type DeltaDeletedGetter interface { - Deleted() (nodeHashes map[common.Hash]struct{}) + MergeWith(deltas tracking.Getter) } // DeltaRecorder records deltas done in a ongoing trie operation. type DeltaRecorder interface { RecordDeleted(nodeHash common.Hash) + RecordUpdated(key, value []byte) } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 99152be798..df89b9cf0d 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -20,10 +20,11 @@ var EmptyHash = common.MustBlake2bHash([]byte{0}) // Trie is a base 16 modified Merkle Patricia trie. type Trie struct { - generation uint64 - root *Node - childTries map[common.Hash]*Trie - db db.Database + childTriePartialKey []byte + generation uint64 + root *Node + childTries map[common.Hash]*Trie + db db.Database // deltas stores trie deltas since the last trie snapshot. // For example node hashes that were deleted since // the last snapshot. These are used by the online @@ -69,34 +70,36 @@ func (t *Trie) Equal(other *Trie) bool { // the set of deleted hashes. func (t *Trie) Snapshot() (newTrie *Trie) { childTries := make(map[common.Hash]*Trie, len(t.childTries)) + rootCopySettings := node.DefaultCopySettings rootCopySettings.CopyMerkleValue = true + for rootHash, childTrie := range t.childTries { childTries[rootHash] = &Trie{ generation: childTrie.generation + 1, root: childTrie.root.Copy(rootCopySettings), - deltas: tracking.New(), + deltas: childTrie.deltas.DeepCopy(), } } + fmt.Printf("len of deltas updated: %d\n", len(t.deltas.Updated())) + return &Trie{ generation: t.generation + 1, root: t.root, db: t.db, childTries: childTries, - deltas: tracking.New(), + deltas: t.deltas.DeepCopy(), } } // handleTrackedDeltas sets the pending deleted node hashes in // the trie deltas tracker if and only if success is true. -func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas DeltaDeletedGetter) { +func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas tracking.Getter) { if !success || t.generation == 0 { // Do not persist tracked deleted node hashes if the operation failed or // if the trie generation is zero (first block, no trie snapshot done yet). - return } - t.deltas.MergeWith(pendingDeltas) } @@ -162,7 +165,7 @@ func (t *Trie) DeepCopy() (trieCopy *Trie) { if t.deltas != nil { // Because DeepCopy() is only used in tests (in this and other packages), // it's fine to type assert deltas to access its DeepCopy method. - trieCopy.deltas = t.deltas.(*tracking.Deltas).DeepCopy() + trieCopy.deltas = t.deltas.DeepCopy() } if t.childTries != nil { @@ -198,12 +201,41 @@ func (t *Trie) MustHash(maxInlineValue int) common.Hash { return h } +func (t *Trie) HashOnlyDeltas(maxInlineValue int) { + fmt.Println("hashing only deltas...") + updatedDeltas := t.deltas.Updated() + + fmt.Println("len of updated:", len(updatedDeltas)) + + for _, entries := range updatedDeltas { + t.MarkAsV1HashedNode(entries.Key) + } + + newTrieHash, _ := t.Hash(maxInlineValue) + fmt.Println("NEW TRIE V1 HASH:", newTrieHash.String()) +} + // Hash returns the hashed root of the trie. func (t *Trie) Hash(maxInlineValue int) (rootHash common.Hash, err error) { if t.root == nil { return EmptyHash, nil } + // TODO: Critical changing the child trie root hash in the state + // needs to reflect also in the childTries map + // or we can use a snapshot to perform the hash encoding + // if maxInlineValue == V1MaxInlineValueSize { + // fmt.Printf("child tries len: %d\n", len(t.childTries)) + // for _, childTrie := range t.childTries { + // v1Hash, err := childTrie.Hash(maxInlineValue) + // if err != nil { + // return rootHash, err + // } + + // t.Put(childTrie.childTriePartialKey, v1Hash[:]) + // } + // } + merkleValue, err := t.root.CalculateRootMerkleValue(maxInlineValue) if err != nil { return rootHash, err @@ -339,6 +371,59 @@ func findNextKeyChild(children []*Node, startIndex byte, return nil } +// Put inserts a value into the trie at the +// key specified in little Endian format. +func (t *Trie) MarkAsV1HashedNode(keyLE []byte) { + t.markAsHashed(keyLE) +} + +func (t *Trie) markAsHashed(keyLE []byte) { + nibblesKey := codec.KeyLEToNibbles(keyLE) + t.findAndMarkNode(t.root, nibblesKey) +} + +func (t *Trie) findAndMarkNode(parent *Node, key []byte) { + if parent == nil { + return + } + + if parent.Kind() == node.Branch { + t.findAndMarkInBranch(parent, key) + return + } + + t.findAndMarkInLeaf(parent, key) +} + +func (t *Trie) findAndMarkInLeaf(parentLeaf *Node, key []byte) { + if bytes.Equal(parentLeaf.PartialKey, key) { + parentLeaf.IsHashedValue = true + } +} + +func (t *Trie) findAndMarkInBranch(parentBranch *Node, key []byte) { + if bytes.Equal(parentBranch.PartialKey, key) { + parentBranch.IsHashedValue = true + return + } + + if bytes.HasPrefix(key, parentBranch.PartialKey) { + // key is included in parent branch key + commonPrefixLength := lenCommonPrefix(key, parentBranch.PartialKey) + childIndex := key[commonPrefixLength] + remainingKey := key[commonPrefixLength+1:] + child := parentBranch.Children[childIndex] + + if child == nil { + return + } + + //parentBranch.IsHashedValue = true + t.findAndMarkNode(child, remainingKey) + return + } +} + // Put inserts a value into the trie at the // key specified in little Endian format. func (t *Trie) Put(keyLE, value []byte) (err error) { @@ -347,7 +432,16 @@ func (t *Trie) Put(keyLE, value []byte) (err error) { const success = true t.handleTrackedDeltas(success, pendingDeltas) }() - return t.insertKeyLE(keyLE, value, pendingDeltas) + + //fmt.Printf("recording key: 0x%x\n", keyLE) + t.deltas.RecordUpdated(keyLE, value) + + err = t.insertKeyLE(keyLE, value, pendingDeltas) + if err != nil { + return err + } + + return nil } func (t *Trie) insertKeyLE(keyLE, value []byte, @@ -405,8 +499,10 @@ func (t *Trie) insert(parent *Node, key, value []byte, pendingDeltas DeltaRecord func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, pendingDeltas DeltaRecorder) ( newParent *Node, mutated bool, nodesCreated uint32, err error) { + if bytes.Equal(parentLeaf.PartialKey, key) { nodesCreated = 0 + if parentLeaf.StorageValueEqual(value) { mutated = false return parentLeaf, mutated, nodesCreated, nil @@ -439,7 +535,6 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if len(key) == commonPrefixLength { // key is included in parent leaf key newBranchParent.StorageValue = value - if len(key) < len(parentLeafKey) { // Move the current leaf parent as a child to the new branch. copySettings := node.DefaultCopySettings @@ -481,12 +576,13 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, nodesCreated++ } childIndex := key[commonPrefixLength] - newBranchParent.Children[childIndex] = &Node{ + newLeaf := &Node{ PartialKey: key[commonPrefixLength+1:], StorageValue: value, Generation: t.generation, Dirty: true, } + newBranchParent.Children[childIndex] = newLeaf newBranchParent.Descendants++ nodesCreated++ diff --git a/lib/trie/trie_test.go b/lib/trie/trie_test.go index 7c78e3afb2..85a9551f0d 100644 --- a/lib/trie/trie_test.go +++ b/lib/trie/trie_test.go @@ -6,6 +6,7 @@ package trie import ( "bytes" "encoding/hex" + "fmt" "reflect" "testing" @@ -110,7 +111,7 @@ func Test_Trie_handleTrackedDeltas(t *testing.T) { testCases := map[string]struct { trie Trie success bool - pendingDeltas DeltaDeletedGetter + pendingDeltas tracking.Getter expectedTrie Trie }{ "no_success_and_generation_1": { @@ -4371,3 +4372,12 @@ func Benchmark_concatSlices(b *testing.B) { } }) } + +func TestTrieDeltaRegisterUpdates(t *testing.T) { + trie := NewEmptyTrie() + trie.Put([]byte("alpha"), make([]byte, 40)) + trie.Put([]byte("al"), make([]byte, 40)) + + fmt.Println("tries deltas updated", trie.deltas.Updated()) + fmt.Println("tries deltas deleted", trie.deltas.Deleted()) +} From 692ee0c2d606b1f28b9e46f1b606a2271685254d Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 29 Jan 2024 13:25:52 -0400 Subject: [PATCH 02/36] chore: hashing nodes while in hybrid state --- internal/trie/node/encode.go | 5 +---- lib/common/hasher.go | 2 +- lib/runtime/wazero/instance_test.go | 11 +---------- lib/trie/trie.go | 3 --- 4 files changed, 3 insertions(+), 18 deletions(-) diff --git a/internal/trie/node/encode.go b/internal/trie/node/encode.go index 13d0a032ae..35fa554efd 100644 --- a/internal/trie/node/encode.go +++ b/internal/trie/node/encode.go @@ -4,7 +4,6 @@ package node import ( - "bytes" "fmt" "github.com/ChainSafe/gossamer/internal/trie/codec" @@ -53,9 +52,7 @@ func (n *Node) Encode(buffer Buffer, maxInlineValue int) (err error) { return fmt.Errorf("hashing storage value: %w", err) } - prefixedValueKey := bytes.Join([][]byte{n.PartialKey, hashedValue.ToBytes()}, nil) - encoder := scale.NewEncoder(buffer) - err = encoder.Encode(prefixedValueKey) + _, err = buffer.Write(hashedValue.ToBytes()) if err != nil { return fmt.Errorf("scale encoding storage value: %w", err) } diff --git a/lib/common/hasher.go b/lib/common/hasher.go index 003754736a..17ba083787 100644 --- a/lib/common/hasher.go +++ b/lib/common/hasher.go @@ -68,7 +68,7 @@ func Blake2bHash(in []byte) (Hash, error) { hash := h.Sum(nil) var buf = [32]byte{} - copy(buf[:], hash) + copy(buf[:], hash[:]) return buf, nil } diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index 5b3ab6eece..d79f3fa4d9 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -6,7 +6,6 @@ package wazero_runtime import ( _ "embed" "fmt" - "strings" "bytes" "encoding/json" @@ -1378,8 +1377,6 @@ func newTrieFromRPC(t *testing.T, filename string) *trie.Trie { err = json.Unmarshal(data, &encodedTrieEntries) require.NoError(t, err) - expectedPrefix := "0x3a6368696c645f73746f726167653a64656661756c743a" - entries := make(map[string]string, len(encodedTrieEntries)) for _, encodedEntry := range encodedTrieEntries { bytesEncodedEntry := common.MustHexToBytes(encodedEntry) @@ -1387,13 +1384,7 @@ func newTrieFromRPC(t *testing.T, filename string) *trie.Trie { err := scale.Unmarshal(bytesEncodedEntry, &entry) require.NoError(t, err) - key := common.BytesToHex(entry.Key) - if strings.HasPrefix(strings.ToLower(key), strings.ToLower(expectedPrefix)) { - fmt.Printf("%s\n", key) - panic("GOTCHA!") - } - - entries[key] = common.BytesToHex(entry.Value) + entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) } tr, err := trie.LoadFromMap(entries) diff --git a/lib/trie/trie.go b/lib/trie/trie.go index df89b9cf0d..e343fba3c9 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -210,9 +210,6 @@ func (t *Trie) HashOnlyDeltas(maxInlineValue int) { for _, entries := range updatedDeltas { t.MarkAsV1HashedNode(entries.Key) } - - newTrieHash, _ := t.Hash(maxInlineValue) - fmt.Println("NEW TRIE V1 HASH:", newTrieHash.String()) } // Hash returns the hashed root of the trie. From 32fb14d556145d57f44716200e60f7b9f2e8b047 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Tue, 6 Feb 2024 14:26:00 -0400 Subject: [PATCH 03/36] fix: use `MustBeHashed` for node inserted/updated in V1 tries --- dot/core/service.go | 15 +-- dot/rpc/modules/helpers_test.go | 2 +- dot/state/base_test.go | 6 +- dot/state/helpers_test.go | 2 +- dot/state/service_integration_test.go | 8 +- dot/state/storage.go | 4 +- dot/state/storage_test.go | 4 +- dot/state/tries.go | 2 +- dot/state/tries_test.go | 2 +- dot/sync/syncer_integration_test.go | 2 +- dot/utils_integration_test.go | 12 +- internal/trie/node/branch_encode.go | 16 +-- internal/trie/node/branch_encode_test.go | 8 +- internal/trie/node/copy.go | 1 + internal/trie/node/encode.go | 12 +- internal/trie/node/encode_decode_test.go | 2 +- internal/trie/node/encode_test.go | 34 ++---- internal/trie/node/hash.go | 23 ++-- internal/trie/node/hash_test.go | 8 +- internal/trie/node/header.go | 4 +- internal/trie/node/header_test.go | 7 +- internal/trie/node/node.go | 1 + lib/babe/helpers_test.go | 4 +- lib/grandpa/helpers_integration_test.go | 2 +- lib/runtime/interfaces.go | 1 + lib/runtime/storage/trie.go | 22 ++-- lib/runtime/wazero/imports.go | 4 +- lib/runtime/wazero/imports_test.go | 4 +- lib/runtime/wazero/instance.go | 18 ++- lib/runtime/wazero/instance_test.go | 23 ++-- lib/trie/child_storage.go | 7 +- lib/trie/database.go | 81 ++++++++++---- lib/trie/genesis.go | 2 +- lib/trie/layout.go | 9 +- lib/trie/proof/generate.go | 4 +- lib/trie/proof/helpers_test.go | 3 +- lib/trie/trie.go | 135 +++++++---------------- lib/trie/trie_endtoend_test.go | 2 +- tests/rpc/rpc_05-state_test.go | 2 +- 39 files changed, 245 insertions(+), 253 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index a7dc445a3e..bd659a61aa 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -218,13 +218,14 @@ func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) er } // store updates state trie nodes in database - err := s.storageState.StoreTrie(state, &block.Header) - if err != nil { - logger.Warnf("failed to store state trie for imported block %s: %s", - block.Header.Hash(), err) - return err - } - + // err := s.storageState.StoreTrie(state, &block.Header) + // if err != nil { + // logger.Warnf("failed to store state trie for imported block %s: %s", + // block.Header.Hash(), err) + // return err + // } + + var err error // store block in database if err = s.blockState.AddBlock(block); err != nil { if errors.Is(err, blocktree.ErrParentNotFound) && block.Header.Number != 0 { diff --git a/dot/rpc/modules/helpers_test.go b/dot/rpc/modules/helpers_test.go index bce60ba019..fad1310ce0 100644 --- a/dot/rpc/modules/helpers_test.go +++ b/dot/rpc/modules/helpers_test.go @@ -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() diff --git a/dot/state/base_test.go b/dot/state/base_test.go index 637ee44bb9..a6bedcde74 100644 --- a/dot/state/base_test.go +++ b/dot/state/base_test.go @@ -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) { diff --git a/dot/state/helpers_test.go b/dot/state/helpers_test.go index 10029e9f01..44abfc4de5 100644 --- a/dot/state/helpers_test.go +++ b/dot/state/helpers_test.go @@ -102,7 +102,7 @@ func newWestendDevGenesisWithTrieAndHeader(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() diff --git a/dot/state/service_integration_test.go b/dot/state/service_integration_test.go index d733b90934..8001fde090 100644 --- a/dot/state/service_integration_test.go +++ b/dot/state/service_integration_test.go @@ -90,7 +90,7 @@ func TestService_Initialise(t *testing.T) { require.NoError(t, err) genesisHeaderPtr := types.NewHeader(common.NewHash([]byte{77}), - genTrie.MustHash(trie.NoMaxInlineValueSize), trie.EmptyHash, 0, types.NewDigest()) + genTrie.MustHash(), trie.EmptyHash, 0, types.NewDigest()) err = state.Initialise(&genData, genesisHeaderPtr, genTrieCopy) require.NoError(t, err) @@ -287,7 +287,7 @@ func TestService_PruneStorage(t *testing.T) { copiedTrie := trieState.Trie().DeepCopy() var rootHash common.Hash - rootHash, err = copiedTrie.Hash(trie.NoMaxInlineValueSize) + rootHash, err = copiedTrie.Hash() require.NoError(t, err) prunedArr = append(prunedArr, prunedBlock{hash: block.Header.StateRoot, dbKey: rootHash[:]}) @@ -400,7 +400,7 @@ func TestService_Import(t *testing.T) { require.NoError(t, err) header := &types.Header{ Number: 77, - StateRoot: tr.MustHash(trie.NoMaxInlineValueSize), + StateRoot: tr.MustHash(), Digest: digest, } @@ -440,7 +440,7 @@ func generateBlockWithRandomTrie(t *testing.T, serv *Service, err = trieState.Put(key, value) require.NoError(t, err) - trieStateRoot, err := trieState.Root(trie.NoMaxInlineValueSize) + trieStateRoot, err := trieState.Root(trie.V0.MaxInlineValue()) require.NoError(t, err) if parent == nil { diff --git a/dot/state/storage.go b/dot/state/storage.go index ed8f8377a0..b9cca0d959 100644 --- a/dot/state/storage.go +++ b/dot/state/storage.go @@ -106,7 +106,7 @@ func (s *StorageState) TrieState(root *common.Hash) (*rtstorage.TrieState, error } s.tries.softSet(*root, t) - } else if t.MustHash(trie.NoMaxInlineValueSize) != *root { + } else if t.MustHash() != *root { panic("trie does not have expected root") } @@ -125,7 +125,7 @@ func (s *StorageState) LoadFromDB(root common.Hash) (*trie.Trie, error) { return nil, err } - s.tries.softSet(t.MustHash(trie.NoMaxInlineValueSize), t) + s.tries.softSet(t.MustHash(), t) return t, nil } diff --git a/dot/state/storage_test.go b/dot/state/storage_test.go index 5c66947c07..3b0039f382 100644 --- a/dot/state/storage_test.go +++ b/dot/state/storage_test.go @@ -102,7 +102,7 @@ func TestStorage_TrieState(t *testing.T) { storage.blockState.tries.delete(root) ts3, err := storage.TrieState(&root) require.NoError(t, err) - require.Equal(t, ts.Trie().MustHash(trie.NoMaxInlineValueSize), ts3.Trie().MustHash(trie.NoMaxInlineValueSize)) + require.Equal(t, ts.Trie().MustHash(), ts3.Trie().MustHash()) } func TestStorage_LoadFromDB(t *testing.T) { @@ -211,7 +211,7 @@ func TestGetStorageChildAndGetStorageFromChild(t *testing.T) { err = storage.StoreTrie(trieState, header) require.NoError(t, err) - rootHash, err := genTrie.Hash(trie.NoMaxInlineValueSize) + rootHash, err := genTrie.Hash() require.NoError(t, err) _, err = storage.GetStorageChild(&rootHash, []byte("keyToChild")) diff --git a/dot/state/tries.go b/dot/state/tries.go index d7c87bc625..19a50f034b 100644 --- a/dot/state/tries.go +++ b/dot/state/tries.go @@ -60,7 +60,7 @@ func (t *Tries) SetEmptyTrie() { // SetTrie sets the trie at its root hash in the tries map. func (t *Tries) SetTrie(tr *trie.Trie) { - t.softSet(tr.MustHash(trie.NoMaxInlineValueSize), tr) + t.softSet(tr.MustHash(), tr) } // softSet sets the given trie at the given root hash diff --git a/dot/state/tries_test.go b/dot/state/tries_test.go index cff32bfac1..16b5afa485 100644 --- a/dot/state/tries_test.go +++ b/dot/state/tries_test.go @@ -59,7 +59,7 @@ func Test_Tries_SetTrie(t *testing.T) { expectedTries := &Tries{ rootToTrie: map[common.Hash]*trie.Trie{ - tr.MustHash(trie.NoMaxInlineValueSize): tr, + tr.MustHash(): tr, }, triesGauge: triesGauge, setCounter: setCounter, diff --git a/dot/sync/syncer_integration_test.go b/dot/sync/syncer_integration_test.go index ac4ddf34e4..fa1d213d5e 100644 --- a/dot/sync/syncer_integration_test.go +++ b/dot/sync/syncer_integration_test.go @@ -137,7 +137,7 @@ func newWestendDevGenesisWithTrieAndHeader(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() diff --git a/dot/utils_integration_test.go b/dot/utils_integration_test.go index 27e0d7c738..7f4e0a67a3 100644 --- a/dot/utils_integration_test.go +++ b/dot/utils_integration_test.go @@ -36,13 +36,13 @@ func TestTrieSnapshot(t *testing.T) { newTrie := tri.Snapshot() // Get the Trie root hash for all the 3 tries. - tHash, err := tri.Hash(trie.NoMaxInlineValueSize) + tHash, err := tri.Hash() require.NoError(t, err) - dcTrieHash, err := deepCopyTrie.Hash(trie.NoMaxInlineValueSize) + dcTrieHash, err := deepCopyTrie.Hash() require.NoError(t, err) - newTrieHash, err := newTrie.Hash(trie.NoMaxInlineValueSize) + newTrieHash, err := newTrie.Hash() require.NoError(t, err) // Root hash for the 3 tries should be equal. @@ -54,13 +54,13 @@ func TestTrieSnapshot(t *testing.T) { newTrie.Put(key, value) // Get the updated root hash of all tries. - tHash, err = tri.Hash(trie.NoMaxInlineValueSize) + tHash, err = tri.Hash() require.NoError(t, err) - dcTrieHash, err = deepCopyTrie.Hash(trie.NoMaxInlineValueSize) + dcTrieHash, err = deepCopyTrie.Hash() require.NoError(t, err) - newTrieHash, err = newTrie.Hash(trie.NoMaxInlineValueSize) + newTrieHash, err = newTrie.Hash() require.NoError(t, err) // Only the current trie should have a different root hash since it is updated. diff --git a/internal/trie/node/branch_encode.go b/internal/trie/node/branch_encode.go index a3c73f714b..605d7003c2 100644 --- a/internal/trie/node/branch_encode.go +++ b/internal/trie/node/branch_encode.go @@ -18,9 +18,9 @@ type encodingAsyncResult struct { err error } -func runEncodeChild(child *Node, index, maxInlineValue int, results chan<- encodingAsyncResult, rateLimit <-chan struct{}) { +func runEncodeChild(child *Node, index int, results chan<- encodingAsyncResult, rateLimit <-chan struct{}) { buffer := bytes.NewBuffer(nil) - err := encodeChild(child, maxInlineValue, buffer) + err := encodeChild(child, buffer) results <- encodingAsyncResult{ index: index, @@ -43,7 +43,7 @@ var parallelEncodingRateLimit = make(chan struct{}, parallelLimit) // goroutines IF they are less than the parallelLimit number of goroutines already // running. This is designed to limit the total number of goroutines in order to // avoid using too much memory on the stack. -func encodeChildrenOpportunisticParallel(children []*Node, maxInlineValue int, buffer io.Writer) (err error) { +func encodeChildrenOpportunisticParallel(children []*Node, buffer io.Writer) (err error) { // Buffered channels since children might be encoded in this // goroutine or another one. resultsCh := make(chan encodingAsyncResult, ChildrenCapacity) @@ -55,7 +55,7 @@ func encodeChildrenOpportunisticParallel(children []*Node, maxInlineValue int, b } if child.Kind() == Leaf { - runEncodeChild(child, i, maxInlineValue, resultsCh, nil) + runEncodeChild(child, i, resultsCh, nil) continue } @@ -64,11 +64,11 @@ func encodeChildrenOpportunisticParallel(children []*Node, maxInlineValue int, b case parallelEncodingRateLimit <- struct{}{}: // We have a goroutine available to encode // the branch in parallel. - go runEncodeChild(child, i, maxInlineValue, resultsCh, parallelEncodingRateLimit) + go runEncodeChild(child, i, resultsCh, parallelEncodingRateLimit) default: // we reached the maximum parallel goroutines // so encode this branch in this goroutine - runEncodeChild(child, i, maxInlineValue, resultsCh, nil) + runEncodeChild(child, i, resultsCh, nil) } } @@ -117,8 +117,8 @@ func encodeChildrenOpportunisticParallel(children []*Node, maxInlineValue int, b // encodeChild computes the Merkle value of the node // and then SCALE encodes it to the given buffer. -func encodeChild(child *Node, maxInlineValue int, buffer io.Writer) (err error) { - merkleValue, err := child.CalculateMerkleValue(maxInlineValue) +func encodeChild(child *Node, buffer io.Writer) (err error) { + merkleValue, err := child.CalculateMerkleValue() if err != nil { return fmt.Errorf("computing %s Merkle value: %w", child.Kind(), err) } diff --git a/internal/trie/node/branch_encode_test.go b/internal/trie/node/branch_encode_test.go index d0be1855e4..2a513af452 100644 --- a/internal/trie/node/branch_encode_test.go +++ b/internal/trie/node/branch_encode_test.go @@ -23,7 +23,7 @@ func Benchmark_encodeChildrenOpportunisticParallel(b *testing.B) { b.Run("", func(b *testing.B) { for i := 0; i < b.N; i++ { - _ = encodeChildrenOpportunisticParallel(children, NoMaxInlineValueSize, io.Discard) + _ = encodeChildrenOpportunisticParallel(children, io.Discard) } }) } @@ -139,7 +139,7 @@ func Test_encodeChildrenOpportunisticParallel(t *testing.T) { previousCall = call } - err := encodeChildrenOpportunisticParallel(testCase.children, NoMaxInlineValueSize, buffer) + err := encodeChildrenOpportunisticParallel(testCase.children, buffer) if testCase.wrappedErr != nil { assert.ErrorIs(t, err, testCase.wrappedErr) @@ -164,7 +164,7 @@ func Test_encodeChildrenOpportunisticParallel(t *testing.T) { // Note this may run in parallel or not depending on other tests // running in parallel. - err := encodeChildrenOpportunisticParallel(children, NoMaxInlineValueSize, buffer) + err := encodeChildrenOpportunisticParallel(children, buffer) require.NoError(t, err) expectedBytes := []byte{ @@ -255,7 +255,7 @@ func Test_encodeChild(t *testing.T) { previousCall = call } - err := encodeChild(testCase.child, NoMaxInlineValueSize, buffer) + err := encodeChild(testCase.child, buffer) if testCase.wrappedErr != nil { assert.ErrorIs(t, err, testCase.wrappedErr) diff --git a/internal/trie/node/copy.go b/internal/trie/node/copy.go index 156f072f0a..1c61698b59 100644 --- a/internal/trie/node/copy.go +++ b/internal/trie/node/copy.go @@ -59,6 +59,7 @@ func (n *Node) Copy(settings CopySettings) *Node { Generation: n.Generation, Descendants: n.Descendants, IsHashedValue: n.IsHashedValue, + MustBeHashed: n.MustBeHashed, } if n.Kind() == Branch { diff --git a/internal/trie/node/encode.go b/internal/trie/node/encode.go index 35fa554efd..c6be45f0ce 100644 --- a/internal/trie/node/encode.go +++ b/internal/trie/node/encode.go @@ -15,8 +15,9 @@ import ( // The encoding format is documented in the README.md // of this package, and specified in the Polkadot spec at // https://spec.polkadot.network/#sect-state-storage -func (n *Node) Encode(buffer Buffer, maxInlineValue int) (err error) { - err = encodeHeader(n, maxInlineValue, buffer) +func (n *Node) Encode(buffer Buffer) (err error) { + // TODO: move trie layout + err = encodeHeader(n, n.MustBeHashed, buffer) if err != nil { return fmt.Errorf("cannot encode header: %w", err) } @@ -46,7 +47,8 @@ func (n *Node) Encode(buffer Buffer, maxInlineValue int) (err error) { // even if it is empty. Do not encode if the branch is without value. // Note leaves and branches with value cannot have a `nil` storage value. if n.StorageValue != nil { - if len(n.StorageValue) > maxInlineValue && n.IsHashedValue { + switch { + case n.MustBeHashed: hashedValue, err := common.Blake2bHash(n.StorageValue) if err != nil { return fmt.Errorf("hashing storage value: %w", err) @@ -56,7 +58,7 @@ func (n *Node) Encode(buffer Buffer, maxInlineValue int) (err error) { if err != nil { return fmt.Errorf("scale encoding storage value: %w", err) } - } else { + default: encoder := scale.NewEncoder(buffer) err = encoder.Encode(n.StorageValue) if err != nil { @@ -66,7 +68,7 @@ func (n *Node) Encode(buffer Buffer, maxInlineValue int) (err error) { } if nodeIsBranch { - err = encodeChildrenOpportunisticParallel(n.Children, maxInlineValue, buffer) + err = encodeChildrenOpportunisticParallel(n.Children, buffer) if err != nil { return fmt.Errorf("cannot encode children of branch: %w", err) } diff --git a/internal/trie/node/encode_decode_test.go b/internal/trie/node/encode_decode_test.go index 8eed629bae..71974ff907 100644 --- a/internal/trie/node/encode_decode_test.go +++ b/internal/trie/node/encode_decode_test.go @@ -118,7 +118,7 @@ func Test_Branch_Encode_Decode(t *testing.T) { buffer := bytes.NewBuffer(nil) - err := testCase.branchToEncode.Encode(buffer, NoMaxInlineValueSize) + err := testCase.branchToEncode.Encode(buffer) require.NoError(t, err) nodeVariant, partialKeyLength, err := decodeHeader(buffer) diff --git a/internal/trie/node/encode_test.go b/internal/trie/node/encode_test.go index e3c13316d6..fa2ea50867 100644 --- a/internal/trie/node/encode_test.go +++ b/internal/trie/node/encode_test.go @@ -5,7 +5,6 @@ package node import ( "errors" - "math" "testing" "github.com/ChainSafe/gossamer/lib/common" @@ -14,8 +13,6 @@ import ( "go.uber.org/mock/gomock" ) -const NoMaxInlineValueSize = math.MaxInt - type writeCall struct { written []byte n int // number of bytes @@ -31,15 +28,13 @@ func Test_Node_Encode(t *testing.T) { hashedLargeValue := common.MustBlake2bHash(largeValue).ToBytes() testCases := map[string]struct { - node *Node - maxInlineValueSize int - writes []writeCall - wrappedErr error - errMessage string + node *Node + writes []writeCall + wrappedErr error + errMessage string }{ "nil_node": { - node: nil, - maxInlineValueSize: NoMaxInlineValueSize, + node: nil, writes: []writeCall{ { written: []byte{emptyVariant.bits}, @@ -50,7 +45,6 @@ func Test_Node_Encode(t *testing.T) { node: &Node{ PartialKey: make([]byte, 1), }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { written: []byte{leafVariant.bits | 1}, @@ -65,7 +59,6 @@ func Test_Node_Encode(t *testing.T) { PartialKey: []byte{1, 2, 3}, StorageValue: []byte{1}, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { written: []byte{leafVariant.bits | 3}, // partial key length 3 @@ -83,7 +76,6 @@ func Test_Node_Encode(t *testing.T) { PartialKey: []byte{1, 2, 3}, StorageValue: []byte{4, 5, 6}, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { written: []byte{leafVariant.bits | 3}, // partial key length 3 @@ -104,7 +96,6 @@ func Test_Node_Encode(t *testing.T) { PartialKey: []byte{1, 2, 3}, StorageValue: []byte{4, 5, 6}, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { written: []byte{leafVariant.bits | 3}, // partial key length 3 @@ -119,7 +110,6 @@ func Test_Node_Encode(t *testing.T) { PartialKey: []byte{1, 2, 3}, StorageValue: []byte{}, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ {written: []byte{leafVariant.bits | 3}}, // partial key length 3 {written: []byte{0x01, 0x23}}, // partial key @@ -131,8 +121,8 @@ func Test_Node_Encode(t *testing.T) { node: &Node{ PartialKey: []byte{1, 2, 3}, StorageValue: largeValue, + MustBeHashed: true, }, - maxInlineValueSize: 32, writes: []writeCall{ { written: []byte{leafWithHashedValueVariant.bits | 3}, @@ -146,8 +136,8 @@ func Test_Node_Encode(t *testing.T) { PartialKey: []byte{1, 2, 3}, StorageValue: largeValue, IsHashedValue: true, + MustBeHashed: false, }, - maxInlineValueSize: 32, writes: []writeCall{ { written: []byte{leafWithHashedValueVariant.bits | 3}, @@ -183,7 +173,6 @@ func Test_Node_Encode(t *testing.T) { PartialKey: []byte{1, 2, 3}, StorageValue: []byte{100}, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { // header written: []byte{branchWithValueVariant.bits | 3}, // partial key length 3 @@ -205,7 +194,6 @@ func Test_Node_Encode(t *testing.T) { nil, nil, nil, {PartialKey: []byte{11}, StorageValue: []byte{1}}, }, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { // header written: []byte{branchWithValueVariant.bits | 3}, // partial key length 3 @@ -230,7 +218,6 @@ func Test_Node_Encode(t *testing.T) { nil, nil, nil, {PartialKey: []byte{11}, StorageValue: []byte{1}}, }, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { // header written: []byte{branchWithValueVariant.bits | 3}, // partial key length 3 @@ -258,7 +245,6 @@ func Test_Node_Encode(t *testing.T) { nil, nil, nil, {PartialKey: []byte{11}, StorageValue: []byte{1}}, }, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { // header written: []byte{branchWithValueVariant.bits | 3}, // partial key length 3 @@ -291,7 +277,6 @@ func Test_Node_Encode(t *testing.T) { nil, nil, nil, {PartialKey: []byte{11}, StorageValue: []byte{1}}, }, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { // header written: []byte{branchWithValueVariant.bits | 3}, // partial key length 3 @@ -321,7 +306,6 @@ func Test_Node_Encode(t *testing.T) { nil, nil, nil, {PartialKey: []byte{11}, StorageValue: []byte{1}}, }, }, - maxInlineValueSize: NoMaxInlineValueSize, writes: []writeCall{ { // header written: []byte{branchVariant.bits | 3}, // partial key length 3 @@ -344,12 +328,12 @@ func Test_Node_Encode(t *testing.T) { node: &Node{ PartialKey: []byte{1, 2, 3}, StorageValue: largeValue, + MustBeHashed: true, Children: []*Node{ nil, nil, nil, {PartialKey: []byte{9}, StorageValue: []byte{1}}, nil, nil, nil, {PartialKey: []byte{11}, StorageValue: []byte{1}}, }, }, - maxInlineValueSize: 32, writes: []writeCall{ { // header written: []byte{branchWithHashedValueVariant.bits | 3}, // partial key length 3 @@ -392,7 +376,7 @@ func Test_Node_Encode(t *testing.T) { previousCall = call } - err := testCase.node.Encode(buffer, testCase.maxInlineValueSize) + err := testCase.node.Encode(buffer) if testCase.wrappedErr != nil { assert.ErrorIs(t, err, testCase.wrappedErr) diff --git a/internal/trie/node/hash.go b/internal/trie/node/hash.go index f721a6830f..595e06fc0f 100644 --- a/internal/trie/node/hash.go +++ b/internal/trie/node/hash.go @@ -55,12 +55,12 @@ func hashEncoding(encoding []byte, writer io.Writer) (err error) { } // CalculateMerkleValue returns the Merkle value of the non-root node. -func (n *Node) CalculateMerkleValue(maxInlineValue int) (merkleValue []byte, err error) { +func (n *Node) CalculateMerkleValue() (merkleValue []byte, err error) { if !n.Dirty && n.MerkleValue != nil { return n.MerkleValue, nil } - _, merkleValue, err = n.EncodeAndHash(maxInlineValue) + _, merkleValue, err = n.EncodeAndHash() if err != nil { return nil, fmt.Errorf("encoding and hashing node: %w", err) } @@ -69,13 +69,13 @@ func (n *Node) CalculateMerkleValue(maxInlineValue int) (merkleValue []byte, err } // CalculateRootMerkleValue returns the Merkle value of the root node. -func (n *Node) CalculateRootMerkleValue(maxInlineValue int) (merkleValue []byte, err error) { +func (n *Node) CalculateRootMerkleValue() (merkleValue []byte, err error) { const rootMerkleValueLength = 32 - // if !n.Dirty && len(n.MerkleValue) == rootMerkleValueLength { - // return n.MerkleValue, nil - // } + if !n.Dirty && len(n.MerkleValue) == rootMerkleValueLength { + return n.MerkleValue, nil + } - _, merkleValue, err = n.EncodeAndHashRoot(maxInlineValue) + _, merkleValue, err = n.EncodeAndHashRoot() if err != nil { return nil, fmt.Errorf("encoding and hashing root node: %w", err) } @@ -89,9 +89,9 @@ func (n *Node) CalculateRootMerkleValue(maxInlineValue int) (merkleValue []byte, // TODO change this function to write to an encoding writer // and a merkle value writer, such that buffer sync pools can be used // by the caller. -func (n *Node) EncodeAndHash(maxInlineValue int) (encoding, merkleValue []byte, err error) { +func (n *Node) EncodeAndHash() (encoding, merkleValue []byte, err error) { encodingBuffer := bytes.NewBuffer(nil) - err = n.Encode(encodingBuffer, maxInlineValue) + err = n.Encode(encodingBuffer) if err != nil { return nil, nil, fmt.Errorf("encoding node: %w", err) } @@ -115,9 +115,9 @@ func (n *Node) EncodeAndHash(maxInlineValue int) (encoding, merkleValue []byte, // TODO change this function to write to an encoding writer // and a merkle value writer, such that buffer sync pools can be used // by the caller. -func (n *Node) EncodeAndHashRoot(maxInlineValue int) (encoding, merkleValue []byte, err error) { +func (n *Node) EncodeAndHashRoot() (encoding, merkleValue []byte, err error) { encodingBuffer := bytes.NewBuffer(nil) - err = n.Encode(encodingBuffer, maxInlineValue) + err = n.Encode(encodingBuffer) if err != nil { return nil, nil, fmt.Errorf("encoding node: %w", err) } @@ -130,7 +130,6 @@ func (n *Node) EncodeAndHashRoot(maxInlineValue int) (encoding, merkleValue []by return nil, nil, fmt.Errorf("merkle value: %w", err) } merkleValue = merkleValueBuffer.Bytes() - fmt.Printf("caching merkle value using %v\n", maxInlineValue) n.MerkleValue = merkleValue // no need to copy return encoding, merkleValue, nil diff --git a/internal/trie/node/hash_test.go b/internal/trie/node/hash_test.go index 62c8fa69c2..66c584b1d2 100644 --- a/internal/trie/node/hash_test.go +++ b/internal/trie/node/hash_test.go @@ -197,7 +197,7 @@ func Test_Node_CalculateMerkleValue(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - merkleValue, err := testCase.node.CalculateMerkleValue(NoMaxInlineValueSize) + merkleValue, err := testCase.node.CalculateMerkleValue() assert.ErrorIs(t, err, testCase.errWrapped) if testCase.errWrapped != nil { @@ -259,7 +259,7 @@ func Test_Node_CalculateRootMerkleValue(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - merkleValue, err := testCase.node.CalculateRootMerkleValue(NoMaxInlineValueSize) + merkleValue, err := testCase.node.CalculateRootMerkleValue() assert.ErrorIs(t, err, testCase.errWrapped) if testCase.errWrapped != nil { @@ -346,7 +346,7 @@ func Test_Node_EncodeAndHash(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - encoding, hash, err := testCase.node.EncodeAndHash(NoMaxInlineValueSize) + encoding, hash, err := testCase.node.EncodeAndHash() assert.ErrorIs(t, err, testCase.errWrapped) if testCase.errWrapped != nil { @@ -400,7 +400,7 @@ func Test_Node_EncodeAndHashRoot(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - encoding, hash, err := testCase.node.EncodeAndHashRoot(NoMaxInlineValueSize) + encoding, hash, err := testCase.node.EncodeAndHashRoot() assert.ErrorIs(t, err, testCase.errWrapped) if testCase.errWrapped != nil { diff --git a/internal/trie/node/header.go b/internal/trie/node/header.go index cfc397fa35..d450d2ded9 100644 --- a/internal/trie/node/header.go +++ b/internal/trie/node/header.go @@ -10,7 +10,7 @@ import ( ) // encodeHeader writes the encoded header for the node. -func encodeHeader(node *Node, maxInlineValueSize int, writer io.Writer) (err error) { +func encodeHeader(node *Node, isHashedValue bool, writer io.Writer) (err error) { if node == nil { _, err = writer.Write([]byte{emptyVariant.bits}) return err @@ -21,8 +21,6 @@ func encodeHeader(node *Node, maxInlineValueSize int, writer io.Writer) (err err panic(fmt.Sprintf("partial key length is too big: %d", partialKeyLength)) } - isHashedValue := len(node.StorageValue) > maxInlineValueSize && node.IsHashedValue - // Merge variant byte and partial key length together var nodeVariant variant if node.Kind() == Leaf { diff --git a/internal/trie/node/header_test.go b/internal/trie/node/header_test.go index 4f26b2e446..bd31f4dd4c 100644 --- a/internal/trie/node/header_test.go +++ b/internal/trie/node/header_test.go @@ -240,7 +240,8 @@ func Test_encodeHeader(t *testing.T) { previousCall = call } - err := encodeHeader(testCase.node, testCase.maxInlineValueSize, writer) + isHashedValue := len(testCase.node.StorageValue) > testCase.maxInlineValueSize + err := encodeHeader(testCase.node, isHashedValue, writer) assert.ErrorIs(t, err, testCase.errWrapped) if testCase.errWrapped != nil { @@ -258,7 +259,7 @@ func Test_encodeHeader(t *testing.T) { } assert.PanicsWithValue(t, "partial key length is too big: 65536", func() { - _ = encodeHeader(node, 0, io.Discard) + _ = encodeHeader(node, true, io.Discard) }) }) } @@ -293,7 +294,7 @@ func Test_encodeHeader_At_Maximum(t *testing.T) { PartialKey: make([]byte, keyLength), } - err := encodeHeader(node, NoMaxInlineValueSize, buffer) + err := encodeHeader(node, false, buffer) require.NoError(t, err) assert.Equal(t, expectedBytes, buffer.Bytes()) diff --git a/internal/trie/node/node.go b/internal/trie/node/node.go index 4510fabd89..42296e5026 100644 --- a/internal/trie/node/node.go +++ b/internal/trie/node/node.go @@ -17,6 +17,7 @@ type Node struct { // PartialKey is the partial key bytes in nibbles (0 to f in hexadecimal) PartialKey []byte StorageValue []byte + MustBeHashed bool // IsHashedValue is true when the StorageValue is a blake2b hash IsHashedValue bool // Generation is incremented on every trie Snapshot() call. diff --git a/lib/babe/helpers_test.go b/lib/babe/helpers_test.go index f21eec6984..264656496d 100644 --- a/lib/babe/helpers_test.go +++ b/lib/babe/helpers_test.go @@ -375,7 +375,7 @@ func newWestendLocalGenesisWithTrieAndHeader(t *testing.T) ( require.NoError(t, err) genesisHeader = *types.NewHeader(common.NewHash([]byte{0}), - genesisTrie.MustHash(trie.NoMaxInlineValueSize), trie.EmptyHash, 0, types.NewDigest()) + genesisTrie.MustHash(), trie.EmptyHash, 0, types.NewDigest()) return gen, genesisTrie, genesisHeader } @@ -394,7 +394,7 @@ func newWestendDevGenesisWithTrieAndHeader(t *testing.T) ( require.NoError(t, err) genesisHeader = *types.NewHeader(common.NewHash([]byte{0}), - genesisTrie.MustHash(trie.NoMaxInlineValueSize), trie.EmptyHash, 0, types.NewDigest()) + genesisTrie.MustHash(), trie.EmptyHash, 0, types.NewDigest()) return gen, genesisTrie, genesisHeader } diff --git a/lib/grandpa/helpers_integration_test.go b/lib/grandpa/helpers_integration_test.go index 0c80b8dce9..2f705d909b 100644 --- a/lib/grandpa/helpers_integration_test.go +++ b/lib/grandpa/helpers_integration_test.go @@ -203,7 +203,7 @@ func newWestendDevGenesisWithTrieAndHeader(t *testing.T) ( assert.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() diff --git a/lib/runtime/interfaces.go b/lib/runtime/interfaces.go index 2fb1f4799d..788b049e52 100644 --- a/lib/runtime/interfaces.go +++ b/lib/runtime/interfaces.go @@ -34,6 +34,7 @@ type Storage interface { CommitTransaction() RollbackTransaction() LoadCode() []byte + SetVersion(v trie.TrieLayout) } // BasicNetwork interface for functions used by runtime network state function diff --git a/lib/runtime/storage/trie.go b/lib/runtime/storage/trie.go index cde6450e79..39ff19e66e 100644 --- a/lib/runtime/storage/trie.go +++ b/lib/runtime/storage/trie.go @@ -44,8 +44,7 @@ func (t *TrieState) StartTransaction() { t.mtx.Lock() defer t.mtx.Unlock() - fmt.Println("STARTING A TRANSACTION") - + fmt.Println("START TRANSACTION") t.transactions.PushBack(t.getCurrentTrie().Snapshot()) } @@ -58,8 +57,6 @@ func (t *TrieState) RollbackTransaction() { panic("no transactions to rollback") } - fmt.Println("ROLLBACK A TRANSACTION") - t.transactions.Remove(t.transactions.Back()) } @@ -72,10 +69,18 @@ func (t *TrieState) CommitTransaction() { panic("no transactions to commit") } - fmt.Println("COMMITING A TRANSACTION") + fmt.Println("COMMIT TRANSACTION") + t.transactions.Back().Prev().Value = t.transactions.Remove(t.transactions.Back()) } +func (t *TrieState) SetVersion(v trie.TrieLayout) { + t.mtx.Lock() + defer t.mtx.Unlock() + fmt.Println("setting curent trie to vesion: ", v) + t.getCurrentTrie().SetVersion(v) +} + // Trie returns the TrieState's underlying trie func (t *TrieState) Trie() *trie.Trie { return t.getCurrentTrie() @@ -108,7 +113,7 @@ func (t *TrieState) MustRoot(maxInlineValue int) common.Hash { t.mtx.RLock() defer t.mtx.RUnlock() - return t.getCurrentTrie().MustHash(maxInlineValue) + return t.getCurrentTrie().MustHash() } // Root returns the trie's root hash @@ -116,10 +121,7 @@ func (t *TrieState) Root(maxInlineValue int) (common.Hash, error) { t.mtx.RLock() defer t.mtx.RUnlock() - currentTrie := t.getCurrentTrie() - currentTrie.HashOnlyDeltas(maxInlineValue) - - return currentTrie.Hash(maxInlineValue) + return t.getCurrentTrie().Hash() } // Has returns whether or not a key exists diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index 01b94df8f2..31faebc3ba 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -2187,8 +2187,8 @@ func ext_storage_next_key_version_1(ctx context.Context, m api.Module, keySpan u key := read(m, keySpan) next := storage.NextKey(key) - fmt.Printf( - "[ext_storage_next_key_version_1] key: 0x%x; next key 0x%x\n", + logger.Debugf( + "[ext_storage_next_key_version_1] key: 0x%x; next key 0x%x", key, next) var encodedOption []byte diff --git a/lib/runtime/wazero/imports_test.go b/lib/runtime/wazero/imports_test.go index 5ecd82b41d..03a5efd29b 100644 --- a/lib/runtime/wazero/imports_test.go +++ b/lib/runtime/wazero/imports_test.go @@ -567,7 +567,7 @@ func Test_ext_trie_blake2_256_root_version_1(t *testing.T) { tt.Put([]byte("noot"), []byte("was")) tt.Put([]byte("here"), []byte("??")) - expected := tt.MustHash(trie.NoMaxInlineValueSize) + expected := tt.MustHash() require.Equal(t, expected[:], hash) } @@ -599,7 +599,7 @@ func Test_ext_trie_blake2_256_root_version_2(t *testing.T) { tt.Put([]byte("dimartiro"), []byte("was")) tt.Put([]byte("here"), []byte("??")) - expected := tt.MustHash(stateVersion.MaxInlineValue()) + expected := tt.MustHash() require.Equal(t, expected[:], hash) } diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index 42743ce9f4..a98df8b4c8 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -417,8 +417,7 @@ func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { } allocator := allocator.NewFreeingBumpHeapAllocator(hb) - - return &Instance{ + instance = &Instance{ Runtime: rt, Context: &runtime.Context{ Storage: cfg.Storage, @@ -433,7 +432,9 @@ func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { }, Module: mod, codeHash: cfg.CodeHash, - }, nil + } + + return instance, nil } var ErrExportFunctionNotFound = errors.New("export function not found") @@ -854,6 +855,17 @@ func (in *Instance) Validator() bool { func (in *Instance) SetContextStorage(s runtime.Storage) { in.Lock() defer in.Unlock() + + if in.Context.Version == nil { + panic("expected runtime version") + } + + runtimeStateVersion, err := trie.ParseVersion(in.Context.Version.StateVersion) + if err != nil { + panic(err) + } + + s.SetVersion(runtimeStateVersion) in.Context.Storage = s } diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index d79f3fa4d9..52cb901af9 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -1285,7 +1285,7 @@ func TestTrie(t *testing.T) { tt.Put([]byte("al"), make([]byte, 40)) tt.Put([]byte("alfa"), make([]byte, 40)) - hash, err := tt.Hash(trie.V0.MaxInlineValue()) + hash, err := tt.Hash() require.NoError(t, err) fmt.Printf("%s\n", hash.String()) // 0xdf1012a786cddcdfa4a8cf015e873677bc2e7a3c8b3579d9bae93117cbcfb7c1 @@ -1295,7 +1295,8 @@ func TestTrie(t *testing.T) { tt.Put([]byte("al"), make([]byte, 40)) tt.Put([]byte("alfa"), make([]byte, 40)) - hash, err = tt.Hash(trie.V1.MaxInlineValue()) + tt.SetVersion(trie.V1) + hash, err = tt.Hash() require.NoError(t, err) fmt.Printf("%s\n", hash.String()) // 0x99a5fee4d1d352a6e6530ce4c965d1063abe92e2a3327da07061c6730f221583 @@ -1336,17 +1337,17 @@ func TestDebugWestendBlock14576855(t *testing.T) { } func TestDebugWestendBlock14576856(t *testing.T) { - wnd14576854StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") + wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") - require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) + require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) - state := storage.NewTrieState(wnd14576854StateTrie) - cfg := Config{ - Storage: state, - LogLvl: log.Critical, - } + state := storage.NewTrieState(wnd14576855StateTrie) + instance, err := NewInstanceFromTrie(wnd14576855StateTrie, Config{ + LogLvl: log.Critical, + }) + instance.version() + instance.SetContextStorage(state) - instance, err := NewInstanceFromTrie(wnd14576854StateTrie, cfg) require.NoError(t, err) blockResponseBytes, err := common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") @@ -1363,8 +1364,6 @@ func TestDebugWestendBlock14576856(t *testing.T) { Body: *blockData.Body, } - instance.version() - _, err = instance.ExecuteBlock(block) require.NoError(t, err) } diff --git a/lib/trie/child_storage.go b/lib/trie/child_storage.go index 9acdae02b3..c5363907cf 100644 --- a/lib/trie/child_storage.go +++ b/lib/trie/child_storage.go @@ -19,7 +19,7 @@ var ErrChildTrieDoesNotExist = errors.New("child trie does not exist") // A child trie is added as a node (K, V) in the main trie. K is the child storage key // associated to the child trie, and V is the root hash of the child trie. func (t *Trie) SetChild(keyToChild []byte, child *Trie) error { - childHash, err := child.Hash(NoMaxInlineValueSize) + childHash, err := child.Hash() if err != nil { return err } @@ -62,8 +62,9 @@ func (t *Trie) PutIntoChild(keyToChild, key, value []byte) error { return fmt.Errorf("getting child: %w", err) } } + child.version = t.version - origChildHash, err := child.Hash(NoMaxInlineValueSize) + origChildHash, err := child.Hash() if err != nil { return err } @@ -117,7 +118,7 @@ func (t *Trie) ClearFromChild(keyToChild, key []byte) error { return fmt.Errorf("%w at key 0x%x%x", ErrChildTrieDoesNotExist, ChildStorageKeyPrefix, keyToChild) } - origChildHash, err := child.Hash(NoMaxInlineValueSize) + origChildHash, err := child.Hash() if err != nil { return err } diff --git a/lib/trie/database.go b/lib/trie/database.go index 667ccec5df..57bac53230 100644 --- a/lib/trie/database.go +++ b/lib/trie/database.go @@ -39,10 +39,36 @@ func (t *Trie) Load(db db.DBGetter, rootHash common.Hash) error { return fmt.Errorf("cannot decode root node: %w", err) } + err = loadStorageValue(db, root) + if err != nil { + return fmt.Errorf("while decoding storage value for root: %w", err) + } + t.root = root t.root.MerkleValue = rootHashBytes - return t.loadNode(db, t.root) + err = t.loadNode(db, t.root) + if err != nil { + return err + } + + for _, key := range t.GetKeysWithPrefix(ChildStorageKeyPrefix) { + childTrie := NewEmptyTrie() + value := t.Get(key) + rootHash := common.BytesToHash(value) + err := childTrie.Load(db, rootHash) + if err != nil { + return fmt.Errorf("failed to load child trie with root hash=%s: %w", rootHash, err) + } + + hash, err := childTrie.Hash() + if err != nil { + return fmt.Errorf("cannot hash chilld trie at key 0x%x: %w", key, err) + } + t.childTries[hash] = childTrie + } + + return nil } func (t *Trie) loadNode(db db.DBGetter, n *Node) error { @@ -61,7 +87,7 @@ func (t *Trie) loadNode(db db.DBGetter, n *Node) error { if len(merkleValue) < 32 { // node has already been loaded inline // just set its encoding - _, err := child.CalculateMerkleValue(NoMaxInlineValueSize) + _, err := child.CalculateMerkleValue() if err != nil { return fmt.Errorf("merkle value: %w", err) } @@ -80,6 +106,11 @@ func (t *Trie) loadNode(db db.DBGetter, n *Node) error { return fmt.Errorf("decoding node with hash 0x%x: %w", nodeHash, err) } + err = loadStorageValue(db, decodedNode) + if err != nil { + return fmt.Errorf("while decoding storage value: %w", err) + } + decodedNode.MerkleValue = nodeHash branch.Children[i] = decodedNode @@ -99,23 +130,24 @@ func (t *Trie) loadNode(db db.DBGetter, n *Node) error { branch.Descendants += childBranchDescendants } } + return nil +} - for _, key := range t.GetKeysWithPrefix(ChildStorageKeyPrefix) { - childTrie := NewEmptyTrie() - value := t.Get(key) - rootHash := common.BytesToHash(value) - err := childTrie.Load(db, rootHash) - if err != nil { - return fmt.Errorf("failed to load child trie with root hash=%s: %w", rootHash, err) - } +func loadStorageValue(db db.DBGetter, node *Node) error { + if !node.IsHashedValue { + return nil + } - hash, err := childTrie.Hash(NoMaxInlineValueSize) - if err != nil { - return fmt.Errorf("cannot hash chilld trie at key 0x%x: %w", key, err) - } - t.childTries[hash] = childTrie + fmt.Println("loading a hashed value!!") + prefixedKey := bytes.Join([][]byte{node.PartialKey, node.StorageValue[:]}, nil) + rawStorageValue, err := db.Get(prefixedKey) + if err != nil { + return err } + node.IsHashedValue = false + node.MustBeHashed = true + node.StorageValue = rawStorageValue return nil } @@ -289,10 +321,21 @@ func (t *Trie) writeDirtyNode(db db.DBPutter, n *Node) (err error) { // TODO: I'm sure we don't need to store the encoded now, we can try storing the (key,value) only but it needs // some refactor and testing. In the meantime we can store the encoded node using the v0 encoding if n == t.root { - encoding, merkleValue, err = n.EncodeAndHashRoot(V0.MaxInlineValue()) + encoding, merkleValue, err = n.EncodeAndHashRoot() } else { - encoding, merkleValue, err = n.EncodeAndHash(V0.MaxInlineValue()) + encoding, merkleValue, err = n.EncodeAndHash() + } + + if n.MustBeHashed { + hashedValue := common.MustBlake2bHash(n.StorageValue) + if err != nil { + return err + } + + prefixedKey := bytes.Join([][]byte{n.PartialKey, hashedValue[:]}, nil) + err = db.Put(prefixedKey, n.StorageValue) } + if err != nil { return fmt.Errorf( "encoding and hashing node with Merkle value 0x%x: %w", @@ -366,9 +409,9 @@ func (t *Trie) getInsertedNodeHashesAtNode(n *Node, nodeHashes map[common.Hash]s var merkleValue []byte if n == t.root { - merkleValue, err = n.CalculateRootMerkleValue(NoMaxInlineValueSize) + merkleValue, err = n.CalculateRootMerkleValue() } else { - merkleValue, err = n.CalculateMerkleValue(NoMaxInlineValueSize) + merkleValue, err = n.CalculateMerkleValue() } if err != nil { return fmt.Errorf("calculating Merkle value: %w", err) diff --git a/lib/trie/genesis.go b/lib/trie/genesis.go index d2205208b1..c4e6e21737 100644 --- a/lib/trie/genesis.go +++ b/lib/trie/genesis.go @@ -12,7 +12,7 @@ import ( // GenesisBlock creates a genesis block from the trie. func (t *Trie) GenesisBlock() (genesisHeader types.Header, err error) { - rootHash, err := t.Hash(NoMaxInlineValueSize) + rootHash, err := t.Hash() if err != nil { return genesisHeader, fmt.Errorf("root hashing trie: %w", err) } diff --git a/lib/trie/layout.go b/lib/trie/layout.go index 5758a7b23a..f83f127a47 100644 --- a/lib/trie/layout.go +++ b/lib/trie/layout.go @@ -74,6 +74,7 @@ func (v TrieLayout) MaxInlineValue() int { // Root returns the root hash of the trie built using the given entries func (v TrieLayout) Root(entries Entries) (common.Hash, error) { t := NewEmptyTrie() + t.SetVersion(v) for _, kv := range entries { err := t.Put(kv.Key, kv.Value) @@ -82,17 +83,19 @@ func (v TrieLayout) Root(entries Entries) (common.Hash, error) { } } - return t.Hash(v.MaxInlineValue()) + return t.Hash() } // Hash returns the root hash of the trie built using the given entries func (v TrieLayout) Hash(t *Trie) (common.Hash, error) { - return t.Hash(v.MaxInlineValue()) + t.SetVersion(v) + return t.Hash() } // MustHash returns the root hash of the trie built using the given entries or panics if it fails func (v TrieLayout) MustHash(t Trie) common.Hash { - return t.MustHash(v.MaxInlineValue()) + t.SetVersion(v) + return t.MustHash() } // ParseVersion parses a state trie version string. diff --git a/lib/trie/proof/generate.go b/lib/trie/proof/generate.go index 0daca83e52..8b6efbf4db 100644 --- a/lib/trie/proof/generate.go +++ b/lib/trie/proof/generate.go @@ -81,7 +81,7 @@ func walkRoot(root *node.Node, fullKey []byte) ( // Note we do not use sync.Pool buffers since we would have // to copy it so it persists in encodedProofNodes. encodingBuffer := bytes.NewBuffer(nil) - err = root.Encode(encodingBuffer, trie.NoMaxInlineValueSize) + err = root.Encode(encodingBuffer) if err != nil { return nil, fmt.Errorf("encode node: %w", err) } @@ -126,7 +126,7 @@ func walk(parent *node.Node, fullKey []byte) ( // Note we do not use sync.Pool buffers since we would have // to copy it so it persists in encodedProofNodes. encodingBuffer := bytes.NewBuffer(nil) - err = parent.Encode(encodingBuffer, trie.NoMaxInlineValueSize) + err = parent.Encode(encodingBuffer) if err != nil { return nil, fmt.Errorf("encode node: %w", err) } diff --git a/lib/trie/proof/helpers_test.go b/lib/trie/proof/helpers_test.go index 58ec6bb417..de3d6fe25a 100644 --- a/lib/trie/proof/helpers_test.go +++ b/lib/trie/proof/helpers_test.go @@ -10,7 +10,6 @@ import ( "github.com/ChainSafe/gossamer/internal/trie/node" "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/stretchr/testify/require" ) @@ -24,7 +23,7 @@ func padRightChildren(slice []*node.Node) (paddedSlice []*node.Node) { func encodeNode(t *testing.T, node node.Node) (encoded []byte) { t.Helper() buffer := bytes.NewBuffer(nil) - err := node.Encode(buffer, trie.NoMaxInlineValueSize) + err := node.Encode(buffer) require.NoError(t, err) return buffer.Bytes() } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index e343fba3c9..5ab4682ed0 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -25,6 +25,7 @@ type Trie struct { root *Node childTries map[common.Hash]*Trie db db.Database + version TrieLayout // deltas stores trie deltas since the last trie snapshot. // For example node hashes that were deleted since // the last snapshot. These are used by the online @@ -46,9 +47,14 @@ func NewTrie(root *Node, db db.Database) *Trie { db: db, generation: 0, // Initially zero but increases after every snapshot. deltas: tracking.New(), + version: V0, } } +func (t *Trie) SetVersion(v TrieLayout) { + t.version = v +} + // Equal is to compare one trie with other, this method will ignore the shared db instance func (t *Trie) Equal(other *Trie) bool { if t == nil && other == nil { @@ -79,27 +85,28 @@ func (t *Trie) Snapshot() (newTrie *Trie) { generation: childTrie.generation + 1, root: childTrie.root.Copy(rootCopySettings), deltas: childTrie.deltas.DeepCopy(), + version: t.version, } } - fmt.Printf("len of deltas updated: %d\n", len(t.deltas.Updated())) - return &Trie{ generation: t.generation + 1, root: t.root, db: t.db, childTries: childTries, deltas: t.deltas.DeepCopy(), + version: t.version, } } // handleTrackedDeltas sets the pending deleted node hashes in // the trie deltas tracker if and only if success is true. func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas tracking.Getter) { - if !success || t.generation == 0 { - // Do not persist tracked deleted node hashes if the operation failed or - // if the trie generation is zero (first block, no trie snapshot done yet). - } + // if !success || t.generation == 0 { + // // Do not persist tracked deleted node hashes if the operation failed or + // // if the trie generation is zero (first block, no trie snapshot done yet). + // return + // } t.deltas.MergeWith(pendingDeltas) } @@ -119,6 +126,7 @@ func (t *Trie) prepForMutation(currentNode *Node, newNode = currentNode.Copy(copySettings) newNode.Generation = t.generation } + newNode.SetDirty() return newNode, nil } @@ -160,6 +168,7 @@ func (t *Trie) DeepCopy() (trieCopy *Trie) { trieCopy = &Trie{ generation: t.generation, db: t.db, + version: t.version, } if t.deltas != nil { @@ -192,8 +201,8 @@ func (t *Trie) RootNode() *Node { // MustHash returns the hashed root of the trie. // It panics if it fails to hash the root node. -func (t *Trie) MustHash(maxInlineValue int) common.Hash { - h, err := t.Hash(maxInlineValue) +func (t *Trie) MustHash() common.Hash { + h, err := t.Hash() if err != nil { panic(err) } @@ -201,39 +210,13 @@ func (t *Trie) MustHash(maxInlineValue int) common.Hash { return h } -func (t *Trie) HashOnlyDeltas(maxInlineValue int) { - fmt.Println("hashing only deltas...") - updatedDeltas := t.deltas.Updated() - - fmt.Println("len of updated:", len(updatedDeltas)) - - for _, entries := range updatedDeltas { - t.MarkAsV1HashedNode(entries.Key) - } -} - // Hash returns the hashed root of the trie. -func (t *Trie) Hash(maxInlineValue int) (rootHash common.Hash, err error) { +func (t *Trie) Hash() (rootHash common.Hash, err error) { if t.root == nil { return EmptyHash, nil } - // TODO: Critical changing the child trie root hash in the state - // needs to reflect also in the childTries map - // or we can use a snapshot to perform the hash encoding - // if maxInlineValue == V1MaxInlineValueSize { - // fmt.Printf("child tries len: %d\n", len(t.childTries)) - // for _, childTrie := range t.childTries { - // v1Hash, err := childTrie.Hash(maxInlineValue) - // if err != nil { - // return rootHash, err - // } - - // t.Put(childTrie.childTriePartialKey, v1Hash[:]) - // } - // } - - merkleValue, err := t.root.CalculateRootMerkleValue(maxInlineValue) + merkleValue, err := t.root.CalculateRootMerkleValue() if err != nil { return rootHash, err } @@ -368,59 +351,6 @@ func findNextKeyChild(children []*Node, startIndex byte, return nil } -// Put inserts a value into the trie at the -// key specified in little Endian format. -func (t *Trie) MarkAsV1HashedNode(keyLE []byte) { - t.markAsHashed(keyLE) -} - -func (t *Trie) markAsHashed(keyLE []byte) { - nibblesKey := codec.KeyLEToNibbles(keyLE) - t.findAndMarkNode(t.root, nibblesKey) -} - -func (t *Trie) findAndMarkNode(parent *Node, key []byte) { - if parent == nil { - return - } - - if parent.Kind() == node.Branch { - t.findAndMarkInBranch(parent, key) - return - } - - t.findAndMarkInLeaf(parent, key) -} - -func (t *Trie) findAndMarkInLeaf(parentLeaf *Node, key []byte) { - if bytes.Equal(parentLeaf.PartialKey, key) { - parentLeaf.IsHashedValue = true - } -} - -func (t *Trie) findAndMarkInBranch(parentBranch *Node, key []byte) { - if bytes.Equal(parentBranch.PartialKey, key) { - parentBranch.IsHashedValue = true - return - } - - if bytes.HasPrefix(key, parentBranch.PartialKey) { - // key is included in parent branch key - commonPrefixLength := lenCommonPrefix(key, parentBranch.PartialKey) - childIndex := key[commonPrefixLength] - remainingKey := key[commonPrefixLength+1:] - child := parentBranch.Children[childIndex] - - if child == nil { - return - } - - //parentBranch.IsHashedValue = true - t.findAndMarkNode(child, remainingKey) - return - } -} - // Put inserts a value into the trie at the // key specified in little Endian format. func (t *Trie) Put(keyLE, value []byte) (err error) { @@ -430,9 +360,7 @@ func (t *Trie) Put(keyLE, value []byte) (err error) { t.handleTrackedDeltas(success, pendingDeltas) }() - //fmt.Printf("recording key: 0x%x\n", keyLE) - t.deltas.RecordUpdated(keyLE, value) - + pendingDeltas.RecordUpdated(keyLE, value) err = t.insertKeyLE(keyLE, value, pendingDeltas) if err != nil { return err @@ -465,9 +393,11 @@ func (t *Trie) insert(parent *Node, key, value []byte, pendingDeltas DeltaRecord if parent == nil { mutated = true nodesCreated = 1 + return &Node{ PartialKey: key, StorageValue: value, + MustBeHashed: mustBeHashed(t.version, value), Generation: t.generation, Dirty: true, }, mutated, nodesCreated, nil @@ -499,6 +429,8 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if bytes.Equal(parentLeaf.PartialKey, key) { nodesCreated = 0 + parentLeaf.MustBeHashed = mustBeHashed(t.version, value) + parentLeaf.SetDirty() if parentLeaf.StorageValueEqual(value) { mutated = false @@ -527,10 +459,12 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, Children: make([]*node.Node, node.ChildrenCapacity), Dirty: true, } + parentLeafKey := parentLeaf.PartialKey if len(key) == commonPrefixLength { // key is included in parent leaf key + newBranchParent.MustBeHashed = mustBeHashed(t.version, value) newBranchParent.StorageValue = value if len(key) < len(parentLeafKey) { // Move the current leaf parent as a child to the new branch. @@ -578,6 +512,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, StorageValue: value, Generation: t.generation, Dirty: true, + MustBeHashed: mustBeHashed(t.version, value), } newBranchParent.Children[childIndex] = newLeaf newBranchParent.Descendants++ @@ -592,10 +527,14 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, copySettings := node.DefaultCopySettings if bytes.Equal(key, parentBranch.PartialKey) { + parentBranch.MustBeHashed = mustBeHashed(t.version, value) + parentBranch.SetDirty() + if parentBranch.StorageValueEqual(value) { mutated = false - return parentBranch, mutated, 0, nil + return parentBranch, mutated, nodesCreated, nil } + parentBranch, err = t.prepForMutation(parentBranch, copySettings, pendingDeltas) if err != nil { return nil, false, 0, fmt.Errorf("preparing branch for mutation: %w", err) @@ -618,6 +557,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, StorageValue: value, Generation: t.generation, Dirty: true, + MustBeHashed: mustBeHashed(t.version, value), } nodesCreated = 1 parentBranch, err = t.prepForMutation(parentBranch, copySettings, pendingDeltas) @@ -675,6 +615,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, if len(key) <= commonPrefixLength { newParentBranch.StorageValue = value + newParentBranch.MustBeHashed = mustBeHashed(t.version, value) } else { childIndex := key[commonPrefixLength] remainingKey := key[commonPrefixLength+1:] @@ -1499,12 +1440,12 @@ func (t *Trie) ensureMerkleValueIsCalculated(parent *Node) (err error) { } if parent == t.root { - _, err = parent.CalculateRootMerkleValue(NoMaxInlineValueSize) + _, err = parent.CalculateRootMerkleValue() if err != nil { return fmt.Errorf("calculating Merkle value of root node: %w", err) } } else { - _, err = parent.CalculateMerkleValue(NoMaxInlineValueSize) + _, err = parent.CalculateMerkleValue() if err != nil { return fmt.Errorf("calculating Merkle value of node: %w", err) } @@ -1559,3 +1500,7 @@ func concatenateSlices(sliceOne, sliceTwo []byte, otherSlices ...[]byte) (concat func intToByteSlice(n int) (slice []byte) { return []byte{byte(n)} } + +func mustBeHashed(trieVersion TrieLayout, storageValue []byte) bool { + return trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() +} diff --git a/lib/trie/trie_endtoend_test.go b/lib/trie/trie_endtoend_test.go index 1cccd342be..152368ea17 100644 --- a/lib/trie/trie_endtoend_test.go +++ b/lib/trie/trie_endtoend_test.go @@ -1042,7 +1042,7 @@ func Test_encodeRoot_fuzz(t *testing.T) { assert.Equal(t, value, retrievedValue) } buffer := bytes.NewBuffer(nil) - err := trie.root.Encode(buffer, DefaultStateVersion.MaxInlineValue()) + err := trie.root.Encode(buffer) require.NoError(t, err) require.NotEmpty(t, buffer.Bytes()) } diff --git a/tests/rpc/rpc_05-state_test.go b/tests/rpc/rpc_05-state_test.go index 9d3573cce8..c3d738e3d0 100644 --- a/tests/rpc/rpc_05-state_test.go +++ b/tests/rpc/rpc_05-state_test.go @@ -56,7 +56,7 @@ func TestStateRPCResponseValidation(t *testing.T) { //nolint:tparallel newTrie, err := trie.LoadFromMap(entries) require.NoError(t, err) - trieHash := newTrie.MustHash(trie.V0.MaxInlineValue()) + trieHash := newTrie.MustHash() require.Equal(t, westendDevStateRoot, trieHash.String()) }) From 0069a00b4577a3209973ff1656ce931a5950b10c Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Wed, 7 Feb 2024 15:01:15 -0400 Subject: [PATCH 04/36] chore: rollback deltas to `core/service.go` --- dot/core/service.go | 17 ++++++++--------- dot/state/storage.go | 4 ++-- lib/runtime/wazero/imports.go | 6 ------ lib/runtime/wazero/instance.go | 3 ++- lib/trie/database.go | 1 - 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index bd659a61aa..29a0726adf 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -217,15 +217,14 @@ func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) er return ErrNilBlockHandlerParameter } - // store updates state trie nodes in database - // err := s.storageState.StoreTrie(state, &block.Header) - // if err != nil { - // logger.Warnf("failed to store state trie for imported block %s: %s", - // block.Header.Hash(), err) - // return err - // } - - var err error + //store updates state trie nodes in database + err := s.storageState.StoreTrie(state, &block.Header) + if err != nil { + logger.Warnf("failed to store state trie for imported block %s: %s", + block.Header.Hash(), err) + return err + } + // store block in database if err = s.blockState.AddBlock(block); err != nil { if errors.Is(err, blocktree.ErrParentNotFound) && block.Header.Number != 0 { diff --git a/dot/state/storage.go b/dot/state/storage.go index b9cca0d959..9a41c7e8af 100644 --- a/dot/state/storage.go +++ b/dot/state/storage.go @@ -92,7 +92,7 @@ func (s *StorageState) TrieState(root *common.Hash) (*rtstorage.TrieState, error if root == nil { sr, err := s.blockState.BestBlockStateRoot() if err != nil { - return nil, err + return nil, fmt.Errorf("while getting best block state root: %w", err) } root = &sr } @@ -102,7 +102,7 @@ func (s *StorageState) TrieState(root *common.Hash) (*rtstorage.TrieState, error var err error t, err = s.LoadFromDB(*root) if err != nil { - return nil, err + return nil, fmt.Errorf("while loading from database: %w", err) } s.tries.softSet(*root, t) diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index 31faebc3ba..4678401318 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -2273,24 +2273,18 @@ func ext_storage_root_version_2(ctx context.Context, m api.Module, version uint3 } storage := rtCtx.Storage - fmt.Printf("ext_storage_root_version_2 with pre parsed: %v\n", version) - stateVersion, err := trie.ParseVersion(version) if err != nil { logger.Errorf("failed parsing state version: %s", err) return mustWrite(m, rtCtx.Allocator, emptyByteVectorEncoded) } - fmt.Printf("ext_storage_root_version_2 with pos parsed: %s\n", stateVersion.String()) - root, err := storage.Root(stateVersion.MaxInlineValue()) if err != nil { logger.Errorf("failed to get storage root: %s", err) panic(err) } - fmt.Printf("root v1 hash is: %s\n", root.String()) - rootSpan, err := write(m, rtCtx.Allocator, root[:]) if err != nil { logger.Errorf("failed to allocate: %s", err) diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index a98df8b4c8..ab112b030a 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -100,6 +100,7 @@ func NewInstanceFromTrie(t *trie.Trie, cfg Config) (*Instance, error) { // NewInstance instantiates a runtime from raw wasm bytecode func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { + logger.Info("instantiating a runtime!") logger.Patch(log.SetLevel(cfg.LogLvl), log.SetCallerFunc(true)) ctx := context.Background() @@ -434,6 +435,7 @@ func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { codeHash: cfg.CodeHash, } + instance.version() return instance, nil } @@ -515,7 +517,6 @@ func (in *Instance) version() error { //skipcq: RVV-B0001 fmt.Println("state version", version.StateVersion) in.Context.Version = &version - return nil } diff --git a/lib/trie/database.go b/lib/trie/database.go index 57bac53230..2cf561cab6 100644 --- a/lib/trie/database.go +++ b/lib/trie/database.go @@ -27,7 +27,6 @@ func (t *Trie) Load(db db.DBGetter, rootHash common.Hash) error { return nil } rootHashBytes := rootHash.ToBytes() - encodedNode, err := db.Get(rootHashBytes) if err != nil { return fmt.Errorf("failed to find root key %s: %w", rootHash, err) From 8cce14e25e41157b04d7a66b8c3ab0a7056aa57f Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Wed, 7 Feb 2024 15:05:51 -0400 Subject: [PATCH 05/36] chore: remove deltas to tracking --- internal/trie/tracking/deltas.go | 50 ++------------------------- internal/trie/tracking/deltas_test.go | 2 +- internal/trie/tracking/interfaces.go | 5 ++- lib/trie/interfaces.go | 5 ++- lib/trie/trie.go | 3 +- lib/trie/trie_test.go | 12 +------ 6 files changed, 9 insertions(+), 68 deletions(-) diff --git a/internal/trie/tracking/deltas.go b/internal/trie/tracking/deltas.go index 87a28097a9..4e80e37a20 100644 --- a/internal/trie/tracking/deltas.go +++ b/internal/trie/tracking/deltas.go @@ -3,25 +3,16 @@ package tracking -import ( - "github.com/ChainSafe/gossamer/lib/common" -) - -type DeltaEntry struct { - Key []byte - Value []byte -} +import "github.com/ChainSafe/gossamer/lib/common" // Deltas tracks the trie deltas, for example deleted node hashes. type Deltas struct { - entries []DeltaEntry deletedNodeHashes map[common.Hash]struct{} } // New returns a new Deltas struct. func New() *Deltas { return &Deltas{ - entries: make([]DeltaEntry, 0), deletedNodeHashes: make(map[common.Hash]struct{}), } } @@ -31,22 +22,6 @@ func (d *Deltas) RecordDeleted(nodeHash common.Hash) { d.deletedNodeHashes[nodeHash] = struct{}{} } -// RecordUpdated records a node hash that was created or updated. -func (d *Deltas) RecordUpdated(key, value []byte) { - newEntry := DeltaEntry{ - Key: make([]byte, len(key)), - Value: make([]byte, len(value)), - } - - copy(newEntry.Key[:], key[:]) - copy(newEntry.Value[:], value[:]) - d.entries = append(d.entries, newEntry) -} - -func (d *Deltas) HasUpdated(partialKeyHash common.Hash) bool { - return false -} - // Deleted returns a set (map) of all the recorded deleted // node hashes. Note the map returned is not deep copied for // performance reasons and so it's not safe for mutation. @@ -54,20 +29,12 @@ func (d *Deltas) Deleted() (nodeHashes map[common.Hash]struct{}) { return d.deletedNodeHashes } -func (d *Deltas) Updated() []DeltaEntry { - return d.entries -} - // MergeWith merges the deltas given as argument in the receiving // deltas struct. -func (d *Deltas) MergeWith(deltas Getter) { +func (d *Deltas) MergeWith(deltas DeletedGetter) { for nodeHash := range deltas.Deleted() { d.RecordDeleted(nodeHash) } - - for _, deltaEntry := range deltas.Updated() { - d.RecordUpdated(deltaEntry.Key, deltaEntry.Value) - } } // DeepCopy returns a deep copy of the deltas. @@ -85,18 +52,5 @@ func (d *Deltas) DeepCopy() (deepCopy *Deltas) { } } - if len(d.entries) != 0 { - deepCopy.entries = make([]DeltaEntry, len(d.entries)) - for idx, deltaEntry := range d.entries { - newEntry := DeltaEntry{ - Key: make([]byte, len(deltaEntry.Key)), - Value: make([]byte, len(deltaEntry.Value)), - } - - copy(newEntry.Key[:], deltaEntry.Key[:]) - copy(newEntry.Value[:], deltaEntry.Value[:]) - deepCopy.entries[idx] = newEntry - } - } return deepCopy } diff --git a/internal/trie/tracking/deltas_test.go b/internal/trie/tracking/deltas_test.go index 5c77cfa8be..3af891a943 100644 --- a/internal/trie/tracking/deltas_test.go +++ b/internal/trie/tracking/deltas_test.go @@ -103,7 +103,7 @@ func Test_Deltas_MergeWith(t *testing.T) { testCases := map[string]struct { deltas Deltas - deltasArg Getter + deltasArg DeletedGetter expectedDeltas Deltas }{ "merge_empty_deltas": { diff --git a/internal/trie/tracking/interfaces.go b/internal/trie/tracking/interfaces.go index 0f13399e94..0e4ea324fd 100644 --- a/internal/trie/tracking/interfaces.go +++ b/internal/trie/tracking/interfaces.go @@ -5,8 +5,7 @@ package tracking import "github.com/ChainSafe/gossamer/lib/common" -// Getter gets deleted node hashes. -type Getter interface { +// DeletedGetter gets deleted node hashes. +type DeletedGetter interface { Deleted() (nodeHashes map[common.Hash]struct{}) - Updated() []DeltaEntry } diff --git a/lib/trie/interfaces.go b/lib/trie/interfaces.go index 6a7fa294dd..440476e5a9 100644 --- a/lib/trie/interfaces.go +++ b/lib/trie/interfaces.go @@ -12,7 +12,7 @@ import ( // the last snapshot. type Deltas interface { DeltaMerger - tracking.Getter + tracking.DeletedGetter DeltaRecorder DeepCopy() (deepCopy *tracking.Deltas) } @@ -20,11 +20,10 @@ type Deltas interface { // DeltaMerger merges the given deltas into the current // deltas. type DeltaMerger interface { - MergeWith(deltas tracking.Getter) + MergeWith(deltas tracking.DeletedGetter) } // DeltaRecorder records deltas done in a ongoing trie operation. type DeltaRecorder interface { RecordDeleted(nodeHash common.Hash) - RecordUpdated(key, value []byte) } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 5ab4682ed0..2d4dbaa03b 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -101,7 +101,7 @@ func (t *Trie) Snapshot() (newTrie *Trie) { // handleTrackedDeltas sets the pending deleted node hashes in // the trie deltas tracker if and only if success is true. -func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas tracking.Getter) { +func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas tracking.DeletedGetter) { // if !success || t.generation == 0 { // // Do not persist tracked deleted node hashes if the operation failed or // // if the trie generation is zero (first block, no trie snapshot done yet). @@ -360,7 +360,6 @@ func (t *Trie) Put(keyLE, value []byte) (err error) { t.handleTrackedDeltas(success, pendingDeltas) }() - pendingDeltas.RecordUpdated(keyLE, value) err = t.insertKeyLE(keyLE, value, pendingDeltas) if err != nil { return err diff --git a/lib/trie/trie_test.go b/lib/trie/trie_test.go index 85a9551f0d..b22bc1bc49 100644 --- a/lib/trie/trie_test.go +++ b/lib/trie/trie_test.go @@ -6,7 +6,6 @@ package trie import ( "bytes" "encoding/hex" - "fmt" "reflect" "testing" @@ -111,7 +110,7 @@ func Test_Trie_handleTrackedDeltas(t *testing.T) { testCases := map[string]struct { trie Trie success bool - pendingDeltas tracking.Getter + pendingDeltas tracking.DeletedGetter expectedTrie Trie }{ "no_success_and_generation_1": { @@ -4372,12 +4371,3 @@ func Benchmark_concatSlices(b *testing.B) { } }) } - -func TestTrieDeltaRegisterUpdates(t *testing.T) { - trie := NewEmptyTrie() - trie.Put([]byte("alpha"), make([]byte, 40)) - trie.Put([]byte("al"), make([]byte, 40)) - - fmt.Println("tries deltas updated", trie.deltas.Updated()) - fmt.Println("tries deltas deleted", trie.deltas.Deleted()) -} From d918b99215670c8fb900d4a4edeb54481d765b26 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Wed, 7 Feb 2024 15:15:09 -0400 Subject: [PATCH 06/36] chore: remove deltas from imports.go --- lib/runtime/wazero/imports.go | 48 +++++++++++++++-------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index e1bf5c1a13..8db3f5e4a9 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -92,23 +92,22 @@ func ext_logging_log_version_1(ctx context.Context, m api.Module, level int32, t target := string(read(m, targetData)) msg := string(read(m, msgData)) - line := fmt.Sprintf("target=%s message=%s\n", target, msg) - fmt.Print(line) - - // switch int(level) { - // case 0: - // logger.Critical(line) - // case 1: - // logger.Warn(line) - // case 2: - // logger.Info(line) - // case 3: - // logger.Debug(line) - // case 4: - // logger.Trace(line) - // default: - // logger.Errorf("level=%d target=%s message=%s", int(level), target, msg) - // } + line := fmt.Sprintf("target=%s message=%s", target, msg) + + switch int(level) { + case 0: + logger.Critical(line) + case 1: + logger.Warn(line) + case 2: + logger.Info(line) + case 3: + logger.Debug(line) + case 4: + logger.Trace(line) + default: + logger.Errorf("level=%d target=%s message=%s", int(level), target, msg) + } } func ext_crypto_ed25519_generate_version_1( @@ -838,16 +837,12 @@ func ext_trie_blake2_256_ordered_root_version_2( data := read(m, dataSpan) - fmt.Printf("ext_trie_blake2_256_ordered_root_version_2 with pre parse: %v\n", version) - stateVersion, err := trie.ParseVersion(version) if err != nil { logger.Errorf("failed parsing state version: %s", err) return 0 } - fmt.Printf("ext_trie_blake2_256_ordered_root_version_2 with pos parse: %s\n", stateVersion.String()) - var values [][]byte err = scale.Unmarshal(data, &values) if err != nil { @@ -880,7 +875,7 @@ func ext_trie_blake2_256_ordered_root_version_2( return 0 } - fmt.Printf("root hash is %s\n", hash) + logger.Debugf("root hash is %s", hash) m.Memory().Write(ptr, hash[:]) return ptr } @@ -2098,7 +2093,7 @@ func ext_storage_clear_prefix_version_1(ctx context.Context, m api.Module, prefi storage := rtCtx.Storage prefix := read(m, prefixSpan) - fmt.Printf("[ext_storage_clear_prefix_version_1] prefix: 0x%x\n", prefix) + logger.Debugf("prefix: 0x%x", prefix) err := storage.ClearPrefix(prefix) if err != nil { @@ -2136,6 +2131,8 @@ func ext_storage_clear_prefix_version_2(ctx context.Context, m api.Module, prefi storage := rtCtx.Storage prefix := read(m, prefixSpan) + logger.Debugf("prefix: 0x%x", prefix) + limitBytes := read(m, lim) var limit []byte @@ -2158,9 +2155,6 @@ func ext_storage_clear_prefix_version_2(ctx context.Context, m api.Module, prefi panic(err) } - fmt.Printf("[ext_storage_clear_prefix_version_2] prefix: 0x%x, lim: %d, removed: %d, all: %v\n", - prefix, limitUint, numRemoved, all) - encBytes, err := toKillStorageResultEnum(all, numRemoved) if err != nil { logger.Errorf("failed to allocate memory: %s", err) @@ -2228,7 +2222,7 @@ func ext_storage_next_key_version_1(ctx context.Context, m api.Module, keySpan u next := storage.NextKey(key) logger.Debugf( - "[ext_storage_next_key_version_1] key: 0x%x; next key 0x%x", + "key: 0x%x; next key 0x%x", key, next) var encodedOption []byte From 927b3b126c314e68c564d48b6e898067a8e3fb8f Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Wed, 7 Feb 2024 16:02:50 -0400 Subject: [PATCH 07/36] chore: remove unneeded deltas to runtime/storage --- internal/trie/node/encode.go | 1 - lib/runtime/storage/trie.go | 3 --- 2 files changed, 4 deletions(-) diff --git a/internal/trie/node/encode.go b/internal/trie/node/encode.go index c6be45f0ce..dca9448b40 100644 --- a/internal/trie/node/encode.go +++ b/internal/trie/node/encode.go @@ -16,7 +16,6 @@ import ( // of this package, and specified in the Polkadot spec at // https://spec.polkadot.network/#sect-state-storage func (n *Node) Encode(buffer Buffer) (err error) { - // TODO: move trie layout err = encodeHeader(n, n.MustBeHashed, buffer) if err != nil { return fmt.Errorf("cannot encode header: %w", err) diff --git a/lib/runtime/storage/trie.go b/lib/runtime/storage/trie.go index 39ff19e66e..99d2aa4aac 100644 --- a/lib/runtime/storage/trie.go +++ b/lib/runtime/storage/trie.go @@ -44,7 +44,6 @@ func (t *TrieState) StartTransaction() { t.mtx.Lock() defer t.mtx.Unlock() - fmt.Println("START TRANSACTION") t.transactions.PushBack(t.getCurrentTrie().Snapshot()) } @@ -69,8 +68,6 @@ func (t *TrieState) CommitTransaction() { panic("no transactions to commit") } - fmt.Println("COMMIT TRANSACTION") - t.transactions.Back().Prev().Value = t.transactions.Remove(t.transactions.Back()) } From 3f5df45af13e3ad61ce16d985c129f3c0009a892 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Wed, 7 Feb 2024 16:10:37 -0400 Subject: [PATCH 08/36] chore: remove unneeded deltas --- lib/runtime/storage/trie.go | 1 - lib/runtime/wazero/imports.go | 2 ++ lib/runtime/wazero/instance.go | 6 +++++- lib/runtime/wazero/instance_test.go | 24 ------------------------ lib/trie/database.go | 1 - lib/trie/trie.go | 10 +++++----- 6 files changed, 12 insertions(+), 32 deletions(-) diff --git a/lib/runtime/storage/trie.go b/lib/runtime/storage/trie.go index 99d2aa4aac..06f11adb71 100644 --- a/lib/runtime/storage/trie.go +++ b/lib/runtime/storage/trie.go @@ -74,7 +74,6 @@ func (t *TrieState) CommitTransaction() { func (t *TrieState) SetVersion(v trie.TrieLayout) { t.mtx.Lock() defer t.mtx.Unlock() - fmt.Println("setting curent trie to vesion: ", v) t.getCurrentTrie().SetVersion(v) } diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index 8db3f5e4a9..52ff16b32b 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -2319,6 +2319,8 @@ func ext_storage_root_version_2(ctx context.Context, m api.Module, version uint3 panic(err) } + logger.Debugf("root hash is: %s", root) + rootSpan, err := write(m, rtCtx.Allocator, root[:]) if err != nil { logger.Errorf("failed to allocate: %s", err) diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index 4e4dc10fbe..5a2df9f1f5 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -435,7 +435,11 @@ func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { codeHash: cfg.CodeHash, } - instance.version() + err = instance.version() + if err != nil { + return nil, fmt.Errorf("while getting runtime version: %w", err) + } + return instance, nil } diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index 998e2c1e6e..2aab9249c3 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -5,7 +5,6 @@ package wazero_runtime import ( _ "embed" - "fmt" "bytes" "encoding/json" @@ -1279,29 +1278,6 @@ func TestInstance_GrandpaSubmitReportEquivocationUnsignedExtrinsic(t *testing.T) require.NoError(t, err) } -func TestTrie(t *testing.T) { - tt := trie.NewEmptyTrie() - tt.Put([]byte("a"), make([]byte, 40)) - tt.Put([]byte("al"), make([]byte, 40)) - tt.Put([]byte("alfa"), make([]byte, 40)) - - hash, err := tt.Hash() - require.NoError(t, err) - - fmt.Printf("%s\n", hash.String()) // 0xdf1012a786cddcdfa4a8cf015e873677bc2e7a3c8b3579d9bae93117cbcfb7c1 - - tt = trie.NewEmptyTrie() - tt.Put([]byte("a"), make([]byte, 40)) - tt.Put([]byte("al"), make([]byte, 40)) - tt.Put([]byte("alfa"), make([]byte, 40)) - - tt.SetVersion(trie.V1) - hash, err = tt.Hash() - require.NoError(t, err) - - fmt.Printf("%s\n", hash.String()) // 0x99a5fee4d1d352a6e6530ce4c965d1063abe92e2a3327da07061c6730f221583 -} - func TestDebugWestendBlock14576855(t *testing.T) { wnd14576854StateTrie := newTrieFromRPC(t, "../test_data/14576854trie_state_data.json") expectedStorageRootHash := common.MustHexToHash("0xedd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b") diff --git a/lib/trie/database.go b/lib/trie/database.go index 2cf561cab6..30b106e103 100644 --- a/lib/trie/database.go +++ b/lib/trie/database.go @@ -137,7 +137,6 @@ func loadStorageValue(db db.DBGetter, node *Node) error { return nil } - fmt.Println("loading a hashed value!!") prefixedKey := bytes.Join([][]byte{node.PartialKey, node.StorageValue[:]}, nil) rawStorageValue, err := db.Get(prefixedKey) if err != nil { diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 2d4dbaa03b..da69fbbf14 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -102,11 +102,11 @@ func (t *Trie) Snapshot() (newTrie *Trie) { // handleTrackedDeltas sets the pending deleted node hashes in // the trie deltas tracker if and only if success is true. func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas tracking.DeletedGetter) { - // if !success || t.generation == 0 { - // // Do not persist tracked deleted node hashes if the operation failed or - // // if the trie generation is zero (first block, no trie snapshot done yet). - // return - // } + if !success || t.generation == 0 { + // Do not persist tracked deleted node hashes if the operation failed or + // if the trie generation is zero (first block, no trie snapshot done yet). + return + } t.deltas.MergeWith(pendingDeltas) } From e4b0689e93bc137671a6011065a4eaf269c50431 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Fri, 9 Feb 2024 09:22:46 -0400 Subject: [PATCH 09/36] chore: testing changing version should not change older trie nodes --- lib/trie/trie_test.go | 99 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/lib/trie/trie_test.go b/lib/trie/trie_test.go index b22bc1bc49..895b9d202a 100644 --- a/lib/trie/trie_test.go +++ b/lib/trie/trie_test.go @@ -9,6 +9,7 @@ import ( "reflect" "testing" + "github.com/ChainSafe/gossamer/internal/trie/codec" "github.com/ChainSafe/gossamer/internal/trie/node" "github.com/ChainSafe/gossamer/internal/trie/tracking" "github.com/ChainSafe/gossamer/lib/common" @@ -4371,3 +4372,101 @@ func Benchmark_concatSlices(b *testing.B) { } }) } + +func TestTrieVersionAndMustHash(t *testing.T) { + newTrie := NewEmptyTrie() + + // setting trie version to 0 + // no entry should be hashed (no matter its size) + newTrie.SetVersion(0) + + type testStruct struct { + key []byte + nibbles []byte + storageValue []byte + mustBeHashed bool + } + + testCases := []testStruct{ + { + key: []byte{1, 2, 3, 4}, + nibbles: codec.KeyLEToNibbles([]byte{1, 2, 3, 4}), + storageValue: make([]byte, 66), + mustBeHashed: false, + }, + { + key: []byte{2, 4, 5, 6}, + nibbles: codec.KeyLEToNibbles([]byte{2, 4, 5, 6}), + storageValue: make([]byte, 66), + mustBeHashed: false, + }, + } + + // inserting the key and values to the trie + for _, tt := range testCases { + require.NoError( + t, + newTrie.Put(tt.key, tt.storageValue), + ) + } + + // asserting each trie node + for _, tt := range testCases { + node := findNode(t, newTrie.root, tt.nibbles) + require.NotNil(t, node) + require.Equal(t, node.MustBeHashed, tt.mustBeHashed) + } + + // setting trie version to 1 a new inserted node + // with storage value greater than 32 should be marked as MustBeHashed + newTrie.SetVersion(1) + + nodeCKey := []byte{9, 8, 7, 5} + nodeDKey := []byte{4, 4, 7, 2} + nodeEKey := []byte{6, 7, 0xa, 0xb} + + require.NoError( + t, + newTrie.Put(nodeCKey, make([]byte, 66)), + ) + + require.NoError( + t, + newTrie.Put(nodeDKey, make([]byte, 66)), + ) + + require.NoError( + t, + newTrie.Put(nodeEKey, make([]byte, 10)), + ) + + testCases = append(testCases, testStruct{nibbles: codec.KeyLEToNibbles(nodeCKey), mustBeHashed: true}) + testCases = append(testCases, testStruct{nibbles: codec.KeyLEToNibbles(nodeDKey), mustBeHashed: true}) + testCases = append(testCases, testStruct{nibbles: codec.KeyLEToNibbles(nodeEKey), mustBeHashed: false}) + + for _, tt := range testCases { + node := findNode(t, newTrie.root, tt.nibbles) + require.NotNil(t, node) + require.Equal(t, tt.mustBeHashed, node.MustBeHashed) + } +} + +func findNode(t *testing.T, currNode *Node, nibbles []byte) *Node { + t.Helper() + + if bytes.Equal(currNode.PartialKey, nibbles) { + return currNode + } + + if currNode.Kind() == node.Leaf { + return nil + } + + commonLen := lenCommonPrefix(currNode.PartialKey, nibbles) + child := currNode.Children[nibbles[commonLen]] + if child == nil { + return nil + } + + return findNode(t, child, nibbles[commonLen+1:]) +} From 239ec11112636fcc8c302583b2671f74d476c9e4 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Fri, 9 Feb 2024 10:30:40 -0400 Subject: [PATCH 10/36] wip: setting runtime storage version while instantiating --- dot/state/block.go | 2 +- lib/runtime/wazero/imports.go | 2 +- lib/runtime/wazero/instance.go | 2 +- lib/runtime/wazero/instance_test.go | 38 ++++++++++++++--------------- lib/trie/trie.go | 2 ++ 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/dot/state/block.go b/dot/state/block.go index 150dcd0179..5abf31897c 100644 --- a/dot/state/block.go +++ b/dot/state/block.go @@ -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() if err != nil { return err } diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index 52ff16b32b..bfb3c552ec 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -2319,7 +2319,7 @@ func ext_storage_root_version_2(ctx context.Context, m api.Module, version uint3 panic(err) } - logger.Debugf("root hash is: %s", root) + fmt.Printf("root hash is: %s\n", root) rootSpan, err := write(m, rtCtx.Allocator, root[:]) if err != nil { diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index 5a2df9f1f5..5bd5714de8 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -421,7 +421,6 @@ func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { instance = &Instance{ Runtime: rt, Context: &runtime.Context{ - Storage: cfg.Storage, Allocator: allocator, Keystore: cfg.Keystore, Validator: cfg.Role == common.AuthorityRole, @@ -440,6 +439,7 @@ func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { return nil, fmt.Errorf("while getting runtime version: %w", err) } + instance.SetContextStorage(cfg.Storage) return instance, nil } diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index 2aab9249c3..68d822bfe5 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -5,6 +5,7 @@ package wazero_runtime import ( _ "embed" + "fmt" "bytes" "encoding/json" @@ -1278,7 +1279,7 @@ func TestInstance_GrandpaSubmitReportEquivocationUnsignedExtrinsic(t *testing.T) require.NoError(t, err) } -func TestDebugWestendBlock14576855(t *testing.T) { +func TestDebugWestendBlock14576855And14576856(t *testing.T) { wnd14576854StateTrie := newTrieFromRPC(t, "../test_data/14576854trie_state_data.json") expectedStorageRootHash := common.MustHexToHash("0xedd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b") require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) @@ -1306,40 +1307,39 @@ func TestDebugWestendBlock14576855(t *testing.T) { Body: *blockData.Body, } - instance.version() - + fmt.Printf("Executing block number %d\n", block.Header.Number) _, err = instance.ExecuteBlock(block) require.NoError(t, err) -} -func TestDebugWestendBlock14576856(t *testing.T) { - wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") - expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") - require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) + // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") + // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") + // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) - state := storage.NewTrieState(wnd14576855StateTrie) - instance, err := NewInstanceFromTrie(wnd14576855StateTrie, Config{ - LogLvl: log.Critical, - }) - instance.version() - instance.SetContextStorage(state) + // state := storage.NewTrieState(wnd14576855StateTrie) + // instance, err := NewInstanceFromTrie(wnd14576855StateTrie, Config{ + // LogLvl: log.Critical, + // }) + // instance.version() + // instance.SetContextStorage(state) - require.NoError(t, err) + // require.NoError(t, err) - blockResponseBytes, err := common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") + blockResponseBytes, err = common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") require.NoError(t, err) - blockResponse := new(network.BlockResponseMessage) + blockResponse = new(network.BlockResponseMessage) err = blockResponse.Decode(blockResponseBytes) require.NoError(t, err) - blockData := blockResponse.BlockData[0] + blockData = blockResponse.BlockData[0] - block := &types.Block{ + block = &types.Block{ Header: *blockData.Header, Body: *blockData.Body, } + fmt.Printf("Executing block number %d\n", block.Header.Number) + _, err = instance.ExecuteBlock(block) require.NoError(t, err) } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index bf64108cc8..c20d07804b 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -220,6 +220,8 @@ func (t *Trie) Hash() (rootHash common.Hash, err error) { return EmptyHash, nil } + fmt.Printf("trie version while hashing: %d\n", t.version) + merkleValue, err := t.root.CalculateRootMerkleValue() if err != nil { return rootHash, err From c643e8009b84432f6c1389bf6b75f3e892c5364f Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Fri, 9 Feb 2024 14:41:57 -0400 Subject: [PATCH 11/36] chore: setting storage context if it is not nil and runtime state version is there --- lib/runtime/wazero/instance.go | 5 ++++- lib/runtime/wazero/instance_test.go | 10 +++++----- lib/trie/trie.go | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index 5bd5714de8..9e3a7aeeec 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -439,7 +439,10 @@ func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { return nil, fmt.Errorf("while getting runtime version: %w", err) } - instance.SetContextStorage(cfg.Storage) + if cfg.Storage != nil { + instance.SetContextStorage(cfg.Storage) + } + return instance, nil } diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index 68d822bfe5..6174ab459d 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -1316,14 +1316,14 @@ func TestDebugWestendBlock14576855And14576856(t *testing.T) { // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) // state := storage.NewTrieState(wnd14576855StateTrie) - // instance, err := NewInstanceFromTrie(wnd14576855StateTrie, Config{ - // LogLvl: log.Critical, - // }) + instance, err = NewInstanceFromTrie(wnd14576854StateTrie, Config{ + Storage: state, + LogLvl: log.Critical, + }) + require.NoError(t, err) // instance.version() // instance.SetContextStorage(state) - // require.NoError(t, err) - blockResponseBytes, err = common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") require.NoError(t, err) diff --git a/lib/trie/trie.go b/lib/trie/trie.go index c20d07804b..d8820e988e 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -220,7 +220,7 @@ func (t *Trie) Hash() (rootHash common.Hash, err error) { return EmptyHash, nil } - fmt.Printf("trie version while hashing: %d\n", t.version) + fmt.Printf("trie version: %v\n", t.version) merkleValue, err := t.root.CalculateRootMerkleValue() if err != nil { From d254c54444255405e12e936d460c1e71bdf7627a Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 12 Feb 2024 09:04:41 -0400 Subject: [PATCH 12/36] chore: testing passing now --- lib/runtime/wazero/instance_test.go | 12 +++++++++++- lib/trie/trie.go | 3 +-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index 6174ab459d..67521745cb 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -1285,6 +1285,11 @@ func TestDebugWestendBlock14576855And14576856(t *testing.T) { require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) state := storage.NewTrieState(wnd14576854StateTrie) + codeHash, err := state.LoadCodeHash() + require.NoError(t, err) + + fmt.Printf("code hash at start: %s\n", codeHash.String()) + cfg := Config{ Storage: state, LogLvl: log.Critical, @@ -1311,12 +1316,17 @@ func TestDebugWestendBlock14576855And14576856(t *testing.T) { _, err = instance.ExecuteBlock(block) require.NoError(t, err) + codeHash, err = state.LoadCodeHash() + require.NoError(t, err) + + fmt.Printf("code hash from updated state: %s\n", codeHash.String()) + // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) // state := storage.NewTrieState(wnd14576855StateTrie) - instance, err = NewInstanceFromTrie(wnd14576854StateTrie, Config{ + instance, err = NewInstanceFromTrie(state.Trie(), Config{ Storage: state, LogLvl: log.Critical, }) diff --git a/lib/trie/trie.go b/lib/trie/trie.go index d8820e988e..1970d8661a 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -56,6 +56,7 @@ func (t *Trie) SetVersion(v TrieLayout) { panic("cannot regress trie version") } + fmt.Printf("setting trie version to: %d\n", v) t.version = v } @@ -220,8 +221,6 @@ func (t *Trie) Hash() (rootHash common.Hash, err error) { return EmptyHash, nil } - fmt.Printf("trie version: %v\n", t.version) - merkleValue, err := t.root.CalculateRootMerkleValue() if err != nil { return rootHash, err From 71870741549524d1717b2e0e8eaec7847fbac632 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 12 Feb 2024 10:05:41 -0400 Subject: [PATCH 13/36] chore: add logs --- lib/runtime/wazero/imports.go | 2 ++ lib/trie/trie.go | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index bfb3c552ec..21fe0fea89 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -830,6 +830,7 @@ func ext_trie_blake2_256_ordered_root_version_1(ctx context.Context, m api.Modul func ext_trie_blake2_256_ordered_root_version_2( ctx context.Context, m api.Module, dataSpan uint64, version uint32) uint32 { + fmt.Println("executing: ext_trie_blake2_256_ordered_root_version_2") rtCtx := ctx.Value(runtimeContextKey).(*runtime.Context) if rtCtx == nil { panic("nil runtime context") @@ -2301,6 +2302,7 @@ func ext_storage_root_version_1(ctx context.Context, m api.Module) uint64 { } func ext_storage_root_version_2(ctx context.Context, m api.Module, version uint32) uint64 { //skipcq: RVV-B0012 + fmt.Println("executing: ext_storage_root_version_2") rtCtx := ctx.Value(runtimeContextKey).(*runtime.Context) if rtCtx == nil { panic("nil runtime context") diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 1970d8661a..578203b529 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -365,6 +365,7 @@ func (t *Trie) Put(keyLE, value []byte) (err error) { t.handleTrackedDeltas(success, pendingDeltas) }() + fmt.Printf("inserting a value, trie version: %d\n", t.version) err = t.insertKeyLE(keyLE, value, pendingDeltas) if err != nil { return err @@ -1506,5 +1507,9 @@ func intToByteSlice(n int) (slice []byte) { } func mustBeHashed(trieVersion TrieLayout, storageValue []byte) bool { - return trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() + mustBe := trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() + if mustBe { + fmt.Printf("must be hashed: %v\n", mustBe) + } + return mustBe } From 015c5b96288285ec1ed6b2816913ef8f2b916f97 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 12 Feb 2024 14:02:49 -0400 Subject: [PATCH 14/36] chore: add logs to `core/service.go` and `chain_sync/handleBlock` method --- dot/core/service.go | 2 +- dot/sync/chain_sync.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dot/core/service.go b/dot/core/service.go index ca69713075..3bcd0b6807 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -246,7 +246,7 @@ func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) er return fmt.Errorf("applying forced changes: %w", err) } - logger.Debugf("imported block %s and stored state trie with root %s", + logger.Infof("imported block %s and stored state trie with root %s", block.Header.Hash(), state.MustRoot(trie.NoMaxInlineValueSize)) parentRuntimeInstance, err := s.blockState.GetRuntime(block.Header.ParentHash) diff --git a/dot/sync/chain_sync.go b/dot/sync/chain_sync.go index dc15370223..4bc98a353e 100644 --- a/dot/sync/chain_sync.go +++ b/dot/sync/chain_sync.go @@ -885,6 +885,7 @@ func (cs *chainSync) handleBlock(block *types.Block, announceImportedBlock bool) return err } + fmt.Printf("RUNTIME HASH: %s\n", rt.GetCodeHash().String()) rt.SetContextStorage(ts) _, err = rt.ExecuteBlock(block) From 06003d57687f810016809207e366b5e68ac868c2 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 12 Feb 2024 16:00:04 -0400 Subject: [PATCH 15/36] chore: use deltas finally --- internal/trie/node/copy.go | 2 +- internal/trie/node/encode.go | 1 + internal/trie/tracking/deltas.go | 43 ++++++++++++- internal/trie/tracking/deltas_test.go | 2 +- internal/trie/tracking/interfaces.go | 5 +- lib/trie/interfaces.go | 5 +- lib/trie/trie.go | 93 ++++++++++++++++++++------- lib/trie/trie_test.go | 2 +- 8 files changed, 119 insertions(+), 34 deletions(-) diff --git a/internal/trie/node/copy.go b/internal/trie/node/copy.go index 1c61698b59..94f7b9ed13 100644 --- a/internal/trie/node/copy.go +++ b/internal/trie/node/copy.go @@ -59,7 +59,7 @@ func (n *Node) Copy(settings CopySettings) *Node { Generation: n.Generation, Descendants: n.Descendants, IsHashedValue: n.IsHashedValue, - MustBeHashed: n.MustBeHashed, + //MustBeHashed: n.MustBeHashed, } if n.Kind() == Branch { diff --git a/internal/trie/node/encode.go b/internal/trie/node/encode.go index dca9448b40..57dd02f67c 100644 --- a/internal/trie/node/encode.go +++ b/internal/trie/node/encode.go @@ -48,6 +48,7 @@ func (n *Node) Encode(buffer Buffer) (err error) { if n.StorageValue != nil { switch { case n.MustBeHashed: + fmt.Println("beign hashed") hashedValue, err := common.Blake2bHash(n.StorageValue) if err != nil { return fmt.Errorf("hashing storage value: %w", err) diff --git a/internal/trie/tracking/deltas.go b/internal/trie/tracking/deltas.go index 4e80e37a20..6e93475510 100644 --- a/internal/trie/tracking/deltas.go +++ b/internal/trie/tracking/deltas.go @@ -3,17 +3,27 @@ package tracking -import "github.com/ChainSafe/gossamer/lib/common" +import ( + "fmt" + + "github.com/ChainSafe/gossamer/lib/common" +) + +type DeltaEntry struct { + Key, Value []byte +} // Deltas tracks the trie deltas, for example deleted node hashes. type Deltas struct { deletedNodeHashes map[common.Hash]struct{} + updatedNodes []DeltaEntry } // New returns a new Deltas struct. func New() *Deltas { return &Deltas{ deletedNodeHashes: make(map[common.Hash]struct{}), + updatedNodes: make([]DeltaEntry, 0), } } @@ -22,6 +32,20 @@ func (d *Deltas) RecordDeleted(nodeHash common.Hash) { d.deletedNodeHashes[nodeHash] = struct{}{} } +func (d *Deltas) RecordUpdated(key, value []byte) { + if len(value) > 32 { + fmt.Println("recording key with value larger than 32") + } + + entryKey := make([]byte, len(key)) + copy(entryKey[:], key[:]) + + entryValue := make([]byte, len(value)) + copy(entryValue[:], value[:]) + + d.updatedNodes = append(d.updatedNodes, DeltaEntry{Key: entryKey, Value: entryValue}) +} + // Deleted returns a set (map) of all the recorded deleted // node hashes. Note the map returned is not deep copied for // performance reasons and so it's not safe for mutation. @@ -29,12 +53,20 @@ func (d *Deltas) Deleted() (nodeHashes map[common.Hash]struct{}) { return d.deletedNodeHashes } +func (d *Deltas) Updated() (entries []DeltaEntry) { + return d.updatedNodes +} + // MergeWith merges the deltas given as argument in the receiving // deltas struct. -func (d *Deltas) MergeWith(deltas DeletedGetter) { +func (d *Deltas) MergeWith(deltas Getter) { for nodeHash := range deltas.Deleted() { d.RecordDeleted(nodeHash) } + + for _, entry := range deltas.Updated() { + d.RecordUpdated(entry.Key, entry.Value) + } } // DeepCopy returns a deep copy of the deltas. @@ -52,5 +84,12 @@ func (d *Deltas) DeepCopy() (deepCopy *Deltas) { } } + if d.updatedNodes != nil { + deepCopy.updatedNodes = make([]DeltaEntry, 0, len(d.updatedNodes)) + for _, entry := range d.updatedNodes { + deepCopy.RecordUpdated(entry.Key, entry.Value) + } + } + return deepCopy } diff --git a/internal/trie/tracking/deltas_test.go b/internal/trie/tracking/deltas_test.go index 3af891a943..5c77cfa8be 100644 --- a/internal/trie/tracking/deltas_test.go +++ b/internal/trie/tracking/deltas_test.go @@ -103,7 +103,7 @@ func Test_Deltas_MergeWith(t *testing.T) { testCases := map[string]struct { deltas Deltas - deltasArg DeletedGetter + deltasArg Getter expectedDeltas Deltas }{ "merge_empty_deltas": { diff --git a/internal/trie/tracking/interfaces.go b/internal/trie/tracking/interfaces.go index 0e4ea324fd..57e02bcb3a 100644 --- a/internal/trie/tracking/interfaces.go +++ b/internal/trie/tracking/interfaces.go @@ -5,7 +5,8 @@ package tracking import "github.com/ChainSafe/gossamer/lib/common" -// DeletedGetter gets deleted node hashes. -type DeletedGetter interface { +// Getter gets deleted node hashes. +type Getter interface { Deleted() (nodeHashes map[common.Hash]struct{}) + Updated() (entries []DeltaEntry) } diff --git a/lib/trie/interfaces.go b/lib/trie/interfaces.go index 440476e5a9..6a7fa294dd 100644 --- a/lib/trie/interfaces.go +++ b/lib/trie/interfaces.go @@ -12,7 +12,7 @@ import ( // the last snapshot. type Deltas interface { DeltaMerger - tracking.DeletedGetter + tracking.Getter DeltaRecorder DeepCopy() (deepCopy *tracking.Deltas) } @@ -20,10 +20,11 @@ type Deltas interface { // DeltaMerger merges the given deltas into the current // deltas. type DeltaMerger interface { - MergeWith(deltas tracking.DeletedGetter) + MergeWith(deltas tracking.Getter) } // DeltaRecorder records deltas done in a ongoing trie operation. type DeltaRecorder interface { RecordDeleted(nodeHash common.Hash) + RecordUpdated(key, value []byte) } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 578203b529..57d50ea9a7 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -58,6 +58,7 @@ func (t *Trie) SetVersion(v TrieLayout) { fmt.Printf("setting trie version to: %d\n", v) t.version = v + t.deltas = tracking.New() } // Equal is to compare one trie with other, this method will ignore the shared db instance @@ -106,12 +107,12 @@ func (t *Trie) Snapshot() (newTrie *Trie) { // handleTrackedDeltas sets the pending deleted node hashes in // the trie deltas tracker if and only if success is true. -func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas tracking.DeletedGetter) { - if !success || t.generation == 0 { - // Do not persist tracked deleted node hashes if the operation failed or - // if the trie generation is zero (first block, no trie snapshot done yet). - return - } +func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas tracking.Getter) { + // if !success || t.generation == 0 { + // // Do not persist tracked deleted node hashes if the operation failed or + // // if the trie generation is zero (first block, no trie snapshot done yet). + // return + // } t.deltas.MergeWith(pendingDeltas) } @@ -221,6 +222,23 @@ func (t *Trie) Hash() (rootHash common.Hash, err error) { return EmptyHash, nil } + if t.version == V1 { + fmt.Println("V1 trie?", t.version == V1) + updatedEntries := t.deltas.Updated() + fmt.Println("len of updated trie:", len(updatedEntries)) + modifiedKeys := make([][]byte, len(updatedEntries)) + for idx, entry := range updatedEntries { + modifiedKeys[idx] = codec.KeyLEToNibbles(entry.Key) + } + + t.applyOver(modifiedKeys, func(n *Node) { + if len(n.StorageValue) > V1MaxInlineValueSize { + fmt.Println("must be updated") + n.MustBeHashed = true + } + }) + } + merkleValue, err := t.root.CalculateRootMerkleValue() if err != nil { return rootHash, err @@ -229,6 +247,31 @@ func (t *Trie) Hash() (rootHash common.Hash, err error) { return rootHash, nil } +func (t *Trie) applyOver(keys [][]byte, f func(n *Node)) { + for _, key := range keys { + findAndApply(t.root, key, f) + } +} + +func findAndApply(n *Node, key []byte, f func(n *Node)) { + if n == nil { + return + } + + if bytes.Equal(n.PartialKey, key) { + f(n) + return + } + + if n.Kind() == node.Branch && bytes.HasPrefix(key, n.PartialKey) { + commonPrefixLength := lenCommonPrefix(n.PartialKey, key) + childIndex := key[commonPrefixLength] + childKey := key[commonPrefixLength+1:] + child := n.Children[childIndex] + findAndApply(child, childKey, f) + } +} + // Entries returns all the key-value pairs in the trie as a map of keys to values // where the keys are encoded in Little Endian. func (t *Trie) Entries() (keyValueMap map[string][]byte) { @@ -365,7 +408,7 @@ func (t *Trie) Put(keyLE, value []byte) (err error) { t.handleTrackedDeltas(success, pendingDeltas) }() - fmt.Printf("inserting a value, trie version: %d\n", t.version) + t.deltas.RecordUpdated(keyLE, value) err = t.insertKeyLE(keyLE, value, pendingDeltas) if err != nil { return err @@ -402,9 +445,9 @@ func (t *Trie) insert(parent *Node, key, value []byte, pendingDeltas DeltaRecord return &Node{ PartialKey: key, StorageValue: value, - MustBeHashed: mustBeHashed(t.version, value), - Generation: t.generation, - Dirty: true, + //MustBeHashed: mustBeHashed(t.version, value), + Generation: t.generation, + Dirty: true, }, mutated, nodesCreated, nil } @@ -434,8 +477,8 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if bytes.Equal(parentLeaf.PartialKey, key) { nodesCreated = 0 - parentLeaf.MustBeHashed = mustBeHashed(t.version, value) - parentLeaf.SetDirty() + //parentLeaf.MustBeHashed = mustBeHashed(t.version, value) + //parentLeaf.SetDirty() if parentLeaf.StorageValueEqual(value) { mutated = false @@ -469,7 +512,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if len(key) == commonPrefixLength { // key is included in parent leaf key - newBranchParent.MustBeHashed = mustBeHashed(t.version, value) + //newBranchParent.MustBeHashed = mustBeHashed(t.version, value) newBranchParent.StorageValue = value if len(key) < len(parentLeafKey) { // Move the current leaf parent as a child to the new branch. @@ -517,7 +560,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, StorageValue: value, Generation: t.generation, Dirty: true, - MustBeHashed: mustBeHashed(t.version, value), + //MustBeHashed: mustBeHashed(t.version, value), } newBranchParent.Children[childIndex] = newLeaf newBranchParent.Descendants++ @@ -532,8 +575,8 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, copySettings := node.DefaultCopySettings if bytes.Equal(key, parentBranch.PartialKey) { - parentBranch.MustBeHashed = mustBeHashed(t.version, value) - parentBranch.SetDirty() + //parentBranch.MustBeHashed = mustBeHashed(t.version, value) + //parentBranch.SetDirty() if parentBranch.StorageValueEqual(value) { mutated = false @@ -562,7 +605,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, StorageValue: value, Generation: t.generation, Dirty: true, - MustBeHashed: mustBeHashed(t.version, value), + //MustBeHashed: mustBeHashed(t.version, value), } nodesCreated = 1 parentBranch, err = t.prepForMutation(parentBranch, copySettings, pendingDeltas) @@ -620,7 +663,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, if len(key) <= commonPrefixLength { newParentBranch.StorageValue = value - newParentBranch.MustBeHashed = mustBeHashed(t.version, value) + //newParentBranch.MustBeHashed = mustBeHashed(t.version, value) } else { childIndex := key[commonPrefixLength] remainingKey := key[commonPrefixLength+1:] @@ -1506,10 +1549,10 @@ func intToByteSlice(n int) (slice []byte) { return []byte{byte(n)} } -func mustBeHashed(trieVersion TrieLayout, storageValue []byte) bool { - mustBe := trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() - if mustBe { - fmt.Printf("must be hashed: %v\n", mustBe) - } - return mustBe -} +// func mustBeHashed(trieVersion TrieLayout, storageValue []byte) bool { +// mustBe := trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() +// if mustBe { +// fmt.Printf("must be hashed: %v\n", mustBe) +// } +// return mustBe +// } diff --git a/lib/trie/trie_test.go b/lib/trie/trie_test.go index 895b9d202a..4602b2e589 100644 --- a/lib/trie/trie_test.go +++ b/lib/trie/trie_test.go @@ -111,7 +111,7 @@ func Test_Trie_handleTrackedDeltas(t *testing.T) { testCases := map[string]struct { trie Trie success bool - pendingDeltas tracking.DeletedGetter + pendingDeltas tracking.Getter expectedTrie Trie }{ "no_success_and_generation_1": { From de8c4c624f556e655e249477075564570438cff8 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Wed, 14 Feb 2024 09:39:42 -0400 Subject: [PATCH 16/36] chore: using deltas and setting nodes as dirty before hashing --- internal/trie/tracking/deltas.go | 6 ------ lib/trie/trie.go | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/internal/trie/tracking/deltas.go b/internal/trie/tracking/deltas.go index 6e93475510..72dbffc8a6 100644 --- a/internal/trie/tracking/deltas.go +++ b/internal/trie/tracking/deltas.go @@ -4,8 +4,6 @@ package tracking import ( - "fmt" - "github.com/ChainSafe/gossamer/lib/common" ) @@ -33,10 +31,6 @@ func (d *Deltas) RecordDeleted(nodeHash common.Hash) { } func (d *Deltas) RecordUpdated(key, value []byte) { - if len(value) > 32 { - fmt.Println("recording key with value larger than 32") - } - entryKey := make([]byte, len(key)) copy(entryKey[:], key[:]) diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 57d50ea9a7..46dca75e80 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -233,8 +233,9 @@ func (t *Trie) Hash() (rootHash common.Hash, err error) { t.applyOver(modifiedKeys, func(n *Node) { if len(n.StorageValue) > V1MaxInlineValueSize { - fmt.Println("must be updated") + fmt.Println("must be hashed") n.MustBeHashed = true + n.SetDirty() } }) } From 52f32dde5caef4ee58a4f012ad7ecd6ecbdc0df4 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Wed, 14 Feb 2024 16:35:35 -0400 Subject: [PATCH 17/36] chore: copy must be hashed in `Copy` method --- internal/trie/node/copy.go | 2 +- lib/trie/trie.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/trie/node/copy.go b/internal/trie/node/copy.go index 94f7b9ed13..1c61698b59 100644 --- a/internal/trie/node/copy.go +++ b/internal/trie/node/copy.go @@ -59,7 +59,7 @@ func (n *Node) Copy(settings CopySettings) *Node { Generation: n.Generation, Descendants: n.Descendants, IsHashedValue: n.IsHashedValue, - //MustBeHashed: n.MustBeHashed, + MustBeHashed: n.MustBeHashed, } if n.Kind() == Branch { diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 46dca75e80..a443e0dc26 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -409,7 +409,7 @@ func (t *Trie) Put(keyLE, value []byte) (err error) { t.handleTrackedDeltas(success, pendingDeltas) }() - t.deltas.RecordUpdated(keyLE, value) + pendingDeltas.RecordUpdated(keyLE, value) err = t.insertKeyLE(keyLE, value, pendingDeltas) if err != nil { return err From 5bbc7b0e967a609379c83dd5b29562fea98fbcc1 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Thu, 15 Feb 2024 14:31:07 -0400 Subject: [PATCH 18/36] wip: bug while storing trie state --- dot/core/service.go | 2 +- dot/state/storage.go | 2 +- dot/sync/chain_sync.go | 3 +- lib/runtime/interfaces.go | 2 +- lib/runtime/storage/trie.go | 4 +- lib/runtime/storage/trie_test.go | 4 +- lib/runtime/wazero/imports.go | 14 ++-- lib/runtime/wazero/instance_test.go | 100 ----------------------- lib/trie/trie.go | 4 +- tests/sync/sync_test.go | 121 ++++++++++++++++++++++++++++ 10 files changed, 139 insertions(+), 117 deletions(-) diff --git a/dot/core/service.go b/dot/core/service.go index 3bcd0b6807..dd327fdcd2 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -247,7 +247,7 @@ func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) er } logger.Infof("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 { diff --git a/dot/state/storage.go b/dot/state/storage.go index 9a41c7e8af..af75b5659a 100644 --- a/dot/state/storage.go +++ b/dot/state/storage.go @@ -59,7 +59,7 @@ func NewStorageState(db database.Database, blockState *BlockState, // StoreTrie stores the given trie in the StorageState and writes it to the database func (s *StorageState) StoreTrie(ts *rtstorage.TrieState, header *types.Header) error { - root := ts.MustRoot(trie.NoMaxInlineValueSize) + root := ts.MustRoot() s.tries.softSet(root, ts.Trie()) diff --git a/dot/sync/chain_sync.go b/dot/sync/chain_sync.go index 4bc98a353e..d080b80bb9 100644 --- a/dot/sync/chain_sync.go +++ b/dot/sync/chain_sync.go @@ -24,7 +24,6 @@ import ( "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/common/variadic" - "github.com/ChainSafe/gossamer/lib/trie" ) var _ ChainSync = (*chainSync)(nil) @@ -875,7 +874,7 @@ func (cs *chainSync) handleBlock(block *types.Block, announceImportedBlock bool) return err } - root := ts.MustRoot(trie.NoMaxInlineValueSize) + root := ts.MustRoot() if !bytes.Equal(parent.StateRoot[:], root[:]) { panic("parent state root does not match snapshot state root") } diff --git a/lib/runtime/interfaces.go b/lib/runtime/interfaces.go index 788b049e52..98af5c7b46 100644 --- a/lib/runtime/interfaces.go +++ b/lib/runtime/interfaces.go @@ -13,7 +13,7 @@ import ( type Storage interface { Put(key []byte, value []byte) (err error) Get(key []byte) []byte - Root(maxInlineValueSize int) (common.Hash, error) + Root() (common.Hash, error) SetChild(keyToChild []byte, child *trie.Trie) error SetChildStorage(keyToChild, key, value []byte) error GetChildStorage(keyToChild, key []byte) ([]byte, error) diff --git a/lib/runtime/storage/trie.go b/lib/runtime/storage/trie.go index 06f11adb71..e975262191 100644 --- a/lib/runtime/storage/trie.go +++ b/lib/runtime/storage/trie.go @@ -105,7 +105,7 @@ func (t *TrieState) Get(key []byte) []byte { } // MustRoot returns the trie's root hash. It panics if it fails to compute the root. -func (t *TrieState) MustRoot(maxInlineValue int) common.Hash { +func (t *TrieState) MustRoot() common.Hash { t.mtx.RLock() defer t.mtx.RUnlock() @@ -113,7 +113,7 @@ func (t *TrieState) MustRoot(maxInlineValue int) common.Hash { } // Root returns the trie's root hash -func (t *TrieState) Root(maxInlineValue int) (common.Hash, error) { +func (t *TrieState) Root() (common.Hash, error) { t.mtx.RLock() defer t.mtx.RUnlock() diff --git a/lib/runtime/storage/trie_test.go b/lib/runtime/storage/trie_test.go index 01acbf0177..773d88f12b 100644 --- a/lib/runtime/storage/trie_test.go +++ b/lib/runtime/storage/trie_test.go @@ -104,8 +104,8 @@ func TestTrieState_Root(t *testing.T) { ts.Put([]byte(tc), []byte(tc)) } - expected := ts.MustRoot(trie.NoMaxInlineValueSize) - require.Equal(t, expected, ts.MustRoot(trie.NoMaxInlineValueSize)) + expected := ts.MustRoot() + require.Equal(t, expected, ts.MustRoot()) } ts := NewTrieState(trie.NewEmptyTrie()) diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index 21fe0fea89..9328fb1cae 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -2285,7 +2285,7 @@ func ext_storage_root_version_1(ctx context.Context, m api.Module) uint64 { } storage := rtCtx.Storage - root, err := storage.Root(trie.V0.MaxInlineValue()) + root, err := storage.Root() if err != nil { logger.Errorf("failed to get storage root: %s", err) panic(err) @@ -2309,13 +2309,13 @@ func ext_storage_root_version_2(ctx context.Context, m api.Module, version uint3 } storage := rtCtx.Storage - stateVersion, err := trie.ParseVersion(version) - if err != nil { - logger.Errorf("failed parsing state version: %s", err) - return mustWrite(m, rtCtx.Allocator, emptyByteVectorEncoded) - } + // stateVersion, err := trie.ParseVersion(version) + // if err != nil { + // logger.Errorf("failed parsing state version: %s", err) + // return mustWrite(m, rtCtx.Allocator, emptyByteVectorEncoded) + // } - root, err := storage.Root(stateVersion.MaxInlineValue()) + root, err := storage.Root() if err != nil { logger.Errorf("failed to get storage root: %s", err) panic(err) diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index 67521745cb..ddf50db845 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -5,7 +5,6 @@ package wazero_runtime import ( _ "embed" - "fmt" "bytes" "encoding/json" @@ -14,7 +13,6 @@ import ( "path/filepath" "testing" - "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" @@ -1278,101 +1276,3 @@ func TestInstance_GrandpaSubmitReportEquivocationUnsignedExtrinsic(t *testing.T) err = runtime.GrandpaSubmitReportEquivocationUnsignedExtrinsic(equivocationProof, opaqueKeyOwnershipProof) require.NoError(t, err) } - -func TestDebugWestendBlock14576855And14576856(t *testing.T) { - wnd14576854StateTrie := newTrieFromRPC(t, "../test_data/14576854trie_state_data.json") - expectedStorageRootHash := common.MustHexToHash("0xedd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b") - require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) - - state := storage.NewTrieState(wnd14576854StateTrie) - codeHash, err := state.LoadCodeHash() - require.NoError(t, err) - - fmt.Printf("code hash at start: %s\n", codeHash.String()) - - cfg := Config{ - Storage: state, - LogLvl: log.Critical, - } - - instance, err := NewInstanceFromTrie(wnd14576854StateTrie, cfg) - require.NoError(t, err) - - blockResponseBytes, err := common.HexToBytes("0x0a91140a200283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4012a10240a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e1a0b280402000b6182c93586011abb11e522042d00400c0100000000b6a695e095d905fda4aa41746c0a0752cc3559eb00687d9a13c2a01745290573f6fa11cf3569c116e125d57ec15723653e8f4cda3ec481df1e0d2938f9c3f6880c0101000000740d6868002741aad034c5ffb5dcf31db78f2bb2eb1349bb02dc17d445e9f837914ec9394d52b6d6a3301fc7597de47bc2e48f6f3965999b4ea48fa5667aa4890c01020000002a0962f0b38163dfc2ed4f18727d530d49c05b4e8dbbd1b2c3af310956651277ed247263db04acedb2076ec99b516dff7598ba1f2d328006d4eb04e4c7e7028a0c0103000000f4a8ad3422500b05b5e91f1bae5db4aaa0d576f201ef8f39104764be34b9f229e3e123aec9f98fc9a64b3c4323428bbee3fb358474e2142f273fc3218cc9248c0c0104000000a6a5ee07dafbff4e52ae279f3149d35023751e61a4174c95e3a1afd56ca3365b939b7437f87bda45bfc052a0b0a71cd731296ed6d9edbc127a8e16cdeb52ff800c0105000000b0901765a119c80051f5000b3418b88f328a425b0fbd67aaa0f48acf6347903747cd681c8c4abd4fcb04f0748de2402a3da9ba59f6da9154e07b17e0c1154f890c01060000004cf0b4ec852a062a2cc599ac764a5bd6d6afb469326cfbf736ef0399d987de06ddf842c42f03c479d683aa7c511eb5ccc8f038192ff1fb8a1e1f234446efcb8c0c01070000004aad3d5f2f24ff187a06db9b87a2affa8ac0e219b02512dfd81549bccf62b8111e9961befb215d7e05d7f9ae14f2726098dd95f971e01daac6e720fde387f08c0c01080000004263728475b9e1e48f313e9e4d10cd9a1938d3bd3a80d48ed1418657d303643fac70ba80a6cdad37746e119eb280b668455d297e3b9113edc80ac6762536d18d0c01090000002a9aef1f1b91400ba0d52126b535393ffbfa60c531265efe2bf3dee09aa6f5453a14f3d94bc7f34f3b3d931d46f4726bc87e117a7baa93dd9bb1ac8a9d41da8e0c010a0000000606a0fbaf5f6ba57bc8276aa3e4ad587a1103563d8ea806ded26c8c751fa51dc3e69b4c1f016446cc711be1172a687ee2a5c52f2cb25b9255bf95c4b0fb57810c010b00000054ef1c2e69dd06552fef2b085c4afe5ea1bede23cb912aefb3eff3a3be820f3f1852e54001c15ba05d8b038e2b72207d94c94f8550b0f02fd8c7ee44bcf4df840c010c000000a6b9492a5bc58a4ca6f975c1c50f0c8f09f6b4e842a04a767867c11cc4910f1528efe6a26579981a7d82bda20cdc346fa805703d0aff9988a61ae63443a5008a0c010d000000ca13f5d6336bf7b54351c831d51c3d3aa37c9c1b806ed5715bb72c6a3206d25c893772dac586a3b3e3a616c637947d86119aa54ee4599c4dad23d4ff2f4e7b860c010e0000000e756428f4382e4e540c46a0ea60fdb094129e0d0be80fb7494498d7e714d832c57b158de81ca0f0df736f89035e7eb7449b609adf5c80ef751fb205acac0a800c010f000000820323f879134b5ca5bdcfa4f45a6089c1f5f198633ca8f841349e0e32a6032d20612506730aa5cf0141d56e156234540548164cf1cb6837d767a14d9d5dc18b04ea03000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e3468b0e01113f2c78d4b7b20efd4bdc38627c60bb4b840c8e7476e891b505d828eb016dba1703a583c3e64688bdf97e2bc29a8b6cb499a432d237a323b1412e90e2f769655c4651e3d298ecdc2a536cb89a3a3f31a0f6441a3ae4aa51c4741d32d1cd99206627a51c448c1dbf1f50009655c98b0c1326ae38420d9515cbbcf93ec8084285c48449903c919b164453fde3c5412badebcee765a01aa1b7a8fd503519283259d37c98ecab006af925b013b57a27fe56800cda5f5feec980cb110f87030f7913bfad164bd2dcff5556e48cf06bc28bb3f1ead5200be27d95adbcac624e714e61e9b3100565ae524c326102f8bc17bd3e9e73a185b8116a9e964e665c000000e902d1eb45830486f22485d977ff49349529742a039db30cb9da5fda419c6302bfa8b6ea0b005ff08f7e128ee3e8d263926c4f682842d2eb319b09f251540a815836db74761490734e7a9fd6e677f451d30e6fe142c52655c15db683a4931659c75ac85fbf6c080661757261204411530800000000056175726101015e53dd83b63d9a65ee2906fcbeb0719f9a7a7281513441e211f448efcdfd472a80fe4cb669fa22b8499961bea7643c3586fd16d26e220cb7e5a9da8a1d07ce8b00000000d66cde001401b0b5c1ee601faedc6101d132c793fcdae39737468c9c3dcc3c57fb5b4e2f14648b002685a67f4aeca1fef16795c2c2c352b5afd91a8fe346b7f278f2fce67b8602d23eb4ca1a20f459e1557a1ccc8976dcc686873f3499262e8cd38d0e6294a4340c1fa00bc26ec9a18df5b1b14d4b90bd3c75c5d35b6dff8eeca23976de2f288301d4fa4f3d94cb63c38ea719e64ae09cd7d6eb409d8d1bc21f1a00377fb30e4118e89dd2b4fba1a538819f4dc57e5cf76e80d953ef4c04ad81918b4d68b050db8f021aba632739c7993e789b4ae276b6c933e82a644d5442443224e9fb12d499e12a41a8b4deeb4ebe503842cf8cb680e84e0e4e6898bf62a3cf722262f654cec086029c38b051968569013dc5c2fbc93db0c4bb86a3f548dc5ddff363f32fbe7704682a5dabb9e9689ba820a5f68ac31a92613e0f760d4862c41f5d97edb22e378d8a141f007d63733ead4d8c05045abe1f10fca05ca02aa44c5aafb59135a841c09afeb3965ab37903edd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b5f6028c17d04a84ec8811461e52a44e489e67b01bfd421b1e25e002200ab433e080642414245b501030d0000008922a610000000002e1e6cadbc719c66a3a4193c2b577cce37eec5e041213ba010823a9b988da947f942254709d3786c37eebb54253f639584dd149883df229258a3ae02ee81860b5945c6ba5fb7990a0fb7ec0ff19c9d5ea8b7d613cfe7de3a8bcb4bdb8f6fed0f05424142450101266ba8cf6a2b5b86a3a1bda16be242d75b042a8dea21e57e0c265cdbc942612c9531ff2178a02871336d6e326d2a71bbb749c3dbc7e3a82ea1c2c0690a73ca8a") - require.NoError(t, err) - - blockResponse := new(network.BlockResponseMessage) - err = blockResponse.Decode(blockResponseBytes) - require.NoError(t, err) - - blockData := blockResponse.BlockData[0] - - block := &types.Block{ - Header: *blockData.Header, - Body: *blockData.Body, - } - - fmt.Printf("Executing block number %d\n", block.Header.Number) - _, err = instance.ExecuteBlock(block) - require.NoError(t, err) - - codeHash, err = state.LoadCodeHash() - require.NoError(t, err) - - fmt.Printf("code hash from updated state: %s\n", codeHash.String()) - - // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") - // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") - // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) - - // state := storage.NewTrieState(wnd14576855StateTrie) - instance, err = NewInstanceFromTrie(state.Trie(), Config{ - Storage: state, - LogLvl: log.Critical, - }) - require.NoError(t, err) - // instance.version() - // instance.SetContextStorage(state) - - blockResponseBytes, err = common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") - require.NoError(t, err) - - blockResponse = new(network.BlockResponseMessage) - err = blockResponse.Decode(blockResponseBytes) - require.NoError(t, err) - - blockData = blockResponse.BlockData[0] - - block = &types.Block{ - Header: *blockData.Header, - Body: *blockData.Body, - } - - fmt.Printf("Executing block number %d\n", block.Header.Number) - - _, err = instance.ExecuteBlock(block) - require.NoError(t, err) -} - -func newTrieFromRPC(t *testing.T, filename string) *trie.Trie { - data, err := os.ReadFile(filename) - require.NoError(t, err) - - encodedTrieEntries := make([]string, 0) - err = json.Unmarshal(data, &encodedTrieEntries) - require.NoError(t, err) - - entries := make(map[string]string, len(encodedTrieEntries)) - for _, encodedEntry := range encodedTrieEntries { - bytesEncodedEntry := common.MustHexToBytes(encodedEntry) - entry := trie.Entry{} - err := scale.Unmarshal(bytesEncodedEntry, &entry) - require.NoError(t, err) - - entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) - } - - tr, err := trie.LoadFromMap(entries) - require.NoError(t, err) - return &tr -} diff --git a/lib/trie/trie.go b/lib/trie/trie.go index a443e0dc26..bee39b022f 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -56,8 +56,10 @@ func (t *Trie) SetVersion(v TrieLayout) { panic("cannot regress trie version") } - fmt.Printf("setting trie version to: %d\n", v) + fmt.Printf("setting trie version as: %d\n", v) t.version = v + + fmt.Printf("cleaning up deltas\n") t.deltas = tracking.New() } diff --git a/tests/sync/sync_test.go b/tests/sync/sync_test.go index 7c631de613..94a70cbe25 100644 --- a/tests/sync/sync_test.go +++ b/tests/sync/sync_test.go @@ -5,9 +5,22 @@ package sync import ( "context" + "encoding/json" + "fmt" + "os" "testing" "time" + "github.com/ChainSafe/gossamer/dot/network" + "github.com/ChainSafe/gossamer/dot/state" + "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" + "github.com/ChainSafe/gossamer/internal/log" + "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/runtime/storage" + wazero_runtime "github.com/ChainSafe/gossamer/lib/runtime/wazero" + "github.com/ChainSafe/gossamer/lib/trie" + "github.com/ChainSafe/gossamer/pkg/scale" "github.com/ChainSafe/gossamer/tests/utils" "github.com/ChainSafe/gossamer/tests/utils/config" "github.com/stretchr/testify/require" @@ -93,3 +106,111 @@ func TestCalls(t *testing.T) { require.True(t, res) } } + +func TestDebugWestendBlock14576855And14576856(t *testing.T) { + wnd14576854StateTrie := newTrieFromRPC(t, "../../lib/runtime/test_data/14576854trie_state_data.json") + expectedStorageRootHash := common.MustHexToHash("0xedd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b") + require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) + + db, err := database.NewPebble(t.TempDir(), true) + require.NoError(t, err) + + storageState, err := state.NewStorageState(db, nil, state.NewTries()) + require.NoError(t, err) + + trieState := storage.NewTrieState(wnd14576854StateTrie) + codeHash, err := trieState.LoadCodeHash() + require.NoError(t, err) + + fmt.Printf("code hash at start: %s\n", codeHash.String()) + + cfg := wazero_runtime.Config{ + Storage: trieState, + LogLvl: log.Critical, + } + + instance, err := wazero_runtime.NewInstanceFromTrie(wnd14576854StateTrie, cfg) + require.NoError(t, err) + + blockResponseBytes, err := common.HexToBytes("0x0a91140a200283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4012a10240a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e1a0b280402000b6182c93586011abb11e522042d00400c0100000000b6a695e095d905fda4aa41746c0a0752cc3559eb00687d9a13c2a01745290573f6fa11cf3569c116e125d57ec15723653e8f4cda3ec481df1e0d2938f9c3f6880c0101000000740d6868002741aad034c5ffb5dcf31db78f2bb2eb1349bb02dc17d445e9f837914ec9394d52b6d6a3301fc7597de47bc2e48f6f3965999b4ea48fa5667aa4890c01020000002a0962f0b38163dfc2ed4f18727d530d49c05b4e8dbbd1b2c3af310956651277ed247263db04acedb2076ec99b516dff7598ba1f2d328006d4eb04e4c7e7028a0c0103000000f4a8ad3422500b05b5e91f1bae5db4aaa0d576f201ef8f39104764be34b9f229e3e123aec9f98fc9a64b3c4323428bbee3fb358474e2142f273fc3218cc9248c0c0104000000a6a5ee07dafbff4e52ae279f3149d35023751e61a4174c95e3a1afd56ca3365b939b7437f87bda45bfc052a0b0a71cd731296ed6d9edbc127a8e16cdeb52ff800c0105000000b0901765a119c80051f5000b3418b88f328a425b0fbd67aaa0f48acf6347903747cd681c8c4abd4fcb04f0748de2402a3da9ba59f6da9154e07b17e0c1154f890c01060000004cf0b4ec852a062a2cc599ac764a5bd6d6afb469326cfbf736ef0399d987de06ddf842c42f03c479d683aa7c511eb5ccc8f038192ff1fb8a1e1f234446efcb8c0c01070000004aad3d5f2f24ff187a06db9b87a2affa8ac0e219b02512dfd81549bccf62b8111e9961befb215d7e05d7f9ae14f2726098dd95f971e01daac6e720fde387f08c0c01080000004263728475b9e1e48f313e9e4d10cd9a1938d3bd3a80d48ed1418657d303643fac70ba80a6cdad37746e119eb280b668455d297e3b9113edc80ac6762536d18d0c01090000002a9aef1f1b91400ba0d52126b535393ffbfa60c531265efe2bf3dee09aa6f5453a14f3d94bc7f34f3b3d931d46f4726bc87e117a7baa93dd9bb1ac8a9d41da8e0c010a0000000606a0fbaf5f6ba57bc8276aa3e4ad587a1103563d8ea806ded26c8c751fa51dc3e69b4c1f016446cc711be1172a687ee2a5c52f2cb25b9255bf95c4b0fb57810c010b00000054ef1c2e69dd06552fef2b085c4afe5ea1bede23cb912aefb3eff3a3be820f3f1852e54001c15ba05d8b038e2b72207d94c94f8550b0f02fd8c7ee44bcf4df840c010c000000a6b9492a5bc58a4ca6f975c1c50f0c8f09f6b4e842a04a767867c11cc4910f1528efe6a26579981a7d82bda20cdc346fa805703d0aff9988a61ae63443a5008a0c010d000000ca13f5d6336bf7b54351c831d51c3d3aa37c9c1b806ed5715bb72c6a3206d25c893772dac586a3b3e3a616c637947d86119aa54ee4599c4dad23d4ff2f4e7b860c010e0000000e756428f4382e4e540c46a0ea60fdb094129e0d0be80fb7494498d7e714d832c57b158de81ca0f0df736f89035e7eb7449b609adf5c80ef751fb205acac0a800c010f000000820323f879134b5ca5bdcfa4f45a6089c1f5f198633ca8f841349e0e32a6032d20612506730aa5cf0141d56e156234540548164cf1cb6837d767a14d9d5dc18b04ea03000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e3468b0e01113f2c78d4b7b20efd4bdc38627c60bb4b840c8e7476e891b505d828eb016dba1703a583c3e64688bdf97e2bc29a8b6cb499a432d237a323b1412e90e2f769655c4651e3d298ecdc2a536cb89a3a3f31a0f6441a3ae4aa51c4741d32d1cd99206627a51c448c1dbf1f50009655c98b0c1326ae38420d9515cbbcf93ec8084285c48449903c919b164453fde3c5412badebcee765a01aa1b7a8fd503519283259d37c98ecab006af925b013b57a27fe56800cda5f5feec980cb110f87030f7913bfad164bd2dcff5556e48cf06bc28bb3f1ead5200be27d95adbcac624e714e61e9b3100565ae524c326102f8bc17bd3e9e73a185b8116a9e964e665c000000e902d1eb45830486f22485d977ff49349529742a039db30cb9da5fda419c6302bfa8b6ea0b005ff08f7e128ee3e8d263926c4f682842d2eb319b09f251540a815836db74761490734e7a9fd6e677f451d30e6fe142c52655c15db683a4931659c75ac85fbf6c080661757261204411530800000000056175726101015e53dd83b63d9a65ee2906fcbeb0719f9a7a7281513441e211f448efcdfd472a80fe4cb669fa22b8499961bea7643c3586fd16d26e220cb7e5a9da8a1d07ce8b00000000d66cde001401b0b5c1ee601faedc6101d132c793fcdae39737468c9c3dcc3c57fb5b4e2f14648b002685a67f4aeca1fef16795c2c2c352b5afd91a8fe346b7f278f2fce67b8602d23eb4ca1a20f459e1557a1ccc8976dcc686873f3499262e8cd38d0e6294a4340c1fa00bc26ec9a18df5b1b14d4b90bd3c75c5d35b6dff8eeca23976de2f288301d4fa4f3d94cb63c38ea719e64ae09cd7d6eb409d8d1bc21f1a00377fb30e4118e89dd2b4fba1a538819f4dc57e5cf76e80d953ef4c04ad81918b4d68b050db8f021aba632739c7993e789b4ae276b6c933e82a644d5442443224e9fb12d499e12a41a8b4deeb4ebe503842cf8cb680e84e0e4e6898bf62a3cf722262f654cec086029c38b051968569013dc5c2fbc93db0c4bb86a3f548dc5ddff363f32fbe7704682a5dabb9e9689ba820a5f68ac31a92613e0f760d4862c41f5d97edb22e378d8a141f007d63733ead4d8c05045abe1f10fca05ca02aa44c5aafb59135a841c09afeb3965ab37903edd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b5f6028c17d04a84ec8811461e52a44e489e67b01bfd421b1e25e002200ab433e080642414245b501030d0000008922a610000000002e1e6cadbc719c66a3a4193c2b577cce37eec5e041213ba010823a9b988da947f942254709d3786c37eebb54253f639584dd149883df229258a3ae02ee81860b5945c6ba5fb7990a0fb7ec0ff19c9d5ea8b7d613cfe7de3a8bcb4bdb8f6fed0f05424142450101266ba8cf6a2b5b86a3a1bda16be242d75b042a8dea21e57e0c265cdbc942612c9531ff2178a02871336d6e326d2a71bbb749c3dbc7e3a82ea1c2c0690a73ca8a") + require.NoError(t, err) + + blockResponse := new(network.BlockResponseMessage) + err = blockResponse.Decode(blockResponseBytes) + require.NoError(t, err) + + blockData := blockResponse.BlockData[0] + + block := &types.Block{ + Header: *blockData.Header, + Body: *blockData.Body, + } + + fmt.Printf("Executing block number %d\n", block.Header.Number) + _, err = instance.ExecuteBlock(block) + require.NoError(t, err) + + fmt.Printf("Storing the trie to the disk, regards block %d\n", block.Header.Number) + err = storageState.StoreTrie(trieState, &block.Header) + require.NoError(t, err) + + codeHash, err = trieState.LoadCodeHash() + require.NoError(t, err) + + fmt.Printf("code hash from updated state: %s\n", codeHash.String()) + + // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") + // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") + // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) + + // state := storage.NewTrieState(wnd14576855StateTrie) + instance, err = wazero_runtime.NewInstanceFromTrie(trieState.Trie(), wazero_runtime.Config{ + Storage: trieState, + LogLvl: log.Critical, + }) + require.NoError(t, err) + // instance.version() + // instance.SetContextStorage(state) + + blockResponseBytes, err = common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") + require.NoError(t, err) + + blockResponse = new(network.BlockResponseMessage) + err = blockResponse.Decode(blockResponseBytes) + require.NoError(t, err) + + blockData = blockResponse.BlockData[0] + + block = &types.Block{ + Header: *blockData.Header, + Body: *blockData.Body, + } + + fmt.Printf("Executing block number %d\n", block.Header.Number) + + _, err = instance.ExecuteBlock(block) + require.NoError(t, err) +} + +func newTrieFromRPC(t *testing.T, filename string) *trie.Trie { + data, err := os.ReadFile(filename) + require.NoError(t, err) + + encodedTrieEntries := make([]string, 0) + err = json.Unmarshal(data, &encodedTrieEntries) + require.NoError(t, err) + + entries := make(map[string]string, len(encodedTrieEntries)) + for _, encodedEntry := range encodedTrieEntries { + bytesEncodedEntry := common.MustHexToBytes(encodedEntry) + entry := trie.Entry{} + err := scale.Unmarshal(bytesEncodedEntry, &entry) + require.NoError(t, err) + + entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) + } + + tr, err := trie.LoadFromMap(entries) + require.NoError(t, err) + return &tr +} From 102fc7cd67591e875d66bd2424c344dad23ff3a5 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Thu, 15 Feb 2024 14:47:49 -0400 Subject: [PATCH 19/36] chore: ... --- tests/sync/sync_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/sync/sync_test.go b/tests/sync/sync_test.go index 94a70cbe25..21e48c0758 100644 --- a/tests/sync/sync_test.go +++ b/tests/sync/sync_test.go @@ -151,7 +151,9 @@ func TestDebugWestendBlock14576855And14576856(t *testing.T) { require.NoError(t, err) fmt.Printf("Storing the trie to the disk, regards block %d\n", block.Header.Number) - err = storageState.StoreTrie(trieState, &block.Header) + + newTrieState := storage.NewTrieState(trieState.Trie().DeepCopy()) + err = storageState.StoreTrie(newTrieState, &block.Header) require.NoError(t, err) codeHash, err = trieState.LoadCodeHash() From e30040b541b80afdf4462a3522c2fe0673cccc53 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Thu, 15 Feb 2024 16:02:34 -0400 Subject: [PATCH 20/36] fix: using must be hashed and modified = true --- dot/state/storage.go | 1 - internal/trie/node/encode.go | 1 - lib/runtime/storage/trie.go | 6 ++ lib/trie/trie.go | 106 +++++++++++------------------------ tests/sync/sync_test.go | 37 ++++++------ 5 files changed, 59 insertions(+), 92 deletions(-) diff --git a/dot/state/storage.go b/dot/state/storage.go index af75b5659a..15eb56c3b0 100644 --- a/dot/state/storage.go +++ b/dot/state/storage.go @@ -60,7 +60,6 @@ func NewStorageState(db database.Database, blockState *BlockState, // StoreTrie stores the given trie in the StorageState and writes it to the database func (s *StorageState) StoreTrie(ts *rtstorage.TrieState, header *types.Header) error { root := ts.MustRoot() - s.tries.softSet(root, ts.Trie()) if header != nil { diff --git a/internal/trie/node/encode.go b/internal/trie/node/encode.go index 57dd02f67c..dca9448b40 100644 --- a/internal/trie/node/encode.go +++ b/internal/trie/node/encode.go @@ -48,7 +48,6 @@ func (n *Node) Encode(buffer Buffer) (err error) { if n.StorageValue != nil { switch { case n.MustBeHashed: - fmt.Println("beign hashed") hashedValue, err := common.Blake2bHash(n.StorageValue) if err != nil { return fmt.Errorf("hashing storage value: %w", err) diff --git a/lib/runtime/storage/trie.go b/lib/runtime/storage/trie.go index e975262191..7da2f3fcee 100644 --- a/lib/runtime/storage/trie.go +++ b/lib/runtime/storage/trie.go @@ -79,6 +79,9 @@ func (t *TrieState) SetVersion(v trie.TrieLayout) { // Trie returns the TrieState's underlying trie func (t *TrieState) Trie() *trie.Trie { + t.mtx.RLock() + defer t.mtx.RUnlock() + return t.getCurrentTrie() } @@ -86,6 +89,9 @@ func (t *TrieState) Trie() *trie.Trie { // can no longer be modified, all further changes are on a new "version" of the trie. // It returns the new version of the trie. func (t *TrieState) Snapshot() *trie.Trie { + t.mtx.RLock() + defer t.mtx.RUnlock() + return t.getCurrentTrie().Snapshot() } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index bee39b022f..d881286d56 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -58,9 +58,6 @@ func (t *Trie) SetVersion(v TrieLayout) { fmt.Printf("setting trie version as: %d\n", v) t.version = v - - fmt.Printf("cleaning up deltas\n") - t.deltas = tracking.New() } // Equal is to compare one trie with other, this method will ignore the shared db instance @@ -92,7 +89,7 @@ func (t *Trie) Snapshot() (newTrie *Trie) { childTries[rootHash] = &Trie{ generation: childTrie.generation + 1, root: childTrie.root.Copy(rootCopySettings), - deltas: childTrie.deltas.DeepCopy(), + deltas: tracking.New(), version: t.version, } } @@ -102,7 +99,7 @@ func (t *Trie) Snapshot() (newTrie *Trie) { root: t.root, db: t.db, childTries: childTries, - deltas: t.deltas.DeepCopy(), + deltas: tracking.New(), version: t.version, } } @@ -110,11 +107,11 @@ func (t *Trie) Snapshot() (newTrie *Trie) { // handleTrackedDeltas sets the pending deleted node hashes in // the trie deltas tracker if and only if success is true. func (t *Trie) handleTrackedDeltas(success bool, pendingDeltas tracking.Getter) { - // if !success || t.generation == 0 { - // // Do not persist tracked deleted node hashes if the operation failed or - // // if the trie generation is zero (first block, no trie snapshot done yet). - // return - // } + if !success || t.generation == 0 { + // Do not persist tracked deleted node hashes if the operation failed or + // if the trie generation is zero (first block, no trie snapshot done yet). + return + } t.deltas.MergeWith(pendingDeltas) } @@ -224,57 +221,15 @@ func (t *Trie) Hash() (rootHash common.Hash, err error) { return EmptyHash, nil } - if t.version == V1 { - fmt.Println("V1 trie?", t.version == V1) - updatedEntries := t.deltas.Updated() - fmt.Println("len of updated trie:", len(updatedEntries)) - modifiedKeys := make([][]byte, len(updatedEntries)) - for idx, entry := range updatedEntries { - modifiedKeys[idx] = codec.KeyLEToNibbles(entry.Key) - } - - t.applyOver(modifiedKeys, func(n *Node) { - if len(n.StorageValue) > V1MaxInlineValueSize { - fmt.Println("must be hashed") - n.MustBeHashed = true - n.SetDirty() - } - }) - } - merkleValue, err := t.root.CalculateRootMerkleValue() if err != nil { return rootHash, err } copy(rootHash[:], merkleValue) + t.deltas = tracking.New() return rootHash, nil } -func (t *Trie) applyOver(keys [][]byte, f func(n *Node)) { - for _, key := range keys { - findAndApply(t.root, key, f) - } -} - -func findAndApply(n *Node, key []byte, f func(n *Node)) { - if n == nil { - return - } - - if bytes.Equal(n.PartialKey, key) { - f(n) - return - } - - if n.Kind() == node.Branch && bytes.HasPrefix(key, n.PartialKey) { - commonPrefixLength := lenCommonPrefix(n.PartialKey, key) - childIndex := key[commonPrefixLength] - childKey := key[commonPrefixLength+1:] - child := n.Children[childIndex] - findAndApply(child, childKey, f) - } -} - // Entries returns all the key-value pairs in the trie as a map of keys to values // where the keys are encoded in Little Endian. func (t *Trie) Entries() (keyValueMap map[string][]byte) { @@ -411,7 +366,7 @@ func (t *Trie) Put(keyLE, value []byte) (err error) { t.handleTrackedDeltas(success, pendingDeltas) }() - pendingDeltas.RecordUpdated(keyLE, value) + //pendingDeltas.RecordUpdated(keyLE, value) err = t.insertKeyLE(keyLE, value, pendingDeltas) if err != nil { return err @@ -448,9 +403,9 @@ func (t *Trie) insert(parent *Node, key, value []byte, pendingDeltas DeltaRecord return &Node{ PartialKey: key, StorageValue: value, - //MustBeHashed: mustBeHashed(t.version, value), - Generation: t.generation, - Dirty: true, + MustBeHashed: mustBeHashed(t.version, value), + Generation: t.generation, + Dirty: true, }, mutated, nodesCreated, nil } @@ -480,11 +435,15 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if bytes.Equal(parentLeaf.PartialKey, key) { nodesCreated = 0 - //parentLeaf.MustBeHashed = mustBeHashed(t.version, value) - //parentLeaf.SetDirty() + mutated = false + + if parentLeaf.MustBeHashed != mustBeHashed(t.version, value) { + mutated = true + parentLeaf.MustBeHashed = mustBeHashed(t.version, value) + parentLeaf.SetDirty() + } if parentLeaf.StorageValueEqual(value) { - mutated = false return parentLeaf, mutated, nodesCreated, nil } @@ -515,7 +474,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if len(key) == commonPrefixLength { // key is included in parent leaf key - //newBranchParent.MustBeHashed = mustBeHashed(t.version, value) + newBranchParent.MustBeHashed = mustBeHashed(t.version, value) newBranchParent.StorageValue = value if len(key) < len(parentLeafKey) { // Move the current leaf parent as a child to the new branch. @@ -563,7 +522,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, StorageValue: value, Generation: t.generation, Dirty: true, - //MustBeHashed: mustBeHashed(t.version, value), + MustBeHashed: mustBeHashed(t.version, value), } newBranchParent.Children[childIndex] = newLeaf newBranchParent.Descendants++ @@ -578,11 +537,14 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, copySettings := node.DefaultCopySettings if bytes.Equal(key, parentBranch.PartialKey) { - //parentBranch.MustBeHashed = mustBeHashed(t.version, value) - //parentBranch.SetDirty() + mutated = false + if parentBranch.MustBeHashed != mustBeHashed(t.version, value) { + mutated = true + parentBranch.MustBeHashed = mustBeHashed(t.version, value) + parentBranch.SetDirty() + } if parentBranch.StorageValueEqual(value) { - mutated = false return parentBranch, mutated, nodesCreated, nil } @@ -608,7 +570,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, StorageValue: value, Generation: t.generation, Dirty: true, - //MustBeHashed: mustBeHashed(t.version, value), + MustBeHashed: mustBeHashed(t.version, value), } nodesCreated = 1 parentBranch, err = t.prepForMutation(parentBranch, copySettings, pendingDeltas) @@ -666,7 +628,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, if len(key) <= commonPrefixLength { newParentBranch.StorageValue = value - //newParentBranch.MustBeHashed = mustBeHashed(t.version, value) + newParentBranch.MustBeHashed = mustBeHashed(t.version, value) } else { childIndex := key[commonPrefixLength] remainingKey := key[commonPrefixLength+1:] @@ -1552,10 +1514,6 @@ func intToByteSlice(n int) (slice []byte) { return []byte{byte(n)} } -// func mustBeHashed(trieVersion TrieLayout, storageValue []byte) bool { -// mustBe := trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() -// if mustBe { -// fmt.Printf("must be hashed: %v\n", mustBe) -// } -// return mustBe -// } +func mustBeHashed(trieVersion TrieLayout, storageValue []byte) bool { + return trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() +} diff --git a/tests/sync/sync_test.go b/tests/sync/sync_test.go index 21e48c0758..b2a786cadd 100644 --- a/tests/sync/sync_test.go +++ b/tests/sync/sync_test.go @@ -1,4 +1,5 @@ // Copyright 2021 ChainSafe Systems (ON) + // SPDX-License-Identifier: LGPL-3.0-only package sync @@ -145,15 +146,16 @@ func TestDebugWestendBlock14576855And14576856(t *testing.T) { Header: *blockData.Header, Body: *blockData.Body, } + parentBlockStateRoot := block.Header.StateRoot - fmt.Printf("Executing block number %d\n", block.Header.Number) + fmt.Printf("Executing block number %d (%s)\n", block.Header.Number, block.Header.Hash().String()) _, err = instance.ExecuteBlock(block) require.NoError(t, err) fmt.Printf("Storing the trie to the disk, regards block %d\n", block.Header.Number) - newTrieState := storage.NewTrieState(trieState.Trie().DeepCopy()) - err = storageState.StoreTrie(newTrieState, &block.Header) + //newTrieState := storage.NewTrieState(trieState.Trie().DeepCopy()) + err = storageState.StoreTrie(trieState, &block.Header) require.NoError(t, err) codeHash, err = trieState.LoadCodeHash() @@ -161,19 +163,6 @@ func TestDebugWestendBlock14576855And14576856(t *testing.T) { fmt.Printf("code hash from updated state: %s\n", codeHash.String()) - // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") - // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") - // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) - - // state := storage.NewTrieState(wnd14576855StateTrie) - instance, err = wazero_runtime.NewInstanceFromTrie(trieState.Trie(), wazero_runtime.Config{ - Storage: trieState, - LogLvl: log.Critical, - }) - require.NoError(t, err) - // instance.version() - // instance.SetContextStorage(state) - blockResponseBytes, err = common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") require.NoError(t, err) @@ -188,6 +177,22 @@ func TestDebugWestendBlock14576855And14576856(t *testing.T) { Body: *blockData.Body, } + ts, err := storageState.TrieState(&parentBlockStateRoot) + require.NoError(t, err) + + // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") + // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") + // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) + + // state := storage.NewTrieState(wnd14576855StateTrie) + instance, err = wazero_runtime.NewInstanceFromTrie(trieState.Trie(), wazero_runtime.Config{ + Storage: ts, + LogLvl: log.Critical, + }) + require.NoError(t, err) + // instance.version() + // instance.SetContextStorage(state) + fmt.Printf("Executing block number %d\n", block.Header.Number) _, err = instance.ExecuteBlock(block) From 1eba0fd5e29859b37ad3d11769268d8539b33596 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Wed, 21 Feb 2024 17:17:48 -0400 Subject: [PATCH 21/36] wip: while deleting a value make sure to keep the correct must be hashed value --- .gitignore | 2 + dot/import.go | 2 +- lib/runtime/genesis.go | 2 +- lib/runtime/storage/trie.go | 13 +++ lib/trie/trie.go | 35 +++++--- scripts/trie_state_script.go | 2 +- tests/sync/sync_test.go | 163 ++++++++++++++++++++++++++++++++++- 7 files changed, 203 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index d5d719704f..c685c55c63 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ tmp # node_modules used by polkadot.js/api tests tests/polkadotjs_test/node_modules !tests/polkadotjs_test/test/*.wasm + +*.json diff --git a/dot/import.go b/dot/import.go index 208d648765..c34e4951da 100644 --- a/dot/import.go +++ b/dot/import.go @@ -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, trie.V0) if err != nil { return nil, err } diff --git a/lib/runtime/genesis.go b/lib/runtime/genesis.go index 5912886bf1..c1c5cb4d94 100644 --- a/lib/runtime/genesis.go +++ b/lib/runtime/genesis.go @@ -26,7 +26,7 @@ func NewTrieFromGenesis(gen genesis.Genesis) (tr trie.Trie, err error) { ErrGenesisTopNotFound, gen.Name) } - tr, err = trie.LoadFromMap(keyValues) + tr, err = trie.LoadFromMap(keyValues, trie.V0) if err != nil { return tr, fmt.Errorf("loading genesis top key values into trie: %w", err) } diff --git a/lib/runtime/storage/trie.go b/lib/runtime/storage/trie.go index 7da2f3fcee..064ab39bc4 100644 --- a/lib/runtime/storage/trie.go +++ b/lib/runtime/storage/trie.go @@ -44,6 +44,7 @@ func (t *TrieState) StartTransaction() { t.mtx.Lock() defer t.mtx.Unlock() + fmt.Printf("STARTING TRANSACTION\n") t.transactions.PushBack(t.getCurrentTrie().Snapshot()) } @@ -55,6 +56,7 @@ func (t *TrieState) RollbackTransaction() { if t.transactions.Len() <= 1 { panic("no transactions to rollback") } + fmt.Printf("ROLLBACK TRANSACTION\n") t.transactions.Remove(t.transactions.Back()) } @@ -68,6 +70,7 @@ func (t *TrieState) CommitTransaction() { panic("no transactions to commit") } + fmt.Printf("COMMITING TRANSACTION\n") t.transactions.Back().Prev().Value = t.transactions.Remove(t.transactions.Back()) } @@ -100,6 +103,7 @@ func (t *TrieState) Put(key, value []byte) (err error) { t.mtx.Lock() defer t.mtx.Unlock() + fmt.Printf("inserting value\nkey: 0x%x\nvalue: 0x%x\n", key, value) return t.getCurrentTrie().Put(key, value) } @@ -140,6 +144,9 @@ func (t *TrieState) Delete(key []byte) (err error) { t.mtx.Lock() defer t.mtx.Unlock() + + fmt.Printf("deleting key: 0x%x\n", key) + err = t.getCurrentTrie().Delete(key) if err != nil { return fmt.Errorf("deleting from trie: %w", err) @@ -189,6 +196,8 @@ func (t *TrieState) SetChild(keyToChild []byte, child *trie.Trie) error { func (t *TrieState) SetChildStorage(keyToChild, key, value []byte) error { t.mtx.Lock() defer t.mtx.Unlock() + + fmt.Printf("setting child storage!") return t.getCurrentTrie().PutIntoChild(keyToChild, key, value) } @@ -196,6 +205,7 @@ func (t *TrieState) SetChildStorage(keyToChild, key, value []byte) error { func (t *TrieState) GetChild(keyToChild []byte) (*trie.Trie, error) { t.mtx.RLock() defer t.mtx.RUnlock() + return t.getCurrentTrie().GetChild(keyToChild) } @@ -203,6 +213,8 @@ func (t *TrieState) GetChild(keyToChild []byte) (*trie.Trie, error) { func (t *TrieState) GetChildStorage(keyToChild, key []byte) ([]byte, error) { t.mtx.RLock() defer t.mtx.RUnlock() + + fmt.Printf("getting child storage!") return t.getCurrentTrie().GetFromChild(keyToChild, key) } @@ -210,6 +222,7 @@ func (t *TrieState) GetChildStorage(keyToChild, key []byte) ([]byte, error) { func (t *TrieState) DeleteChild(key []byte) (err error) { t.mtx.Lock() defer t.mtx.Unlock() + return t.getCurrentTrie().DeleteChild(key) } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index d881286d56..840a291b6b 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -435,11 +435,10 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if bytes.Equal(parentLeaf.PartialKey, key) { nodesCreated = 0 - mutated = false - - if parentLeaf.MustBeHashed != mustBeHashed(t.version, value) { + ok := mustBeHashed(t.version, value) + if parentLeaf.MustBeHashed != ok { mutated = true - parentLeaf.MustBeHashed = mustBeHashed(t.version, value) + parentLeaf.MustBeHashed = ok parentLeaf.SetDirty() } @@ -471,7 +470,6 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, } parentLeafKey := parentLeaf.PartialKey - if len(key) == commonPrefixLength { // key is included in parent leaf key newBranchParent.MustBeHashed = mustBeHashed(t.version, value) @@ -499,6 +497,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if len(parentLeaf.PartialKey) == commonPrefixLength { // the key of the parent leaf is at this new branch newBranchParent.StorageValue = parentLeaf.StorageValue + newBranchParent.MustBeHashed = parentLeaf.MustBeHashed newBranchParent.IsHashedValue = parentLeaf.IsHashedValue } else { // make the leaf a child of the new branch @@ -537,10 +536,10 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, copySettings := node.DefaultCopySettings if bytes.Equal(key, parentBranch.PartialKey) { - mutated = false - if parentBranch.MustBeHashed != mustBeHashed(t.version, value) { + ok := mustBeHashed(t.version, value) + if parentBranch.MustBeHashed != ok { mutated = true - parentBranch.MustBeHashed = mustBeHashed(t.version, value) + parentBranch.MustBeHashed = ok parentBranch.SetDirty() } @@ -650,8 +649,9 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, // LoadFromMap loads the given data mapping of key to value into a new empty trie. // The keys are in hexadecimal little Endian encoding and the values // are hexadecimal encoded. -func LoadFromMap(data map[string]string) (trie Trie, err error) { +func LoadFromMap(data map[string]string, version TrieLayout) (trie Trie, err error) { trie = *NewEmptyTrie() + trie.SetVersion(version) pendingDeltas := tracking.New() defer func() { @@ -1279,6 +1279,10 @@ func (t *Trie) deleteLeaf(parent *Node, key []byte, return parent, nil } + if len(parent.StorageValue) > 32 { + fmt.Printf("removing a must be hashed storage value\n") + } + newParent = nil err = t.registerDeletedNodeHash(parent, pendingDeltas) @@ -1293,6 +1297,10 @@ func (t *Trie) deleteBranch(branch *Node, key []byte, pendingDeltas DeltaRecorder) ( newParent *Node, deleted bool, nodesRemoved uint32, err error) { if len(key) == 0 || bytes.Equal(branch.PartialKey, key) { + if len(branch.StorageValue) > 32 { + fmt.Printf("removing a must be hashed storage value\n") + } + copySettings := node.DefaultCopySettings copySettings.CopyStorageValue = false branch, err = t.prepForMutation(branch, copySettings, pendingDeltas) @@ -1392,6 +1400,7 @@ func (t *Trie) handleDeletion(branch *Node, key []byte, return &Node{ PartialKey: key[:commonPrefixLength], StorageValue: branch.StorageValue, + MustBeHashed: branch.MustBeHashed, Dirty: true, Generation: branch.Generation, }, branchChildMerged, nil @@ -1415,6 +1424,7 @@ func (t *Trie) handleDeletion(branch *Node, key []byte, IsHashedValue: child.IsHashedValue, Dirty: true, Generation: branch.Generation, + MustBeHashed: child.MustBeHashed, }, branchChildMerged, nil } @@ -1423,6 +1433,7 @@ func (t *Trie) handleDeletion(branch *Node, key []byte, newBranch := &Node{ PartialKey: newBranchKey, StorageValue: childBranch.StorageValue, + MustBeHashed: childBranch.MustBeHashed, Generation: branch.Generation, Children: make([]*node.Node, node.ChildrenCapacity), Dirty: true, @@ -1515,5 +1526,9 @@ func intToByteSlice(n int) (slice []byte) { } func mustBeHashed(trieVersion TrieLayout, storageValue []byte) bool { - return trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() + ok := trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() + if ok { + fmt.Printf("must be hashed\n") + } + return ok } diff --git a/scripts/trie_state_script.go b/scripts/trie_state_script.go index 0348134c54..834e6bb697 100644 --- a/scripts/trie_state_script.go +++ b/scripts/trie_state_script.go @@ -79,7 +79,7 @@ func compareStateRoots(response modules.StateTrieResponse, expectedStateRoot com entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) } - newTrie, err := trie.LoadFromMap(entries) + newTrie, err := trie.LoadFromMap(entries, trieVersion) if err != nil { panic(fmt.Sprintf("loading trie from map %v", err)) } diff --git a/tests/sync/sync_test.go b/tests/sync/sync_test.go index b2a786cadd..29a7eb3e31 100644 --- a/tests/sync/sync_test.go +++ b/tests/sync/sync_test.go @@ -5,6 +5,7 @@ package sync import ( + "bytes" "context" "encoding/json" "fmt" @@ -18,6 +19,7 @@ import ( "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/runtime" "github.com/ChainSafe/gossamer/lib/runtime/storage" wazero_runtime "github.com/ChainSafe/gossamer/lib/runtime/wazero" "github.com/ChainSafe/gossamer/lib/trie" @@ -109,7 +111,7 @@ func TestCalls(t *testing.T) { } func TestDebugWestendBlock14576855And14576856(t *testing.T) { - wnd14576854StateTrie := newTrieFromRPC(t, "../../lib/runtime/test_data/14576854trie_state_data.json") + wnd14576854StateTrie := newTrieFromRPC(t, "../../lib/runtime/test_data/14576854trie_state_data.json", trie.V0) expectedStorageRootHash := common.MustHexToHash("0xedd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b") require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) @@ -199,7 +201,31 @@ func TestDebugWestendBlock14576855And14576856(t *testing.T) { require.NoError(t, err) } -func newTrieFromRPC(t *testing.T, filename string) *trie.Trie { +func getRuntimeFromTrieState(t *testing.T, filename string) []byte { + t.Helper() + + data, err := os.ReadFile(filename) + require.NoError(t, err) + + encodedTrieEntries := make([]string, 0) + err = json.Unmarshal(data, &encodedTrieEntries) + require.NoError(t, err) + + for _, encodedEntry := range encodedTrieEntries { + bytesEncodedEntry := common.MustHexToBytes(encodedEntry) + entry := trie.Entry{} + err := scale.Unmarshal(bytesEncodedEntry, &entry) + require.NoError(t, err) + + if bytes.Equal(entry.Key, common.CodeKey) { + return entry.Value + } + } + + return nil +} + +func newTrieFromRPC(t *testing.T, filename string, trieVersion trie.TrieLayout) *trie.Trie { data, err := os.ReadFile(filename) require.NoError(t, err) @@ -217,7 +243,138 @@ func newTrieFromRPC(t *testing.T, filename string) *trie.Trie { entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) } - tr, err := trie.LoadFromMap(entries) + tr, err := trie.LoadFromMap(entries, trieVersion) require.NoError(t, err) return &tr } + +func TestDebugWestendBlock14577546(t *testing.T) { + wnd14576854Runtime := newTrieFromRPC(t, "../../block14577546triestate.json", trie.V0) + require.NotNil(t, wnd14576854Runtime) + + // emptyTrieState := storage.NewTrieState(trie.NewEmptyTrie()) + // emptyTrieState.SetVersion(trie.V1) + + // emptyTrieState.Put(common.CodeKey, wnd14576854Runtime) + // codeHash, err := emptyTrieState.LoadCodeHash() + // require.NoError(t, err) + + // const expectedRuntimeHash = "0x6eb47852c4f8f8b1ec2cb6084564f88c353f5d6d3a5edd1c85dcd744847652cb" + // require.Equal(t, codeHash.String(), expectedRuntimeHash) + + ts := storage.NewTrieState(wnd14576854Runtime) + + cfg := wazero_runtime.Config{ + NodeStorage: runtime.NodeStorage{ + BaseDB: runtime.NewInMemoryDB(t), + }, + Storage: ts, + LogLvl: log.Critical, + } + + instance, err := wazero_runtime.NewInstanceFromTrie(ts.Trie(), cfg) + require.NoError(t, err) + + blockResponseBytes, err := common.HexToBytes("0x0ae0260a2012e044179cd1d2ee191c71f8fc5d17bc68f70bf97c6d1250be951e1ac524d41412c9075a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40ac2ebe79035e6e7e19bae1468b3b77494c8c020f5455ae8b2b27d7d1c3b4084be42c95b2c04443ebec754aa968aa6e7954549fdf93ea3ad35f44db433781681e65f9075a180c0642414245b50103050000003f25a61000000000645dad89d04f57c9c7f55882ac70ea42588380a3e35757b49b04ff11bd3c9d7a3763ede2161cc70c1c41202fe2b6260e6a23a5a487bc731e010e3a8fb1d3d6057da69c5a47443f3a32436a5be6cd1703472787831270b823a3792b9bba3aaf0b0442414245890a01402694e4bf063c232bc5d1c0068e9bfb28bee7ca7c177372ca2cd1134698c03d6901000000000000009a09fe0aa06b45e97820029311e172bddf0c3ce7fd1597b06590499d380e77710100000000000000bc7c0e3f41b9af06798373c40225afbc599f4b8509997fdde8abf9e522064c66010000000000000054204d0e6b1d4492cfb91e9eb9ecf348dbe70b078c47b893194b611dce8100630100000000000000bafafa4a206ccc38ad5afa73a5cde8cba3aa89d6de94ab60c7e59c868280977d01000000000000009e4971f0d6f1d35badecaf7e9032829ff4a2629122250a5d9cb714f4805641490100000000000000fed87bf3437f55b8b813a9bb751045c6c724481eb9535ba5e120b09d843f1820010000000000000016a03c740cd6b746cbfc9ae2d7c630b4ddd14ca6de6e08034163995e6283396001000000000000000468e29aa426b75e51d9f8d98a9b21688a96d093bcdc9ac82b24e508ea6c8b1d010000000000000076a5a1a0b2b4bef5524de64cf7d5d27b48e35825142b393b1ff297b925f5eb3f0100000000000000ba0085a91f9028cf1ee961c1e5c9ac3cef6e9db6944524dcd3baa178271be13b0100000000000000284b21a986abcb1dc8449e75d1039296d15d9170b709d1d8f80e13f965d2826701000000000000000483b0689164171cca2215638b17d2f70346a072dea3e2a5cda2b0a11614914c0100000000000000d6459c910d17bb21d596611bf08f6e690cdd757a33ac0e7c8c820f77de132e5b01000000000000001c480cd50beda967ba7d31cd02e1fa7e341256b57fd20392634e2db5d298c04b0100000000000000d650846b5a3b4e026efc6a87c8e4c4048ffdc46f5895c5307cf1d1a257a5e8260100000000000000f71b9104c477173500092159d69b7ce6da7e88f3fa2902bb5a54c5facec77d0605424142450101bc7cf81cd40358fc343846e388340c4baed507c32aacc0bd66b7717435615c0e56c4124730fc9bcb529299b126e8d6bad0015ff963b3cbd75bd173fa8869d6891a0b280402000b90f4083686011ae21e813d042d00400c0000000000282cd878ee3c4d099656395bef3ca75ab8db3f20acb25b6130ac883b7de7af2f902eccdcaaa509437ce0f850d6368d17e9e38d8889df479c7b5decc5376f008a0c00010000009aa2ce35475fa20b79a27f33791fdf65408af545b4efcca8ad91840c3db74a2b1440bd9364ff443aaffc2f53d58359eeef952152293f97231fdb9257af24dd830c000200000034dbe9a6359045e8e913f56ca301153f0e7d83bf87c0caac18ddbd3257b44a3e63b7348650146671a5e88f9badac0186952bdc94a37b05b259defe710ce826820c00030000008eceac5be204b40818d16b28b2c5a6f7bbdcc65a4fd734caa06d65faf2c7c7749da4d385d23fa02fb6e2c837ce41ee7af9670ab45391c1c9d4c7e2ae5268c28d0c000400000006df086355e3a189af73e6cff2b9a0f7bcb0960ac2990be164ce02762e0fce75e9d66775f774b87a92e485e72b67617b9f7fbb98dd2e12ee296706d562c069800c0005000000aa268e78631163c127d6613c127916257147a4c54d74e7621c6ae70ed5e27251653e699ce45415cbb6c3c4195b44e6054a45543444c180e6b4b2b67202bf81820c000600000030da3834d2db04e52604bba9359846a4eeaa4e304c0fea26586e8c8497db8a0f543f3c0c079ceeea8f12ad730666d3b21453261f1572cbafb08d70ef9462f9880c000700000016de277fabf66ea966f44e3d5c74902e3b20b6c1259448131ed9505cb1e70b3ec26336f6ae94fc8b5e5c272e6720dbcf6d3fe84ab64b6c56dd0b750879190f810c00080000003215988a218fae78a4d2d1387a5f1be47fae812be03edef900cf0c17e93e646db957e434cff70a5fc768693a6672dc28ce58468970013388bb3ecea4ad440a890c000900000010622ef8626a403ba790ebc1b6baf151e5157b96fb8a2a907dbb494a036abc38897ae5f987228ec9fc5f98ed4b04001fb7170946e5c92996d151327025b45e8e0c000a00000082947afd222ec1e6f064e9bcd2211be9f2426e992cc35ba043e4760445bde03fe51ef26feaf1f4a328ea19b99a67e2a14ca257a02ddf4b53a807349e7485118a0c000b000000c0380013c086ac13292350bfe4d845bc73c4656beeb1bc371d09bc907b694a2b0af79c42a7e6e1706f022cf096894e09a316e5c97f14b688c36910adadbcc98f0c000c0000004a57e784fe9266e053b0da84efdffde29c1b28862cc988239aafa1f3f090e069dbe61b6ab898f261036cc45fe1199e4a8176b2615be52735a8180dbba3fee88b0c000d0000002233fc7ca2dbe698a26901b476a437e4e74fa72544b6243eb07d9a6dd6a27f58ce67d57911c9b156cdf0f1192241c98a0c2de4fa7db98d0c2d280b1f5db238810c000e000000dcbcdfca9945c7ae2435c967deb7b22880fcf4f5f7773381aa2440dba4071c305e92a3511b91c41b696f60fc4c8ba77f9eccaf7753b023f383403b7469152a880c000f000000180e459a053ddc2e861d9515d267ba7f657566623ca01ffa9e968adc33f3545e3789ece8a428ee5cc376cc811dfe1f463a4635a12cdd54571791748bfb61058f0ce80300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40acfcac6d0a0541ca368261d0d6eef36f15016366108af4c0c7df5abcf7dd3f2d63e47d8c713e6e0704b31c4af7fe9bbe6cfba766ea3a89cbb2734359ec7094d521436395e4a4436135785e3537d13de36fbaa4967926ccf90f0cab5522c225b795021b8a3b8c1e9b69a3672206c25a9974db19f1aa186ccdf30239dfcbbf35af1a18045f924a02a0a3cefa7bcbfafab4d3cb8c789615c727e87899ac421b1614366e0ecfd619df6e4b4f4aecbc96156cab4ee2fe16b7138fa6e6c72765b87c778190dd1078d333c796d76a68ecb75eeaadd5cd49765b877a65258828e5327040ca07f4c5b9c3a6d001a54d9a96bc1b0e69e9266bfa4bf0f8ba0b6256ca10c23d1e000000e9025c1b988e3c110da6d2c8ed6de7b430a00f0dc2cda610ab8a47d392c80ee64781c2b3ef0045e847ea1bf5355597d5a112c3af5859aea9a6951bec5dca635ca24765459fb9d9eb42eabfb44fddb25dc19520c0ba327a5b883bd7215a6bbfebc3cda34e74af080661757261209f1253080000000005617572610101c4244a3f1bfa9c7add7a890d7054fbd05ba40c266de3a65041024eaf756c0b2bb2b1d2d6a2a662cb7f4a9c219d735a2e48621f1bedcf50ea790722a486585087000000008a6fde001402ea7014b10a51a1d68ec75474d38efcfda095472ca575c4aa5c5f4103714749167b67dac947ff57b27066ba64df2ad5dd8180329c79d6d6a2d2c2db9ad059f48701f2d04beb608dd69ed1850e79b1f45fa212f6e84d69489585842b7128b828dc676ae34d870220233503374c0be18fbcb45eaaa206ed706cc1586c275b09b76a8601e2617495b1877a544f5dfcbfb79d863cb7e6ff3670c7a3d8a805ff5fd8ae0248ff4b940c27408443ac53dc81205a9c78ec712d129247dbbbce0cb048a81e648602dc244ca12936e4d9fe49e6ac21de74018691481a5af618e57d1e1067f6c7775e05e4ce9739cdb2549f7a37a9cbcdfc0978cf002ef6b14dfdc0b54ee6b48d698a01d8f68e65630f3209473d780ff68d1cfdd6379a46525c88a25be662c2fe50f121ccc8d658be2089ddc8a4f5602c7a8ed3df751eebf37637c2576ffa17c7ce548e141fe90300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40acfc9891270d421262a649631f6f0abf2dafdbd88080bade974a352c9be7c55903c67e2361e43357f8f71b2e6bd231c4690ab3226628dc821fd2db56c2355f0aae5880a69c4cefe465bb41098aceaa6b2b92d64762c92a70bb28d3c6c4d1d987bd6914222a13f5e216fc7f68252708c961d12f2ebe25ccef107aa81ef1904c81552401967c4c4403e002be2be5d9cd979193bdacc86beea12ca7d1f5142ed08e0a0de6daf1ef3fc6e88ee6c98f202c1b439cf8a659d7015ae2c87ee5accef8348fd4d2fc780ff36ef444aaee59c5a0afa1b79c18a4696a6f3475876dc7284797f1dcc6cda49b51efbe0fd184b974074d1258ca9f15b9fccfedc35b7dee6e1ab9e9000000e902e00f87682d3d0c208425c144859f621e33f8e001c889b1f1e03988be7093f06206992f00ecd5da9a370f5c514ec210f554bfb2b4fc1b578f91167caa6508e89b51fd62970e10a1124d7b133d14706af98fe1602fda88b547897ee847821533f900fc7713080661757261209f12530800000000056175726101018630144dce66464df6d51dd511e3a2cc8b23a03d2d817d27dbc9a72beda81d187093379c491f50f5fad802ee1ee2ae088f92bb0818b762c1dbe07f17de665880000000008a6fde0018021c58cbb963b4e4897c4fb4b2e0d9222deb069152a439716f71fae9cc1f78d56fce80ced3f584ec9160678d1d50231d69796ee2a400f7e801eb7528a5371de98f0258556fd015c61d55c47b99ebe642854dc6909ceabf7bdc4416f54e3a8f2e5b6f55c8d29baf8c9092eea3515cb4b45f25fb90aa2cb115ee2cfbc46c3894d31b810120ffa6b942052f1ba9c9d9ea3ec6605b4ef761cdc6dbab1dc7f7c1556d1fad1523343837a94c4468df191dbf657075f5dc4ffab509309137cf3151ec6298a98d02eeb0bc2b560b0d8016a885543fabf07e2bbb1c3239f94a42bc2a91d59e684019be4a9929cb9642c8f1540e5bec6c7488fa393132eeae60b200b7a4b5f6c64b8b0120e4cd84d399b0a39a2ec947570d014200928c7f3f552a80be4915b483906f2acb8d642d3c733da1df00834a0e304c72a6a9fd94a06bd7c0d456351e302e4b8d015e56e2c35b417fe427f9656d362c74d6b97750af50e814b9afa3ed5230cffe6f4cfb0e25041ed96043f34f91b7776ee0a2415e58455608260710ec23ae240987183fea0300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40ac2e382b3b34921a40e50343cf2ebe326059fd0f972cb34a060ee159c56acca44836568000e96ed361f8e35f2fc825c729b0a412b5427865249067f3106528a351330b63c2ceccfbe6e8d7658bc8c177827b21d85612adcaac5bc72add07f1b0d5d3885f7e6b46f198c2284120ac5a4867efe4480df0305d1c65e8be4d2864ebdd084e445f9d0c9d389f2e24c630b5c5545851e2f52703b4ca89bc0ff69745461864f5a77afd0ab8f373702a2ee2b4914e67707a9270004527126a3fa11361b189223821c406f958a20700021444299d6ae72fc900428f0b7c0106ce55a9a3e19b4e714e61e9b3100565ae524c326102f8bc17bd3e9e73a185b8116a9e964e665c000000e902924645e09c811193071c23010729e40ea2b03bcaec22108ff91dc04daedcfe9f1ef00b008039066af19c53ec45a5d491be58392fa9ba2575407e1977265070b56e8d45492ca3b04e42f429749aa691199813f5d526ea26346456bfdc940b07429be23a52080661757261209f1253080000000005617572610101389ac297b3b047f0825537e1845479951c25a3a2f1c5037350b98ea25aaaa61489cb053a36ade2933ea9794a5972b2222efb746605fb90f8e27abd8493424c89000000008a6fde001401b0ad4d6ab7c5bdecb1314b76c0c2b0c5e97c6a26a1fca9f2c2c78c86fb85070047cc0405609e9a4455effb72d261f6fa37ee04dbd1b274d68540a2375709988c01f4d0977086efc2b63294f9a5afbaa94085b02964f6f2a8b42257a3ccde0d6b4adaccb0884f5ce827af1d0fba6e96a1ab6ef8fb2dd6b12f582512fa8206ba718a01ea8c4ac88cc5c7a59c181beee80192a512ce7d3a3080ab3ddd164af17faa3f0279930108dce00540ff19658f63725ad2b766d61b645f555955b4870b3763898f0178fc4005624ec6baf421055f45c6aedcee3878fdbdeca8c6c52a7ed672a202059668fa6eb617da2b12ef8445ff624b8110b295a33b4ce1a1d135cdf6735e6f8502d214e61f0ac9af706b545a75bc53bbec0c9a9cf218862c540f667e9b9875a158a882486390be76751fddaf7f8110b3e888328846ec6884fe1591e3658b1d7883141f00da7ab5b7ad416bed4b0774f8e971c54ed4a2d2ff842da496df36fd0e1db70cb52abe79031fef5448ee43a28cb3c48e1890b7eeabdc9bb96dd689e23796a8514add12640ba40bda317e4c6103419a926c93deb156ad8148916ffeaf171e5b3740e36efc1b080642414245b501010e0000003e25a6100000000008db4e182734dcbff213060c659394561644cbd04bc908201b25b43a0108892a858f25b729ab79582898cd06b9e9255ad07489cb44536bfe7eb31104776e410aef9ee077326492d813a40146879691a1dcf19b1ce645f897c2b392ac306d0d07054241424501018a94a290fd5070e1df9b78f5feebce41be592777a001e125e521caa0fb99a70970fdb35df5d6551fe9b970a8423a652b2d98783160c49a63268a6d5d97dd8b8b") + require.NoError(t, err) + + blockResponse := new(network.BlockResponseMessage) + err = blockResponse.Decode(blockResponseBytes) + require.NoError(t, err) + + blockData := blockResponse.BlockData[0] + + block := &types.Block{ + Header: *blockData.Header, + Body: *blockData.Body, + } + + fmt.Printf("Executing block number %d (%s)\n", block.Header.Number, block.Header.Hash().String()) + _, err = instance.ExecuteBlock(block) + require.NoError(t, err) + + // db, err := database.NewPebble(t.TempDir(), true) + // require.NoError(t, err) + + // storageState, err := state.NewStorageState(db, nil, state.NewTries()) + // require.NoError(t, err) + + // trieState := storage.NewTrieState(wnd14576854StateTrie) + // codeHash, err := trieState.LoadCodeHash() + // require.NoError(t, err) + + // fmt.Printf("code hash at start: %s\n", codeHash.String()) + + // cfg := wazero_runtime.Config{ + // Storage: trieState, + // LogLvl: log.Critical, + // } + + // instance, err := wazero_runtime.NewInstanceFromTrie(wnd14576854StateTrie, cfg) + // require.NoError(t, err) + + // blockResponseBytes, err := common.HexToBytes("0x0ae0260a2012e044179cd1d2ee191c71f8fc5d17bc68f70bf97c6d1250be951e1ac524d41412c9075a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40ac2ebe79035e6e7e19bae1468b3b77494c8c020f5455ae8b2b27d7d1c3b4084be42c95b2c04443ebec754aa968aa6e7954549fdf93ea3ad35f44db433781681e65f9075a180c0642414245b50103050000003f25a61000000000645dad89d04f57c9c7f55882ac70ea42588380a3e35757b49b04ff11bd3c9d7a3763ede2161cc70c1c41202fe2b6260e6a23a5a487bc731e010e3a8fb1d3d6057da69c5a47443f3a32436a5be6cd1703472787831270b823a3792b9bba3aaf0b0442414245890a01402694e4bf063c232bc5d1c0068e9bfb28bee7ca7c177372ca2cd1134698c03d6901000000000000009a09fe0aa06b45e97820029311e172bddf0c3ce7fd1597b06590499d380e77710100000000000000bc7c0e3f41b9af06798373c40225afbc599f4b8509997fdde8abf9e522064c66010000000000000054204d0e6b1d4492cfb91e9eb9ecf348dbe70b078c47b893194b611dce8100630100000000000000bafafa4a206ccc38ad5afa73a5cde8cba3aa89d6de94ab60c7e59c868280977d01000000000000009e4971f0d6f1d35badecaf7e9032829ff4a2629122250a5d9cb714f4805641490100000000000000fed87bf3437f55b8b813a9bb751045c6c724481eb9535ba5e120b09d843f1820010000000000000016a03c740cd6b746cbfc9ae2d7c630b4ddd14ca6de6e08034163995e6283396001000000000000000468e29aa426b75e51d9f8d98a9b21688a96d093bcdc9ac82b24e508ea6c8b1d010000000000000076a5a1a0b2b4bef5524de64cf7d5d27b48e35825142b393b1ff297b925f5eb3f0100000000000000ba0085a91f9028cf1ee961c1e5c9ac3cef6e9db6944524dcd3baa178271be13b0100000000000000284b21a986abcb1dc8449e75d1039296d15d9170b709d1d8f80e13f965d2826701000000000000000483b0689164171cca2215638b17d2f70346a072dea3e2a5cda2b0a11614914c0100000000000000d6459c910d17bb21d596611bf08f6e690cdd757a33ac0e7c8c820f77de132e5b01000000000000001c480cd50beda967ba7d31cd02e1fa7e341256b57fd20392634e2db5d298c04b0100000000000000d650846b5a3b4e026efc6a87c8e4c4048ffdc46f5895c5307cf1d1a257a5e8260100000000000000f71b9104c477173500092159d69b7ce6da7e88f3fa2902bb5a54c5facec77d0605424142450101bc7cf81cd40358fc343846e388340c4baed507c32aacc0bd66b7717435615c0e56c4124730fc9bcb529299b126e8d6bad0015ff963b3cbd75bd173fa8869d6891a0b280402000b90f4083686011ae21e813d042d00400c0000000000282cd878ee3c4d099656395bef3ca75ab8db3f20acb25b6130ac883b7de7af2f902eccdcaaa509437ce0f850d6368d17e9e38d8889df479c7b5decc5376f008a0c00010000009aa2ce35475fa20b79a27f33791fdf65408af545b4efcca8ad91840c3db74a2b1440bd9364ff443aaffc2f53d58359eeef952152293f97231fdb9257af24dd830c000200000034dbe9a6359045e8e913f56ca301153f0e7d83bf87c0caac18ddbd3257b44a3e63b7348650146671a5e88f9badac0186952bdc94a37b05b259defe710ce826820c00030000008eceac5be204b40818d16b28b2c5a6f7bbdcc65a4fd734caa06d65faf2c7c7749da4d385d23fa02fb6e2c837ce41ee7af9670ab45391c1c9d4c7e2ae5268c28d0c000400000006df086355e3a189af73e6cff2b9a0f7bcb0960ac2990be164ce02762e0fce75e9d66775f774b87a92e485e72b67617b9f7fbb98dd2e12ee296706d562c069800c0005000000aa268e78631163c127d6613c127916257147a4c54d74e7621c6ae70ed5e27251653e699ce45415cbb6c3c4195b44e6054a45543444c180e6b4b2b67202bf81820c000600000030da3834d2db04e52604bba9359846a4eeaa4e304c0fea26586e8c8497db8a0f543f3c0c079ceeea8f12ad730666d3b21453261f1572cbafb08d70ef9462f9880c000700000016de277fabf66ea966f44e3d5c74902e3b20b6c1259448131ed9505cb1e70b3ec26336f6ae94fc8b5e5c272e6720dbcf6d3fe84ab64b6c56dd0b750879190f810c00080000003215988a218fae78a4d2d1387a5f1be47fae812be03edef900cf0c17e93e646db957e434cff70a5fc768693a6672dc28ce58468970013388bb3ecea4ad440a890c000900000010622ef8626a403ba790ebc1b6baf151e5157b96fb8a2a907dbb494a036abc38897ae5f987228ec9fc5f98ed4b04001fb7170946e5c92996d151327025b45e8e0c000a00000082947afd222ec1e6f064e9bcd2211be9f2426e992cc35ba043e4760445bde03fe51ef26feaf1f4a328ea19b99a67e2a14ca257a02ddf4b53a807349e7485118a0c000b000000c0380013c086ac13292350bfe4d845bc73c4656beeb1bc371d09bc907b694a2b0af79c42a7e6e1706f022cf096894e09a316e5c97f14b688c36910adadbcc98f0c000c0000004a57e784fe9266e053b0da84efdffde29c1b28862cc988239aafa1f3f090e069dbe61b6ab898f261036cc45fe1199e4a8176b2615be52735a8180dbba3fee88b0c000d0000002233fc7ca2dbe698a26901b476a437e4e74fa72544b6243eb07d9a6dd6a27f58ce67d57911c9b156cdf0f1192241c98a0c2de4fa7db98d0c2d280b1f5db238810c000e000000dcbcdfca9945c7ae2435c967deb7b22880fcf4f5f7773381aa2440dba4071c305e92a3511b91c41b696f60fc4c8ba77f9eccaf7753b023f383403b7469152a880c000f000000180e459a053ddc2e861d9515d267ba7f657566623ca01ffa9e968adc33f3545e3789ece8a428ee5cc376cc811dfe1f463a4635a12cdd54571791748bfb61058f0ce80300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40acfcac6d0a0541ca368261d0d6eef36f15016366108af4c0c7df5abcf7dd3f2d63e47d8c713e6e0704b31c4af7fe9bbe6cfba766ea3a89cbb2734359ec7094d521436395e4a4436135785e3537d13de36fbaa4967926ccf90f0cab5522c225b795021b8a3b8c1e9b69a3672206c25a9974db19f1aa186ccdf30239dfcbbf35af1a18045f924a02a0a3cefa7bcbfafab4d3cb8c789615c727e87899ac421b1614366e0ecfd619df6e4b4f4aecbc96156cab4ee2fe16b7138fa6e6c72765b87c778190dd1078d333c796d76a68ecb75eeaadd5cd49765b877a65258828e5327040ca07f4c5b9c3a6d001a54d9a96bc1b0e69e9266bfa4bf0f8ba0b6256ca10c23d1e000000e9025c1b988e3c110da6d2c8ed6de7b430a00f0dc2cda610ab8a47d392c80ee64781c2b3ef0045e847ea1bf5355597d5a112c3af5859aea9a6951bec5dca635ca24765459fb9d9eb42eabfb44fddb25dc19520c0ba327a5b883bd7215a6bbfebc3cda34e74af080661757261209f1253080000000005617572610101c4244a3f1bfa9c7add7a890d7054fbd05ba40c266de3a65041024eaf756c0b2bb2b1d2d6a2a662cb7f4a9c219d735a2e48621f1bedcf50ea790722a486585087000000008a6fde001402ea7014b10a51a1d68ec75474d38efcfda095472ca575c4aa5c5f4103714749167b67dac947ff57b27066ba64df2ad5dd8180329c79d6d6a2d2c2db9ad059f48701f2d04beb608dd69ed1850e79b1f45fa212f6e84d69489585842b7128b828dc676ae34d870220233503374c0be18fbcb45eaaa206ed706cc1586c275b09b76a8601e2617495b1877a544f5dfcbfb79d863cb7e6ff3670c7a3d8a805ff5fd8ae0248ff4b940c27408443ac53dc81205a9c78ec712d129247dbbbce0cb048a81e648602dc244ca12936e4d9fe49e6ac21de74018691481a5af618e57d1e1067f6c7775e05e4ce9739cdb2549f7a37a9cbcdfc0978cf002ef6b14dfdc0b54ee6b48d698a01d8f68e65630f3209473d780ff68d1cfdd6379a46525c88a25be662c2fe50f121ccc8d658be2089ddc8a4f5602c7a8ed3df751eebf37637c2576ffa17c7ce548e141fe90300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40acfc9891270d421262a649631f6f0abf2dafdbd88080bade974a352c9be7c55903c67e2361e43357f8f71b2e6bd231c4690ab3226628dc821fd2db56c2355f0aae5880a69c4cefe465bb41098aceaa6b2b92d64762c92a70bb28d3c6c4d1d987bd6914222a13f5e216fc7f68252708c961d12f2ebe25ccef107aa81ef1904c81552401967c4c4403e002be2be5d9cd979193bdacc86beea12ca7d1f5142ed08e0a0de6daf1ef3fc6e88ee6c98f202c1b439cf8a659d7015ae2c87ee5accef8348fd4d2fc780ff36ef444aaee59c5a0afa1b79c18a4696a6f3475876dc7284797f1dcc6cda49b51efbe0fd184b974074d1258ca9f15b9fccfedc35b7dee6e1ab9e9000000e902e00f87682d3d0c208425c144859f621e33f8e001c889b1f1e03988be7093f06206992f00ecd5da9a370f5c514ec210f554bfb2b4fc1b578f91167caa6508e89b51fd62970e10a1124d7b133d14706af98fe1602fda88b547897ee847821533f900fc7713080661757261209f12530800000000056175726101018630144dce66464df6d51dd511e3a2cc8b23a03d2d817d27dbc9a72beda81d187093379c491f50f5fad802ee1ee2ae088f92bb0818b762c1dbe07f17de665880000000008a6fde0018021c58cbb963b4e4897c4fb4b2e0d9222deb069152a439716f71fae9cc1f78d56fce80ced3f584ec9160678d1d50231d69796ee2a400f7e801eb7528a5371de98f0258556fd015c61d55c47b99ebe642854dc6909ceabf7bdc4416f54e3a8f2e5b6f55c8d29baf8c9092eea3515cb4b45f25fb90aa2cb115ee2cfbc46c3894d31b810120ffa6b942052f1ba9c9d9ea3ec6605b4ef761cdc6dbab1dc7f7c1556d1fad1523343837a94c4468df191dbf657075f5dc4ffab509309137cf3151ec6298a98d02eeb0bc2b560b0d8016a885543fabf07e2bbb1c3239f94a42bc2a91d59e684019be4a9929cb9642c8f1540e5bec6c7488fa393132eeae60b200b7a4b5f6c64b8b0120e4cd84d399b0a39a2ec947570d014200928c7f3f552a80be4915b483906f2acb8d642d3c733da1df00834a0e304c72a6a9fd94a06bd7c0d456351e302e4b8d015e56e2c35b417fe427f9656d362c74d6b97750af50e814b9afa3ed5230cffe6f4cfb0e25041ed96043f34f91b7776ee0a2415e58455608260710ec23ae240987183fea0300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40ac2e382b3b34921a40e50343cf2ebe326059fd0f972cb34a060ee159c56acca44836568000e96ed361f8e35f2fc825c729b0a412b5427865249067f3106528a351330b63c2ceccfbe6e8d7658bc8c177827b21d85612adcaac5bc72add07f1b0d5d3885f7e6b46f198c2284120ac5a4867efe4480df0305d1c65e8be4d2864ebdd084e445f9d0c9d389f2e24c630b5c5545851e2f52703b4ca89bc0ff69745461864f5a77afd0ab8f373702a2ee2b4914e67707a9270004527126a3fa11361b189223821c406f958a20700021444299d6ae72fc900428f0b7c0106ce55a9a3e19b4e714e61e9b3100565ae524c326102f8bc17bd3e9e73a185b8116a9e964e665c000000e902924645e09c811193071c23010729e40ea2b03bcaec22108ff91dc04daedcfe9f1ef00b008039066af19c53ec45a5d491be58392fa9ba2575407e1977265070b56e8d45492ca3b04e42f429749aa691199813f5d526ea26346456bfdc940b07429be23a52080661757261209f1253080000000005617572610101389ac297b3b047f0825537e1845479951c25a3a2f1c5037350b98ea25aaaa61489cb053a36ade2933ea9794a5972b2222efb746605fb90f8e27abd8493424c89000000008a6fde001401b0ad4d6ab7c5bdecb1314b76c0c2b0c5e97c6a26a1fca9f2c2c78c86fb85070047cc0405609e9a4455effb72d261f6fa37ee04dbd1b274d68540a2375709988c01f4d0977086efc2b63294f9a5afbaa94085b02964f6f2a8b42257a3ccde0d6b4adaccb0884f5ce827af1d0fba6e96a1ab6ef8fb2dd6b12f582512fa8206ba718a01ea8c4ac88cc5c7a59c181beee80192a512ce7d3a3080ab3ddd164af17faa3f0279930108dce00540ff19658f63725ad2b766d61b645f555955b4870b3763898f0178fc4005624ec6baf421055f45c6aedcee3878fdbdeca8c6c52a7ed672a202059668fa6eb617da2b12ef8445ff624b8110b295a33b4ce1a1d135cdf6735e6f8502d214e61f0ac9af706b545a75bc53bbec0c9a9cf218862c540f667e9b9875a158a882486390be76751fddaf7f8110b3e888328846ec6884fe1591e3658b1d7883141f00da7ab5b7ad416bed4b0774f8e971c54ed4a2d2ff842da496df36fd0e1db70cb52abe79031fef5448ee43a28cb3c48e1890b7eeabdc9bb96dd689e23796a8514add12640ba40bda317e4c6103419a926c93deb156ad8148916ffeaf171e5b3740e36efc1b080642414245b501010e0000003e25a6100000000008db4e182734dcbff213060c659394561644cbd04bc908201b25b43a0108892a858f25b729ab79582898cd06b9e9255ad07489cb44536bfe7eb31104776e410aef9ee077326492d813a40146879691a1dcf19b1ce645f897c2b392ac306d0d07054241424501018a94a290fd5070e1df9b78f5feebce41be592777a001e125e521caa0fb99a70970fdb35df5d6551fe9b970a8423a652b2d98783160c49a63268a6d5d97dd8b8b") + // require.NoError(t, err) + + // blockResponse := new(network.BlockResponseMessage) + // err = blockResponse.Decode(blockResponseBytes) + // require.NoError(t, err) + + // blockData := blockResponse.BlockData[0] + + // block := &types.Block{ + // Header: *blockData.Header, + // Body: *blockData.Body, + // } + // parentBlockStateRoot := block.Header.StateRoot + + // fmt.Printf("Executing block number %d (%s)\n", block.Header.Number, block.Header.Hash().String()) + // _, err = instance.ExecuteBlock(block) + // require.NoError(t, err) + + // fmt.Printf("Storing the trie to the disk, regards block %d\n", block.Header.Number) + + // //newTrieState := storage.NewTrieState(trieState.Trie().DeepCopy()) + // err = storageState.StoreTrie(trieState, &block.Header) + // require.NoError(t, err) + + // codeHash, err = trieState.LoadCodeHash() + // require.NoError(t, err) + + // fmt.Printf("code hash from updated state: %s\n", codeHash.String()) + + // blockResponseBytes, err = common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") + // require.NoError(t, err) + + // blockResponse = new(network.BlockResponseMessage) + // err = blockResponse.Decode(blockResponseBytes) + // require.NoError(t, err) + + // blockData = blockResponse.BlockData[0] + + // block = &types.Block{ + // Header: *blockData.Header, + // Body: *blockData.Body, + // } + + // ts, err := storageState.TrieState(&parentBlockStateRoot) + // require.NoError(t, err) + + // // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") + // // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") + // // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) + + // // state := storage.NewTrieState(wnd14576855StateTrie) + // instance, err = wazero_runtime.NewInstanceFromTrie(trieState.Trie(), wazero_runtime.Config{ + // Storage: ts, + // LogLvl: log.Critical, + // }) + // require.NoError(t, err) + // // instance.version() + // // instance.SetContextStorage(state) + + // fmt.Printf("Executing block number %d\n", block.Header.Number) + + // _, err = instance.ExecuteBlock(block) + // require.NoError(t, err) +} From fb920d41dbdede880364651bfc1d010450a51fc9 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Thu, 22 Feb 2024 07:57:08 -0400 Subject: [PATCH 22/36] chore: remove useless logs --- lib/runtime/storage/trie.go | 8 -------- lib/trie/trie.go | 15 +-------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/lib/runtime/storage/trie.go b/lib/runtime/storage/trie.go index 064ab39bc4..eeda92d9ea 100644 --- a/lib/runtime/storage/trie.go +++ b/lib/runtime/storage/trie.go @@ -44,7 +44,6 @@ func (t *TrieState) StartTransaction() { t.mtx.Lock() defer t.mtx.Unlock() - fmt.Printf("STARTING TRANSACTION\n") t.transactions.PushBack(t.getCurrentTrie().Snapshot()) } @@ -56,7 +55,6 @@ func (t *TrieState) RollbackTransaction() { if t.transactions.Len() <= 1 { panic("no transactions to rollback") } - fmt.Printf("ROLLBACK TRANSACTION\n") t.transactions.Remove(t.transactions.Back()) } @@ -70,7 +68,6 @@ func (t *TrieState) CommitTransaction() { panic("no transactions to commit") } - fmt.Printf("COMMITING TRANSACTION\n") t.transactions.Back().Prev().Value = t.transactions.Remove(t.transactions.Back()) } @@ -103,7 +100,6 @@ func (t *TrieState) Put(key, value []byte) (err error) { t.mtx.Lock() defer t.mtx.Unlock() - fmt.Printf("inserting value\nkey: 0x%x\nvalue: 0x%x\n", key, value) return t.getCurrentTrie().Put(key, value) } @@ -145,8 +141,6 @@ func (t *TrieState) Delete(key []byte) (err error) { t.mtx.Lock() defer t.mtx.Unlock() - fmt.Printf("deleting key: 0x%x\n", key) - err = t.getCurrentTrie().Delete(key) if err != nil { return fmt.Errorf("deleting from trie: %w", err) @@ -197,7 +191,6 @@ func (t *TrieState) SetChildStorage(keyToChild, key, value []byte) error { t.mtx.Lock() defer t.mtx.Unlock() - fmt.Printf("setting child storage!") return t.getCurrentTrie().PutIntoChild(keyToChild, key, value) } @@ -214,7 +207,6 @@ func (t *TrieState) GetChildStorage(keyToChild, key []byte) ([]byte, error) { t.mtx.RLock() defer t.mtx.RUnlock() - fmt.Printf("getting child storage!") return t.getCurrentTrie().GetFromChild(keyToChild, key) } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index 840a291b6b..a59430e176 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -56,7 +56,6 @@ func (t *Trie) SetVersion(v TrieLayout) { panic("cannot regress trie version") } - fmt.Printf("setting trie version as: %d\n", v) t.version = v } @@ -1279,10 +1278,6 @@ func (t *Trie) deleteLeaf(parent *Node, key []byte, return parent, nil } - if len(parent.StorageValue) > 32 { - fmt.Printf("removing a must be hashed storage value\n") - } - newParent = nil err = t.registerDeletedNodeHash(parent, pendingDeltas) @@ -1297,10 +1292,6 @@ func (t *Trie) deleteBranch(branch *Node, key []byte, pendingDeltas DeltaRecorder) ( newParent *Node, deleted bool, nodesRemoved uint32, err error) { if len(key) == 0 || bytes.Equal(branch.PartialKey, key) { - if len(branch.StorageValue) > 32 { - fmt.Printf("removing a must be hashed storage value\n") - } - copySettings := node.DefaultCopySettings copySettings.CopyStorageValue = false branch, err = t.prepForMutation(branch, copySettings, pendingDeltas) @@ -1526,9 +1517,5 @@ func intToByteSlice(n int) (slice []byte) { } func mustBeHashed(trieVersion TrieLayout, storageValue []byte) bool { - ok := trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() - if ok { - fmt.Printf("must be hashed\n") - } - return ok + return trieVersion == V1 && len(storageValue) > V1.MaxInlineValue() } From f5a39e89f96eabf2d3751de83b67ad797fd5e129 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Thu, 22 Feb 2024 14:10:20 -0400 Subject: [PATCH 23/36] chore: cleanup --- dot/node_integration_test.go | 2 +- .../modules/childstate_integration_test.go | 2 +- dot/rpc/modules/childstate_test.go | 2 +- dot/rpc/modules/state_integration_test.go | 3 +-- dot/rpc/modules/system_integration_test.go | 2 +- dot/state/service_integration_test.go | 2 +- dot/state/storage_test.go | 10 +++---- dot/sync/chain_sync.go | 1 - dot/sync/chain_sync_test.go | 10 +++---- dot/sync/syncer_integration_test.go | 2 +- internal/trie/tracking/deltas.go | 27 ------------------- internal/trie/tracking/interfaces.go | 1 - lib/runtime/wazero/imports.go | 12 +-------- lib/runtime/wazero/instance_test.go | 2 +- lib/trie/interfaces.go | 1 - lib/trie/trie.go | 13 +++++---- lib/trie/trie_test.go | 2 +- tests/rpc/rpc_05-state_test.go | 2 +- 18 files changed, 27 insertions(+), 69 deletions(-) diff --git a/dot/node_integration_test.go b/dot/node_integration_test.go index ce0a2d999c..fdbabde5de 100644 --- a/dot/node_integration_test.go +++ b/dot/node_integration_test.go @@ -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 diff --git a/dot/rpc/modules/childstate_integration_test.go b/dot/rpc/modules/childstate_integration_test.go index 74c7ae53e0..c9e7481051 100644 --- a/dot/rpc/modules/childstate_integration_test.go +++ b/dot/rpc/modules/childstate_integration_test.go @@ -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() diff --git a/dot/rpc/modules/childstate_test.go b/dot/rpc/modules/childstate_test.go index e56b776b3b..b58e5887f8 100644 --- a/dot/rpc/modules/childstate_test.go +++ b/dot/rpc/modules/childstate_test.go @@ -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 diff --git a/dot/rpc/modules/state_integration_test.go b/dot/rpc/modules/state_integration_test.go index a37cb667e1..2e96210b21 100644 --- a/dot/rpc/modules/state_integration_test.go +++ b/dot/rpc/modules/state_integration_test.go @@ -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/lib/trie" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -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) diff --git a/dot/rpc/modules/system_integration_test.go b/dot/rpc/modules/system_integration_test.go index 195624be4c..4b244cccea 100644 --- a/dot/rpc/modules/system_integration_test.go +++ b/dot/rpc/modules/system_integration_test.go @@ -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{}, diff --git a/dot/state/service_integration_test.go b/dot/state/service_integration_test.go index 8001fde090..692439838d 100644 --- a/dot/state/service_integration_test.go +++ b/dot/state/service_integration_test.go @@ -440,7 +440,7 @@ func generateBlockWithRandomTrie(t *testing.T, serv *Service, err = trieState.Put(key, value) require.NoError(t, err) - trieStateRoot, err := trieState.Root(trie.V0.MaxInlineValue()) + trieStateRoot, err := trieState.Root() require.NoError(t, err) if parent == nil { diff --git a/dot/state/storage_test.go b/dot/state/storage_test.go index 3b0039f382..47d649daab 100644 --- a/dot/state/storage_test.go +++ b/dot/state/storage_test.go @@ -35,7 +35,7 @@ func TestStorage_StoreAndLoadTrie(t *testing.T) { ts, err := storage.TrieState(&trie.EmptyHash) require.NoError(t, err) - root, err := ts.Root(trie.NoMaxInlineValueSize) + root, err := ts.Root() require.NoError(t, err) err = storage.StoreTrie(ts, nil) require.NoError(t, err) @@ -59,7 +59,7 @@ func TestStorage_GetStorageByBlockHash(t *testing.T) { value := []byte("testvalue") ts.Put(key, value) - root, err := ts.Root(trie.NoMaxInlineValueSize) + root, err := ts.Root() require.NoError(t, err) err = storage.StoreTrie(ts, nil) require.NoError(t, err) @@ -91,7 +91,7 @@ func TestStorage_TrieState(t *testing.T) { require.NoError(t, err) ts.Put([]byte("noot"), []byte("washere")) - root, err := ts.Root(trie.NoMaxInlineValueSize) + root, err := ts.Root() require.NoError(t, err) err = storage.StoreTrie(ts, nil) require.NoError(t, err) @@ -125,7 +125,7 @@ func TestStorage_LoadFromDB(t *testing.T) { ts.Put(kv.key, kv.value) } - root, err := ts.Root(trie.NoMaxInlineValueSize) + root, err := ts.Root() require.NoError(t, err) // Write trie to disk. @@ -205,7 +205,7 @@ func TestGetStorageChildAndGetStorageFromChild(t *testing.T) { trieState := runtime.NewTrieState(&genTrie) - header := types.NewHeader(blockState.GenesisHash(), trieState.MustRoot(trie.NoMaxInlineValueSize), + header := types.NewHeader(blockState.GenesisHash(), trieState.MustRoot(), common.Hash{}, 1, types.NewDigest()) err = storage.StoreTrie(trieState, header) diff --git a/dot/sync/chain_sync.go b/dot/sync/chain_sync.go index d080b80bb9..eea30c9299 100644 --- a/dot/sync/chain_sync.go +++ b/dot/sync/chain_sync.go @@ -884,7 +884,6 @@ func (cs *chainSync) handleBlock(block *types.Block, announceImportedBlock bool) return err } - fmt.Printf("RUNTIME HASH: %s\n", rt.GetCodeHash().String()) rt.SetContextStorage(ts) _, err = rt.ExecuteBlock(block) diff --git a/dot/sync/chain_sync_test.go b/dot/sync/chain_sync_test.go index 1dbc5c67e1..590d5e0a19 100644 --- a/dot/sync/chain_sync_test.go +++ b/dot/sync/chain_sync_test.go @@ -64,10 +64,10 @@ func Test_chainSync_onBlockAnnounce(t *testing.T) { errTest := errors.New("test error") emptyTrieState := storage.NewTrieState(trie.NewEmptyTrie()) - block1AnnounceHeader := types.NewHeader(common.Hash{}, emptyTrieState.MustRoot(trie.NoMaxInlineValueSize), + block1AnnounceHeader := types.NewHeader(common.Hash{}, emptyTrieState.MustRoot(), common.Hash{}, 1, nil) block2AnnounceHeader := types.NewHeader(block1AnnounceHeader.Hash(), - emptyTrieState.MustRoot(trie.NoMaxInlineValueSize), + emptyTrieState.MustRoot(), common.Hash{}, 2, nil) testCases := map[string]struct { @@ -249,10 +249,10 @@ func Test_chainSync_onBlockAnnounceHandshake_tipModeNeedToCatchup(t *testing.T) const somePeer = peer.ID("abc") emptyTrieState := storage.NewTrieState(trie.NewEmptyTrie()) - block1AnnounceHeader := types.NewHeader(common.Hash{}, emptyTrieState.MustRoot(trie.NoMaxInlineValueSize), + block1AnnounceHeader := types.NewHeader(common.Hash{}, emptyTrieState.MustRoot(), common.Hash{}, 1, nil) block2AnnounceHeader := types.NewHeader(block1AnnounceHeader.Hash(), - emptyTrieState.MustRoot(trie.NoMaxInlineValueSize), + emptyTrieState.MustRoot(), common.Hash{}, 130, nil) blockStateMock := NewMockBlockState(ctrl) @@ -1286,7 +1286,7 @@ func createSuccesfullBlockResponse(t *testing.T, parentHeader common.Hash, response.BlockData = make([]*types.BlockData, numBlocks) emptyTrieState := storage.NewTrieState(trie.NewEmptyTrie()) - tsRoot := emptyTrieState.MustRoot(trie.NoMaxInlineValueSize) + tsRoot := emptyTrieState.MustRoot() firstHeader := types.NewHeader(parentHeader, tsRoot, common.Hash{}, uint(startingAt), nil) diff --git a/dot/sync/syncer_integration_test.go b/dot/sync/syncer_integration_test.go index fa1d213d5e..c10e2e3ef2 100644 --- a/dot/sync/syncer_integration_test.go +++ b/dot/sync/syncer_integration_test.go @@ -99,7 +99,7 @@ func newTestSyncer(t *testing.T) *Service { stateSrvc.Block.StoreRuntime(block.Header.Hash(), instance) logger.Debugf("imported block %s and stored state trie with root %s", - block.Header.Hash(), ts.MustRoot(trie.NoMaxInlineValueSize)) + block.Header.Hash(), ts.MustRoot()) return nil }).AnyTimes() cfg.BlockImportHandler = blockImportHandler diff --git a/internal/trie/tracking/deltas.go b/internal/trie/tracking/deltas.go index 72dbffc8a6..84ae859e9e 100644 --- a/internal/trie/tracking/deltas.go +++ b/internal/trie/tracking/deltas.go @@ -14,14 +14,12 @@ type DeltaEntry struct { // Deltas tracks the trie deltas, for example deleted node hashes. type Deltas struct { deletedNodeHashes map[common.Hash]struct{} - updatedNodes []DeltaEntry } // New returns a new Deltas struct. func New() *Deltas { return &Deltas{ deletedNodeHashes: make(map[common.Hash]struct{}), - updatedNodes: make([]DeltaEntry, 0), } } @@ -30,16 +28,6 @@ func (d *Deltas) RecordDeleted(nodeHash common.Hash) { d.deletedNodeHashes[nodeHash] = struct{}{} } -func (d *Deltas) RecordUpdated(key, value []byte) { - entryKey := make([]byte, len(key)) - copy(entryKey[:], key[:]) - - entryValue := make([]byte, len(value)) - copy(entryValue[:], value[:]) - - d.updatedNodes = append(d.updatedNodes, DeltaEntry{Key: entryKey, Value: entryValue}) -} - // Deleted returns a set (map) of all the recorded deleted // node hashes. Note the map returned is not deep copied for // performance reasons and so it's not safe for mutation. @@ -47,20 +35,12 @@ func (d *Deltas) Deleted() (nodeHashes map[common.Hash]struct{}) { return d.deletedNodeHashes } -func (d *Deltas) Updated() (entries []DeltaEntry) { - return d.updatedNodes -} - // MergeWith merges the deltas given as argument in the receiving // deltas struct. func (d *Deltas) MergeWith(deltas Getter) { for nodeHash := range deltas.Deleted() { d.RecordDeleted(nodeHash) } - - for _, entry := range deltas.Updated() { - d.RecordUpdated(entry.Key, entry.Value) - } } // DeepCopy returns a deep copy of the deltas. @@ -78,12 +58,5 @@ func (d *Deltas) DeepCopy() (deepCopy *Deltas) { } } - if d.updatedNodes != nil { - deepCopy.updatedNodes = make([]DeltaEntry, 0, len(d.updatedNodes)) - for _, entry := range d.updatedNodes { - deepCopy.RecordUpdated(entry.Key, entry.Value) - } - } - return deepCopy } diff --git a/internal/trie/tracking/interfaces.go b/internal/trie/tracking/interfaces.go index 57e02bcb3a..ce303e5816 100644 --- a/internal/trie/tracking/interfaces.go +++ b/internal/trie/tracking/interfaces.go @@ -8,5 +8,4 @@ import "github.com/ChainSafe/gossamer/lib/common" // Getter gets deleted node hashes. type Getter interface { Deleted() (nodeHashes map[common.Hash]struct{}) - Updated() (entries []DeltaEntry) } diff --git a/lib/runtime/wazero/imports.go b/lib/runtime/wazero/imports.go index 9328fb1cae..12abfda890 100644 --- a/lib/runtime/wazero/imports.go +++ b/lib/runtime/wazero/imports.go @@ -830,7 +830,6 @@ func ext_trie_blake2_256_ordered_root_version_1(ctx context.Context, m api.Modul func ext_trie_blake2_256_ordered_root_version_2( ctx context.Context, m api.Module, dataSpan uint64, version uint32) uint32 { - fmt.Println("executing: ext_trie_blake2_256_ordered_root_version_2") rtCtx := ctx.Value(runtimeContextKey).(*runtime.Context) if rtCtx == nil { panic("nil runtime context") @@ -2301,28 +2300,19 @@ func ext_storage_root_version_1(ctx context.Context, m api.Module) uint64 { return rootSpan } -func ext_storage_root_version_2(ctx context.Context, m api.Module, version uint32) uint64 { //skipcq: RVV-B0012 - fmt.Println("executing: ext_storage_root_version_2") +func ext_storage_root_version_2(ctx context.Context, m api.Module, _ uint32) uint64 { //skipcq: RVV-B0012 rtCtx := ctx.Value(runtimeContextKey).(*runtime.Context) if rtCtx == nil { panic("nil runtime context") } storage := rtCtx.Storage - // stateVersion, err := trie.ParseVersion(version) - // if err != nil { - // logger.Errorf("failed parsing state version: %s", err) - // return mustWrite(m, rtCtx.Allocator, emptyByteVectorEncoded) - // } - root, err := storage.Root() if err != nil { logger.Errorf("failed to get storage root: %s", err) panic(err) } - fmt.Printf("root hash is: %s\n", root) - rootSpan, err := write(m, rtCtx.Allocator, root[:]) if err != nil { logger.Errorf("failed to allocate: %s", err) diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index ddf50db845..35a975c4db 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -1094,7 +1094,7 @@ func newTrieFromPairs(t *testing.T, filename string) *trie.Trie { entries[pairArr[0].(string)] = pairArr[1].(string) } - tr, err := trie.LoadFromMap(entries) + tr, err := trie.LoadFromMap(entries, trie.V0) require.NoError(t, err) return &tr } diff --git a/lib/trie/interfaces.go b/lib/trie/interfaces.go index 6a7fa294dd..d0a32a25ba 100644 --- a/lib/trie/interfaces.go +++ b/lib/trie/interfaces.go @@ -26,5 +26,4 @@ type DeltaMerger interface { // DeltaRecorder records deltas done in a ongoing trie operation. type DeltaRecorder interface { RecordDeleted(nodeHash common.Hash) - RecordUpdated(key, value []byte) } diff --git a/lib/trie/trie.go b/lib/trie/trie.go index a59430e176..efdbcbfd75 100644 --- a/lib/trie/trie.go +++ b/lib/trie/trie.go @@ -365,7 +365,6 @@ func (t *Trie) Put(keyLE, value []byte) (err error) { t.handleTrackedDeltas(success, pendingDeltas) }() - //pendingDeltas.RecordUpdated(keyLE, value) err = t.insertKeyLE(keyLE, value, pendingDeltas) if err != nil { return err @@ -434,10 +433,10 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte, if bytes.Equal(parentLeaf.PartialKey, key) { nodesCreated = 0 - ok := mustBeHashed(t.version, value) - if parentLeaf.MustBeHashed != ok { + needsToBeHashed := mustBeHashed(t.version, value) + if parentLeaf.MustBeHashed != needsToBeHashed { mutated = true - parentLeaf.MustBeHashed = ok + parentLeaf.MustBeHashed = needsToBeHashed parentLeaf.SetDirty() } @@ -535,10 +534,10 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte, copySettings := node.DefaultCopySettings if bytes.Equal(key, parentBranch.PartialKey) { - ok := mustBeHashed(t.version, value) - if parentBranch.MustBeHashed != ok { + needsToBeHashed := mustBeHashed(t.version, value) + if parentBranch.MustBeHashed != needsToBeHashed { mutated = true - parentBranch.MustBeHashed = ok + parentBranch.MustBeHashed = needsToBeHashed parentBranch.SetDirty() } diff --git a/lib/trie/trie_test.go b/lib/trie/trie_test.go index 4602b2e589..bd6e9b021f 100644 --- a/lib/trie/trie_test.go +++ b/lib/trie/trie_test.go @@ -1767,7 +1767,7 @@ func Test_LoadFromMap(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - trie, err := LoadFromMap(testCase.data) + trie, err := LoadFromMap(testCase.data, V0) assert.ErrorIs(t, err, testCase.errWrapped) if testCase.errWrapped != nil { diff --git a/tests/rpc/rpc_05-state_test.go b/tests/rpc/rpc_05-state_test.go index c3d738e3d0..bfe3c682a3 100644 --- a/tests/rpc/rpc_05-state_test.go +++ b/tests/rpc/rpc_05-state_test.go @@ -53,7 +53,7 @@ func TestStateRPCResponseValidation(t *testing.T) { //nolint:tparallel entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) } - newTrie, err := trie.LoadFromMap(entries) + newTrie, err := trie.LoadFromMap(entries, trie.V0) require.NoError(t, err) trieHash := newTrie.MustHash() From 4379b04236043805c6c31803de83c4cf3fd41d13 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 26 Feb 2024 10:47:29 -0400 Subject: [PATCH 24/36] chore: remove unneeded print --- lib/runtime/wazero/instance.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index 9e3a7aeeec..d4dd187d60 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -521,8 +521,6 @@ func (in *Instance) version() error { //skipcq: RVV-B0001 return fmt.Errorf("decoding version: %w", err) } - fmt.Println("state version", version.StateVersion) - in.Context.Version = &version return nil } From c3b070b733a4f5c822da2cab0ac947b3788054ad Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 26 Feb 2024 11:02:50 -0400 Subject: [PATCH 25/36] chore: cleaning up tests --- .gitignore | 2 - dot/core/service.go | 2 +- lib/runtime/wazero/instance.go | 2 +- pkg/trie/proof/helpers_test.go | 1 - pkg/trie/tracking/deltas.go | 4 - pkg/trie/trie.go | 1 - tests/sync/sync_test.go | 284 --------------------------------- 7 files changed, 2 insertions(+), 294 deletions(-) diff --git a/.gitignore b/.gitignore index c685c55c63..d5d719704f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,5 +26,3 @@ tmp # node_modules used by polkadot.js/api tests tests/polkadotjs_test/node_modules !tests/polkadotjs_test/test/*.wasm - -*.json diff --git a/dot/core/service.go b/dot/core/service.go index dc7ab1bdf6..3fbf53f1e4 100644 --- a/dot/core/service.go +++ b/dot/core/service.go @@ -246,7 +246,7 @@ func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) er return fmt.Errorf("applying forced changes: %w", err) } - logger.Infof("imported block %s and stored state trie with root %s", + logger.Debugf("imported block %s and stored state trie with root %s", block.Header.Hash(), state.MustRoot()) parentRuntimeInstance, err := s.blockState.GetRuntime(block.Header.ParentHash) diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index 4c2cf6833f..5a6da2511f 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -866,7 +866,7 @@ func (in *Instance) SetContextStorage(s runtime.Storage) { defer in.Unlock() if in.Context.Version == nil { - panic("expected runtime version") + panic("expected runtime version got nil") } runtimeStateVersion, err := trie.ParseVersion(in.Context.Version.StateVersion) diff --git a/pkg/trie/proof/helpers_test.go b/pkg/trie/proof/helpers_test.go index 38b8800ce0..959825cf3f 100644 --- a/pkg/trie/proof/helpers_test.go +++ b/pkg/trie/proof/helpers_test.go @@ -10,7 +10,6 @@ import ( "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/pkg/scale" - "github.com/ChainSafe/gossamer/pkg/trie" "github.com/ChainSafe/gossamer/pkg/trie/node" "github.com/stretchr/testify/require" ) diff --git a/pkg/trie/tracking/deltas.go b/pkg/trie/tracking/deltas.go index 84ae859e9e..7d3566e631 100644 --- a/pkg/trie/tracking/deltas.go +++ b/pkg/trie/tracking/deltas.go @@ -7,10 +7,6 @@ import ( "github.com/ChainSafe/gossamer/lib/common" ) -type DeltaEntry struct { - Key, Value []byte -} - // Deltas tracks the trie deltas, for example deleted node hashes. type Deltas struct { deletedNodeHashes map[common.Hash]struct{} diff --git a/pkg/trie/trie.go b/pkg/trie/trie.go index 43aac23e19..9537453a17 100644 --- a/pkg/trie/trie.go +++ b/pkg/trie/trie.go @@ -225,7 +225,6 @@ func (t *Trie) Hash() (rootHash common.Hash, err error) { return rootHash, err } copy(rootHash[:], merkleValue) - t.deltas = tracking.New() return rootHash, nil } diff --git a/tests/sync/sync_test.go b/tests/sync/sync_test.go index 29a7eb3e31..631349fef4 100644 --- a/tests/sync/sync_test.go +++ b/tests/sync/sync_test.go @@ -5,25 +5,10 @@ package sync import ( - "bytes" "context" - "encoding/json" - "fmt" - "os" "testing" "time" - "github.com/ChainSafe/gossamer/dot/network" - "github.com/ChainSafe/gossamer/dot/state" - "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/internal/database" - "github.com/ChainSafe/gossamer/internal/log" - "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/lib/runtime" - "github.com/ChainSafe/gossamer/lib/runtime/storage" - wazero_runtime "github.com/ChainSafe/gossamer/lib/runtime/wazero" - "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/pkg/scale" "github.com/ChainSafe/gossamer/tests/utils" "github.com/ChainSafe/gossamer/tests/utils/config" "github.com/stretchr/testify/require" @@ -109,272 +94,3 @@ func TestCalls(t *testing.T) { require.True(t, res) } } - -func TestDebugWestendBlock14576855And14576856(t *testing.T) { - wnd14576854StateTrie := newTrieFromRPC(t, "../../lib/runtime/test_data/14576854trie_state_data.json", trie.V0) - expectedStorageRootHash := common.MustHexToHash("0xedd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b") - require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576854StateTrie)) - - db, err := database.NewPebble(t.TempDir(), true) - require.NoError(t, err) - - storageState, err := state.NewStorageState(db, nil, state.NewTries()) - require.NoError(t, err) - - trieState := storage.NewTrieState(wnd14576854StateTrie) - codeHash, err := trieState.LoadCodeHash() - require.NoError(t, err) - - fmt.Printf("code hash at start: %s\n", codeHash.String()) - - cfg := wazero_runtime.Config{ - Storage: trieState, - LogLvl: log.Critical, - } - - instance, err := wazero_runtime.NewInstanceFromTrie(wnd14576854StateTrie, cfg) - require.NoError(t, err) - - blockResponseBytes, err := common.HexToBytes("0x0a91140a200283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4012a10240a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e1a0b280402000b6182c93586011abb11e522042d00400c0100000000b6a695e095d905fda4aa41746c0a0752cc3559eb00687d9a13c2a01745290573f6fa11cf3569c116e125d57ec15723653e8f4cda3ec481df1e0d2938f9c3f6880c0101000000740d6868002741aad034c5ffb5dcf31db78f2bb2eb1349bb02dc17d445e9f837914ec9394d52b6d6a3301fc7597de47bc2e48f6f3965999b4ea48fa5667aa4890c01020000002a0962f0b38163dfc2ed4f18727d530d49c05b4e8dbbd1b2c3af310956651277ed247263db04acedb2076ec99b516dff7598ba1f2d328006d4eb04e4c7e7028a0c0103000000f4a8ad3422500b05b5e91f1bae5db4aaa0d576f201ef8f39104764be34b9f229e3e123aec9f98fc9a64b3c4323428bbee3fb358474e2142f273fc3218cc9248c0c0104000000a6a5ee07dafbff4e52ae279f3149d35023751e61a4174c95e3a1afd56ca3365b939b7437f87bda45bfc052a0b0a71cd731296ed6d9edbc127a8e16cdeb52ff800c0105000000b0901765a119c80051f5000b3418b88f328a425b0fbd67aaa0f48acf6347903747cd681c8c4abd4fcb04f0748de2402a3da9ba59f6da9154e07b17e0c1154f890c01060000004cf0b4ec852a062a2cc599ac764a5bd6d6afb469326cfbf736ef0399d987de06ddf842c42f03c479d683aa7c511eb5ccc8f038192ff1fb8a1e1f234446efcb8c0c01070000004aad3d5f2f24ff187a06db9b87a2affa8ac0e219b02512dfd81549bccf62b8111e9961befb215d7e05d7f9ae14f2726098dd95f971e01daac6e720fde387f08c0c01080000004263728475b9e1e48f313e9e4d10cd9a1938d3bd3a80d48ed1418657d303643fac70ba80a6cdad37746e119eb280b668455d297e3b9113edc80ac6762536d18d0c01090000002a9aef1f1b91400ba0d52126b535393ffbfa60c531265efe2bf3dee09aa6f5453a14f3d94bc7f34f3b3d931d46f4726bc87e117a7baa93dd9bb1ac8a9d41da8e0c010a0000000606a0fbaf5f6ba57bc8276aa3e4ad587a1103563d8ea806ded26c8c751fa51dc3e69b4c1f016446cc711be1172a687ee2a5c52f2cb25b9255bf95c4b0fb57810c010b00000054ef1c2e69dd06552fef2b085c4afe5ea1bede23cb912aefb3eff3a3be820f3f1852e54001c15ba05d8b038e2b72207d94c94f8550b0f02fd8c7ee44bcf4df840c010c000000a6b9492a5bc58a4ca6f975c1c50f0c8f09f6b4e842a04a767867c11cc4910f1528efe6a26579981a7d82bda20cdc346fa805703d0aff9988a61ae63443a5008a0c010d000000ca13f5d6336bf7b54351c831d51c3d3aa37c9c1b806ed5715bb72c6a3206d25c893772dac586a3b3e3a616c637947d86119aa54ee4599c4dad23d4ff2f4e7b860c010e0000000e756428f4382e4e540c46a0ea60fdb094129e0d0be80fb7494498d7e714d832c57b158de81ca0f0df736f89035e7eb7449b609adf5c80ef751fb205acac0a800c010f000000820323f879134b5ca5bdcfa4f45a6089c1f5f198633ca8f841349e0e32a6032d20612506730aa5cf0141d56e156234540548164cf1cb6837d767a14d9d5dc18b04ea03000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e3468b0e01113f2c78d4b7b20efd4bdc38627c60bb4b840c8e7476e891b505d828eb016dba1703a583c3e64688bdf97e2bc29a8b6cb499a432d237a323b1412e90e2f769655c4651e3d298ecdc2a536cb89a3a3f31a0f6441a3ae4aa51c4741d32d1cd99206627a51c448c1dbf1f50009655c98b0c1326ae38420d9515cbbcf93ec8084285c48449903c919b164453fde3c5412badebcee765a01aa1b7a8fd503519283259d37c98ecab006af925b013b57a27fe56800cda5f5feec980cb110f87030f7913bfad164bd2dcff5556e48cf06bc28bb3f1ead5200be27d95adbcac624e714e61e9b3100565ae524c326102f8bc17bd3e9e73a185b8116a9e964e665c000000e902d1eb45830486f22485d977ff49349529742a039db30cb9da5fda419c6302bfa8b6ea0b005ff08f7e128ee3e8d263926c4f682842d2eb319b09f251540a815836db74761490734e7a9fd6e677f451d30e6fe142c52655c15db683a4931659c75ac85fbf6c080661757261204411530800000000056175726101015e53dd83b63d9a65ee2906fcbeb0719f9a7a7281513441e211f448efcdfd472a80fe4cb669fa22b8499961bea7643c3586fd16d26e220cb7e5a9da8a1d07ce8b00000000d66cde001401b0b5c1ee601faedc6101d132c793fcdae39737468c9c3dcc3c57fb5b4e2f14648b002685a67f4aeca1fef16795c2c2c352b5afd91a8fe346b7f278f2fce67b8602d23eb4ca1a20f459e1557a1ccc8976dcc686873f3499262e8cd38d0e6294a4340c1fa00bc26ec9a18df5b1b14d4b90bd3c75c5d35b6dff8eeca23976de2f288301d4fa4f3d94cb63c38ea719e64ae09cd7d6eb409d8d1bc21f1a00377fb30e4118e89dd2b4fba1a538819f4dc57e5cf76e80d953ef4c04ad81918b4d68b050db8f021aba632739c7993e789b4ae276b6c933e82a644d5442443224e9fb12d499e12a41a8b4deeb4ebe503842cf8cb680e84e0e4e6898bf62a3cf722262f654cec086029c38b051968569013dc5c2fbc93db0c4bb86a3f548dc5ddff363f32fbe7704682a5dabb9e9689ba820a5f68ac31a92613e0f760d4862c41f5d97edb22e378d8a141f007d63733ead4d8c05045abe1f10fca05ca02aa44c5aafb59135a841c09afeb3965ab37903edd08c8c9453f56727a1b307d7458eb192b42830b03ef1314be104b4a6aefd9b5f6028c17d04a84ec8811461e52a44e489e67b01bfd421b1e25e002200ab433e080642414245b501030d0000008922a610000000002e1e6cadbc719c66a3a4193c2b577cce37eec5e041213ba010823a9b988da947f942254709d3786c37eebb54253f639584dd149883df229258a3ae02ee81860b5945c6ba5fb7990a0fb7ec0ff19c9d5ea8b7d613cfe7de3a8bcb4bdb8f6fed0f05424142450101266ba8cf6a2b5b86a3a1bda16be242d75b042a8dea21e57e0c265cdbc942612c9531ff2178a02871336d6e326d2a71bbb749c3dbc7e3a82ea1c2c0690a73ca8a") - require.NoError(t, err) - - blockResponse := new(network.BlockResponseMessage) - err = blockResponse.Decode(blockResponseBytes) - require.NoError(t, err) - - blockData := blockResponse.BlockData[0] - - block := &types.Block{ - Header: *blockData.Header, - Body: *blockData.Body, - } - parentBlockStateRoot := block.Header.StateRoot - - fmt.Printf("Executing block number %d (%s)\n", block.Header.Number, block.Header.Hash().String()) - _, err = instance.ExecuteBlock(block) - require.NoError(t, err) - - fmt.Printf("Storing the trie to the disk, regards block %d\n", block.Header.Number) - - //newTrieState := storage.NewTrieState(trieState.Trie().DeepCopy()) - err = storageState.StoreTrie(trieState, &block.Header) - require.NoError(t, err) - - codeHash, err = trieState.LoadCodeHash() - require.NoError(t, err) - - fmt.Printf("code hash from updated state: %s\n", codeHash.String()) - - blockResponseBytes, err = common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") - require.NoError(t, err) - - blockResponse = new(network.BlockResponseMessage) - err = blockResponse.Decode(blockResponseBytes) - require.NoError(t, err) - - blockData = blockResponse.BlockData[0] - - block = &types.Block{ - Header: *blockData.Header, - Body: *blockData.Body, - } - - ts, err := storageState.TrieState(&parentBlockStateRoot) - require.NoError(t, err) - - // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") - // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") - // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) - - // state := storage.NewTrieState(wnd14576855StateTrie) - instance, err = wazero_runtime.NewInstanceFromTrie(trieState.Trie(), wazero_runtime.Config{ - Storage: ts, - LogLvl: log.Critical, - }) - require.NoError(t, err) - // instance.version() - // instance.SetContextStorage(state) - - fmt.Printf("Executing block number %d\n", block.Header.Number) - - _, err = instance.ExecuteBlock(block) - require.NoError(t, err) -} - -func getRuntimeFromTrieState(t *testing.T, filename string) []byte { - t.Helper() - - data, err := os.ReadFile(filename) - require.NoError(t, err) - - encodedTrieEntries := make([]string, 0) - err = json.Unmarshal(data, &encodedTrieEntries) - require.NoError(t, err) - - for _, encodedEntry := range encodedTrieEntries { - bytesEncodedEntry := common.MustHexToBytes(encodedEntry) - entry := trie.Entry{} - err := scale.Unmarshal(bytesEncodedEntry, &entry) - require.NoError(t, err) - - if bytes.Equal(entry.Key, common.CodeKey) { - return entry.Value - } - } - - return nil -} - -func newTrieFromRPC(t *testing.T, filename string, trieVersion trie.TrieLayout) *trie.Trie { - data, err := os.ReadFile(filename) - require.NoError(t, err) - - encodedTrieEntries := make([]string, 0) - err = json.Unmarshal(data, &encodedTrieEntries) - require.NoError(t, err) - - entries := make(map[string]string, len(encodedTrieEntries)) - for _, encodedEntry := range encodedTrieEntries { - bytesEncodedEntry := common.MustHexToBytes(encodedEntry) - entry := trie.Entry{} - err := scale.Unmarshal(bytesEncodedEntry, &entry) - require.NoError(t, err) - - entries[common.BytesToHex(entry.Key)] = common.BytesToHex(entry.Value) - } - - tr, err := trie.LoadFromMap(entries, trieVersion) - require.NoError(t, err) - return &tr -} - -func TestDebugWestendBlock14577546(t *testing.T) { - wnd14576854Runtime := newTrieFromRPC(t, "../../block14577546triestate.json", trie.V0) - require.NotNil(t, wnd14576854Runtime) - - // emptyTrieState := storage.NewTrieState(trie.NewEmptyTrie()) - // emptyTrieState.SetVersion(trie.V1) - - // emptyTrieState.Put(common.CodeKey, wnd14576854Runtime) - // codeHash, err := emptyTrieState.LoadCodeHash() - // require.NoError(t, err) - - // const expectedRuntimeHash = "0x6eb47852c4f8f8b1ec2cb6084564f88c353f5d6d3a5edd1c85dcd744847652cb" - // require.Equal(t, codeHash.String(), expectedRuntimeHash) - - ts := storage.NewTrieState(wnd14576854Runtime) - - cfg := wazero_runtime.Config{ - NodeStorage: runtime.NodeStorage{ - BaseDB: runtime.NewInMemoryDB(t), - }, - Storage: ts, - LogLvl: log.Critical, - } - - instance, err := wazero_runtime.NewInstanceFromTrie(ts.Trie(), cfg) - require.NoError(t, err) - - blockResponseBytes, err := common.HexToBytes("0x0ae0260a2012e044179cd1d2ee191c71f8fc5d17bc68f70bf97c6d1250be951e1ac524d41412c9075a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40ac2ebe79035e6e7e19bae1468b3b77494c8c020f5455ae8b2b27d7d1c3b4084be42c95b2c04443ebec754aa968aa6e7954549fdf93ea3ad35f44db433781681e65f9075a180c0642414245b50103050000003f25a61000000000645dad89d04f57c9c7f55882ac70ea42588380a3e35757b49b04ff11bd3c9d7a3763ede2161cc70c1c41202fe2b6260e6a23a5a487bc731e010e3a8fb1d3d6057da69c5a47443f3a32436a5be6cd1703472787831270b823a3792b9bba3aaf0b0442414245890a01402694e4bf063c232bc5d1c0068e9bfb28bee7ca7c177372ca2cd1134698c03d6901000000000000009a09fe0aa06b45e97820029311e172bddf0c3ce7fd1597b06590499d380e77710100000000000000bc7c0e3f41b9af06798373c40225afbc599f4b8509997fdde8abf9e522064c66010000000000000054204d0e6b1d4492cfb91e9eb9ecf348dbe70b078c47b893194b611dce8100630100000000000000bafafa4a206ccc38ad5afa73a5cde8cba3aa89d6de94ab60c7e59c868280977d01000000000000009e4971f0d6f1d35badecaf7e9032829ff4a2629122250a5d9cb714f4805641490100000000000000fed87bf3437f55b8b813a9bb751045c6c724481eb9535ba5e120b09d843f1820010000000000000016a03c740cd6b746cbfc9ae2d7c630b4ddd14ca6de6e08034163995e6283396001000000000000000468e29aa426b75e51d9f8d98a9b21688a96d093bcdc9ac82b24e508ea6c8b1d010000000000000076a5a1a0b2b4bef5524de64cf7d5d27b48e35825142b393b1ff297b925f5eb3f0100000000000000ba0085a91f9028cf1ee961c1e5c9ac3cef6e9db6944524dcd3baa178271be13b0100000000000000284b21a986abcb1dc8449e75d1039296d15d9170b709d1d8f80e13f965d2826701000000000000000483b0689164171cca2215638b17d2f70346a072dea3e2a5cda2b0a11614914c0100000000000000d6459c910d17bb21d596611bf08f6e690cdd757a33ac0e7c8c820f77de132e5b01000000000000001c480cd50beda967ba7d31cd02e1fa7e341256b57fd20392634e2db5d298c04b0100000000000000d650846b5a3b4e026efc6a87c8e4c4048ffdc46f5895c5307cf1d1a257a5e8260100000000000000f71b9104c477173500092159d69b7ce6da7e88f3fa2902bb5a54c5facec77d0605424142450101bc7cf81cd40358fc343846e388340c4baed507c32aacc0bd66b7717435615c0e56c4124730fc9bcb529299b126e8d6bad0015ff963b3cbd75bd173fa8869d6891a0b280402000b90f4083686011ae21e813d042d00400c0000000000282cd878ee3c4d099656395bef3ca75ab8db3f20acb25b6130ac883b7de7af2f902eccdcaaa509437ce0f850d6368d17e9e38d8889df479c7b5decc5376f008a0c00010000009aa2ce35475fa20b79a27f33791fdf65408af545b4efcca8ad91840c3db74a2b1440bd9364ff443aaffc2f53d58359eeef952152293f97231fdb9257af24dd830c000200000034dbe9a6359045e8e913f56ca301153f0e7d83bf87c0caac18ddbd3257b44a3e63b7348650146671a5e88f9badac0186952bdc94a37b05b259defe710ce826820c00030000008eceac5be204b40818d16b28b2c5a6f7bbdcc65a4fd734caa06d65faf2c7c7749da4d385d23fa02fb6e2c837ce41ee7af9670ab45391c1c9d4c7e2ae5268c28d0c000400000006df086355e3a189af73e6cff2b9a0f7bcb0960ac2990be164ce02762e0fce75e9d66775f774b87a92e485e72b67617b9f7fbb98dd2e12ee296706d562c069800c0005000000aa268e78631163c127d6613c127916257147a4c54d74e7621c6ae70ed5e27251653e699ce45415cbb6c3c4195b44e6054a45543444c180e6b4b2b67202bf81820c000600000030da3834d2db04e52604bba9359846a4eeaa4e304c0fea26586e8c8497db8a0f543f3c0c079ceeea8f12ad730666d3b21453261f1572cbafb08d70ef9462f9880c000700000016de277fabf66ea966f44e3d5c74902e3b20b6c1259448131ed9505cb1e70b3ec26336f6ae94fc8b5e5c272e6720dbcf6d3fe84ab64b6c56dd0b750879190f810c00080000003215988a218fae78a4d2d1387a5f1be47fae812be03edef900cf0c17e93e646db957e434cff70a5fc768693a6672dc28ce58468970013388bb3ecea4ad440a890c000900000010622ef8626a403ba790ebc1b6baf151e5157b96fb8a2a907dbb494a036abc38897ae5f987228ec9fc5f98ed4b04001fb7170946e5c92996d151327025b45e8e0c000a00000082947afd222ec1e6f064e9bcd2211be9f2426e992cc35ba043e4760445bde03fe51ef26feaf1f4a328ea19b99a67e2a14ca257a02ddf4b53a807349e7485118a0c000b000000c0380013c086ac13292350bfe4d845bc73c4656beeb1bc371d09bc907b694a2b0af79c42a7e6e1706f022cf096894e09a316e5c97f14b688c36910adadbcc98f0c000c0000004a57e784fe9266e053b0da84efdffde29c1b28862cc988239aafa1f3f090e069dbe61b6ab898f261036cc45fe1199e4a8176b2615be52735a8180dbba3fee88b0c000d0000002233fc7ca2dbe698a26901b476a437e4e74fa72544b6243eb07d9a6dd6a27f58ce67d57911c9b156cdf0f1192241c98a0c2de4fa7db98d0c2d280b1f5db238810c000e000000dcbcdfca9945c7ae2435c967deb7b22880fcf4f5f7773381aa2440dba4071c305e92a3511b91c41b696f60fc4c8ba77f9eccaf7753b023f383403b7469152a880c000f000000180e459a053ddc2e861d9515d267ba7f657566623ca01ffa9e968adc33f3545e3789ece8a428ee5cc376cc811dfe1f463a4635a12cdd54571791748bfb61058f0ce80300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40acfcac6d0a0541ca368261d0d6eef36f15016366108af4c0c7df5abcf7dd3f2d63e47d8c713e6e0704b31c4af7fe9bbe6cfba766ea3a89cbb2734359ec7094d521436395e4a4436135785e3537d13de36fbaa4967926ccf90f0cab5522c225b795021b8a3b8c1e9b69a3672206c25a9974db19f1aa186ccdf30239dfcbbf35af1a18045f924a02a0a3cefa7bcbfafab4d3cb8c789615c727e87899ac421b1614366e0ecfd619df6e4b4f4aecbc96156cab4ee2fe16b7138fa6e6c72765b87c778190dd1078d333c796d76a68ecb75eeaadd5cd49765b877a65258828e5327040ca07f4c5b9c3a6d001a54d9a96bc1b0e69e9266bfa4bf0f8ba0b6256ca10c23d1e000000e9025c1b988e3c110da6d2c8ed6de7b430a00f0dc2cda610ab8a47d392c80ee64781c2b3ef0045e847ea1bf5355597d5a112c3af5859aea9a6951bec5dca635ca24765459fb9d9eb42eabfb44fddb25dc19520c0ba327a5b883bd7215a6bbfebc3cda34e74af080661757261209f1253080000000005617572610101c4244a3f1bfa9c7add7a890d7054fbd05ba40c266de3a65041024eaf756c0b2bb2b1d2d6a2a662cb7f4a9c219d735a2e48621f1bedcf50ea790722a486585087000000008a6fde001402ea7014b10a51a1d68ec75474d38efcfda095472ca575c4aa5c5f4103714749167b67dac947ff57b27066ba64df2ad5dd8180329c79d6d6a2d2c2db9ad059f48701f2d04beb608dd69ed1850e79b1f45fa212f6e84d69489585842b7128b828dc676ae34d870220233503374c0be18fbcb45eaaa206ed706cc1586c275b09b76a8601e2617495b1877a544f5dfcbfb79d863cb7e6ff3670c7a3d8a805ff5fd8ae0248ff4b940c27408443ac53dc81205a9c78ec712d129247dbbbce0cb048a81e648602dc244ca12936e4d9fe49e6ac21de74018691481a5af618e57d1e1067f6c7775e05e4ce9739cdb2549f7a37a9cbcdfc0978cf002ef6b14dfdc0b54ee6b48d698a01d8f68e65630f3209473d780ff68d1cfdd6379a46525c88a25be662c2fe50f121ccc8d658be2089ddc8a4f5602c7a8ed3df751eebf37637c2576ffa17c7ce548e141fe90300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40acfc9891270d421262a649631f6f0abf2dafdbd88080bade974a352c9be7c55903c67e2361e43357f8f71b2e6bd231c4690ab3226628dc821fd2db56c2355f0aae5880a69c4cefe465bb41098aceaa6b2b92d64762c92a70bb28d3c6c4d1d987bd6914222a13f5e216fc7f68252708c961d12f2ebe25ccef107aa81ef1904c81552401967c4c4403e002be2be5d9cd979193bdacc86beea12ca7d1f5142ed08e0a0de6daf1ef3fc6e88ee6c98f202c1b439cf8a659d7015ae2c87ee5accef8348fd4d2fc780ff36ef444aaee59c5a0afa1b79c18a4696a6f3475876dc7284797f1dcc6cda49b51efbe0fd184b974074d1258ca9f15b9fccfedc35b7dee6e1ab9e9000000e902e00f87682d3d0c208425c144859f621e33f8e001c889b1f1e03988be7093f06206992f00ecd5da9a370f5c514ec210f554bfb2b4fc1b578f91167caa6508e89b51fd62970e10a1124d7b133d14706af98fe1602fda88b547897ee847821533f900fc7713080661757261209f12530800000000056175726101018630144dce66464df6d51dd511e3a2cc8b23a03d2d817d27dbc9a72beda81d187093379c491f50f5fad802ee1ee2ae088f92bb0818b762c1dbe07f17de665880000000008a6fde0018021c58cbb963b4e4897c4fb4b2e0d9222deb069152a439716f71fae9cc1f78d56fce80ced3f584ec9160678d1d50231d69796ee2a400f7e801eb7528a5371de98f0258556fd015c61d55c47b99ebe642854dc6909ceabf7bdc4416f54e3a8f2e5b6f55c8d29baf8c9092eea3515cb4b45f25fb90aa2cb115ee2cfbc46c3894d31b810120ffa6b942052f1ba9c9d9ea3ec6605b4ef761cdc6dbab1dc7f7c1556d1fad1523343837a94c4468df191dbf657075f5dc4ffab509309137cf3151ec6298a98d02eeb0bc2b560b0d8016a885543fabf07e2bbb1c3239f94a42bc2a91d59e684019be4a9929cb9642c8f1540e5bec6c7488fa393132eeae60b200b7a4b5f6c64b8b0120e4cd84d399b0a39a2ec947570d014200928c7f3f552a80be4915b483906f2acb8d642d3c733da1df00834a0e304c72a6a9fd94a06bd7c0d456351e302e4b8d015e56e2c35b417fe427f9656d362c74d6b97750af50e814b9afa3ed5230cffe6f4cfb0e25041ed96043f34f91b7776ee0a2415e58455608260710ec23ae240987183fea0300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40ac2e382b3b34921a40e50343cf2ebe326059fd0f972cb34a060ee159c56acca44836568000e96ed361f8e35f2fc825c729b0a412b5427865249067f3106528a351330b63c2ceccfbe6e8d7658bc8c177827b21d85612adcaac5bc72add07f1b0d5d3885f7e6b46f198c2284120ac5a4867efe4480df0305d1c65e8be4d2864ebdd084e445f9d0c9d389f2e24c630b5c5545851e2f52703b4ca89bc0ff69745461864f5a77afd0ab8f373702a2ee2b4914e67707a9270004527126a3fa11361b189223821c406f958a20700021444299d6ae72fc900428f0b7c0106ce55a9a3e19b4e714e61e9b3100565ae524c326102f8bc17bd3e9e73a185b8116a9e964e665c000000e902924645e09c811193071c23010729e40ea2b03bcaec22108ff91dc04daedcfe9f1ef00b008039066af19c53ec45a5d491be58392fa9ba2575407e1977265070b56e8d45492ca3b04e42f429749aa691199813f5d526ea26346456bfdc940b07429be23a52080661757261209f1253080000000005617572610101389ac297b3b047f0825537e1845479951c25a3a2f1c5037350b98ea25aaaa61489cb053a36ade2933ea9794a5972b2222efb746605fb90f8e27abd8493424c89000000008a6fde001401b0ad4d6ab7c5bdecb1314b76c0c2b0c5e97c6a26a1fca9f2c2c78c86fb85070047cc0405609e9a4455effb72d261f6fa37ee04dbd1b274d68540a2375709988c01f4d0977086efc2b63294f9a5afbaa94085b02964f6f2a8b42257a3ccde0d6b4adaccb0884f5ce827af1d0fba6e96a1ab6ef8fb2dd6b12f582512fa8206ba718a01ea8c4ac88cc5c7a59c181beee80192a512ce7d3a3080ab3ddd164af17faa3f0279930108dce00540ff19658f63725ad2b766d61b645f555955b4870b3763898f0178fc4005624ec6baf421055f45c6aedcee3878fdbdeca8c6c52a7ed672a202059668fa6eb617da2b12ef8445ff624b8110b295a33b4ce1a1d135cdf6735e6f8502d214e61f0ac9af706b545a75bc53bbec0c9a9cf218862c540f667e9b9875a158a882486390be76751fddaf7f8110b3e888328846ec6884fe1591e3658b1d7883141f00da7ab5b7ad416bed4b0774f8e971c54ed4a2d2ff842da496df36fd0e1db70cb52abe79031fef5448ee43a28cb3c48e1890b7eeabdc9bb96dd689e23796a8514add12640ba40bda317e4c6103419a926c93deb156ad8148916ffeaf171e5b3740e36efc1b080642414245b501010e0000003e25a6100000000008db4e182734dcbff213060c659394561644cbd04bc908201b25b43a0108892a858f25b729ab79582898cd06b9e9255ad07489cb44536bfe7eb31104776e410aef9ee077326492d813a40146879691a1dcf19b1ce645f897c2b392ac306d0d07054241424501018a94a290fd5070e1df9b78f5feebce41be592777a001e125e521caa0fb99a70970fdb35df5d6551fe9b970a8423a652b2d98783160c49a63268a6d5d97dd8b8b") - require.NoError(t, err) - - blockResponse := new(network.BlockResponseMessage) - err = blockResponse.Decode(blockResponseBytes) - require.NoError(t, err) - - blockData := blockResponse.BlockData[0] - - block := &types.Block{ - Header: *blockData.Header, - Body: *blockData.Body, - } - - fmt.Printf("Executing block number %d (%s)\n", block.Header.Number, block.Header.Hash().String()) - _, err = instance.ExecuteBlock(block) - require.NoError(t, err) - - // db, err := database.NewPebble(t.TempDir(), true) - // require.NoError(t, err) - - // storageState, err := state.NewStorageState(db, nil, state.NewTries()) - // require.NoError(t, err) - - // trieState := storage.NewTrieState(wnd14576854StateTrie) - // codeHash, err := trieState.LoadCodeHash() - // require.NoError(t, err) - - // fmt.Printf("code hash at start: %s\n", codeHash.String()) - - // cfg := wazero_runtime.Config{ - // Storage: trieState, - // LogLvl: log.Critical, - // } - - // instance, err := wazero_runtime.NewInstanceFromTrie(wnd14576854StateTrie, cfg) - // require.NoError(t, err) - - // blockResponseBytes, err := common.HexToBytes("0x0ae0260a2012e044179cd1d2ee191c71f8fc5d17bc68f70bf97c6d1250be951e1ac524d41412c9075a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40ac2ebe79035e6e7e19bae1468b3b77494c8c020f5455ae8b2b27d7d1c3b4084be42c95b2c04443ebec754aa968aa6e7954549fdf93ea3ad35f44db433781681e65f9075a180c0642414245b50103050000003f25a61000000000645dad89d04f57c9c7f55882ac70ea42588380a3e35757b49b04ff11bd3c9d7a3763ede2161cc70c1c41202fe2b6260e6a23a5a487bc731e010e3a8fb1d3d6057da69c5a47443f3a32436a5be6cd1703472787831270b823a3792b9bba3aaf0b0442414245890a01402694e4bf063c232bc5d1c0068e9bfb28bee7ca7c177372ca2cd1134698c03d6901000000000000009a09fe0aa06b45e97820029311e172bddf0c3ce7fd1597b06590499d380e77710100000000000000bc7c0e3f41b9af06798373c40225afbc599f4b8509997fdde8abf9e522064c66010000000000000054204d0e6b1d4492cfb91e9eb9ecf348dbe70b078c47b893194b611dce8100630100000000000000bafafa4a206ccc38ad5afa73a5cde8cba3aa89d6de94ab60c7e59c868280977d01000000000000009e4971f0d6f1d35badecaf7e9032829ff4a2629122250a5d9cb714f4805641490100000000000000fed87bf3437f55b8b813a9bb751045c6c724481eb9535ba5e120b09d843f1820010000000000000016a03c740cd6b746cbfc9ae2d7c630b4ddd14ca6de6e08034163995e6283396001000000000000000468e29aa426b75e51d9f8d98a9b21688a96d093bcdc9ac82b24e508ea6c8b1d010000000000000076a5a1a0b2b4bef5524de64cf7d5d27b48e35825142b393b1ff297b925f5eb3f0100000000000000ba0085a91f9028cf1ee961c1e5c9ac3cef6e9db6944524dcd3baa178271be13b0100000000000000284b21a986abcb1dc8449e75d1039296d15d9170b709d1d8f80e13f965d2826701000000000000000483b0689164171cca2215638b17d2f70346a072dea3e2a5cda2b0a11614914c0100000000000000d6459c910d17bb21d596611bf08f6e690cdd757a33ac0e7c8c820f77de132e5b01000000000000001c480cd50beda967ba7d31cd02e1fa7e341256b57fd20392634e2db5d298c04b0100000000000000d650846b5a3b4e026efc6a87c8e4c4048ffdc46f5895c5307cf1d1a257a5e8260100000000000000f71b9104c477173500092159d69b7ce6da7e88f3fa2902bb5a54c5facec77d0605424142450101bc7cf81cd40358fc343846e388340c4baed507c32aacc0bd66b7717435615c0e56c4124730fc9bcb529299b126e8d6bad0015ff963b3cbd75bd173fa8869d6891a0b280402000b90f4083686011ae21e813d042d00400c0000000000282cd878ee3c4d099656395bef3ca75ab8db3f20acb25b6130ac883b7de7af2f902eccdcaaa509437ce0f850d6368d17e9e38d8889df479c7b5decc5376f008a0c00010000009aa2ce35475fa20b79a27f33791fdf65408af545b4efcca8ad91840c3db74a2b1440bd9364ff443aaffc2f53d58359eeef952152293f97231fdb9257af24dd830c000200000034dbe9a6359045e8e913f56ca301153f0e7d83bf87c0caac18ddbd3257b44a3e63b7348650146671a5e88f9badac0186952bdc94a37b05b259defe710ce826820c00030000008eceac5be204b40818d16b28b2c5a6f7bbdcc65a4fd734caa06d65faf2c7c7749da4d385d23fa02fb6e2c837ce41ee7af9670ab45391c1c9d4c7e2ae5268c28d0c000400000006df086355e3a189af73e6cff2b9a0f7bcb0960ac2990be164ce02762e0fce75e9d66775f774b87a92e485e72b67617b9f7fbb98dd2e12ee296706d562c069800c0005000000aa268e78631163c127d6613c127916257147a4c54d74e7621c6ae70ed5e27251653e699ce45415cbb6c3c4195b44e6054a45543444c180e6b4b2b67202bf81820c000600000030da3834d2db04e52604bba9359846a4eeaa4e304c0fea26586e8c8497db8a0f543f3c0c079ceeea8f12ad730666d3b21453261f1572cbafb08d70ef9462f9880c000700000016de277fabf66ea966f44e3d5c74902e3b20b6c1259448131ed9505cb1e70b3ec26336f6ae94fc8b5e5c272e6720dbcf6d3fe84ab64b6c56dd0b750879190f810c00080000003215988a218fae78a4d2d1387a5f1be47fae812be03edef900cf0c17e93e646db957e434cff70a5fc768693a6672dc28ce58468970013388bb3ecea4ad440a890c000900000010622ef8626a403ba790ebc1b6baf151e5157b96fb8a2a907dbb494a036abc38897ae5f987228ec9fc5f98ed4b04001fb7170946e5c92996d151327025b45e8e0c000a00000082947afd222ec1e6f064e9bcd2211be9f2426e992cc35ba043e4760445bde03fe51ef26feaf1f4a328ea19b99a67e2a14ca257a02ddf4b53a807349e7485118a0c000b000000c0380013c086ac13292350bfe4d845bc73c4656beeb1bc371d09bc907b694a2b0af79c42a7e6e1706f022cf096894e09a316e5c97f14b688c36910adadbcc98f0c000c0000004a57e784fe9266e053b0da84efdffde29c1b28862cc988239aafa1f3f090e069dbe61b6ab898f261036cc45fe1199e4a8176b2615be52735a8180dbba3fee88b0c000d0000002233fc7ca2dbe698a26901b476a437e4e74fa72544b6243eb07d9a6dd6a27f58ce67d57911c9b156cdf0f1192241c98a0c2de4fa7db98d0c2d280b1f5db238810c000e000000dcbcdfca9945c7ae2435c967deb7b22880fcf4f5f7773381aa2440dba4071c305e92a3511b91c41b696f60fc4c8ba77f9eccaf7753b023f383403b7469152a880c000f000000180e459a053ddc2e861d9515d267ba7f657566623ca01ffa9e968adc33f3545e3789ece8a428ee5cc376cc811dfe1f463a4635a12cdd54571791748bfb61058f0ce80300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40acfcac6d0a0541ca368261d0d6eef36f15016366108af4c0c7df5abcf7dd3f2d63e47d8c713e6e0704b31c4af7fe9bbe6cfba766ea3a89cbb2734359ec7094d521436395e4a4436135785e3537d13de36fbaa4967926ccf90f0cab5522c225b795021b8a3b8c1e9b69a3672206c25a9974db19f1aa186ccdf30239dfcbbf35af1a18045f924a02a0a3cefa7bcbfafab4d3cb8c789615c727e87899ac421b1614366e0ecfd619df6e4b4f4aecbc96156cab4ee2fe16b7138fa6e6c72765b87c778190dd1078d333c796d76a68ecb75eeaadd5cd49765b877a65258828e5327040ca07f4c5b9c3a6d001a54d9a96bc1b0e69e9266bfa4bf0f8ba0b6256ca10c23d1e000000e9025c1b988e3c110da6d2c8ed6de7b430a00f0dc2cda610ab8a47d392c80ee64781c2b3ef0045e847ea1bf5355597d5a112c3af5859aea9a6951bec5dca635ca24765459fb9d9eb42eabfb44fddb25dc19520c0ba327a5b883bd7215a6bbfebc3cda34e74af080661757261209f1253080000000005617572610101c4244a3f1bfa9c7add7a890d7054fbd05ba40c266de3a65041024eaf756c0b2bb2b1d2d6a2a662cb7f4a9c219d735a2e48621f1bedcf50ea790722a486585087000000008a6fde001402ea7014b10a51a1d68ec75474d38efcfda095472ca575c4aa5c5f4103714749167b67dac947ff57b27066ba64df2ad5dd8180329c79d6d6a2d2c2db9ad059f48701f2d04beb608dd69ed1850e79b1f45fa212f6e84d69489585842b7128b828dc676ae34d870220233503374c0be18fbcb45eaaa206ed706cc1586c275b09b76a8601e2617495b1877a544f5dfcbfb79d863cb7e6ff3670c7a3d8a805ff5fd8ae0248ff4b940c27408443ac53dc81205a9c78ec712d129247dbbbce0cb048a81e648602dc244ca12936e4d9fe49e6ac21de74018691481a5af618e57d1e1067f6c7775e05e4ce9739cdb2549f7a37a9cbcdfc0978cf002ef6b14dfdc0b54ee6b48d698a01d8f68e65630f3209473d780ff68d1cfdd6379a46525c88a25be662c2fe50f121ccc8d658be2089ddc8a4f5602c7a8ed3df751eebf37637c2576ffa17c7ce548e141fe90300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40acfc9891270d421262a649631f6f0abf2dafdbd88080bade974a352c9be7c55903c67e2361e43357f8f71b2e6bd231c4690ab3226628dc821fd2db56c2355f0aae5880a69c4cefe465bb41098aceaa6b2b92d64762c92a70bb28d3c6c4d1d987bd6914222a13f5e216fc7f68252708c961d12f2ebe25ccef107aa81ef1904c81552401967c4c4403e002be2be5d9cd979193bdacc86beea12ca7d1f5142ed08e0a0de6daf1ef3fc6e88ee6c98f202c1b439cf8a659d7015ae2c87ee5accef8348fd4d2fc780ff36ef444aaee59c5a0afa1b79c18a4696a6f3475876dc7284797f1dcc6cda49b51efbe0fd184b974074d1258ca9f15b9fccfedc35b7dee6e1ab9e9000000e902e00f87682d3d0c208425c144859f621e33f8e001c889b1f1e03988be7093f06206992f00ecd5da9a370f5c514ec210f554bfb2b4fc1b578f91167caa6508e89b51fd62970e10a1124d7b133d14706af98fe1602fda88b547897ee847821533f900fc7713080661757261209f12530800000000056175726101018630144dce66464df6d51dd511e3a2cc8b23a03d2d817d27dbc9a72beda81d187093379c491f50f5fad802ee1ee2ae088f92bb0818b762c1dbe07f17de665880000000008a6fde0018021c58cbb963b4e4897c4fb4b2e0d9222deb069152a439716f71fae9cc1f78d56fce80ced3f584ec9160678d1d50231d69796ee2a400f7e801eb7528a5371de98f0258556fd015c61d55c47b99ebe642854dc6909ceabf7bdc4416f54e3a8f2e5b6f55c8d29baf8c9092eea3515cb4b45f25fb90aa2cb115ee2cfbc46c3894d31b810120ffa6b942052f1ba9c9d9ea3ec6605b4ef761cdc6dbab1dc7f7c1556d1fad1523343837a94c4468df191dbf657075f5dc4ffab509309137cf3151ec6298a98d02eeb0bc2b560b0d8016a885543fabf07e2bbb1c3239f94a42bc2a91d59e684019be4a9929cb9642c8f1540e5bec6c7488fa393132eeae60b200b7a4b5f6c64b8b0120e4cd84d399b0a39a2ec947570d014200928c7f3f552a80be4915b483906f2acb8d642d3c733da1df00834a0e304c72a6a9fd94a06bd7c0d456351e302e4b8d015e56e2c35b417fe427f9656d362c74d6b97750af50e814b9afa3ed5230cffe6f4cfb0e25041ed96043f34f91b7776ee0a2415e58455608260710ec23ae240987183fea0300005a9e648bfe78322945e25a0c39d3b825fa8a60091903fa2238b2fa173aee40ac2e382b3b34921a40e50343cf2ebe326059fd0f972cb34a060ee159c56acca44836568000e96ed361f8e35f2fc825c729b0a412b5427865249067f3106528a351330b63c2ceccfbe6e8d7658bc8c177827b21d85612adcaac5bc72add07f1b0d5d3885f7e6b46f198c2284120ac5a4867efe4480df0305d1c65e8be4d2864ebdd084e445f9d0c9d389f2e24c630b5c5545851e2f52703b4ca89bc0ff69745461864f5a77afd0ab8f373702a2ee2b4914e67707a9270004527126a3fa11361b189223821c406f958a20700021444299d6ae72fc900428f0b7c0106ce55a9a3e19b4e714e61e9b3100565ae524c326102f8bc17bd3e9e73a185b8116a9e964e665c000000e902924645e09c811193071c23010729e40ea2b03bcaec22108ff91dc04daedcfe9f1ef00b008039066af19c53ec45a5d491be58392fa9ba2575407e1977265070b56e8d45492ca3b04e42f429749aa691199813f5d526ea26346456bfdc940b07429be23a52080661757261209f1253080000000005617572610101389ac297b3b047f0825537e1845479951c25a3a2f1c5037350b98ea25aaaa61489cb053a36ade2933ea9794a5972b2222efb746605fb90f8e27abd8493424c89000000008a6fde001401b0ad4d6ab7c5bdecb1314b76c0c2b0c5e97c6a26a1fca9f2c2c78c86fb85070047cc0405609e9a4455effb72d261f6fa37ee04dbd1b274d68540a2375709988c01f4d0977086efc2b63294f9a5afbaa94085b02964f6f2a8b42257a3ccde0d6b4adaccb0884f5ce827af1d0fba6e96a1ab6ef8fb2dd6b12f582512fa8206ba718a01ea8c4ac88cc5c7a59c181beee80192a512ce7d3a3080ab3ddd164af17faa3f0279930108dce00540ff19658f63725ad2b766d61b645f555955b4870b3763898f0178fc4005624ec6baf421055f45c6aedcee3878fdbdeca8c6c52a7ed672a202059668fa6eb617da2b12ef8445ff624b8110b295a33b4ce1a1d135cdf6735e6f8502d214e61f0ac9af706b545a75bc53bbec0c9a9cf218862c540f667e9b9875a158a882486390be76751fddaf7f8110b3e888328846ec6884fe1591e3658b1d7883141f00da7ab5b7ad416bed4b0774f8e971c54ed4a2d2ff842da496df36fd0e1db70cb52abe79031fef5448ee43a28cb3c48e1890b7eeabdc9bb96dd689e23796a8514add12640ba40bda317e4c6103419a926c93deb156ad8148916ffeaf171e5b3740e36efc1b080642414245b501010e0000003e25a6100000000008db4e182734dcbff213060c659394561644cbd04bc908201b25b43a0108892a858f25b729ab79582898cd06b9e9255ad07489cb44536bfe7eb31104776e410aef9ee077326492d813a40146879691a1dcf19b1ce645f897c2b392ac306d0d07054241424501018a94a290fd5070e1df9b78f5feebce41be592777a001e125e521caa0fb99a70970fdb35df5d6551fe9b970a8423a652b2d98783160c49a63268a6d5d97dd8b8b") - // require.NoError(t, err) - - // blockResponse := new(network.BlockResponseMessage) - // err = blockResponse.Decode(blockResponseBytes) - // require.NoError(t, err) - - // blockData := blockResponse.BlockData[0] - - // block := &types.Block{ - // Header: *blockData.Header, - // Body: *blockData.Body, - // } - // parentBlockStateRoot := block.Header.StateRoot - - // fmt.Printf("Executing block number %d (%s)\n", block.Header.Number, block.Header.Hash().String()) - // _, err = instance.ExecuteBlock(block) - // require.NoError(t, err) - - // fmt.Printf("Storing the trie to the disk, regards block %d\n", block.Header.Number) - - // //newTrieState := storage.NewTrieState(trieState.Trie().DeepCopy()) - // err = storageState.StoreTrie(trieState, &block.Header) - // require.NoError(t, err) - - // codeHash, err = trieState.LoadCodeHash() - // require.NoError(t, err) - - // fmt.Printf("code hash from updated state: %s\n", codeHash.String()) - - // blockResponseBytes, err = common.HexToBytes("0x0ade0d0a20396e794b25deac6c25bc8b5e7b00892934fea53c87bb7128983c7921d72f758112a0020283b22f28a02825206b5cfd1668e117c4c1d3b49ec02a5b4731aff2c3ac1c4062b37903d1b4e4621243629a494fc62b91c92f2d8c378e2c3a0be552af2a05dc3d0dbd7b7ad6e998c94d604101a7e147cf401b041e0ce4996f609b3f5601c77c4922a529080642414245b50103000000008b22a6100000000054741a1a0fbb59012ce3b6c28a9e37487a49113964713cb85485ac24b0b46a5d18785ae8cca9a49ebc11657be3774bca3f93d8326af163290479a77be944370c6b3b763783d6bc086da473b2438389e0d6ae31abbc4a37441b27a6516e57920f05424142450101e2629d073bca188b537fd4715da7f0d3c0be8474a01935f7c25e1c5f374bde742e99423d97698db3975ebbd40819ea352f6d1d1f510dc761c9a623cf3a8975831a0b280402000bd099c93586011a890b1d16042d00400c040000000076b8399ace2a50d5b6fd5cbf464b048178c6fffa047702a416f3d8c8d264ad4a41a4853dc73e37dd91dfaec5d0d41dc01a542a13232cfc56b9372ffcbb83ef840c0401000000d2f839d7eaa667fc2e48a16d98807290e7c10a5ecd2583f8568fcc1bb7d5351e8656146d1365c8619f3202e966877e0f5870c90ecf910ef03f0f1a3dd87266830c0402000000fa36f6a59008ff66a4229c482e8a50315fd5251fc53cd9469b6543bc4930cd2528e827a4fcef270dc9722d37ae23ac04953c4fb08725e1e6bd5615babc42dd800c04030000009497e81b8089a8189918c58c2d5f80690d07f3e0353801e9378efc5a76912b41a8d34b1dd0d93b897441dff3b8c68544bceb9cf27c6e0c83be911ba6eb9574870c04040000006adb55ddc67509b0ddff38ce482fb437d96b0faae302e2b7cf5d5979f5ec45655fafc6045104d9b0d234f42c1ed8ec35c88fe420c8ea6123b780112cb92fa4890c0405000000b80a4c5a180e71a741110b020bacbffba9082d9b76c3e8ce79714be476f144626d6757c6e0efb878754e692c8be83bc2deacd5582f96ceb4f91d68b3e0acaa8a0c0406000000ce8b4daede74064db15bc9a924bc046bde7c9cce04cae4e543266aa691225f2dfc41119900287c9fa43965f82e0e48cc54fc31bf3a06e38a29730b996931e88c0c0407000000b68e00e032c1316faf1415e81501158eba96906b35281f1ff9862dc0b92881430c8d3ae74f16054ab24b313dd3a6e26ca0e57b5206f1a0ee46deb82946a231820c0408000000902e9429fb62ea6de61b0a0da1aae498fe28b27321540848d4ef86c52d684416d3262c3f03826a92dd26eedb5b1ccc220429277822ac0531350c31e43aae90830c04090000007cb92e3ce7438b34d56f5af43af0363520ebd4810c1b8ea8fe717ff1bbcea404528a1765ae3602d3975347ea17554d34613969cdc69718e7fdc47ea7cdc159800c040a0000005ecb6f76ac28e9c9596b46f2571a8380ad0742f7dfae673544b71e7000dbd0039cd13e10fe3e5d7ae14614c5f100f2c72373ea4d2df1f6a34be831db81f62a8a0c040b0000009ca60150ef177cb3168b28470364b611825ad2d86e3e38056b79903d4639205c2799926328d205c4cc66e0f2ca832e6ff8fa4ff9f05f1b57103d63ab465190860c040c00000020aa8c3c211ca39b7d1ae912ef2045064742eb1cb04e073bdb87814386f32a40547f8ba9029d3b830052011273dd6f6bcafdad40efd031bed27fca87747bdf8d0c040d0000006e7204ad9b80e56429c17d0de2aa231dd9b933bb7469bcd124d44aa9c0406b71bedb4a7037bebf8605afb3cf904ed60f359335d9ce2fe3884129f81f4f2e0e850c040e000000a869927414a693a1ff6794fcd975a737434556b1b6970c841657aa831bb1dc1910d9ce3c27d46e59cf4355077ce2b1e76964e0ba5907f2a57a522944e6c73b8b0c040f000000b858993e3b38f0cc7a70b226a40b9a49b11d75ddd0fbf7158d66127830ddca78f50277fe22d6f5b13bf98b82fedaca5fcee11868bbbe3afe2f25ff7d57584583000040a65a5bad9b346fc4d86fe33eadfa0cd49d0378910b0af5e73159ed503611e35eb37903e8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605cf34d6de3155b72a0818608103915619964369e8599482e246a4cdf43df1a7500c0642414245b501030f0000008a22a61000000000821ded3b100e3f68e3ae8109c028e91b0d084bfa6458d5a28203e35b2d01e87bf4f8ef774929e4522b451e3abf892dbbb5aaf21ba7870db5e0efa8d481268e0159463ac6be5114cb953e7bb5d070e785b3ace95680bc6040bab4aed1575bed0708054241424501014ea332ce7e94687b6103adaf88e0fd370879926e95834ca700852fdaff0e260857572d8c7798150b0ffdf60d85d90fc6c6bf10c974606307245d4d4683b64e8e") - // require.NoError(t, err) - - // blockResponse = new(network.BlockResponseMessage) - // err = blockResponse.Decode(blockResponseBytes) - // require.NoError(t, err) - - // blockData = blockResponse.BlockData[0] - - // block = &types.Block{ - // Header: *blockData.Header, - // Body: *blockData.Body, - // } - - // ts, err := storageState.TrieState(&parentBlockStateRoot) - // require.NoError(t, err) - - // // wnd14576855StateTrie := newTrieFromRPC(t, "../test_data/14576855trie_state_data.json") - // // expectedStorageRootHash := common.MustHexToHash("0xe8c4636bd5f01d9f9a18fa96949787975c9c3b78a0624ae95e3078da20c33605") - // // require.Equal(t, expectedStorageRootHash, trie.V0.MustHash(*wnd14576855StateTrie)) - - // // state := storage.NewTrieState(wnd14576855StateTrie) - // instance, err = wazero_runtime.NewInstanceFromTrie(trieState.Trie(), wazero_runtime.Config{ - // Storage: ts, - // LogLvl: log.Critical, - // }) - // require.NoError(t, err) - // // instance.version() - // // instance.SetContextStorage(state) - - // fmt.Printf("Executing block number %d\n", block.Header.Number) - - // _, err = instance.ExecuteBlock(block) - // require.NoError(t, err) -} From 868b2ebe145f0d0d3e16b41bb519cf3fb59d32b0 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 26 Feb 2024 14:58:47 -0400 Subject: [PATCH 26/36] chore: fix `Test_Service_StorageRoot` --- dot/core/service_test.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 52a2df46af..23568a5b2c 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -126,8 +126,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 @@ -152,7 +150,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, }, @@ -161,7 +159,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, }, From fcc4acec7b582110c383846a774417011a6e4a4d Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 26 Feb 2024 16:42:57 -0400 Subject: [PATCH 27/36] chore: set a default runtime version to avoid calling `Core_version` --- lib/runtime/wazero/instance.go | 27 ++++++++++++++++----------- lib/runtime/wazero/test_helpers.go | 9 ++++++++- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/runtime/wazero/instance.go b/lib/runtime/wazero/instance.go index 5a6da2511f..6e7157cd2e 100644 --- a/lib/runtime/wazero/instance.go +++ b/lib/runtime/wazero/instance.go @@ -47,14 +47,15 @@ type Instance struct { // Config is the configuration used to create a Wasmer runtime instance. type Config struct { - Storage runtime.Storage - Keystore *keystore.GlobalKeystore - LogLvl log.Level - Role common.NetworkRole - NodeStorage runtime.NodeStorage - Network runtime.BasicNetwork - Transaction runtime.TransactionState - CodeHash common.Hash + Storage runtime.Storage + Keystore *keystore.GlobalKeystore + LogLvl log.Level + Role common.NetworkRole + NodeStorage runtime.NodeStorage + Network runtime.BasicNetwork + Transaction runtime.TransactionState + CodeHash common.Hash + DefaultVersion *runtime.Version } func decompressWasm(code []byte) ([]byte, error) { @@ -437,9 +438,13 @@ func NewInstance(code []byte, cfg Config) (instance *Instance, err error) { codeHash: cfg.CodeHash, } - err = instance.version() - if err != nil { - return nil, fmt.Errorf("while getting runtime version: %w", err) + if cfg.DefaultVersion == nil { + err = instance.version() + if err != nil { + return nil, fmt.Errorf("while getting runtime version: %w", err) + } + } else { + instance.Context.Version = cfg.DefaultVersion } if cfg.Storage != nil { diff --git a/lib/runtime/wazero/test_helpers.go b/lib/runtime/wazero/test_helpers.go index 06725197b0..7071a0ee00 100644 --- a/lib/runtime/wazero/test_helpers.go +++ b/lib/runtime/wazero/test_helpers.go @@ -5,6 +5,7 @@ package wazero_runtime import ( "context" + "errors" "fmt" "os" "path/filepath" @@ -46,6 +47,10 @@ func setupConfig(t *testing.T, ctrl *gomock.Controller, tt *trie.Trie, lvl log.L Network: new(runtime.TestRuntimeNetwork), Transaction: mocks.NewMockTransactionState(ctrl), Role: role, + DefaultVersion: &runtime.Version{ + SpecName: []byte("test-runtime"), + StateVersion: 0, + }, } } @@ -65,7 +70,9 @@ func NewTestInstanceWithTrie(t *testing.T, targetRuntime string, tt *trie.Trie) require.NoError(t, err) r, err := NewInstanceFromFile(targetRuntime, cfg) - require.NoError(t, err) + if !errors.Is(err, ErrExportFunctionNotFound) { + require.NoError(t, err) + } return r } From 5f441a43612acb4a570c4198c781183174da921a Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 26 Feb 2024 17:20:59 -0400 Subject: [PATCH 28/36] chore: refactor test runtime instance to use a set of options to change the runtime config --- dot/rpc/modules/dev_integration_test.go | 2 +- dot/rpc/modules/system_integration_test.go | 2 +- lib/runtime/wazero/imports_test.go | 147 +++++++++++---------- lib/runtime/wazero/instance_test.go | 10 +- lib/runtime/wazero/test_helpers.go | 87 ++++++------ 5 files changed, 124 insertions(+), 124 deletions(-) diff --git a/dot/rpc/modules/dev_integration_test.go b/dot/rpc/modules/dev_integration_test.go index 293643a0c7..4abf2a9b5c 100644 --- a/dot/rpc/modules/dev_integration_test.go +++ b/dot/rpc/modules/dev_integration_test.go @@ -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"), diff --git a/dot/rpc/modules/system_integration_test.go b/dot/rpc/modules/system_integration_test.go index c6bd5de480..bc2d4e8398 100644 --- a/dot/rpc/modules/system_integration_test.go +++ b/dot/rpc/modules/system_integration_test.go @@ -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() diff --git a/lib/runtime/wazero/imports_test.go b/lib/runtime/wazero/imports_test.go index 4660934808..245afcc847 100644 --- a/lib/runtime/wazero/imports_test.go +++ b/lib/runtime/wazero/imports_test.go @@ -31,8 +31,19 @@ import ( "github.com/stretchr/testify/require" ) +var DefaultVersion = &runtime.Version{ + SpecName: []byte("goss-test-runtime"), + ImplName: []byte("goss-test-impl"), + AuthoringVersion: 0, + SpecVersion: 0, + ImplVersion: 0, + APIItems: nil, + TransactionVersion: 0, + StateVersion: 0, +} + func Test_ext_offchain_index_clear_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.NodeStorage.BaseDB.Put(testKey, testValue) require.NoError(t, err) @@ -52,7 +63,7 @@ func Test_ext_offchain_index_clear_version_1(t *testing.T) { } func Test_ext_crypto_ed25519_generate_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) idData := []byte(keystore.AccoName) ks, _ := inst.Context.Keystore.GetKeystore(idData) @@ -85,7 +96,7 @@ func Test_ext_crypto_ed25519_generate_version_1(t *testing.T) { } func Test_ext_crypto_ed25519_public_keys_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) idData := []byte(keystore.DumyName) ks, _ := inst.Context.Keystore.GetKeystore(idData) @@ -124,7 +135,7 @@ func Test_ext_crypto_ed25519_public_keys_version_1(t *testing.T) { } func Test_ext_crypto_ed25519_sign_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) kp, err := ed25519.GenerateKeypair() require.NoError(t, err) @@ -162,7 +173,7 @@ func Test_ext_crypto_ed25519_sign_version_1(t *testing.T) { } func Test_ext_crypto_ed25519_verify_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) kp, err := ed25519.GenerateKeypair() require.NoError(t, err) @@ -194,7 +205,7 @@ func Test_ext_crypto_ed25519_verify_version_1(t *testing.T) { } func Test_ext_crypto_secp256k1_ecdsa_recover_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) msgData := []byte("Hello world!") blakeHash, err := common.Blake2bHash(msgData) @@ -239,7 +250,7 @@ func Test_ext_crypto_secp256k1_ecdsa_recover_version_1(t *testing.T) { } func Test_ext_crypto_ecdsa_verify_version_2(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) kp, err := secp256k1.GenerateKeypair() require.NoError(t, err) @@ -273,7 +284,7 @@ func Test_ext_crypto_ecdsa_verify_version_2(t *testing.T) { func Test_ext_crypto_secp256k1_ecdsa_recover_compressed_version_1(t *testing.T) { // TODO: fix this t.Skip("host API tester does not yet contain rtm_ext_crypto_secp256k1_ecdsa_recover_compressed_version_1") - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) msgData := []byte("Hello world!") blakeHash, err := common.Blake2bHash(msgData) @@ -356,7 +367,7 @@ func Test_ext_crypto_ecdsa_verify_version_2_Table(t *testing.T) { for name, tc := range testCases { tc := tc t.Run(name, func(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) ret, err := inst.Exec("rtm_ext_crypto_ecdsa_verify_version_2", append(append(tc.sig, tc.msg...), tc.key...)) assert.Equal(t, tc.expected, ret) @@ -370,7 +381,7 @@ func Test_ext_crypto_ecdsa_verify_version_2_Table(t *testing.T) { } func Test_ext_crypto_sr25519_generate_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) idData := []byte(keystore.AccoName) ks, _ := inst.Context.Keystore.GetKeystore(idData) @@ -402,7 +413,7 @@ func Test_ext_crypto_sr25519_generate_version_1(t *testing.T) { } func Test_ext_crypto_sr25519_public_keys_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) idData := []byte(keystore.DumyName) ks, _ := inst.Context.Keystore.GetKeystore(idData) @@ -441,7 +452,7 @@ func Test_ext_crypto_sr25519_public_keys_version_1(t *testing.T) { } func Test_ext_crypto_sr25519_sign_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) kp, err := sr25519.GenerateKeypair() require.NoError(t, err) @@ -481,7 +492,7 @@ func Test_ext_crypto_sr25519_sign_version_1(t *testing.T) { } func Test_ext_crypto_sr25519_verify_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) kp, err := sr25519.GenerateKeypair() require.NoError(t, err) @@ -515,7 +526,7 @@ func Test_ext_crypto_sr25519_verify_version_1(t *testing.T) { func Test_ext_crypto_sr25519_verify_version_2(t *testing.T) { // TODO: add to test runtime since this is required for Westend t.Skip("host API tester does not yet contain rtm_ext_crypto_sr25519_verify_version_2") - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) kp, err := sr25519.GenerateKeypair() require.NoError(t, err) @@ -547,7 +558,7 @@ func Test_ext_crypto_sr25519_verify_version_2(t *testing.T) { } func Test_ext_trie_blake2_256_root_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testinput := []string{"noot", "was", "here", "??"} encInput, err := scale.Marshal(testinput) @@ -572,7 +583,7 @@ func Test_ext_trie_blake2_256_root_version_1(t *testing.T) { } func Test_ext_trie_blake2_256_root_version_2(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testinput := []string{"dimartiro", "was", "here", "??"} encInput, err := scale.Marshal(testinput) @@ -604,7 +615,7 @@ func Test_ext_trie_blake2_256_root_version_2(t *testing.T) { } func Test_ext_trie_blake2_256_ordered_root_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testvalues := []string{"static", "even-keeled", "Future-proofed"} encValues, err := scale.Marshal(testvalues) @@ -622,7 +633,7 @@ func Test_ext_trie_blake2_256_ordered_root_version_1(t *testing.T) { } func Test_ext_trie_blake2_256_ordered_root_version_2(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testvalues := []string{"static", "even-keeled", "Future-proofed"} encValues, err := scale.Marshal(testvalues) @@ -708,7 +719,7 @@ func Test_ext_trie_blake2_256_verify_proof_version_1(t *testing.T) { root: root, key: []byte("do"), proof: [][]byte{}, value: nil, expect: false}, } - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) for name, testcase := range testcases { testcase := testcase @@ -806,7 +817,7 @@ func Test_ext_trie_blake2_256_verify_proof_version_2(t *testing.T) { root: root, key: []byte("do"), proof: [][]byte{}, value: nil, expect: false}, } - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) for name, testcase := range testcases { testcase := testcase @@ -842,7 +853,7 @@ func Test_ext_trie_blake2_256_verify_proof_version_2(t *testing.T) { } func Test_ext_misc_runtime_version_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) fp, err := runtime.GetRuntime(context.Background(), runtime.WESTEND_RUNTIME_v0929) require.NoError(t, err) @@ -911,14 +922,14 @@ func Test_ext_default_child_storage_read_version_1(t *testing.T) { }{ "should_return_none_if_child_doesnt_exist": { setupInstance: func(t *testing.T) *Instance { - return NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + return NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) }, expected: nil, }, "child_exists_return_value": { setupInstance: func(t *testing.T) *Instance { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -979,7 +990,7 @@ func Test_ext_default_child_storage_set_version_1(t *testing.T) { "child_trie_exists_should_not_panic": { existsBeforehand: true, setupInstance: func(t *testing.T) *Instance { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -990,7 +1001,7 @@ func Test_ext_default_child_storage_set_version_1(t *testing.T) { "child_trie_not_found_should_create_a_empty_one": { existsBeforehand: false, setupInstance: func(t *testing.T) *Instance { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) return inst }, }, @@ -1058,7 +1069,7 @@ func Test_ext_default_child_storage_set_version_1(t *testing.T) { } func Test_ext_default_child_storage_clear_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -1087,7 +1098,7 @@ func Test_ext_default_child_storage_clear_version_1(t *testing.T) { } func Test_ext_default_child_storage_clear_prefix_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) prefix := []byte("key") @@ -1128,7 +1139,7 @@ func Test_ext_default_child_storage_clear_prefix_version_1(t *testing.T) { } func Test_ext_default_child_storage_exists_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -1158,7 +1169,7 @@ func Test_ext_default_child_storage_get_version_1(t *testing.T) { }{ "value_exists_expected_value": { setupInstance: func(t *testing.T) *Instance { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -1170,7 +1181,7 @@ func Test_ext_default_child_storage_get_version_1(t *testing.T) { }, "value_not_found_expected_none": { setupInstance: func(t *testing.T) *Instance { - return NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + return NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) }, expected: nil, }, @@ -1215,7 +1226,7 @@ func Test_ext_default_child_storage_next_key_version_1(t *testing.T) { }{ "next_key_exists": { setupInstance: func(t *testing.T) *Instance { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -1231,13 +1242,13 @@ func Test_ext_default_child_storage_next_key_version_1(t *testing.T) { }, "child_tree_not_exists": { setupInstance: func(t *testing.T) *Instance { - return NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + return NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) }, expected: nil, }, "with_only_one_key": { setupInstance: func(t *testing.T) *Instance { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -1279,7 +1290,7 @@ func Test_ext_default_child_storage_next_key_version_1(t *testing.T) { } func Test_ext_default_child_storage_root_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -1313,7 +1324,7 @@ func Test_ext_default_child_storage_root_version_1(t *testing.T) { } func Test_ext_default_child_storage_root_version_2(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) stateVersion := trie.V1 @@ -1352,7 +1363,7 @@ func Test_ext_default_child_storage_root_version_2(t *testing.T) { } func Test_ext_default_child_storage_storage_kill_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) err := inst.Context.Storage.SetChild(testChildKey, trie.NewEmptyTrie()) require.NoError(t, err) @@ -1373,7 +1384,7 @@ func Test_ext_default_child_storage_storage_kill_version_1(t *testing.T) { } func Test_ext_default_child_storage_storage_kill_version_2_limit_all(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) tr := trie.NewEmptyTrie() tr.Put([]byte(`key2`), []byte(`value2`)) @@ -1406,7 +1417,7 @@ func Test_ext_default_child_storage_storage_kill_version_2_limit_all(t *testing. } func Test_ext_default_child_storage_storage_kill_version_2_limit_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) tr := trie.NewEmptyTrie() tr.Put([]byte(`key2`), []byte(`value2`)) @@ -1439,7 +1450,7 @@ func Test_ext_default_child_storage_storage_kill_version_2_limit_1(t *testing.T) } func Test_ext_default_child_storage_storage_kill_version_2_limit_none(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) tr := trie.NewEmptyTrie() tr.Put([]byte(`key2`), []byte(`value2`)) @@ -1469,7 +1480,7 @@ func Test_ext_default_child_storage_storage_kill_version_2_limit_none(t *testing } func Test_ext_default_child_storage_storage_kill_version_3(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) tr := trie.NewEmptyTrie() tr.Put([]byte(`key2`), []byte(`value2`)) @@ -1522,7 +1533,7 @@ func Test_ext_default_child_storage_storage_kill_version_3(t *testing.T) { } func Test_ext_hashing_blake2_128_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) data := []byte("helloworld") enc, err := scale.Marshal(data) @@ -1541,7 +1552,7 @@ func Test_ext_hashing_blake2_128_version_1(t *testing.T) { } func Test_ext_hashing_blake2_256_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) data := []byte("helloworld") enc, err := scale.Marshal(data) @@ -1560,7 +1571,7 @@ func Test_ext_hashing_blake2_256_version_1(t *testing.T) { } func Test_ext_hashing_keccak_256_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) data := []byte("helloworld") enc, err := scale.Marshal(data) @@ -1579,7 +1590,7 @@ func Test_ext_hashing_keccak_256_version_1(t *testing.T) { } func Test_ext_hashing_twox_128_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) data := []byte("helloworld") enc, err := scale.Marshal(data) @@ -1598,7 +1609,7 @@ func Test_ext_hashing_twox_128_version_1(t *testing.T) { } func Test_ext_hashing_twox_64_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) data := []byte("helloworld") enc, err := scale.Marshal(data) @@ -1617,7 +1628,7 @@ func Test_ext_hashing_twox_64_version_1(t *testing.T) { } func Test_ext_hashing_sha2_256_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) data := []byte("helloworld") enc, err := scale.Marshal(data) @@ -1635,7 +1646,7 @@ func Test_ext_hashing_sha2_256_version_1(t *testing.T) { } func Test_ext_offchain_timestamp_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) ret, err := inst.Exec("rtm_ext_offchain_timestamp_version_1", []byte{}) require.NoError(t, err) @@ -1649,7 +1660,7 @@ func Test_ext_offchain_timestamp_version_1(t *testing.T) { } func Test_ext_offchain_sleep_until_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) input := time.Now().UnixMilli() enc, err := scale.Marshal(input) @@ -1660,7 +1671,7 @@ func Test_ext_offchain_sleep_until_version_1(t *testing.T) { } func Test_ext_default_child_storage_clear_prefix_version_2(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) prefix := []byte("key") @@ -1712,7 +1723,7 @@ func Test_ext_default_child_storage_clear_prefix_version_2(t *testing.T) { } func Test_ext_offchain_local_storage_clear_version_1_Persistent(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("key1") err := inst.Context.NodeStorage.PersistentStorage.Put(testkey, []byte{1}) @@ -1734,7 +1745,7 @@ func Test_ext_offchain_local_storage_clear_version_1_Persistent(t *testing.T) { } func Test_ext_offchain_local_storage_clear_version_1_Local(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("key1") err := inst.Context.NodeStorage.LocalStorage.Put(testkey, []byte{1}) @@ -1756,7 +1767,7 @@ func Test_ext_offchain_local_storage_clear_version_1_Local(t *testing.T) { } func Test_ext_offchain_http_request_start_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) encMethod, err := scale.Marshal([]byte("GET")) require.NoError(t, err) @@ -1812,7 +1823,7 @@ func Test_ext_offchain_http_request_start_version_1(t *testing.T) { } func Test_ext_offchain_http_request_add_header(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) cases := map[string]struct { key, value string @@ -1874,7 +1885,7 @@ func Test_ext_offchain_http_request_add_header(t *testing.T) { } func Test_ext_storage_clear_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") inst.Context.Storage.Put(testkey, []byte{1}) @@ -1890,7 +1901,7 @@ func Test_ext_storage_clear_version_1(t *testing.T) { } func Test_ext_storage_clear_prefix_version_1_hostAPI(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("static") inst.Context.Storage.Put(testkey, []byte("Inverse")) @@ -1912,7 +1923,7 @@ func Test_ext_storage_clear_prefix_version_1_hostAPI(t *testing.T) { } func Test_ext_storage_clear_prefix_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") inst.Context.Storage.Put(testkey, []byte{1}) @@ -1934,7 +1945,7 @@ func Test_ext_storage_clear_prefix_version_1(t *testing.T) { } func Test_ext_storage_clear_prefix_version_2(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") inst.Context.Storage.Put(testkey, []byte{1}) @@ -2006,7 +2017,7 @@ func Test_ext_storage_clear_prefix_version_2(t *testing.T) { } func Test_ext_storage_get_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") testvalue := []byte{1, 2} @@ -2050,7 +2061,7 @@ func Test_ext_storage_exists_version_1(t *testing.T) { for name, testCase := range testCases { testCase := testCase t.Run(name, func(t *testing.T) { - instance := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + instance := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) if testCase.value != nil { instance.Context.Storage.Put(testCase.key, testCase.value) @@ -2072,7 +2083,7 @@ func Test_ext_storage_exists_version_1(t *testing.T) { } func Test_ext_storage_next_key_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") inst.Context.Storage.Put(testkey, []byte{1}) @@ -2094,7 +2105,7 @@ func Test_ext_storage_next_key_version_1(t *testing.T) { } func Test_ext_storage_read_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") testvalue := []byte("washere") @@ -2122,7 +2133,7 @@ func Test_ext_storage_read_version_1(t *testing.T) { } func Test_ext_storage_read_version_1_again(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") testvalue := []byte("_was_here_") @@ -2151,7 +2162,7 @@ func Test_ext_storage_read_version_1_again(t *testing.T) { } func Test_ext_storage_read_version_1_OffsetLargerThanValue(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") testvalue := []byte("washere") @@ -2179,7 +2190,7 @@ func Test_ext_storage_read_version_1_OffsetLargerThanValue(t *testing.T) { } func Test_ext_storage_root_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) ret, err := inst.Exec("rtm_ext_storage_root_version_1", []byte{}) require.NoError(t, err) @@ -2193,7 +2204,7 @@ func Test_ext_storage_root_version_1(t *testing.T) { } func Test_ext_storage_root_version_2(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) stateVersion := uint32(trie.V1) encVersion, err := scale.Marshal(stateVersion) @@ -2211,7 +2222,7 @@ func Test_ext_storage_root_version_2(t *testing.T) { } func Test_ext_storage_set_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") testvalue := []byte("washere") @@ -2229,7 +2240,7 @@ func Test_ext_storage_set_version_1(t *testing.T) { } func Test_ext_storage_append_version_1(t *testing.T) { - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") testvalue := []byte("was") @@ -2278,7 +2289,7 @@ func Test_ext_storage_append_version_1(t *testing.T) { func Test_ext_storage_append_version_1_again(t *testing.T) { DefaultTestLogLvl = 5 - inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME, TestWithVersion(DefaultVersion)) testkey := []byte("noot") testvalue := []byte("abc") diff --git a/lib/runtime/wazero/instance_test.go b/lib/runtime/wazero/instance_test.go index 723b17e12b..3ed7813913 100644 --- a/lib/runtime/wazero/instance_test.go +++ b/lib/runtime/wazero/instance_test.go @@ -259,7 +259,7 @@ func TestInstance_GrandpaAuthorities_NodeRuntime(t *testing.T) { key := common.MustHexToBytes(genesis.GrandpaAuthoritiesKeyHex) tt.Put(key, value) - rt := NewTestInstanceWithTrie(t, runtime.WESTEND_RUNTIME_v0929, tt) + rt := NewTestInstance(t, runtime.WESTEND_RUNTIME_v0929, TestWithTrie(tt)) auths, err := rt.GrandpaAuthorities() require.NoError(t, err) @@ -287,7 +287,7 @@ func TestInstance_GrandpaAuthorities_PolkadotRuntime(t *testing.T) { key := common.MustHexToBytes(genesis.GrandpaAuthoritiesKeyHex) tt.Put(key, value) - rt := NewTestInstanceWithTrie(t, runtime.POLKADOT_RUNTIME_v0929, tt) + rt := NewTestInstance(t, runtime.POLKADOT_RUNTIME_v0929, TestWithTrie(tt)) auths, err := rt.GrandpaAuthorities() require.NoError(t, err) @@ -336,7 +336,7 @@ func TestInstance_BabeGenerateKeyOwnershipProof(t *testing.T) { key = common.MustHexToBytes(genesis.BABEAuthoritiesKeyHex) tt.Put(key, authorityValue) - rt := NewTestInstanceWithTrie(t, testCase.targetRuntime, tt) + rt := NewTestInstance(t, testCase.targetRuntime, TestWithTrie(tt)) babeConfig, err := rt.BabeConfiguration() require.NoError(t, err) @@ -371,7 +371,7 @@ func TestInstance_BabeSubmitReportEquivocationUnsignedExtrinsic(t *testing.T) { testCase := testCase t.Run(testCase.name, func(t *testing.T) { tt := trie.NewEmptyTrie() - rt := NewTestInstanceWithTrie(t, testCase.targetRuntime, tt) + rt := NewTestInstance(t, testCase.targetRuntime, TestWithTrie(tt)) authorityID := types.AuthorityID{1} const slot = uint64(1) @@ -549,7 +549,7 @@ func TestInstance_BabeConfiguration_WestendRuntime_WithAuthorities(t *testing.T) key = common.MustHexToBytes(genesis.BABEAuthoritiesKeyHex) tt.Put(key, authorityValue) - rt := NewTestInstanceWithTrie(t, runtime.WESTEND_RUNTIME_v0929, tt) + rt := NewTestInstance(t, runtime.WESTEND_RUNTIME_v0929, TestWithTrie(tt)) cfg, err := rt.BabeConfiguration() require.NoError(t, err) diff --git a/lib/runtime/wazero/test_helpers.go b/lib/runtime/wazero/test_helpers.go index 7071a0ee00..3c28f91baf 100644 --- a/lib/runtime/wazero/test_helpers.go +++ b/lib/runtime/wazero/test_helpers.go @@ -5,8 +5,6 @@ package wazero_runtime import ( "context" - "errors" - "fmt" "os" "path/filepath" "testing" @@ -22,69 +20,60 @@ import ( "go.uber.org/mock/gomock" ) -// NewTestInstance will create a new runtime instance using the given target runtime -func NewTestInstance(t *testing.T, targetRuntime string) *Instance { - t.Helper() - return NewTestInstanceWithTrie(t, targetRuntime, trie.NewEmptyTrie()) -} - -func setupConfig(t *testing.T, ctrl *gomock.Controller, tt *trie.Trie, lvl log.Level, role common.NetworkRole) Config { - t.Helper() +// DefaultTestLogLvl is the log level used for test runtime instances +var DefaultTestLogLvl = log.Info - s := storage.NewTrieState(tt) +type TestInstanceOption func(*Config) - ns := runtime.NodeStorage{ - LocalStorage: runtime.NewInMemoryDB(t), - PersistentStorage: runtime.NewInMemoryDB(t), // we're using a local storage here since this is a test runtime - BaseDB: runtime.NewInMemoryDB(t), // we're using a local storage here since this is a test runtime +func TestWithLogLevel(lvl log.Level) TestInstanceOption { + return func(c *Config) { + c.LogLvl = lvl } +} - return Config{ - Storage: s, - Keystore: keystore.NewGlobalKeystore(), - LogLvl: lvl, - NodeStorage: ns, - Network: new(runtime.TestRuntimeNetwork), - Transaction: mocks.NewMockTransactionState(ctrl), - Role: role, - DefaultVersion: &runtime.Version{ - SpecName: []byte("test-runtime"), - StateVersion: 0, - }, +func TestWithTrie(tt *trie.Trie) TestInstanceOption { + return func(c *Config) { + c.Storage = storage.NewTrieState(trie.NewEmptyTrie()) } } -// DefaultTestLogLvl is the log level used for test runtime instances -var DefaultTestLogLvl = log.Info +func TestWithVersion(version *runtime.Version) TestInstanceOption { + return func(c *Config) { + c.DefaultVersion = version + } +} -// NewTestInstanceWithTrie returns an instance based on the target runtime string specified, -// which can be a file path or a constant from the constants defined in `lib/runtime/constants.go`. -// The instance uses the trie given as argument for its storage. -func NewTestInstanceWithTrie(t *testing.T, targetRuntime string, tt *trie.Trie) *Instance { +func NewTestInstance(t *testing.T, targetRuntime string, opts ...TestInstanceOption) *Instance { t.Helper() ctrl := gomock.NewController(t) + cfg := &Config{ + Storage: storage.NewTrieState(trie.NewEmptyTrie()), + Keystore: keystore.NewGlobalKeystore(), + LogLvl: DefaultTestLogLvl, + NodeStorage: runtime.NodeStorage{ + LocalStorage: runtime.NewInMemoryDB(t), + PersistentStorage: runtime.NewInMemoryDB(t), // we're using a local storage here since this is a test runtime + BaseDB: runtime.NewInMemoryDB(t), // we're using a local storage here since this is a test runtime + }, + Network: new(runtime.TestRuntimeNetwork), + Transaction: mocks.NewMockTransactionState(ctrl), + Role: common.NoNetworkRole, + } - cfg := setupConfig(t, ctrl, tt, DefaultTestLogLvl, common.NoNetworkRole) - targetRuntime, err := runtime.GetRuntime(context.Background(), targetRuntime) - require.NoError(t, err) - - r, err := NewInstanceFromFile(targetRuntime, cfg) - if !errors.Is(err, ErrExportFunctionNotFound) { - require.NoError(t, err) + for _, opt := range opts { + opt(cfg) } - return r -} + targetRuntime, err := runtime.GetRuntime(context.Background(), targetRuntime) + require.NoError(t, err) -// NewInstanceFromFile instantiates a runtime from a .wasm file -func NewInstanceFromFile(fp string, cfg Config) (*Instance, error) { // Reads the WebAssembly module as bytes. // Retrieve WASM binary - bytes, err := os.ReadFile(filepath.Clean(fp)) - if err != nil { - return nil, fmt.Errorf("failed to read wasm file: %s", err) - } + bytes, err := os.ReadFile(filepath.Clean(targetRuntime)) + require.NoError(t, err) - return NewInstance(bytes, cfg) + r, err := NewInstance(bytes, *cfg) + require.NoError(t, err) + return r } From f3ff9ecb3deaa83be04fceea63d905d2d4c9fff6 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Mon, 26 Feb 2024 20:17:27 -0400 Subject: [PATCH 29/36] chore: remove unneeded delta --- pkg/trie/child_storage.go | 1 - pkg/trie/database.go | 2 +- pkg/trie/database_test.go | 2 +- pkg/trie/trie.go | 11 +++++------ tests/sync/sync_test.go | 1 - 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/pkg/trie/child_storage.go b/pkg/trie/child_storage.go index c5363907cf..bd7fcd0bf9 100644 --- a/pkg/trie/child_storage.go +++ b/pkg/trie/child_storage.go @@ -28,7 +28,6 @@ func (t *Trie) SetChild(keyToChild []byte, child *Trie) error { copy(key, ChildStorageKeyPrefix) copy(key[len(ChildStorageKeyPrefix):], keyToChild) - child.childTriePartialKey = key err = t.Put(key, childHash.ToBytes()) if err != nil { return fmt.Errorf("putting child trie root hash %s in trie: %w", childHash, err) diff --git a/pkg/trie/database.go b/pkg/trie/database.go index 0fcfcfb402..315ef33d8c 100644 --- a/pkg/trie/database.go +++ b/pkg/trie/database.go @@ -52,8 +52,8 @@ func (t *Trie) Load(db db.DBGetter, rootHash common.Hash) error { } for _, key := range t.GetKeysWithPrefix(ChildStorageKeyPrefix) { - childTrie := NewEmptyTrie() value := t.Get(key) + childTrie := NewEmptyTrie() rootHash := common.BytesToHash(value) err := childTrie.Load(db, rootHash) if err != nil { diff --git a/pkg/trie/database_test.go b/pkg/trie/database_test.go index 0e2b6bb4b5..3303c33a3b 100644 --- a/pkg/trie/database_test.go +++ b/pkg/trie/database_test.go @@ -325,7 +325,7 @@ func Test_Trie_PutChild_Store_Load(t *testing.T) { require.NoError(t, err) trieFromDB := NewEmptyTrie() - err = trieFromDB.Load(db, V0.MustHash(*trie)) + err = trieFromDB.Load(db, trie.MustHash()) require.NoError(t, err) assert.Equal(t, trie.childTries, trieFromDB.childTries) diff --git a/pkg/trie/trie.go b/pkg/trie/trie.go index 9537453a17..1c3b6a9df2 100644 --- a/pkg/trie/trie.go +++ b/pkg/trie/trie.go @@ -20,12 +20,11 @@ var EmptyHash = common.MustBlake2bHash([]byte{0}) // Trie is a base 16 modified Merkle Patricia trie. type Trie struct { - childTriePartialKey []byte - generation uint64 - root *Node - childTries map[common.Hash]*Trie - db db.Database - version TrieLayout + generation uint64 + root *Node + childTries map[common.Hash]*Trie + db db.Database + version TrieLayout // deltas stores trie deltas since the last trie snapshot. // For example node hashes that were deleted since // the last snapshot. These are used by the online diff --git a/tests/sync/sync_test.go b/tests/sync/sync_test.go index 631349fef4..7c631de613 100644 --- a/tests/sync/sync_test.go +++ b/tests/sync/sync_test.go @@ -1,5 +1,4 @@ // Copyright 2021 ChainSafe Systems (ON) - // SPDX-License-Identifier: LGPL-3.0-only package sync From 2ec5496da3fe077ecdbde2e0949f4b734bcbf5e4 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Tue, 27 Feb 2024 10:59:35 -0400 Subject: [PATCH 30/36] chore: fix `Test_Service_handleCodeSubstitution` --- dot/core/service_test.go | 191 +++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 96 deletions(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 23568a5b2c..da9f21be32 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -6,9 +6,7 @@ package core import ( "bytes" "context" - "encoding/hex" "errors" - "io" "testing" "github.com/ChainSafe/gossamer/dot/network" @@ -205,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 { @@ -215,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": { + // 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) @@ -337,6 +335,7 @@ func Test_Service_handleCodeSubstitution(t *testing.T) { } }, blockHash: common.Hash{0x01}, + trieState: rtstorage.NewTrieState(trie.NewEmptyTrie()), }, } From a23d51f6a821808e3aade58efeb679026e9dd6c1 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Tue, 27 Feb 2024 11:29:49 -0400 Subject: [PATCH 31/36] chore: fix `TestService_Initialise` --- dot/state/service_integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dot/state/service_integration_test.go b/dot/state/service_integration_test.go index 6453796041..7075cd1957 100644 --- a/dot/state/service_integration_test.go +++ b/dot/state/service_integration_test.go @@ -90,7 +90,7 @@ func TestService_Initialise(t *testing.T) { require.NoError(t, err) genesisHeaderPtr := types.NewHeader(common.NewHash([]byte{77}), - genTrie.MustHash(), trie.EmptyHash, 0, types.NewDigest()) + genTrie.MustHash(), trie.EmptyHash, 0, nil) err = state.Initialise(&genData, genesisHeaderPtr, genTrieCopy) require.NoError(t, err) From 439320cda8fbbd80f9bd2e12c3089d8d43f22712 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Tue, 27 Feb 2024 11:36:49 -0400 Subject: [PATCH 32/36] chore: fix `Test_newTrieFromPairs` --- dot/import.go | 6 +++--- dot/import_integration_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dot/import.go b/dot/import.go index 151b29b183..f8c24151ef 100644 --- a/dot/import.go +++ b/dot/import.go @@ -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 } @@ -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 @@ -62,7 +62,7 @@ func newTrieFromPairs(filename string) (*trie.Trie, error) { entries[pairArr[0].(string)] = pairArr[1].(string) } - tr, err := trie.LoadFromMap(entries, trie.V0) + tr, err := trie.LoadFromMap(entries, version) if err != nil { return nil, err } diff --git a/dot/import_integration_test.go b/dot/import_integration_test.go index 1cd39f7b37..9f657b5c96 100644 --- a/dot/import_integration_test.go +++ b/dot/import_integration_test.go @@ -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 { From 15f73051bc4dc34deb56ece81ec8a6e8fbb919e2 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Tue, 27 Feb 2024 11:47:10 -0400 Subject: [PATCH 33/36] chore: fix `TestWithTrie` while instantiating a runtime --- lib/runtime/wazero/test_helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runtime/wazero/test_helpers.go b/lib/runtime/wazero/test_helpers.go index 3c28f91baf..f52fe1aa82 100644 --- a/lib/runtime/wazero/test_helpers.go +++ b/lib/runtime/wazero/test_helpers.go @@ -33,7 +33,7 @@ func TestWithLogLevel(lvl log.Level) TestInstanceOption { func TestWithTrie(tt *trie.Trie) TestInstanceOption { return func(c *Config) { - c.Storage = storage.NewTrieState(trie.NewEmptyTrie()) + c.Storage = storage.NewTrieState(tt) } } From 0162df36894e12d2d9235523788013e539b90b87 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Tue, 27 Feb 2024 12:06:21 -0400 Subject: [PATCH 34/36] chore: fix `Test_Node_Encode` --- pkg/trie/node/encode.go | 12 ++++++------ pkg/trie/node/encode_test.go | 4 ++-- pkg/trie/node/header.go | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/pkg/trie/node/encode.go b/pkg/trie/node/encode.go index 1ad480b1e8..c0025d7330 100644 --- a/pkg/trie/node/encode.go +++ b/pkg/trie/node/encode.go @@ -16,16 +16,16 @@ import ( // of this package, and specified in the Polkadot spec at // https://spec.polkadot.network/#sect-state-storage func (n *Node) Encode(buffer Buffer) (err error) { + if n == nil { + _, err = buffer.Write([]byte{emptyVariant.bits}) + return err + } + err = encodeHeader(n, n.MustBeHashed, buffer) if err != nil { return fmt.Errorf("cannot encode header: %w", err) } - if n == nil { - // only encode the empty variant byte header - return nil - } - keyLE := codec.NibblesToKeyLE(n.PartialKey) _, err = buffer.Write(keyLE) if err != nil { @@ -55,7 +55,7 @@ func (n *Node) Encode(buffer Buffer) (err error) { _, err = buffer.Write(hashedValue.ToBytes()) if err != nil { - return fmt.Errorf("scale encoding storage value: %w", err) + return fmt.Errorf("writing hashed storage value: %w", err) } default: encoder := scale.NewEncoder(buffer) diff --git a/pkg/trie/node/encode_test.go b/pkg/trie/node/encode_test.go index fa2ea50867..496673b5bd 100644 --- a/pkg/trie/node/encode_test.go +++ b/pkg/trie/node/encode_test.go @@ -136,7 +136,7 @@ func Test_Node_Encode(t *testing.T) { PartialKey: []byte{1, 2, 3}, StorageValue: largeValue, IsHashedValue: true, - MustBeHashed: false, + MustBeHashed: true, }, writes: []writeCall{ { @@ -151,7 +151,7 @@ func Test_Node_Encode(t *testing.T) { }, }, wrappedErr: errTest, - errMessage: "encoding hashed storage value: test error", + errMessage: "writing hashed storage value: test error", }, "branch_header_encoding_error": { node: &Node{ diff --git a/pkg/trie/node/header.go b/pkg/trie/node/header.go index d450d2ded9..90d43195bf 100644 --- a/pkg/trie/node/header.go +++ b/pkg/trie/node/header.go @@ -11,11 +11,6 @@ import ( // encodeHeader writes the encoded header for the node. func encodeHeader(node *Node, isHashedValue bool, writer io.Writer) (err error) { - if node == nil { - _, err = writer.Write([]byte{emptyVariant.bits}) - return err - } - partialKeyLength := len(node.PartialKey) if partialKeyLength > int(maxPartialKeyLength) { panic(fmt.Sprintf("partial key length is too big: %d", partialKeyLength)) From 5de40ac34c5af785fabf964d98ec0fa486ca2608 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Tue, 27 Feb 2024 12:29:23 -0400 Subject: [PATCH 35/36] chore: uncomment --- dot/core/service_test.go | 190 ++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 94 deletions(-) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index da9f21be32..43aec43f1c 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -6,7 +6,9 @@ package core import ( "bytes" "context" + "encoding/hex" "errors" + "io" "testing" "github.com/ChainSafe/gossamer/dot/network" @@ -203,7 +205,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 { @@ -213,99 +215,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": { + 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) From 1560eb5f4c5e33401b77fbe5ed46cbbb68b01162 Mon Sep 17 00:00:00 2001 From: EclesioMeloJunior Date: Tue, 27 Feb 2024 17:14:57 -0400 Subject: [PATCH 36/36] chore: fix `Test_Service_handleCodeSubstitution` --- dot/core/service_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 43aec43f1c..cd7bd645b3 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -280,6 +280,7 @@ func Test_Service_handleCodeSubstitution(t *testing.T) { errWrapped: io.ErrUnexpectedEOF, }, "store_code_substitution_block_hash_error": { + trieState: rtstorage.NewTrieState(trie.NewEmptyTrie()), serviceBuilder: func(ctrl *gomock.Controller) *Service { storedRuntime := NewMockInstance(ctrl) storedRuntime.EXPECT().Keystore().Return(nil)