diff options
Diffstat (limited to 'core/transaction_util.go')
-rw-r--r-- | core/transaction_util.go | 100 |
1 files changed, 80 insertions, 20 deletions
diff --git a/core/transaction_util.go b/core/transaction_util.go index 0efeddfde..ce2ceac46 100644 --- a/core/transaction_util.go +++ b/core/transaction_util.go @@ -1,40 +1,53 @@ // Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify +// The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. package core import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/rlp" + "github.com/syndtr/goleveldb/leveldb" ) -var receiptsPre = []byte("receipts-") +var ( + receiptsPre = []byte("receipts-") + blockReceiptsPre = []byte("receipts-block-") +) // PutTransactions stores the transactions in the given database func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) { + batch := new(leveldb.Batch) + _, batchWrite := db.(*ethdb.LDBDatabase) + for i, tx := range block.Transactions() { rlpEnc, err := rlp.EncodeToBytes(tx) if err != nil { glog.V(logger.Debug).Infoln("Failed encoding tx", err) return } - db.Put(tx.Hash().Bytes(), rlpEnc) + + if batchWrite { + batch.Put(tx.Hash().Bytes(), rlpEnc) + } else { + db.Put(tx.Hash().Bytes(), rlpEnc) + } var txExtra struct { BlockHash common.Hash @@ -49,20 +62,44 @@ func PutTransactions(db common.Database, block *types.Block, txs types.Transacti glog.V(logger.Debug).Infoln("Failed encoding tx meta data", err) return } - db.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta) + + if batchWrite { + batch.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta) + } else { + db.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta) + } + } + + if db, ok := db.(*ethdb.LDBDatabase); ok { + if err := db.LDB().Write(batch, nil); err != nil { + glog.V(logger.Error).Infoln("db write err:", err) + } } } // PutReceipts stores the receipts in the current database func PutReceipts(db common.Database, receipts types.Receipts) error { + batch := new(leveldb.Batch) + _, batchWrite := db.(*ethdb.LDBDatabase) + for _, receipt := range receipts { storageReceipt := (*types.ReceiptForStorage)(receipt) bytes, err := rlp.EncodeToBytes(storageReceipt) if err != nil { return err } - err = db.Put(append(receiptsPre, receipt.TxHash[:]...), bytes) - if err != nil { + + if batchWrite { + batch.Put(append(receiptsPre, receipt.TxHash[:]...), bytes) + } else { + err = db.Put(append(receiptsPre, receipt.TxHash[:]...), bytes) + if err != nil { + return err + } + } + } + if db, ok := db.(*ethdb.LDBDatabase); ok { + if err := db.LDB().Write(batch, nil); err != nil { return err } } @@ -85,17 +122,40 @@ func GetReceipt(db common.Database, txHash common.Hash) *types.Receipt { return &receipt } -// GetReceiptFromBlock returns all receipts with the given block -func GetReceiptsFromBlock(db common.Database, block *types.Block) types.Receipts { - // at some point we want: - //receipts := make(types.Receipts, len(block.Transactions())) - // but since we need to support legacy, we can't (yet) - var receipts types.Receipts - for _, tx := range block.Transactions() { - if receipt := GetReceipt(db, tx.Hash()); receipt != nil { - receipts = append(receipts, receipt) - } +// GetBlockReceipts returns the receipts generated by the transactions +// included in block's given hash. +func GetBlockReceipts(db common.Database, hash common.Hash) types.Receipts { + data, _ := db.Get(append(blockReceiptsPre, hash[:]...)) + if len(data) == 0 { + return nil } + var receipts types.Receipts + err := rlp.DecodeBytes(data, &receipts) + if err != nil { + glog.V(logger.Core).Infoln("GetReceiptse err", err) + } return receipts } + +// PutBlockReceipts stores the block's transactions associated receipts +// and stores them by block hash in a single slice. This is required for +// forks and chain reorgs +func PutBlockReceipts(db common.Database, block *types.Block, receipts types.Receipts) error { + rs := make([]*types.ReceiptForStorage, len(receipts)) + for i, receipt := range receipts { + rs[i] = (*types.ReceiptForStorage)(receipt) + } + bytes, err := rlp.EncodeToBytes(rs) + if err != nil { + return err + } + + hash := block.Hash() + err = db.Put(append(blockReceiptsPre, hash[:]...), bytes) + if err != nil { + return err + } + + return nil +} |