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 }