github.com/calmw/ethereum@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  	"fmt"
    21  
    22  	"github.com/calmw/ethereum/common"
    23  )
    24  
    25  // Reader wraps the Node method of a backing trie store.
    26  type Reader interface {
    27  	// Node retrieves the RLP-encoded trie node blob with the provided trie
    28  	// identifier, node path and the corresponding node hash. No error will
    29  	// be returned if the node is not found.
    30  	Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error)
    31  }
    32  
    33  // NodeReader wraps all the necessary functions for accessing trie node.
    34  type NodeReader interface {
    35  	// Reader returns a reader for accessing all trie nodes with provided
    36  	// state root. Nil is returned in case the state is not available.
    37  	Reader(root common.Hash) Reader
    38  }
    39  
    40  // trieReader is a wrapper of the underlying node reader. It's not safe
    41  // for concurrent usage.
    42  type trieReader struct {
    43  	owner  common.Hash
    44  	reader Reader
    45  	banned map[string]struct{} // Marker to prevent node from being accessed, for tests
    46  }
    47  
    48  // newTrieReader initializes the trie reader with the given node reader.
    49  func newTrieReader(stateRoot, owner common.Hash, db NodeReader) (*trieReader, error) {
    50  	reader := db.Reader(stateRoot)
    51  	if reader == nil {
    52  		return nil, fmt.Errorf("state not found #%x", stateRoot)
    53  	}
    54  	return &trieReader{owner: owner, reader: reader}, nil
    55  }
    56  
    57  // newEmptyReader initializes the pure in-memory reader. All read operations
    58  // should be forbidden and returns the MissingNodeError.
    59  func newEmptyReader() *trieReader {
    60  	return &trieReader{}
    61  }
    62  
    63  // node retrieves the rlp-encoded trie node with the provided trie node
    64  // information. An MissingNodeError will be returned in case the node is
    65  // not found or any error is encountered.
    66  func (r *trieReader) node(path []byte, hash common.Hash) ([]byte, error) {
    67  	// Perform the logics in tests for preventing trie node access.
    68  	if r.banned != nil {
    69  		if _, ok := r.banned[string(path)]; ok {
    70  			return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path}
    71  		}
    72  	}
    73  	if r.reader == nil {
    74  		return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path}
    75  	}
    76  	blob, err := r.reader.Node(r.owner, path, hash)
    77  	if err != nil || len(blob) == 0 {
    78  		return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path, err: err}
    79  	}
    80  	return blob, nil
    81  }