github.com/theQRL/go-zond@v0.1.1/trie/trie_reader.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  import (
    20  	"github.com/theQRL/go-zond/common"
    21  	"github.com/theQRL/go-zond/core/types"
    22  	"github.com/theQRL/go-zond/log"
    23  	"github.com/theQRL/go-zond/trie/triestate"
    24  )
    25  
    26  // Reader wraps the Node method of a backing trie store.
    27  type Reader interface {
    28  	// Node retrieves the trie node blob with the provided trie identifier, node path and
    29  	// the corresponding node hash. No error will be returned if the node is not found.
    30  	//
    31  	// When looking up nodes in the account trie, 'owner' is the zero hash. For contract
    32  	// storage trie nodes, 'owner' is the hash of the account address that containing the
    33  	// storage.
    34  	//
    35  	// TODO(rjl493456442): remove the 'hash' parameter, it's redundant in PBSS.
    36  	Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error)
    37  }
    38  
    39  // trieReader is a wrapper of the underlying node reader. It's not safe
    40  // for concurrent usage.
    41  type trieReader struct {
    42  	owner  common.Hash
    43  	reader Reader
    44  	banned map[string]struct{} // Marker to prevent node from being accessed, for tests
    45  }
    46  
    47  // newTrieReader initializes the trie reader with the given node reader.
    48  func newTrieReader(stateRoot, owner common.Hash, db *Database) (*trieReader, error) {
    49  	if stateRoot == (common.Hash{}) || stateRoot == types.EmptyRootHash {
    50  		if stateRoot == (common.Hash{}) {
    51  			log.Error("Zero state root hash!")
    52  		}
    53  		return &trieReader{owner: owner}, nil
    54  	}
    55  	reader, err := db.Reader(stateRoot)
    56  	if err != nil {
    57  		return nil, &MissingNodeError{Owner: owner, NodeHash: stateRoot, err: err}
    58  	}
    59  	return &trieReader{owner: owner, reader: reader}, nil
    60  }
    61  
    62  // newEmptyReader initializes the pure in-memory reader. All read operations
    63  // should be forbidden and returns the MissingNodeError.
    64  func newEmptyReader() *trieReader {
    65  	return &trieReader{}
    66  }
    67  
    68  // node retrieves the rlp-encoded trie node with the provided trie node
    69  // information. An MissingNodeError will be returned in case the node is
    70  // not found or any error is encountered.
    71  func (r *trieReader) node(path []byte, hash common.Hash) ([]byte, error) {
    72  	// Perform the logics in tests for preventing trie node access.
    73  	if r.banned != nil {
    74  		if _, ok := r.banned[string(path)]; ok {
    75  			return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path}
    76  		}
    77  	}
    78  	if r.reader == nil {
    79  		return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path}
    80  	}
    81  	blob, err := r.reader.Node(r.owner, path, hash)
    82  	if err != nil || len(blob) == 0 {
    83  		return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path, err: err}
    84  	}
    85  	return blob, nil
    86  }
    87  
    88  // trieLoader implements triestate.TrieLoader for constructing tries.
    89  type trieLoader struct {
    90  	db *Database
    91  }
    92  
    93  // OpenTrie opens the main account trie.
    94  func (l *trieLoader) OpenTrie(root common.Hash) (triestate.Trie, error) {
    95  	return New(TrieID(root), l.db)
    96  }
    97  
    98  // OpenStorageTrie opens the storage trie of an account.
    99  func (l *trieLoader) OpenStorageTrie(stateRoot common.Hash, addrHash, root common.Hash) (triestate.Trie, error) {
   100  	return New(StorageTrieID(stateRoot, addrHash, root), l.db)
   101  }