github.com/Cleverse/go-ethereum@v0.0.0-20220927095127-45113064e7f2/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  // Besides, it's also used for recording the original value of the nodes
    33  // when they are resolved from the disk. The pre-value of the nodes will
    34  // be used to construct reverse-diffs in the future.
    35  //
    36  // Note tracer is not thread-safe, callers should be responsible for handling
    37  // the concurrency issues by themselves.
    38  type tracer struct {
    39  	insert map[string]struct{}
    40  	delete map[string]struct{}
    41  	origin map[string][]byte
    42  }
    43  
    44  // newTracer initializes the tracer for capturing trie changes.
    45  func newTracer() *tracer {
    46  	return &tracer{
    47  		insert: make(map[string]struct{}),
    48  		delete: make(map[string]struct{}),
    49  		origin: make(map[string][]byte),
    50  	}
    51  }
    52  
    53  /*
    54  // onRead tracks the newly loaded trie node and caches the rlp-encoded blob internally.
    55  // Don't change the value outside of function since it's not deep-copied.
    56  func (t *tracer) onRead(key []byte, val []byte) {
    57  	// Tracer isn't used right now, remove this check later.
    58  	if t == nil {
    59  		return
    60  	}
    61  	t.origin[string(key)] = val
    62  }
    63  */
    64  
    65  // onInsert tracks the newly inserted trie node. If it's already in the deletion set
    66  // (resurrected node), then just wipe it from the deletion set as the "untouched".
    67  func (t *tracer) onInsert(key []byte) {
    68  	// Tracer isn't used right now, remove this check later.
    69  	if t == nil {
    70  		return
    71  	}
    72  	if _, present := t.delete[string(key)]; present {
    73  		delete(t.delete, string(key))
    74  		return
    75  	}
    76  	t.insert[string(key)] = struct{}{}
    77  }
    78  
    79  // onDelete tracks the newly deleted trie node. If it's already
    80  // in the addition set, then just wipe it from the addition set
    81  // as it's untouched.
    82  func (t *tracer) onDelete(key []byte) {
    83  	// Tracer isn't used right now, remove this check later.
    84  	if t == nil {
    85  		return
    86  	}
    87  	if _, present := t.insert[string(key)]; present {
    88  		delete(t.insert, string(key))
    89  		return
    90  	}
    91  	t.delete[string(key)] = struct{}{}
    92  }
    93  
    94  // insertList returns the tracked inserted trie nodes in list format.
    95  func (t *tracer) insertList() [][]byte {
    96  	// Tracer isn't used right now, remove this check later.
    97  	if t == nil {
    98  		return nil
    99  	}
   100  	var ret [][]byte
   101  	for key := range t.insert {
   102  		ret = append(ret, []byte(key))
   103  	}
   104  	return ret
   105  }
   106  
   107  // deleteList returns the tracked deleted trie nodes in list format.
   108  func (t *tracer) deleteList() [][]byte {
   109  	// Tracer isn't used right now, remove this check later.
   110  	if t == nil {
   111  		return nil
   112  	}
   113  	var ret [][]byte
   114  	for key := range t.delete {
   115  		ret = append(ret, []byte(key))
   116  	}
   117  	return ret
   118  }
   119  
   120  /*
   121  // getPrev returns the cached original value of the specified node.
   122  func (t *tracer) getPrev(key []byte) []byte {
   123  	// Don't panic on uninitialized tracer, it's possible in testing.
   124  	if t == nil {
   125  		return nil
   126  	}
   127  	return t.origin[string(key)]
   128  }
   129  */
   130  
   131  // reset clears the content tracked by tracer.
   132  func (t *tracer) reset() {
   133  	// Tracer isn't used right now, remove this check later.
   134  	if t == nil {
   135  		return
   136  	}
   137  	t.insert = make(map[string]struct{})
   138  	t.delete = make(map[string]struct{})
   139  	t.origin = make(map[string][]byte)
   140  }
   141  
   142  // copy returns a deep copied tracer instance.
   143  func (t *tracer) copy() *tracer {
   144  	// Tracer isn't used right now, remove this check later.
   145  	if t == nil {
   146  		return nil
   147  	}
   148  	var (
   149  		insert = make(map[string]struct{})
   150  		delete = make(map[string]struct{})
   151  		origin = make(map[string][]byte)
   152  	)
   153  	for key := range t.insert {
   154  		insert[key] = struct{}{}
   155  	}
   156  	for key := range t.delete {
   157  		delete[key] = struct{}{}
   158  	}
   159  	for key, val := range t.origin {
   160  		origin[key] = val
   161  	}
   162  	return &tracer{
   163  		insert: insert,
   164  		delete: delete,
   165  		origin: origin,
   166  	}
   167  }