diff --git a/migration/migrator_newstate.go b/migration/migrator_newstate.go index a2bbf230e..99a9e0029 100644 --- a/migration/migrator_newstate.go +++ b/migration/migrator_newstate.go @@ -97,7 +97,7 @@ func (m *StateMigrator) applyAccountChanges(tr *trie.StateTrie, bn uint64, root } // if set is nil, it means there are no changes, so we skip verification in that case. if set != nil { - if err := m.validateStorage(storageTr, id, addr, set, bn); err != nil { + if err := m.validateStorage(storageTr, addr, set, bn); err != nil { return err } } diff --git a/migration/migrator_validate.go b/migration/migrator_validate.go index 4c503a926..218e43169 100644 --- a/migration/migrator_validate.go +++ b/migration/migrator_validate.go @@ -7,7 +7,6 @@ import ( "sync/atomic" "time" - "github.com/status-im/keycard-go/hexutils" "golang.org/x/sync/errgroup" "github.com/ethereum/go-ethereum/common" @@ -175,61 +174,49 @@ func (m *StateMigrator) validateState(tr *trie.StateTrie, set *trienode.NodeSet, if err != nil { return err } - originTrie, err := trie.NewStateTrie(trie.StateTrieID(prevRoot), m.mptdb) - if err != nil { - return err - } - updatedRootNode := set.Nodes[""].Blob - originRootNode, _, err := originTrie.GetNode([]byte("")) + + rootNode := set.Nodes[""].Blob if err != nil { return err } var deletedLeaves []*StateAccount var updatedLeaves []*StateAccount + + for hk := range set.DeletedKeys { + preimage := tr.GetKey(hk.Bytes()) + if preimage == nil { + return fmt.Errorf("failed to get preimage for hashKey: %x", hk) + } else { + addr := common.BytesToAddress(preimage) + deletedLeaves = append(deletedLeaves, &StateAccount{addr, nil}) + } + } + for path, node := range set.Nodes { - if node.IsDeleted() { - blob, _, err := originTrie.GetNode(trie.HexToCompact(path)) + if !node.IsDeleted() { + hk, err := trie.GetKeyFromPath(rootNode, m.db, []byte(path)) if err != nil { return err } - if blob != nil && trie.IsLeafNode(blob) { - hk, err := trie.GetKeyFromPath(originRootNode, m.db, []byte(path)) - if err != nil { - return err - } - preimage := tr.GetKey(hk) - if preimage == nil { - return fmt.Errorf("failed to get preimage for hashKey: %x", hk) - } - addr := common.BytesToAddress(preimage) - deletedLeaves = append(deletedLeaves, &StateAccount{addr, nil}) + preimage := tr.GetKey(hk) + if preimage == nil { + return fmt.Errorf("failed to get preimage for hashKey: %x", hk) } - } else { - if trie.IsLeafNode(node.Blob) { - hk, err := trie.GetKeyFromPath(updatedRootNode, m.db, []byte(path)) - if err != nil { - return err - } - preimage := tr.GetKey(hk) - if preimage == nil { - return fmt.Errorf("failed to get preimage for hashKey: %x", hk) - } - addr := common.BytesToAddress(preimage) - acc, err := trie.NodeBlobToAccount(node.Blob) - if err != nil { - return err - } - // StorageRoot is already validated in storage verification stage - if zkAcc, err := zkTr.GetAccount(addr); err != nil { - return err - } else if zkAcc == nil { - acc.Root = common.Hash{} - } else { - acc.Root = zkAcc.Root - } - updatedLeaves = append(updatedLeaves, &StateAccount{addr, acc}) + addr := common.BytesToAddress(preimage) + acc, err := trie.NodeBlobToAccount(node.Blob) + if err != nil { + return err + } + // StorageRoot is already validated in storage verification stage + if zkAcc, err := zkTr.GetAccount(addr); err != nil { + return err + } else if zkAcc == nil { + acc.Root = common.Hash{} + } else { + acc.Root = zkAcc.Root } + updatedLeaves = append(updatedLeaves, &StateAccount{addr, acc}) } } @@ -256,7 +243,7 @@ func (m *StateMigrator) validateState(tr *trie.StateTrie, set *trienode.NodeSet, return nil } -func (m *StateMigrator) validateStorage(tr *trie.StateTrie, id *trie.ID, addr common.Address, set *trienode.NodeSet, bn uint64) error { +func (m *StateMigrator) validateStorage(tr *trie.StateTrie, addr common.Address, set *trienode.NodeSet, bn uint64) error { if set == nil { return nil } @@ -283,46 +270,29 @@ func (m *StateMigrator) validateStorage(tr *trie.StateTrie, id *trie.ID, addr co if err != nil { return err } - originTrie, err := trie.NewStateTrie(id, m.mptdb) - if err != nil { - return err - } - updatedRootNode := set.Nodes[""].Blob - originRootNode, _, err := originTrie.GetNode([]byte("")) + rootNode := set.Nodes[""].Blob if err != nil { return err } var deletedLeaves []*Slot var updatedLeaves []*Slot - for path, node := range set.Nodes { - if node.IsDeleted() { - blob, _, err := originTrie.GetNode(trie.HexToCompact(path)) - if err != nil { - return err - } - - if blob != nil && trie.IsLeafNode(blob) { - hk, err := trie.GetKeyFromPath(originRootNode, m.db, []byte(path)) - if err != nil { - return err - } - preimage := tr.GetKey(hk) - if preimage == nil { - return fmt.Errorf("failed to get preimage for hashKey: %x", hk) - } - slot := common.BytesToHash(preimage).Bytes() - deletedLeaves = append(deletedLeaves, &Slot{slot, nil}) - if addr.Cmp(common.HexToAddress("0x51901916b0a8A67b18299bb6fA16da4D7428f9cA")) == 0 { - if bytes.Compare(slot, hexutils.HexToBytes("5be7a1449cff78980bfa293037675a1770f220327e9386d49ba469c7210536a4")) == 0 { - fmt.Printf("[DeleteStorage]\n") - } - } - } + for hk := range set.DeletedKeys { + preimage := tr.GetKey(hk.Bytes()) + if preimage == nil { + return fmt.Errorf("failed to get preimage for hashKey: %x", hk) } else { + slot := common.BytesToHash(preimage).Bytes() + deletedLeaves = append(deletedLeaves, &Slot{slot, nil}) + + } + } + + for path, node := range set.Nodes { + if !node.IsDeleted() { if trie.IsLeafNode(node.Blob) { - hk, err := trie.GetKeyFromPath(updatedRootNode, m.db, []byte(path)) + hk, err := trie.GetKeyFromPath(rootNode, m.db, []byte(path)) if err != nil { return err } @@ -336,11 +306,6 @@ func (m *StateMigrator) validateStorage(tr *trie.StateTrie, id *trie.ID, addr co return err } updatedLeaves = append(updatedLeaves, &Slot{slot, val}) - if addr.Cmp(common.HexToAddress("0x51901916b0a8A67b18299bb6fA16da4D7428f9cA")) == 0 { - if bytes.Compare(slot, hexutils.HexToBytes("5be7a1449cff78980bfa293037675a1770f220327e9386d49ba469c7210536a4")) == 0 { - fmt.Printf("[UpdateStorage] path %x slot %x\n", []byte(path), slot) - } - } } } } @@ -376,10 +341,10 @@ func (m *StateMigrator) validateStorage(tr *trie.StateTrie, id *trie.ID, addr co return fmt.Errorf("account doesn't exist: %s", addr.Hex()) } else { if zktRoot.Cmp(zkAcc.Root) != 0 { - //err := m.printStoragesForDebug(zkAcc.Root, parentZkt) - //if err != nil { - // panic(err) - //} + err := m.printStoragesForDebug(zkAcc.Root, parentZkt) + if err != nil { + panic(err) + } return fmt.Errorf("invalid migrated storage of account: %s", addr.Hex()) } } diff --git a/trie/tracer.go b/trie/tracer.go index 5786af4d3..07595d53a 100644 --- a/trie/tracer.go +++ b/trie/tracer.go @@ -43,6 +43,9 @@ type tracer struct { inserts map[string]struct{} deletes map[string]struct{} accessList map[string][]byte + // [Kroma: START] + deletedKeys map[common.Hash]bool + // [Kroma: ENd] } // newTracer initializes the tracer for capturing trie changes. @@ -51,6 +54,9 @@ func newTracer() *tracer { inserts: make(map[string]struct{}), deletes: make(map[string]struct{}), accessList: make(map[string][]byte), + // [Kroma: START] + deletedKeys: make(map[common.Hash]bool), + // [Kroma: END] } } @@ -88,6 +94,9 @@ func (t *tracer) reset() { t.inserts = make(map[string]struct{}) t.deletes = make(map[string]struct{}) t.accessList = make(map[string][]byte) + // [Kroma: START] + t.deletedKeys = make(map[common.Hash]bool) + // [Kroma: END] } // copy returns a deep copied tracer instance. @@ -128,3 +137,10 @@ func (t *tracer) deletedNodes() []string { } return paths } + +// [Kroma: START] +func (t *tracer) onDeleteKroma(key []byte) { + t.deletedKeys[common.BytesToHash(key)] = true +} + +// [Kroma: END] diff --git a/trie/trie.go b/trie/trie.go index 07467ac69..872435c6a 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -448,6 +448,9 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { // need to be tracked at all since it's always embedded. t.tracer.onDelete(prefix) + // [Kroma: START] + t.tracer.onDeleteKroma(hexToKeybytes(append(prefix, key...))) + // [Kroma: END] return true, nil, nil // remove n entirely for whole matches } // The key is longer than n.Key. Remove the remaining suffix @@ -528,8 +531,8 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { // Replace the entire full node with the short node. // Mark the original short node as deleted since the // value is embedded into the parent now. - t.tracer.onDelete(append(prefix, byte(pos))) + t.tracer.onDelete(append(prefix, byte(pos))) k := append([]byte{byte(pos)}, cnode.Key...) return true, &shortNode{k, cnode.Val, t.newFlag()}, nil } @@ -625,6 +628,9 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) for _, path := range paths { nodes.AddNode([]byte(path), trienode.NewDeleted()) } + // [Kroma: START] + nodes.DeletedKeys = t.tracer.deletedKeys + // [Kroma: END] return types.EmptyRootHash, nodes, nil // case (b) } // Derive the hash for all dirty nodes first. We hold the assumption @@ -643,6 +649,9 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) for _, path := range t.tracer.deletedNodes() { nodes.AddNode([]byte(path), trienode.NewDeleted()) } + // [Kroma: START] + nodes.DeletedKeys = t.tracer.deletedKeys + // [Kroma: END] t.root = newCommitter(nodes, t.tracer, collectLeaf).Commit(t.root) return rootHash, nodes, nil } diff --git a/trie/trienode/node.go b/trie/trienode/node.go index 286e0d7d8..d2623cb6c 100644 --- a/trie/trienode/node.go +++ b/trie/trienode/node.go @@ -59,11 +59,12 @@ type leaf struct { // NodeSet contains a set of nodes collected during the commit operation. // Each node is keyed by path. It's not thread-safe to use. type NodeSet struct { - Owner common.Hash - Leaves []*leaf - Nodes map[string]*Node - updates int // the count of updated and inserted nodes - deletes int // the count of deleted nodes + Owner common.Hash + Leaves []*leaf + Nodes map[string]*Node + updates int // the count of updated and inserted nodes + deletes int // the count of deleted nodes + DeletedKeys map[common.Hash]bool } // NewNodeSet initializes a node set. The owner is zero for the account trie and @@ -142,7 +143,7 @@ func (set *NodeSet) Hashes() []common.Hash { // Summary returns a string-representation of the NodeSet. func (set *NodeSet) Summary() string { - var out = new(strings.Builder) + out := new(strings.Builder) fmt.Fprintf(out, "nodeset owner: %v\n", set.Owner) if set.Nodes != nil { for path, n := range set.Nodes {