github.com/codysnider/go-ethereum@v1.10.18-0.20220420071915-14f4ae99222a/trie/utils.go (about) 1 // Copyright 2022 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package trie 18 19 // tracer tracks the changes of trie nodes. During the trie operations, 20 // some nodes can be deleted from the trie, while these deleted nodes 21 // won't be captured by trie.Hasher or trie.Committer. Thus, these deleted 22 // nodes won't be removed from the disk at all. Tracer is an auxiliary tool 23 // used to track all insert and delete operations of trie and capture all 24 // deleted nodes eventually. 25 // 26 // The changed nodes can be mainly divided into two categories: the leaf 27 // node and intermediate node. The former is inserted/deleted by callers 28 // while the latter is inserted/deleted in order to follow the rule of trie. 29 // This tool can track all of them no matter the node is embedded in its 30 // parent or not, but valueNode is never tracked. 31 // 32 // Note tracer is not thread-safe, callers should be responsible for handling 33 // the concurrency issues by themselves. 34 type tracer struct { 35 insert map[string]struct{} 36 delete map[string]struct{} 37 } 38 39 // newTracer initializes trie node diff tracer. 40 func newTracer() *tracer { 41 return &tracer{ 42 insert: make(map[string]struct{}), 43 delete: make(map[string]struct{}), 44 } 45 } 46 47 // onInsert tracks the newly inserted trie node. If it's already 48 // in the deletion set(resurrected node), then just wipe it from 49 // the deletion set as it's untouched. 50 func (t *tracer) onInsert(key []byte) { 51 // Tracer isn't used right now, remove this check later. 52 if t == nil { 53 return 54 } 55 if _, present := t.delete[string(key)]; present { 56 delete(t.delete, string(key)) 57 return 58 } 59 t.insert[string(key)] = struct{}{} 60 } 61 62 // onDelete tracks the newly deleted trie node. If it's already 63 // in the addition set, then just wipe it from the addition set 64 // as it's untouched. 65 func (t *tracer) onDelete(key []byte) { 66 // Tracer isn't used right now, remove this check later. 67 if t == nil { 68 return 69 } 70 if _, present := t.insert[string(key)]; present { 71 delete(t.insert, string(key)) 72 return 73 } 74 t.delete[string(key)] = struct{}{} 75 } 76 77 // insertList returns the tracked inserted trie nodes in list format. 78 func (t *tracer) insertList() [][]byte { 79 // Tracer isn't used right now, remove this check later. 80 if t == nil { 81 return nil 82 } 83 var ret [][]byte 84 for key := range t.insert { 85 ret = append(ret, []byte(key)) 86 } 87 return ret 88 } 89 90 // deleteList returns the tracked deleted trie nodes in list format. 91 func (t *tracer) deleteList() [][]byte { 92 // Tracer isn't used right now, remove this check later. 93 if t == nil { 94 return nil 95 } 96 var ret [][]byte 97 for key := range t.delete { 98 ret = append(ret, []byte(key)) 99 } 100 return ret 101 } 102 103 // reset clears the content tracked by tracer. 104 func (t *tracer) reset() { 105 // Tracer isn't used right now, remove this check later. 106 if t == nil { 107 return 108 } 109 t.insert = make(map[string]struct{}) 110 t.delete = make(map[string]struct{}) 111 } 112 113 // copy returns a deep copied tracer instance. 114 func (t *tracer) copy() *tracer { 115 // Tracer isn't used right now, remove this check later. 116 if t == nil { 117 return nil 118 } 119 var ( 120 insert = make(map[string]struct{}) 121 delete = make(map[string]struct{}) 122 ) 123 for key := range t.insert { 124 insert[key] = struct{}{} 125 } 126 for key := range t.delete { 127 delete[key] = struct{}{} 128 } 129 return &tracer{ 130 insert: insert, 131 delete: delete, 132 } 133 }