github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/core/rawdb/accessors_indexes.go (about)

     1  // Copyright 2018 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 rawdb
    18  
    19  import (
    20  	"github.com/ethereum/go-ethereum/common"
    21  	"github.com/ethereum/go-ethereum/core/types"
    22  	"github.com/ethereum/go-ethereum/ethdb"
    23  	"github.com/ethereum/go-ethereum/log"
    24  	"github.com/ethereum/go-ethereum/params"
    25  	"github.com/ethereum/go-ethereum/rlp"
    26  )
    27  
    28  // ReadTxLookupEntry retrieves the positional metadata associated with a transaction
    29  // hash to allow retrieving the transaction or receipt by hash.
    30  func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) common.Hash {
    31  	data, _ := db.Get(txLookupKey(hash))
    32  	if len(data) == 0 {
    33  		return common.Hash{}
    34  	}
    35  	if len(data) == common.HashLength {
    36  		return common.BytesToHash(data)
    37  	}
    38  	// Probably it's legacy txlookup entry data, try to decode it.
    39  	var entry LegacyTxLookupEntry
    40  	if err := rlp.DecodeBytes(data, &entry); err != nil {
    41  		log.Error("Invalid transaction lookup entry RLP", "hash", hash, "blob", data, "err", err)
    42  		return common.Hash{}
    43  	}
    44  	return entry.BlockHash
    45  }
    46  
    47  // WriteTxLookupEntries stores a positional metadata for every transaction from
    48  // a block, enabling hash based transaction and receipt lookups.
    49  func WriteTxLookupEntries(db ethdb.Writer, block *types.Block) {
    50  	for _, tx := range block.Transactions() {
    51  		if err := db.Put(txLookupKey(tx.Hash()), block.Hash().Bytes()); err != nil {
    52  			log.Crit("Failed to store transaction lookup entry", "err", err)
    53  		}
    54  	}
    55  }
    56  
    57  // DeleteTxLookupEntry removes all transaction data associated with a hash.
    58  func DeleteTxLookupEntry(db ethdb.Writer, hash common.Hash) {
    59  	db.Delete(txLookupKey(hash))
    60  }
    61  
    62  // ReadTransaction retrieves a specific transaction from the database, along with
    63  // its added positional metadata.
    64  func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
    65  	blockHash := ReadTxLookupEntry(db, hash)
    66  	if blockHash == (common.Hash{}) {
    67  		return nil, common.Hash{}, 0, 0
    68  	}
    69  	blockNumber := ReadHeaderNumber(db, blockHash)
    70  	if blockNumber == nil {
    71  		return nil, common.Hash{}, 0, 0
    72  	}
    73  	body := ReadBody(db, blockHash, *blockNumber)
    74  	if body == nil {
    75  		log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash)
    76  		return nil, common.Hash{}, 0, 0
    77  	}
    78  	for txIndex, tx := range body.Transactions {
    79  		if tx.Hash() == hash {
    80  			return tx, blockHash, *blockNumber, uint64(txIndex)
    81  		}
    82  	}
    83  	log.Error("Transaction not found", "number", blockNumber, "hash", blockHash, "txhash", hash)
    84  	return nil, common.Hash{}, 0, 0
    85  }
    86  
    87  // ReadReceipt retrieves a specific transaction receipt from the database, along with
    88  // its added positional metadata.
    89  func ReadReceipt(db ethdb.Reader, hash common.Hash, config *params.ChainConfig) (*types.Receipt, common.Hash, uint64, uint64) {
    90  	// Retrieve the context of the receipt based on the transaction hash
    91  	blockHash := ReadTxLookupEntry(db, hash)
    92  	if blockHash == (common.Hash{}) {
    93  		return nil, common.Hash{}, 0, 0
    94  	}
    95  	blockNumber := ReadHeaderNumber(db, blockHash)
    96  	if blockNumber == nil {
    97  		return nil, common.Hash{}, 0, 0
    98  	}
    99  	// Read all the receipts from the block and return the one with the matching hash
   100  	receipts := ReadReceipts(db, blockHash, *blockNumber, config)
   101  	for receiptIndex, receipt := range receipts {
   102  		if receipt.TxHash == hash {
   103  			return receipt, blockHash, *blockNumber, uint64(receiptIndex)
   104  		}
   105  	}
   106  	log.Error("Receipt not found", "number", blockNumber, "hash", blockHash, "txhash", hash)
   107  	return nil, common.Hash{}, 0, 0
   108  }
   109  
   110  // ReadBloomBits retrieves the compressed bloom bit vector belonging to the given
   111  // section and bit index from the.
   112  func ReadBloomBits(db ethdb.Reader, bit uint, section uint64, head common.Hash) ([]byte, error) {
   113  	return db.Get(bloomBitsKey(bit, section, head))
   114  }
   115  
   116  // WriteBloomBits stores the compressed bloom bits vector belonging to the given
   117  // section and bit index.
   118  func WriteBloomBits(db ethdb.Writer, bit uint, section uint64, head common.Hash, bits []byte) {
   119  	if err := db.Put(bloomBitsKey(bit, section, head), bits); err != nil {
   120  		log.Crit("Failed to store bloom bits", "err", err)
   121  	}
   122  }