-
Notifications
You must be signed in to change notification settings - Fork 20.9k
core: differentiate receipt concensus and storage decoding #1857
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -150,11 +150,14 @@ func GetBlockReceipts(db ethdb.Database, hash common.Hash) types.Receipts { | |
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) | ||
rs := []*types.ReceiptForStorage{} | ||
if err := rlp.DecodeBytes(data, &rs); err != nil { | ||
glog.V(logger.Error).Infof("invalid receipt array RLP for hash %x: %v", hash, err) | ||
return nil | ||
} | ||
receipts := make(types.Receipts, len(rs)) | ||
for i, receipt := range rs { | ||
receipts[i] = (*types.Receipt)(receipt) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. last parentheses can be skipped? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No (otherwise gofmt would have stripped it). The syntax is |
||
} | ||
return receipts | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,6 @@ | |
package types | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"math/big" | ||
|
@@ -27,89 +26,116 @@ import ( | |
"github.com/ethereum/go-ethereum/rlp" | ||
) | ||
|
||
// Receipt represents the results of a transaction. | ||
type Receipt struct { | ||
// Consensus fields | ||
PostState []byte | ||
CumulativeGasUsed *big.Int | ||
Bloom Bloom | ||
TxHash common.Hash | ||
ContractAddress common.Address | ||
logs state.Logs | ||
GasUsed *big.Int | ||
Logs state.Logs | ||
|
||
// Implementation fields | ||
TxHash common.Hash | ||
ContractAddress common.Address | ||
GasUsed *big.Int | ||
} | ||
|
||
// NewReceipt creates a barebone transaction receipt, copying the init fields. | ||
func NewReceipt(root []byte, cumalativeGasUsed *big.Int) *Receipt { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cumulativeGasUsed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not my typo, but will correct in a follow up PR that does a few more changes all over core :) |
||
return &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumalativeGasUsed)} | ||
} | ||
|
||
func (self *Receipt) SetLogs(logs state.Logs) { | ||
self.logs = logs | ||
} | ||
|
||
func (self *Receipt) Logs() state.Logs { | ||
return self.logs | ||
} | ||
|
||
func (self *Receipt) EncodeRLP(w io.Writer) error { | ||
return rlp.Encode(w, []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs}) | ||
// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt | ||
// into an RLP stream. | ||
func (r *Receipt) EncodeRLP(w io.Writer) error { | ||
return rlp.Encode(w, []interface{}{r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs}) | ||
} | ||
|
||
func (self *Receipt) DecodeRLP(s *rlp.Stream) error { | ||
var r struct { | ||
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt | ||
// from an RLP stream. | ||
func (r *Receipt) DecodeRLP(s *rlp.Stream) error { | ||
var receipt struct { | ||
PostState []byte | ||
CumulativeGasUsed *big.Int | ||
Bloom Bloom | ||
TxHash common.Hash | ||
ContractAddress common.Address | ||
Logs state.Logs | ||
GasUsed *big.Int | ||
} | ||
if err := s.Decode(&r); err != nil { | ||
if err := s.Decode(&receipt); err != nil { | ||
return err | ||
} | ||
self.PostState, self.CumulativeGasUsed, self.Bloom, self.TxHash, self.ContractAddress, self.logs, self.GasUsed = r.PostState, r.CumulativeGasUsed, r.Bloom, r.TxHash, r.ContractAddress, r.Logs, r.GasUsed | ||
|
||
r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs = receipt.PostState, receipt.CumulativeGasUsed, receipt.Bloom, receipt.Logs | ||
return nil | ||
} | ||
|
||
type ReceiptForStorage Receipt | ||
|
||
func (self *ReceiptForStorage) EncodeRLP(w io.Writer) error { | ||
storageLogs := make([]*state.LogForStorage, len(self.logs)) | ||
for i, log := range self.logs { | ||
storageLogs[i] = (*state.LogForStorage)(log) | ||
} | ||
return rlp.Encode(w, []interface{}{self.PostState, self.CumulativeGasUsed, self.Bloom, self.TxHash, self.ContractAddress, storageLogs, self.GasUsed}) | ||
} | ||
|
||
func (self *Receipt) RlpEncode() []byte { | ||
bytes, err := rlp.EncodeToBytes(self) | ||
// RlpEncode implements common.RlpEncode required for SHA derivation. | ||
func (r *Receipt) RlpEncode() []byte { | ||
bytes, err := rlp.EncodeToBytes(r) | ||
if err != nil { | ||
fmt.Println("TMP -- RECEIPT ENCODE ERROR", err) | ||
panic(err) | ||
} | ||
return bytes | ||
} | ||
|
||
func (self *Receipt) Cmp(other *Receipt) bool { | ||
if bytes.Compare(self.PostState, other.PostState) != 0 { | ||
return false | ||
} | ||
// String implements the Stringer interface. | ||
func (r *Receipt) String() string { | ||
return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, I just reorganized the code, didn't touch the implementation. Don't really want to fix it here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's reorganised that's refactoring, no? In which case it would be nice to change things like these. Otherwise why was the function moved at all? |
||
} | ||
|
||
return true | ||
// ReceiptForStorage is a wrapper around a Receipt that flattens and parses the | ||
// entire content of a receipt, opposed to only the consensus fields originally. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
type ReceiptForStorage Receipt | ||
|
||
// EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt | ||
// into an RLP stream. | ||
func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { | ||
logs := make([]*state.LogForStorage, len(r.Logs)) | ||
for i, log := range r.Logs { | ||
logs[i] = (*state.LogForStorage)(log) | ||
} | ||
return rlp.Encode(w, []interface{}{r.PostState, r.CumulativeGasUsed, r.Bloom, r.TxHash, r.ContractAddress, logs, r.GasUsed}) | ||
} | ||
|
||
func (self *Receipt) String() string { | ||
return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", self.PostState, self.CumulativeGasUsed, self.Bloom, self.logs) | ||
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt | ||
// from an RLP stream. | ||
func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { | ||
var receipt struct { | ||
PostState []byte | ||
CumulativeGasUsed *big.Int | ||
Bloom Bloom | ||
TxHash common.Hash | ||
ContractAddress common.Address | ||
Logs []*state.LogForStorage | ||
GasUsed *big.Int | ||
} | ||
if err := s.Decode(&receipt); err != nil { | ||
return err | ||
} | ||
// Assign the consensus fields | ||
r.PostState, r.CumulativeGasUsed, r.Bloom = receipt.PostState, receipt.CumulativeGasUsed, receipt.Bloom | ||
r.Logs = make(state.Logs, len(receipt.Logs)) | ||
for i, log := range receipt.Logs { | ||
r.Logs[i] = (*state.Log)(log) | ||
} | ||
// Assign the implementation fields | ||
r.TxHash, r.ContractAddress, r.GasUsed = receipt.TxHash, receipt.ContractAddress, receipt.GasUsed | ||
|
||
return nil | ||
} | ||
|
||
// Receipts is a wrapper around a Receipt array to implement types.DerivableList. | ||
type Receipts []*Receipt | ||
|
||
func (self Receipts) RlpEncode() []byte { | ||
bytes, err := rlp.EncodeToBytes(self) | ||
// RlpEncode implements common.RlpEncode required for SHA derivation. | ||
func (r Receipts) RlpEncode() []byte { | ||
bytes, err := rlp.EncodeToBytes(r) | ||
if err != nil { | ||
fmt.Println("TMP -- RECEIPTS ENCODE ERROR", err) | ||
panic(err) | ||
} | ||
return bytes | ||
} | ||
|
||
func (self Receipts) Len() int { return len(self) } | ||
func (self Receipts) GetRlp(i int) []byte { return common.Rlp(self[i]) } | ||
// Len returns the number of receipts in this list. | ||
func (r Receipts) Len() int { return len(r) } | ||
|
||
// GetRlp returns the RLP encoding of one receipt from the list. | ||
func (r Receipts) GetRlp(i int) []byte { return common.Rlp(r[i]) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably be
as opposed to