github.com/klaytn/klaytn@v1.12.1/storage/statedb/trie.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2015 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from trie/trie.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package statedb
    22  
    23  import (
    24  	"bytes"
    25  	"errors"
    26  	"fmt"
    27  
    28  	"github.com/klaytn/klaytn/common"
    29  	"github.com/klaytn/klaytn/crypto"
    30  )
    31  
    32  var (
    33  	// emptyRoot is the known root hash of an empty trie.
    34  	emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
    35  
    36  	// emptyState is the known hash of an empty state trie entry.
    37  	emptyState = crypto.Keccak256Hash(nil)
    38  )
    39  
    40  // TrieOpts consists of trie operation options
    41  type TrieOpts struct {
    42  	Prefetching bool // If true, certain metric is enabled
    43  
    44  	// If PruningBlockNumber is nonzero, trie update and delete operations
    45  	// will schedule obsolete nodes to be pruned when the given block number becomes obsolete.
    46  	// This option is only viable when the pruning is enabled on database.
    47  	PruningBlockNumber uint64
    48  }
    49  
    50  // LeafCallback is a callback type invoked when a trie operation reaches a leaf
    51  // node.
    52  //
    53  // The paths is a path tuple identifying a particular trie node either in a single
    54  // trie (account) or a layered trie (account -> storage). Each path in the tuple
    55  // is in the raw format(32 bytes).
    56  //
    57  // The hexpath is a composite hexary path identifying the trie node. All the key
    58  // bytes are converted to the hexary nibbles and composited with the parent path
    59  // if the trie node is in a layered trie.
    60  //
    61  // It's used by state sync and commit to allow handling external references
    62  // between account and storage tries. And also it's used in the state healing
    63  // for extracting the raw states(leaf nodes) with corresponding paths.
    64  type LeafCallback func(paths [][]byte, hexpath []byte, leaf []byte, parent common.ExtHash, parentDepth int) error
    65  
    66  // Trie is a Merkle Patricia Trie.
    67  // The zero value is an empty trie with no database.
    68  // Use NewTrie to create a trie that sits on top of a database.
    69  //
    70  // Trie is not safe for concurrent use.
    71  type Trie struct {
    72  	TrieOpts
    73  	db           *Database
    74  	root         node
    75  	originalRoot common.ExtHash
    76  
    77  	pruning           bool // True if the underlying database has pruning enabled.
    78  	storage           bool // If storage and Pruning are both true, root hash is attached a fresh nonce.
    79  	pruningMarksCache map[common.ExtHash]uint64
    80  }
    81  
    82  // newFlag returns the cache flag value for a newly created node.
    83  func (t *Trie) newFlag() nodeFlag {
    84  	return nodeFlag{dirty: true}
    85  }
    86  
    87  // NewTrie creates a trie with an existing root node from db.
    88  //
    89  // If root is the zero hash or the sha3 hash of an empty string, the
    90  // trie is initially empty and does not require a database. Otherwise,
    91  // NewTrie will panic if db is nil and returns a MissingNodeError if root does
    92  // not exist in the database. Accessing the trie loads nodes from db on demand.
    93  func NewTrie(root common.Hash, db *Database, opts *TrieOpts) (*Trie, error) {
    94  	return newTrie(root.ExtendZero(), db, opts, false)
    95  }
    96  
    97  // NewStorageTrie creates a storage trie with an existing root node from db.
    98  //
    99  // If root is the zero hash or the sha3 hash of an empty string, the
   100  // trie is initially empty and does not require a database. Otherwise,
   101  // NewTrie will panic if db is nil and returns a MissingNodeError if root does
   102  // not exist in the database. Accessing the trie loads nodes from db on demand.
   103  //
   104  // A storage trie is identified with an ExtHash root node. With Live Pruning enabled,
   105  // its root hash will be extended with a nonzero nonce.
   106  func NewStorageTrie(root common.ExtHash, db *Database, opts *TrieOpts) (*Trie, error) {
   107  	return newTrie(root, db, opts, true)
   108  }
   109  
   110  func newTrie(root common.ExtHash, db *Database, opts *TrieOpts, storage bool) (*Trie, error) {
   111  	if db == nil {
   112  		panic("statedb.NewTrie called without a database")
   113  	}
   114  	if opts == nil {
   115  		opts = &TrieOpts{}
   116  	}
   117  
   118  	trie := &Trie{
   119  		TrieOpts:          *opts,
   120  		db:                db,
   121  		originalRoot:      root,
   122  		pruning:           db.diskDB.ReadPruningEnabled(),
   123  		storage:           storage,
   124  		pruningMarksCache: make(map[common.ExtHash]uint64),
   125  	}
   126  	if !trie.pruning && trie.PruningBlockNumber != 0 {
   127  		return nil, ErrPruningDisabled
   128  	}
   129  	if !common.EmptyExtHash(root) && root.Unextend() != emptyRoot {
   130  		rootnode, err := trie.resolveHash(root[:], nil)
   131  		if err != nil {
   132  			return nil, err
   133  		}
   134  		trie.root = rootnode
   135  	}
   136  	return trie, nil
   137  }
   138  
   139  // NodeIterator returns an iterator that returns nodes of the trie. Iteration starts at
   140  // the key after the given start key.
   141  func (t *Trie) NodeIterator(start []byte) NodeIterator {
   142  	return newNodeIterator(t, start)
   143  }
   144  
   145  // Get returns the value for key stored in the trie.
   146  // The value bytes must not be modified by the caller.
   147  func (t *Trie) Get(key []byte) []byte {
   148  	res, err := t.TryGet(key)
   149  	if err != nil {
   150  		logger.Error("Unhandled trie error in Trie.Get", "err", err)
   151  	}
   152  	return res
   153  }
   154  
   155  // TryGet returns the value for key stored in the trie.
   156  // The value bytes must not be modified by the caller.
   157  // If a node was not found in the database, a MissingNodeError is returned.
   158  func (t *Trie) TryGet(key []byte) ([]byte, error) {
   159  	key = keybytesToHex(key)
   160  	value, newroot, didResolve, err := t.tryGet(t.root, key, 0)
   161  	if err == nil && didResolve {
   162  		t.root = newroot
   163  	}
   164  	return value, err
   165  }
   166  
   167  func (t *Trie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode node, didResolve bool, err error) {
   168  	switch n := (origNode).(type) {
   169  	case nil:
   170  		return nil, nil, false, nil
   171  	case valueNode:
   172  		return n, n, false, nil
   173  	case *shortNode:
   174  		if len(key)-pos < len(n.Key) || !bytes.Equal(n.Key, key[pos:pos+len(n.Key)]) {
   175  			// key not found in trie
   176  			return nil, n, false, nil
   177  		}
   178  		value, newnode, didResolve, err = t.tryGet(n.Val, key, pos+len(n.Key))
   179  		if err == nil && didResolve {
   180  			n = n.copy()
   181  			n.Val = newnode
   182  		}
   183  		return value, n, didResolve, err
   184  	case *fullNode:
   185  		value, newnode, didResolve, err = t.tryGet(n.Children[key[pos]], key, pos+1)
   186  		if err == nil && didResolve {
   187  			n = n.copy()
   188  			n.Children[key[pos]] = newnode
   189  		}
   190  		return value, n, didResolve, err
   191  	case hashNode:
   192  		child, err := t.resolveHash(n, key[:pos])
   193  		if err != nil {
   194  			return nil, n, true, err
   195  		}
   196  		value, newnode, _, err := t.tryGet(child, key, pos)
   197  		return value, newnode, true, err
   198  	default:
   199  		panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode))
   200  	}
   201  }
   202  
   203  // TryGetNode attempts to retrieve a trie node by compact-encoded path. It is not
   204  // possible to use keybyte-encoding as the path might contain odd nibbles.
   205  func (t *Trie) TryGetNode(path []byte) ([]byte, int, error) {
   206  	item, newroot, resolved, err := t.tryGetNode(t.root, compactToHex(path), 0)
   207  	if err != nil {
   208  		return nil, resolved, err
   209  	}
   210  	if resolved > 0 {
   211  		t.root = newroot
   212  	}
   213  	if item == nil {
   214  		return nil, resolved, nil
   215  	}
   216  	return item, resolved, err
   217  }
   218  
   219  func (t *Trie) tryGetNode(origNode node, path []byte, pos int) (item []byte, newnode node, resolved int, err error) {
   220  	// If non-existent path requested, abort
   221  	if origNode == nil {
   222  		return nil, nil, 0, nil
   223  	}
   224  	// If we reached the requested path, return the current node
   225  	if pos >= len(path) {
   226  		// Although we most probably have the original node expanded, encoding
   227  		// that into consensus form can be nasty (needs to cascade down) and
   228  		// time consuming. Instead, just pull the hash up from disk directly.
   229  		var hash hashNode
   230  		if node, ok := origNode.(hashNode); ok {
   231  			hash = node
   232  		} else {
   233  			hash, _ = origNode.cache()
   234  		}
   235  		if hash == nil {
   236  			return nil, origNode, 0, errors.New("non-consensus node")
   237  		}
   238  		blob, err := t.db.Node(common.BytesToExtHash(hash))
   239  		return blob, origNode, 1, err
   240  	}
   241  	// Path still needs to be traversed, descend into children
   242  	switch n := (origNode).(type) {
   243  	case valueNode:
   244  		// Path prematurely ended, abort
   245  		return nil, nil, 0, nil
   246  
   247  	case *shortNode:
   248  		if len(path)-pos < len(n.Key) || !bytes.Equal(n.Key, path[pos:pos+len(n.Key)]) {
   249  			// Path branches off from short node
   250  			return nil, n, 0, nil
   251  		}
   252  		item, newnode, resolved, err = t.tryGetNode(n.Val, path, pos+len(n.Key))
   253  		if err == nil && resolved > 0 {
   254  			n = n.copy()
   255  			n.Val = newnode
   256  		}
   257  		return item, n, resolved, err
   258  
   259  	case *fullNode:
   260  		item, newnode, resolved, err = t.tryGetNode(n.Children[path[pos]], path, pos+1)
   261  		if err == nil && resolved > 0 {
   262  			n = n.copy()
   263  			n.Children[path[pos]] = newnode
   264  		}
   265  		return item, n, resolved, err
   266  
   267  	case hashNode:
   268  		child, err := t.resolveHash(n, path[:pos])
   269  		if err != nil {
   270  			return nil, n, 1, err
   271  		}
   272  		item, newnode, resolved, err := t.tryGetNode(child, path, pos)
   273  		return item, newnode, resolved + 1, err
   274  
   275  	default:
   276  		panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode))
   277  	}
   278  }
   279  
   280  // Update associates key with value in the trie. Subsequent calls to
   281  // Get will return value. If value has length zero, any existing value
   282  // is deleted from the trie and calls to Get will return nil.
   283  //
   284  // The value bytes must not be modified by the caller while they are
   285  // stored in the trie.
   286  func (t *Trie) Update(key, value []byte) {
   287  	if err := t.TryUpdate(key, value); err != nil {
   288  		logger.Error("Unhandled trie error in Trie.Update", "err", err)
   289  	}
   290  }
   291  
   292  // TryUpdate associates key with value in the trie. Subsequent calls to
   293  // Get will return value. If value has length zero, any existing value
   294  // is deleted from the trie and calls to Get will return nil.
   295  //
   296  // The value bytes must not be modified by the caller while they are
   297  // stored in the trie.
   298  //
   299  // If a node was not found in the database, a MissingNodeError is returned.
   300  func (t *Trie) TryUpdate(key, value []byte) error {
   301  	hexKey := keybytesToHex(key)
   302  	return t.TryUpdateWithHexKey(hexKey, value)
   303  }
   304  
   305  // TryUpdateWithHexKey uses pre-generated hexKey.
   306  // It is both called from TryUpdate and SecureTrie.TryUpdateWithKeys.
   307  func (t *Trie) TryUpdateWithHexKey(hexKey, value []byte) error {
   308  	if len(value) != 0 {
   309  		_, n, err := t.insert(t.root, nil, hexKey, valueNode(value))
   310  		if err != nil {
   311  			return err
   312  		}
   313  		t.root = n
   314  	} else {
   315  		_, n, err := t.delete(t.root, nil, hexKey)
   316  		if err != nil {
   317  			return err
   318  		}
   319  		t.root = n
   320  	}
   321  	return nil
   322  }
   323  
   324  func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error) {
   325  	if len(key) == 0 {
   326  		if v, ok := n.(valueNode); ok {
   327  			return !bytes.Equal(v, value.(valueNode)), value, nil
   328  		}
   329  		return true, value, nil
   330  	}
   331  	switch n := n.(type) {
   332  	case *shortNode:
   333  		matchlen := prefixLen(key, n.Key)
   334  		// If the whole key matches, keep this short node as is
   335  		// and only update the value.
   336  		if matchlen == len(n.Key) {
   337  			dirty, nn, err := t.insert(n.Val, append(prefix, key[:matchlen]...), key[matchlen:], value)
   338  			if !dirty || err != nil {
   339  				return false, n, err
   340  			}
   341  			t.markPrunableNode(n) // dirty; something's changed in the child
   342  			return true, &shortNode{n.Key, nn, t.newFlag()}, nil
   343  		}
   344  		// Otherwise branch out at the index where they differ.
   345  		branch := &fullNode{flags: t.newFlag()}
   346  		var err error
   347  		_, branch.Children[n.Key[matchlen]], err = t.insert(nil, append(prefix, n.Key[:matchlen+1]...), n.Key[matchlen+1:], n.Val)
   348  		if err != nil {
   349  			return false, nil, err
   350  		}
   351  		_, branch.Children[key[matchlen]], err = t.insert(nil, append(prefix, key[:matchlen+1]...), key[matchlen+1:], value)
   352  		if err != nil {
   353  			return false, nil, err
   354  		}
   355  		t.markPrunableNode(n) // this node has changed
   356  		// Replace this shortNode with the branch if it occurs at index 0.
   357  		if matchlen == 0 {
   358  			return true, branch, nil
   359  		}
   360  		// Otherwise, replace it with a short node leading up to the branch.
   361  		return true, &shortNode{key[:matchlen], branch, t.newFlag()}, nil
   362  
   363  	case *fullNode:
   364  		dirty, nn, err := t.insert(n.Children[key[0]], append(prefix, key[0]), key[1:], value)
   365  		if !dirty || err != nil {
   366  			return false, n, err
   367  		}
   368  		t.markPrunableNode(n) // dirty; something's changed in the child
   369  		n = n.copy()
   370  		n.flags = t.newFlag()
   371  		n.Children[key[0]] = nn
   372  		return true, n, nil
   373  
   374  	case nil:
   375  		return true, &shortNode{key, value, t.newFlag()}, nil
   376  
   377  	case hashNode:
   378  		// We've hit a part of the trie that isn't loaded yet. Load
   379  		// the node and insert into it. This leaves all child nodes on
   380  		// the path to the value in the trie.
   381  		rn, err := t.resolveHash(n, prefix)
   382  		if err != nil {
   383  			return false, nil, err
   384  		}
   385  		dirty, nn, err := t.insert(rn, prefix, key, value)
   386  		if !dirty || err != nil {
   387  			return false, rn, err
   388  		}
   389  		return true, nn, nil
   390  
   391  	default:
   392  		panic(fmt.Sprintf("%T: invalid node: %v", n, n))
   393  	}
   394  }
   395  
   396  // Delete removes any existing value for key from the trie.
   397  func (t *Trie) Delete(key []byte) {
   398  	if err := t.TryDelete(key); err != nil {
   399  		logger.Error("Unhandled trie error in Trie.Delete", "err", err)
   400  	}
   401  }
   402  
   403  // TryDelete removes any existing value for key from the trie.
   404  // If a node was not found in the database, a MissingNodeError is returned.
   405  func (t *Trie) TryDelete(key []byte) error {
   406  	k := keybytesToHex(key)
   407  	_, n, err := t.delete(t.root, nil, k)
   408  	if err != nil {
   409  		return err
   410  	}
   411  	t.root = n
   412  	return nil
   413  }
   414  
   415  // delete returns the new root of the trie with key deleted.
   416  // It reduces the trie to minimal form by simplifying
   417  // nodes on the way up after deleting recursively.
   418  func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
   419  	switch n := n.(type) {
   420  	case *shortNode:
   421  		matchlen := prefixLen(key, n.Key)
   422  		if matchlen < len(n.Key) {
   423  			return false, n, nil // don't replace n on mismatch
   424  		}
   425  		if matchlen == len(key) {
   426  			t.markPrunableNode(n) // it's the target leaf
   427  			return true, nil, nil // remove n entirely for whole matches
   428  		}
   429  		// The key is longer than n.Key. Remove the remaining suffix
   430  		// from the subtrie. Child can never be nil here since the
   431  		// subtrie must contain at least two other values with keys
   432  		// longer than n.Key.
   433  		dirty, child, err := t.delete(n.Val, append(prefix, key[:len(n.Key)]...), key[len(n.Key):])
   434  		if !dirty || err != nil {
   435  			return false, n, err
   436  		}
   437  		t.markPrunableNode(n) // dirty; something's changed in the child
   438  		switch child := child.(type) {
   439  		case *shortNode:
   440  			// Deleting from the subtrie reduced it to another
   441  			// short node. Merge the nodes to avoid creating a
   442  			// shortNode{..., shortNode{...}}. Use concat (which
   443  			// always creates a new slice) instead of append to
   444  			// avoid modifying n.Key since it might be shared with
   445  			// other nodes.
   446  			return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil
   447  		default:
   448  			return true, &shortNode{n.Key, child, t.newFlag()}, nil
   449  		}
   450  
   451  	case *fullNode:
   452  		dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:])
   453  		if !dirty || err != nil {
   454  			return false, n, err
   455  		}
   456  		t.markPrunableNode(n) // dirty; something's changed in the child
   457  		n = n.copy()
   458  		n.flags = t.newFlag()
   459  		n.Children[key[0]] = nn
   460  
   461  		// Check how many non-nil entries are left after deleting and
   462  		// reduce the full node to a short node if only one entry is
   463  		// left. Since n must've contained at least two children
   464  		// before deletion (otherwise it would not be a full node) n
   465  		// can never be reduced to nil.
   466  		//
   467  		// When the loop is done, pos contains the index of the single
   468  		// value that is left in n or -2 if n contains at least two
   469  		// values.
   470  		pos := -1
   471  		for i, cld := range &n.Children {
   472  			if cld != nil {
   473  				if pos == -1 {
   474  					pos = i
   475  				} else {
   476  					pos = -2
   477  					break
   478  				}
   479  			}
   480  		}
   481  		if pos >= 0 {
   482  			if pos != 16 {
   483  				// If the remaining entry is a short node, it replaces
   484  				// n and its key gets the missing nibble tacked to the
   485  				// front. This avoids creating an invalid
   486  				// shortNode{..., shortNode{...}}.  Since the entry
   487  				// might not be loaded yet, resolve it just for this
   488  				// check.
   489  				cnode, err := t.resolve(n.Children[pos], prefix)
   490  				if err != nil {
   491  					return false, nil, err
   492  				}
   493  				if cnode, ok := cnode.(*shortNode); ok {
   494  					k := append([]byte{byte(pos)}, cnode.Key...)
   495  					return true, &shortNode{k, cnode.Val, t.newFlag()}, nil
   496  				}
   497  			}
   498  			// Otherwise, n is replaced by a one-nibble short node
   499  			// containing the child.
   500  			return true, &shortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil
   501  		}
   502  		// n still contains at least two values and cannot be reduced.
   503  		return true, n, nil
   504  
   505  	case valueNode:
   506  		return true, nil, nil
   507  
   508  	case nil:
   509  		return false, nil, nil
   510  
   511  	case hashNode:
   512  		// We've hit a part of the trie that isn't loaded yet. Load
   513  		// the node and delete from it. This leaves all child nodes on
   514  		// the path to the value in the trie.
   515  		rn, err := t.resolveHash(n, prefix)
   516  		if err != nil {
   517  			return false, nil, err
   518  		}
   519  		dirty, nn, err := t.delete(rn, prefix, key)
   520  		if !dirty || err != nil {
   521  			return false, rn, err
   522  		}
   523  		return true, nn, nil
   524  
   525  	default:
   526  		panic(fmt.Sprintf("%T: invalid node: %v (%v)", n, n, key))
   527  	}
   528  }
   529  
   530  func concat(s1 []byte, s2 ...byte) []byte {
   531  	r := make([]byte, len(s1)+len(s2))
   532  	copy(r, s1)
   533  	copy(r[len(s1):], s2)
   534  	return r
   535  }
   536  
   537  func (t *Trie) resolve(n node, prefix []byte) (node, error) {
   538  	if n, ok := n.(hashNode); ok {
   539  		return t.resolveHash(n, prefix)
   540  	}
   541  	return n, nil
   542  }
   543  
   544  func (t *Trie) resolveHash(n hashNode, prefix []byte) (node, error) {
   545  	hash := common.BytesToExtHash(n)
   546  	node, fromDB := t.db.node(hash)
   547  	if t.Prefetching && fromDB {
   548  		memcacheCleanPrefetchMissMeter.Mark(1)
   549  	}
   550  	if node != nil {
   551  		return node, nil
   552  	}
   553  	return nil, &MissingNodeError{NodeHash: hash.Unextend(), Path: prefix}
   554  }
   555  
   556  // Hash returns the root hash of the trie. It does not write to the
   557  // database and can be used even if the trie doesn't have one.
   558  func (t *Trie) Hash() common.Hash {
   559  	return t.HashExt().Unextend()
   560  }
   561  
   562  // HashExt returns the root hash of the trie in ExtHash type. It does not write to the
   563  // database and can be used even if the trie doesn't have one.
   564  func (t *Trie) HashExt() common.ExtHash {
   565  	hash, cached := t.hashRoot(nil, nil)
   566  	t.root = cached
   567  	return hash
   568  }
   569  
   570  // Commit writes all nodes to the trie's memory database, tracking the internal
   571  // and external (for account tries) references. Returns the root hash.
   572  func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
   573  	extroot, err := t.CommitExt(onleaf)
   574  	return extroot.Unextend(), err
   575  }
   576  
   577  // CommitExt writes all nodes to the trie's memory database, tracking the internal
   578  // and external (for account tries) references. Returns the root hash in ExtHash type.
   579  func (t *Trie) CommitExt(onleaf LeafCallback) (root common.ExtHash, err error) {
   580  	if t.db == nil {
   581  		panic("commit called on trie with nil database")
   582  	}
   583  	t.commitPruningMarks()
   584  	hash, cached := t.hashRoot(t.db, onleaf)
   585  	t.root = cached
   586  	return hash, nil
   587  }
   588  
   589  func (t *Trie) hashRoot(db *Database, onleaf LeafCallback) (common.ExtHash, node) {
   590  	if t.root == nil {
   591  		return emptyRoot.ExtendZero(), nil
   592  	}
   593  	h := newHasher(&hasherOpts{
   594  		onleaf:      onleaf,
   595  		pruning:     t.pruning,
   596  		storageRoot: t.storage,
   597  	})
   598  
   599  	defer returnHasherToPool(h)
   600  	hashed, cached := h.hashRoot(t.root, db, true)
   601  	hash := common.BytesToExtHash(hashed.(hashNode))
   602  	return hash, cached
   603  }
   604  
   605  // Mark the node for later pruning by writing PruningMark to database.
   606  func (t *Trie) markPrunableNode(n node) {
   607  	// Mark nodes only if both conditions are met:
   608  	// - t.pruning: database has pruning enabled, i.e. nodes are stored with ExtHash
   609  	// - t.PruningBlockNumber: requested pruning through state.New -> OpenTrie -> NewTrie.
   610  	if !t.pruning || t.PruningBlockNumber == 0 {
   611  		return
   612  	}
   613  
   614  	if hn, ok := n.(hashNode); ok {
   615  		// If a node exists as a hashNode, it means the node is either:
   616  		// (1) lives in database but yet to be resolved - subject to pruning,
   617  		// (2) collapsed by Hash or Commit - may or may not be in database, add the mark anyway.
   618  		t.pruningMarksCache[common.BytesToExtHash(hn)] = t.PruningBlockNumber
   619  	} else if hn, _ := n.cache(); hn != nil {
   620  		// If node.flags.hash is nonempty, it means the node is either:
   621  		// (1) loaded from databas - subject to pruning,
   622  		// (2) went through hasher by Hash or Commit - may or may not be in database, add the mark anyway.
   623  		t.pruningMarksCache[common.BytesToExtHash(hn)] = t.PruningBlockNumber
   624  	}
   625  }
   626  
   627  // commitPruningMarks writes all the pruning marks
   628  func (t *Trie) commitPruningMarks() {
   629  	if len(t.pruningMarksCache) > 0 {
   630  		t.db.lock.Lock()
   631  		for hash, blockNum := range t.pruningMarksCache {
   632  			t.db.insertPruningMark(hash, blockNum)
   633  		}
   634  		t.db.lock.Unlock()
   635  
   636  		t.pruningMarksCache = make(map[common.ExtHash]uint64)
   637  	}
   638  }
   639  
   640  func GetHashAndHexKey(key []byte) ([]byte, []byte) {
   641  	var hashKeyBuf [common.HashLength]byte
   642  	h := newHasher(nil)
   643  	h.sha.Reset()
   644  	h.sha.Write(key)
   645  	hashKey := h.sha.Sum(hashKeyBuf[:0])
   646  	returnHasherToPool(h)
   647  	hexKey := keybytesToHex(hashKey)
   648  	return hashKey, hexKey
   649  }