mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
core/types: make receipt PostState optional
This commit is contained in:
parent
1f7e091b09
commit
f7212a43df
4 changed files with 36 additions and 21 deletions
|
|
@ -105,15 +105,15 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
|
||||||
|
|
||||||
// Update the state with pending changes
|
// Update the state with pending changes
|
||||||
usedGas.Add(usedGas, gas)
|
usedGas.Add(usedGas, gas)
|
||||||
var root common.Hash
|
var root []byte
|
||||||
if config.IsMetropolis(header.Number) {
|
if config.IsMetropolis(header.Number) {
|
||||||
statedb.Finalise()
|
statedb.Finalise()
|
||||||
} else {
|
} else {
|
||||||
root = statedb.IntermediateRoot(config.IsEIP158(header.Number))
|
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
|
||||||
}
|
}
|
||||||
// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
|
// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
|
||||||
// based on the eip phase, we're passing wether the root touch-delete accounts.
|
// based on the eip phase, we're passing wether the root touch-delete accounts.
|
||||||
receipt := types.NewReceipt(root.Bytes(), usedGas)
|
receipt := types.NewReceipt(root, usedGas)
|
||||||
receipt.TxHash = tx.Hash()
|
receipt.TxHash = tx.Hash()
|
||||||
receipt.GasUsed = new(big.Int).Set(gas)
|
receipt.GasUsed = new(big.Int).Set(gas)
|
||||||
// if the transaction created a contract, store the creation address in the receipt.
|
// if the transaction created a contract, store the creation address in the receipt.
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
func (r Receipt) MarshalJSON() ([]byte, error) {
|
func (r Receipt) MarshalJSON() ([]byte, error) {
|
||||||
type Receipt struct {
|
type Receipt struct {
|
||||||
PostState hexutil.Bytes `json:"root" gencodec:"required"`
|
PostState hexutil.Bytes `json:"root"`
|
||||||
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
|
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
|
||||||
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
||||||
Logs []*Log `json:"logs" gencodec:"required"`
|
Logs []*Log `json:"logs" gencodec:"required"`
|
||||||
|
|
@ -34,7 +34,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
|
||||||
|
|
||||||
func (r *Receipt) UnmarshalJSON(input []byte) error {
|
func (r *Receipt) UnmarshalJSON(input []byte) error {
|
||||||
type Receipt struct {
|
type Receipt struct {
|
||||||
PostState hexutil.Bytes `json:"root" gencodec:"required"`
|
PostState hexutil.Bytes `json:"root"`
|
||||||
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
|
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
|
||||||
Bloom *Bloom `json:"logsBloom" gencodec:"required"`
|
Bloom *Bloom `json:"logsBloom" gencodec:"required"`
|
||||||
Logs []*Log `json:"logs" gencodec:"required"`
|
Logs []*Log `json:"logs" gencodec:"required"`
|
||||||
|
|
@ -46,10 +46,9 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
|
||||||
if err := json.Unmarshal(input, &dec); err != nil {
|
if err := json.Unmarshal(input, &dec); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if dec.PostState == nil {
|
if dec.PostState != nil {
|
||||||
return errors.New("missing required field 'root' for Receipt")
|
r.PostState = dec.PostState
|
||||||
}
|
}
|
||||||
r.PostState = dec.PostState
|
|
||||||
if dec.CumulativeGasUsed == nil {
|
if dec.CumulativeGasUsed == nil {
|
||||||
return errors.New("missing required field 'cumulativeGasUsed' for Receipt")
|
return errors.New("missing required field 'cumulativeGasUsed' for Receipt")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import (
|
||||||
// Receipt represents the results of a transaction.
|
// Receipt represents the results of a transaction.
|
||||||
type Receipt struct {
|
type Receipt struct {
|
||||||
// Consensus fields
|
// Consensus fields
|
||||||
PostState []byte `json:"root" gencodec:"required"`
|
PostState []byte `json:"root"`
|
||||||
CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"`
|
CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"`
|
||||||
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
||||||
Logs []*Log `json:"logs" gencodec:"required"`
|
Logs []*Log `json:"logs" gencodec:"required"`
|
||||||
|
|
@ -48,6 +48,19 @@ type receiptMarshaling struct {
|
||||||
GasUsed *hexutil.Big
|
GasUsed *hexutil.Big
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type homesteadReceiptRLP struct {
|
||||||
|
PostState []byte
|
||||||
|
CumulativeGasUsed *big.Int
|
||||||
|
Bloom Bloom
|
||||||
|
Logs []*Log
|
||||||
|
}
|
||||||
|
|
||||||
|
type metropolisReceiptRLP struct {
|
||||||
|
CumulativeGasUsed *big.Int
|
||||||
|
Bloom Bloom
|
||||||
|
Logs []*Log
|
||||||
|
}
|
||||||
|
|
||||||
// NewReceipt creates a barebone transaction receipt, copying the init fields.
|
// NewReceipt creates a barebone transaction receipt, copying the init fields.
|
||||||
func NewReceipt(root []byte, cumulativeGasUsed *big.Int) *Receipt {
|
func NewReceipt(root []byte, cumulativeGasUsed *big.Int) *Receipt {
|
||||||
return &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)}
|
return &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)}
|
||||||
|
|
@ -56,23 +69,28 @@ func NewReceipt(root []byte, cumulativeGasUsed *big.Int) *Receipt {
|
||||||
// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt
|
// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt
|
||||||
// into an RLP stream.
|
// into an RLP stream.
|
||||||
func (r *Receipt) EncodeRLP(w io.Writer) error {
|
func (r *Receipt) EncodeRLP(w io.Writer) error {
|
||||||
return rlp.Encode(w, []interface{}{r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs})
|
if r.PostState == nil {
|
||||||
|
return rlp.Encode(w, &metropolisReceiptRLP{r.CumulativeGasUsed, r.Bloom, r.Logs})
|
||||||
|
} else {
|
||||||
|
return rlp.Encode(w, &homesteadReceiptRLP{r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt
|
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt
|
||||||
// from an RLP stream.
|
// from an RLP stream.
|
||||||
func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
|
func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
|
||||||
var receipt struct {
|
raw, err := s.Raw()
|
||||||
PostState []byte
|
if err != nil {
|
||||||
CumulativeGasUsed *big.Int
|
|
||||||
Bloom Bloom
|
|
||||||
Logs []*Log
|
|
||||||
}
|
|
||||||
if err := s.Decode(&receipt); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs = receipt.PostState, receipt.CumulativeGasUsed, receipt.Bloom, receipt.Logs
|
var hr homesteadReceiptRLP
|
||||||
return nil
|
var mr metropolisReceiptRLP
|
||||||
|
if err = rlp.DecodeBytes(raw, &mr); err == nil {
|
||||||
|
r.CumulativeGasUsed, r.Bloom, r.Logs = mr.CumulativeGasUsed, mr.Bloom, mr.Logs
|
||||||
|
} else if err = rlp.DecodeBytes(raw, &hr); err == nil {
|
||||||
|
r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs = hr.PostState[:], hr.CumulativeGasUsed, hr.Bloom, hr.Logs
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the Stringer interface.
|
// String implements the Stringer interface.
|
||||||
|
|
|
||||||
|
|
@ -203,8 +203,6 @@ func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil, ethereum.NotFound
|
return nil, ethereum.NotFound
|
||||||
} else if len(r.PostState) == 0 {
|
|
||||||
return nil, fmt.Errorf("server returned receipt without post state")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r, err
|
return r, err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue