aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJeffrey Wilcke <geffobscura@gmail.com>2015-07-04 08:25:04 +0800
committerJeffrey Wilcke <geffobscura@gmail.com>2015-07-04 08:32:10 +0800
commit2feb23c1dacf1cc7ef664d92f28b63dd46502f21 (patch)
tree5532c0a82ae0d39104977f5bc022e024de3043be /core
parentacd85fe95f025384885ed09560e32b227d80b26f (diff)
downloadgo-tangerine-2feb23c1dacf1cc7ef664d92f28b63dd46502f21.tar
go-tangerine-2feb23c1dacf1cc7ef664d92f28b63dd46502f21.tar.gz
go-tangerine-2feb23c1dacf1cc7ef664d92f28b63dd46502f21.tar.bz2
go-tangerine-2feb23c1dacf1cc7ef664d92f28b63dd46502f21.tar.lz
go-tangerine-2feb23c1dacf1cc7ef664d92f28b63dd46502f21.tar.xz
go-tangerine-2feb23c1dacf1cc7ef664d92f28b63dd46502f21.tar.zst
go-tangerine-2feb23c1dacf1cc7ef664d92f28b63dd46502f21.zip
core, eth, miner, xeth: receipt storage fix
* Added GetReceiptsFromBlock, GetReceipt, PutReceipts * Added ContractAddress to receipt. See #1042
Diffstat (limited to 'core')
-rw-r--r--core/block_processor.go34
-rw-r--r--core/block_processor_test.go11
-rw-r--r--core/chain_manager.go2
-rw-r--r--core/transaction_util.go50
-rw-r--r--core/types/receipt.go8
5 files changed, 68 insertions, 37 deletions
diff --git a/core/block_processor.go b/core/block_processor.go
index 7171e3b2e..e8014ec22 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -9,12 +9,12 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/pow"
- "github.com/ethereum/go-ethereum/rlp"
"gopkg.in/fatih/set.v0"
)
@@ -24,8 +24,6 @@ const (
BlockChainVersion = 3
)
-var receiptsPre = []byte("receipts-")
-
type BlockProcessor struct {
db common.Database
extraDb common.Database
@@ -83,6 +81,12 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated
usedGas.Add(usedGas, gas)
receipt := types.NewReceipt(statedb.Root().Bytes(), usedGas)
+ receipt.TxHash = tx.Hash()
+ if MessageCreatesContract(tx) {
+ from, _ := tx.From()
+ receipt.ContractAddress = crypto.CreateAddress(from, tx.Nonce())
+ }
+
logs := statedb.GetLogs(tx.Hash())
receipt.SetLogs(logs)
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
@@ -319,16 +323,20 @@ func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *ty
}
// GetBlockReceipts returns the receipts beloniging to the block hash
-func (sm *BlockProcessor) GetBlockReceipts(bhash common.Hash) (receipts types.Receipts, err error) {
- return getBlockReceipts(sm.extraDb, bhash)
+func (sm *BlockProcessor) GetBlockReceipts(bhash common.Hash) types.Receipts {
+ if block := sm.ChainManager().GetBlock(bhash); block != nil {
+ return GetReceiptsFromBlock(sm.extraDb, block)
+ }
+
+ return nil
}
// GetLogs returns the logs of the given block. This method is using a two step approach
// where it tries to get it from the (updated) method which gets them from the receipts or
// the depricated way by re-processing the block.
func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) {
- receipts, err := sm.GetBlockReceipts(block.Hash())
- if err == nil && len(receipts) > 0 {
+ receipts := GetReceiptsFromBlock(sm.extraDb, block)
+ if len(receipts) > 0 {
// coalesce logs
for _, receipt := range receipts {
logs = append(logs, receipt.Logs()...)
@@ -391,15 +399,3 @@ func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, check
return nil
}
-
-func getBlockReceipts(db common.Database, bhash common.Hash) (receipts types.Receipts, err error) {
- var rdata []byte
- rdata, err = db.Get(append(receiptsPre, bhash[:]...))
-
- if err == nil {
- err = rlp.DecodeBytes(rdata, &receipts)
- } else {
- glog.V(logger.Detail).Infof("getBlockReceipts error %v\n", err)
- }
- return
-}
diff --git a/core/block_processor_test.go b/core/block_processor_test.go
index 99681dabf..8c38d531f 100644
--- a/core/block_processor_test.go
+++ b/core/block_processor_test.go
@@ -64,12 +64,9 @@ func TestPutReceipt(t *testing.T) {
Index: 0,
}})
- PutReceipts(db, hash, types.Receipts{receipt})
- receipts, err := getBlockReceipts(db, hash)
- if err != nil {
- t.Error("got err:", err)
- }
- if len(receipts) != 1 {
- t.Error("expected to get 1 receipt, got", len(receipts))
+ PutReceipts(db, types.Receipts{receipt})
+ receipt = GetReceipt(db, common.Hash{})
+ if receipt == nil {
+ t.Error("expected to get 1 receipt, got none.")
}
}
diff --git a/core/chain_manager.go b/core/chain_manager.go
index b5381e336..4855162b5 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -632,7 +632,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
// This puts transactions in a extra db for rpc
PutTransactions(self.extraDb, block, block.Transactions())
// store the receipts
- PutReceipts(self.extraDb, block.Hash(), receipts)
+ PutReceipts(self.extraDb, receipts)
case SideStatTy:
if glog.V(logger.Detail) {
glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart))
diff --git a/core/transaction_util.go b/core/transaction_util.go
index bbb215d91..cb5d6c7f7 100644
--- a/core/transaction_util.go
+++ b/core/transaction_util.go
@@ -8,6 +8,9 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
+var receiptsPre = []byte("receipts-")
+
+// PutTransactions stores the transactions in the given database
func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) {
for i, tx := range block.Transactions() {
rlpEnc, err := rlp.EncodeToBytes(tx)
@@ -34,18 +37,49 @@ func PutTransactions(db common.Database, block *types.Block, txs types.Transacti
}
}
-func PutReceipts(db common.Database, hash common.Hash, receipts types.Receipts) error {
- storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
- for i, receipt := range receipts {
- storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
+// PutReceipts stores the receipts in the current database
+func PutReceipts(db common.Database, receipts types.Receipts) error {
+ 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 {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// GetReceipt returns a receipt by hash
+func GetReceipt(db common.Database, txHash common.Hash) *types.Receipt {
+ data, _ := db.Get(append(receiptsPre, txHash[:]...))
+ if len(data) == 0 {
+ return nil
}
- bytes, err := rlp.EncodeToBytes(storageReceipts)
+ var receipt types.Receipt
+ err := rlp.DecodeBytes(data, &receipt)
if err != nil {
- return err
+ glog.V(logger.Error).Infoln("GetReceipt err:", err)
}
+ return &receipt
+}
- db.Put(append(receiptsPre, hash[:]...), bytes)
+// 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)
+ }
+ }
- return nil
+ return receipts
}
diff --git a/core/types/receipt.go b/core/types/receipt.go
index 6b4024ada..ab52c6e60 100644
--- a/core/types/receipt.go
+++ b/core/types/receipt.go
@@ -15,6 +15,8 @@ type Receipt struct {
PostState []byte
CumulativeGasUsed *big.Int
Bloom Bloom
+ TxHash common.Hash
+ ContractAddress common.Address
logs state.Logs
}
@@ -39,12 +41,14 @@ func (self *Receipt) DecodeRLP(s *rlp.Stream) error {
PostState []byte
CumulativeGasUsed *big.Int
Bloom Bloom
+ TxHash common.Hash
+ ContractAddress common.Address
Logs state.Logs
}
if err := s.Decode(&r); err != nil {
return err
}
- self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs = r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs
+ self.PostState, self.CumulativeGasUsed, self.Bloom, self.TxHash, self.ContractAddress, self.logs = r.PostState, r.CumulativeGasUsed, r.Bloom, r.TxHash, r.ContractAddress, r.Logs
return nil
}
@@ -56,7 +60,7 @@ func (self *ReceiptForStorage) EncodeRLP(w io.Writer) error {
for i, log := range self.logs {
storageLogs[i] = (*state.LogForStorage)(log)
}
- return rlp.Encode(w, []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, storageLogs})
+ return rlp.Encode(w, []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.TxHash, self.ContractAddress, storageLogs})
}
func (self *Receipt) RlpEncode() []byte {