github.com/immesys/bw2bc@v1.1.0/core/transaction_util.go (about)

     1  // Copyright 2015 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 core
    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/logger"
    24  	"github.com/ethereum/go-ethereum/logger/glog"
    25  	"github.com/ethereum/go-ethereum/rlp"
    26  	"github.com/syndtr/goleveldb/leveldb"
    27  )
    28  
    29  var (
    30  	receiptsPre      = []byte("receipts-")
    31  	blockReceiptsPre = []byte("receipts-block-")
    32  )
    33  
    34  // PutTransactions stores the transactions in the given database
    35  func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) {
    36  	batch := new(leveldb.Batch)
    37  	_, batchWrite := db.(*ethdb.LDBDatabase)
    38  
    39  	for i, tx := range block.Transactions() {
    40  		rlpEnc, err := rlp.EncodeToBytes(tx)
    41  		if err != nil {
    42  			glog.V(logger.Debug).Infoln("Failed encoding tx", err)
    43  			return
    44  		}
    45  
    46  		if batchWrite {
    47  			batch.Put(tx.Hash().Bytes(), rlpEnc)
    48  		} else {
    49  			db.Put(tx.Hash().Bytes(), rlpEnc)
    50  		}
    51  
    52  		var txExtra struct {
    53  			BlockHash  common.Hash
    54  			BlockIndex uint64
    55  			Index      uint64
    56  		}
    57  		txExtra.BlockHash = block.Hash()
    58  		txExtra.BlockIndex = block.NumberU64()
    59  		txExtra.Index = uint64(i)
    60  		rlpMeta, err := rlp.EncodeToBytes(txExtra)
    61  		if err != nil {
    62  			glog.V(logger.Debug).Infoln("Failed encoding tx meta data", err)
    63  			return
    64  		}
    65  
    66  		if batchWrite {
    67  			batch.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta)
    68  		} else {
    69  			db.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta)
    70  		}
    71  	}
    72  
    73  	if db, ok := db.(*ethdb.LDBDatabase); ok {
    74  		if err := db.LDB().Write(batch, nil); err != nil {
    75  			glog.V(logger.Error).Infoln("db write err:", err)
    76  		}
    77  	}
    78  }
    79  
    80  // PutReceipts stores the receipts in the current database
    81  func PutReceipts(db common.Database, receipts types.Receipts) error {
    82  	batch := new(leveldb.Batch)
    83  	_, batchWrite := db.(*ethdb.LDBDatabase)
    84  
    85  	for _, receipt := range receipts {
    86  		storageReceipt := (*types.ReceiptForStorage)(receipt)
    87  		bytes, err := rlp.EncodeToBytes(storageReceipt)
    88  		if err != nil {
    89  			return err
    90  		}
    91  
    92  		if batchWrite {
    93  			batch.Put(append(receiptsPre, receipt.TxHash[:]...), bytes)
    94  		} else {
    95  			err = db.Put(append(receiptsPre, receipt.TxHash[:]...), bytes)
    96  			if err != nil {
    97  				return err
    98  			}
    99  		}
   100  	}
   101  	if db, ok := db.(*ethdb.LDBDatabase); ok {
   102  		if err := db.LDB().Write(batch, nil); err != nil {
   103  			return err
   104  		}
   105  	}
   106  
   107  	return nil
   108  }
   109  
   110  // GetReceipt returns a receipt by hash
   111  func GetReceipt(db common.Database, txHash common.Hash) *types.Receipt {
   112  	data, _ := db.Get(append(receiptsPre, txHash[:]...))
   113  	if len(data) == 0 {
   114  		return nil
   115  	}
   116  
   117  	var receipt types.Receipt
   118  	err := rlp.DecodeBytes(data, &receipt)
   119  	if err != nil {
   120  		glog.V(logger.Core).Infoln("GetReceipt err:", err)
   121  	}
   122  	return &receipt
   123  }
   124  
   125  // GetBlockReceipts returns the receipts generated by the transactions
   126  // included in block's given hash.
   127  func GetBlockReceipts(db common.Database, hash common.Hash) types.Receipts {
   128  	data, _ := db.Get(append(blockReceiptsPre, hash[:]...))
   129  	if len(data) == 0 {
   130  		return nil
   131  	}
   132  
   133  	var receipts types.Receipts
   134  	err := rlp.DecodeBytes(data, &receipts)
   135  	if err != nil {
   136  		glog.V(logger.Core).Infoln("GetReceiptse err", err)
   137  	}
   138  	return receipts
   139  }
   140  
   141  // PutBlockReceipts stores the block's transactions associated receipts
   142  // and stores them by block hash in a single slice. This is required for
   143  // forks and chain reorgs
   144  func PutBlockReceipts(db common.Database, block *types.Block, receipts types.Receipts) error {
   145  	rs := make([]*types.ReceiptForStorage, len(receipts))
   146  	for i, receipt := range receipts {
   147  		rs[i] = (*types.ReceiptForStorage)(receipt)
   148  	}
   149  	bytes, err := rlp.EncodeToBytes(rs)
   150  	if err != nil {
   151  		return err
   152  	}
   153  
   154  	hash := block.Hash()
   155  	err = db.Put(append(blockReceiptsPre, hash[:]...), bytes)
   156  	if err != nil {
   157  		return err
   158  	}
   159  
   160  	return nil
   161  }