github.com/carter-ya/go-ethereum@v0.0.0-20230628080049-d2309be3983b/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  	"fmt"
    21  
    22  	"github.com/ethereum/go-ethereum/common"
    23  )
    24  
    25  // Reader wraps the Node and NodeBlob method of a backing trie store.
    26  type Reader interface {
    27  	// Node retrieves the trie node with the provided trie identifier, hexary
    28  	// node path and the corresponding node hash.
    29  	// No error will be returned if the node is not found.
    30  	Node(owner common.Hash, path []byte, hash common.Hash) (node, error)
    31  
    32  	// NodeBlob retrieves the RLP-encoded trie node blob with the provided trie
    33  	// identifier, hexary node path and the corresponding node hash.
    34  	// No error will be returned if the node is not found.
    35  	NodeBlob(owner common.Hash, path []byte, hash common.Hash) ([]byte, error)
    36  }
    37  
    38  // NodeReader wraps all the necessary functions for accessing trie node.
    39  type NodeReader interface {
    40  	// GetReader returns a reader for accessing all trie nodes with provided
    41  	// state root. Nil is returned in case the state is not available.
    42  	GetReader(root common.Hash) Reader
    43  }
    44  
    45  // trieReader is a wrapper of the underlying node reader. It's not safe
    46  // for concurrent usage.
    47  type trieReader struct {
    48  	owner  common.Hash
    49  	reader Reader
    50  	banned map[string]struct{} // Marker to prevent node from being accessed, for tests
    51  }
    52  
    53  // newTrieReader initializes the trie reader with the given node reader.
    54  func newTrieReader(stateRoot, owner common.Hash, db NodeReader) (*trieReader, error) {
    55  	reader := db.GetReader(stateRoot)
    56  	if reader == nil {
    57  		return nil, fmt.Errorf("state not found #%x", stateRoot)
    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 trie node with the provided trie node information.
    69  // An MissingNodeError will be returned in case the node is not found or
    70  // any error is encountered.
    71  func (r *trieReader) node(path []byte, hash common.Hash) (node, 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  	node, err := r.reader.Node(r.owner, path, hash)
    82  	if err != nil || node == nil {
    83  		return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path, err: err}
    84  	}
    85  	return node, nil
    86  }
    87  
    88  // node retrieves the rlp-encoded trie node with the provided trie node
    89  // information. An MissingNodeError will be returned in case the node is
    90  // not found or any error is encountered.
    91  func (r *trieReader) nodeBlob(path []byte, hash common.Hash) ([]byte, error) {
    92  	// Perform the logics in tests for preventing trie node access.
    93  	if r.banned != nil {
    94  		if _, ok := r.banned[string(path)]; ok {
    95  			return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path}
    96  		}
    97  	}
    98  	if r.reader == nil {
    99  		return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path}
   100  	}
   101  	blob, err := r.reader.NodeBlob(r.owner, path, hash)
   102  	if err != nil || len(blob) == 0 {
   103  		return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path, err: err}
   104  	}
   105  	return blob, nil
   106  }