github.com/gochain-io/gochain@v2.2.26+incompatible/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  	"encoding/binary"
    21  
    22  	"github.com/gochain-io/gochain/common"
    23  	"github.com/gochain-io/gochain/core/types"
    24  	"github.com/gochain-io/gochain/log"
    25  	"github.com/gochain-io/gochain/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 DatabaseReader, hash common.Hash) (common.Hash, uint64, uint64) {
    31  	var data []byte
    32  	Must("get tx lookup entry", func() (err error) {
    33  		data, err = db.Get(hashKey(lookupPrefix, hash))
    34  		if err == common.ErrNotFound {
    35  			err = nil
    36  		}
    37  		return
    38  	})
    39  	if len(data) == 0 {
    40  		return common.Hash{}, 0, 0
    41  	}
    42  	var entry TxLookupEntry
    43  	if err := rlp.DecodeBytes(data, &entry); err != nil {
    44  		log.Error("Invalid transaction lookup entry RLP", "hash", hash, "err", err)
    45  		return common.Hash{}, 0, 0
    46  	}
    47  	return entry.BlockHash, entry.BlockIndex, entry.Index
    48  }
    49  
    50  // WriteTxLookupEntries stores a positional metadata for every transaction from
    51  // a block, enabling hash based transaction and receipt lookups.
    52  func WriteTxLookupEntries(db DatabaseWriter, block *types.Block) {
    53  	for i, tx := range block.Transactions() {
    54  		entry := TxLookupEntry{
    55  			BlockHash:  block.Hash(),
    56  			BlockIndex: block.NumberU64(),
    57  			Index:      uint64(i),
    58  		}
    59  		data, err := rlp.EncodeToBytes(entry)
    60  		if err != nil {
    61  			log.Crit("Failed to encode transaction lookup entry", "err", err)
    62  		}
    63  		Must("put tx lookup entry", func() (err error) {
    64  			return db.Put(hashKey(lookupPrefix, tx.Hash()), data)
    65  		})
    66  	}
    67  }
    68  
    69  // DeleteTxLookupEntry removes all transaction data associated with a hash.
    70  func DeleteTxLookupEntry(db DatabaseDeleter, hash common.Hash) {
    71  	Must("delete tx lookup entry", func() error {
    72  		return db.Delete(hashKey(lookupPrefix, hash))
    73  	})
    74  }
    75  
    76  // ReadTransaction retrieves a specific transaction from the database, along with
    77  // its added positional metadata.
    78  func ReadTransaction(db common.Database, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
    79  	blockHash, blockNumber, txIndex := ReadTxLookupEntry(db.GlobalTable(), hash)
    80  	if blockHash == (common.Hash{}) {
    81  		return nil, common.Hash{}, 0, 0
    82  	}
    83  	body := ReadBody(db.BodyTable(), blockHash, blockNumber)
    84  	if body == nil || len(body.Transactions) <= int(txIndex) {
    85  		log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash, "index", txIndex)
    86  		return nil, common.Hash{}, 0, 0
    87  	}
    88  	return body.Transactions[txIndex], blockHash, blockNumber, txIndex
    89  }
    90  
    91  // ReadReceipt retrieves a specific transaction receipt from the database, along with
    92  // its added positional metadata.
    93  func ReadReceipt(db common.Database, hash common.Hash) (*types.Receipt, common.Hash, uint64, uint64) {
    94  	blockHash, blockNumber, receiptIndex := ReadTxLookupEntry(db.GlobalTable(), hash)
    95  	if blockHash == (common.Hash{}) {
    96  		return nil, common.Hash{}, 0, 0
    97  	}
    98  	receipts := ReadReceipts(db.ReceiptTable(), blockHash, blockNumber)
    99  	if len(receipts) <= int(receiptIndex) {
   100  		log.Error("Receipt referenced missing", "number", blockNumber, "hash", blockHash, "index", receiptIndex)
   101  		return nil, common.Hash{}, 0, 0
   102  	}
   103  	return receipts[receiptIndex], blockHash, blockNumber, receiptIndex
   104  }
   105  
   106  // ReadBloomBits retrieves the compressed bloom bit vector belonging to the given
   107  // section and bit index from the.
   108  func ReadBloomBits(db DatabaseReader, bit uint, section uint64, head common.Hash) []byte {
   109  	var key [43]byte
   110  	key[0] = bloomBitsPrefix
   111  	binary.BigEndian.PutUint16(key[1:], uint16(bit))
   112  	binary.BigEndian.PutUint64(key[3:], section)
   113  	copy(key[11:], head[:])
   114  	var data []byte
   115  	Must("get bloom bits", func() (err error) {
   116  		data, err = db.Get(key[:])
   117  		if err == common.ErrNotFound {
   118  			err = nil
   119  		}
   120  		return
   121  	})
   122  	return data
   123  }
   124  
   125  // WriteBloomBits stores the compressed bloom bits vector belonging to the given
   126  // section and bit index.
   127  func WriteBloomBits(db DatabaseWriter, bit uint, section uint64, head common.Hash, bits []byte) {
   128  	var key [43]byte
   129  	key[0] = bloomBitsPrefix
   130  	binary.BigEndian.PutUint16(key[1:], uint16(bit))
   131  	binary.BigEndian.PutUint64(key[3:], section)
   132  	copy(key[11:], head[:])
   133  
   134  	Must("put bloom bits", func() error {
   135  		return db.Put(key[:], bits)
   136  	})
   137  }