github.com/theQRL/go-zond@v0.2.1/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  	"bytes"
    21  	"math/big"
    22  
    23  	"github.com/theQRL/go-zond/common"
    24  	"github.com/theQRL/go-zond/core/types"
    25  	"github.com/theQRL/go-zond/log"
    26  	"github.com/theQRL/go-zond/params"
    27  	"github.com/theQRL/go-zond/zonddb"
    28  )
    29  
    30  // ReadTxLookupEntry retrieves the positional metadata associated with a transaction
    31  // hash to allow retrieving the transaction or receipt by hash.
    32  func ReadTxLookupEntry(db zonddb.Reader, hash common.Hash) *uint64 {
    33  	data, _ := db.Get(txLookupKey(hash))
    34  	if len(data) == 0 {
    35  		return nil
    36  	}
    37  
    38  	number := new(big.Int).SetBytes(data).Uint64()
    39  	return &number
    40  }
    41  
    42  // writeTxLookupEntry stores a positional metadata for a transaction,
    43  // enabling hash based transaction and receipt lookups.
    44  func writeTxLookupEntry(db zonddb.KeyValueWriter, hash common.Hash, numberBytes []byte) {
    45  	if err := db.Put(txLookupKey(hash), numberBytes); err != nil {
    46  		log.Crit("Failed to store transaction lookup entry", "err", err)
    47  	}
    48  }
    49  
    50  // WriteTxLookupEntries is identical to WriteTxLookupEntry, but it works on
    51  // a list of hashes
    52  func WriteTxLookupEntries(db zonddb.KeyValueWriter, number uint64, hashes []common.Hash) {
    53  	numberBytes := new(big.Int).SetUint64(number).Bytes()
    54  	for _, hash := range hashes {
    55  		writeTxLookupEntry(db, hash, numberBytes)
    56  	}
    57  }
    58  
    59  // WriteTxLookupEntriesByBlock stores a positional metadata for every transaction from
    60  // a block, enabling hash based transaction and receipt lookups.
    61  func WriteTxLookupEntriesByBlock(db zonddb.KeyValueWriter, block *types.Block) {
    62  	numberBytes := block.Number().Bytes()
    63  	for _, tx := range block.Transactions() {
    64  		writeTxLookupEntry(db, tx.Hash(), numberBytes)
    65  	}
    66  }
    67  
    68  // DeleteTxLookupEntry removes all transaction data associated with a hash.
    69  func DeleteTxLookupEntry(db zonddb.KeyValueWriter, hash common.Hash) {
    70  	if err := db.Delete(txLookupKey(hash)); err != nil {
    71  		log.Crit("Failed to delete transaction lookup entry", "err", err)
    72  	}
    73  }
    74  
    75  // DeleteTxLookupEntries removes all transaction lookups for a given block.
    76  func DeleteTxLookupEntries(db zonddb.KeyValueWriter, hashes []common.Hash) {
    77  	for _, hash := range hashes {
    78  		DeleteTxLookupEntry(db, hash)
    79  	}
    80  }
    81  
    82  // ReadTransaction retrieves a specific transaction from the database, along with
    83  // its added positional metadata.
    84  func ReadTransaction(db zonddb.Reader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
    85  	blockNumber := ReadTxLookupEntry(db, hash)
    86  	if blockNumber == nil {
    87  		return nil, common.Hash{}, 0, 0
    88  	}
    89  	blockHash := ReadCanonicalHash(db, *blockNumber)
    90  	if blockHash == (common.Hash{}) {
    91  		return nil, common.Hash{}, 0, 0
    92  	}
    93  	body := ReadBody(db, blockHash, *blockNumber)
    94  	if body == nil {
    95  		log.Error("Transaction referenced missing", "number", *blockNumber, "hash", blockHash)
    96  		return nil, common.Hash{}, 0, 0
    97  	}
    98  	for txIndex, tx := range body.Transactions {
    99  		if tx.Hash() == hash {
   100  			return tx, blockHash, *blockNumber, uint64(txIndex)
   101  		}
   102  	}
   103  	log.Error("Transaction not found", "number", *blockNumber, "hash", blockHash, "txhash", hash)
   104  	return nil, common.Hash{}, 0, 0
   105  }
   106  
   107  // ReadReceipt retrieves a specific transaction receipt from the database, along with
   108  // its added positional metadata.
   109  func ReadReceipt(db zonddb.Reader, hash common.Hash, config *params.ChainConfig) (*types.Receipt, common.Hash, uint64, uint64) {
   110  	// Retrieve the context of the receipt based on the transaction hash
   111  	blockNumber := ReadTxLookupEntry(db, hash)
   112  	if blockNumber == nil {
   113  		return nil, common.Hash{}, 0, 0
   114  	}
   115  	blockHash := ReadCanonicalHash(db, *blockNumber)
   116  	if blockHash == (common.Hash{}) {
   117  		return nil, common.Hash{}, 0, 0
   118  	}
   119  	blockHeader := ReadHeader(db, blockHash, *blockNumber)
   120  	if blockHeader == nil {
   121  		return nil, common.Hash{}, 0, 0
   122  	}
   123  	// Read all the receipts from the block and return the one with the matching hash
   124  	receipts := ReadReceipts(db, blockHash, *blockNumber, blockHeader.Time, config)
   125  	for receiptIndex, receipt := range receipts {
   126  		if receipt.TxHash == hash {
   127  			return receipt, blockHash, *blockNumber, uint64(receiptIndex)
   128  		}
   129  	}
   130  	log.Error("Receipt not found", "number", *blockNumber, "hash", blockHash, "txhash", hash)
   131  	return nil, common.Hash{}, 0, 0
   132  }
   133  
   134  // ReadBloomBits retrieves the compressed bloom bit vector belonging to the given
   135  // section and bit index from the.
   136  func ReadBloomBits(db zonddb.KeyValueReader, bit uint, section uint64, head common.Hash) ([]byte, error) {
   137  	return db.Get(bloomBitsKey(bit, section, head))
   138  }
   139  
   140  // WriteBloomBits stores the compressed bloom bits vector belonging to the given
   141  // section and bit index.
   142  func WriteBloomBits(db zonddb.KeyValueWriter, bit uint, section uint64, head common.Hash, bits []byte) {
   143  	if err := db.Put(bloomBitsKey(bit, section, head), bits); err != nil {
   144  		log.Crit("Failed to store bloom bits", "err", err)
   145  	}
   146  }
   147  
   148  // DeleteBloombits removes all compressed bloom bits vector belonging to the
   149  // given section range and bit index.
   150  func DeleteBloombits(db zonddb.Database, bit uint, from uint64, to uint64) {
   151  	start, end := bloomBitsKey(bit, from, common.Hash{}), bloomBitsKey(bit, to, common.Hash{})
   152  	it := db.NewIterator(nil, start)
   153  	defer it.Release()
   154  
   155  	for it.Next() {
   156  		if bytes.Compare(it.Key(), end) >= 0 {
   157  			break
   158  		}
   159  		if len(it.Key()) != len(bloomBitsPrefix)+2+8+32 {
   160  			continue
   161  		}
   162  		db.Delete(it.Key())
   163  	}
   164  	if it.Error() != nil {
   165  		log.Crit("Failed to delete bloom bits", "err", it.Error())
   166  	}
   167  }