Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Effective gas price #4759

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ install:
# /home/travis/gopath/src/github.com/harmony-one/harmony
# https://docs.travis-ci.com/user/languages/go/#go-import-path
- echo $TRAVIS_PULL_REQUEST_BRANCH
- TEST_REPO_BRANCH="master"
- TEST_REPO_BRANCH="feature/effective-gas-price"
- git clone https://github.com/harmony-one/mcl.git $GOPATH/src/github.com/harmony-one/mcl
- git clone https://github.com/harmony-one/bls.git $GOPATH/src/github.com/harmony-one/bls
- git clone --branch $TEST_REPO_BRANCH https://github.com/harmony-one/harmony-test.git $GOPATH/src/github.com/harmony-one/harmony-test
Expand Down
1 change: 1 addition & 0 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ func ApplyTransaction(bc ChainContext, author *common.Address, gp *GasPool, stat
receipt := types.NewReceipt(root, failedExe, *usedGas)
receipt.TxHash = tx.Hash()
receipt.GasUsed = result.UsedGas
receipt.EffectiveGasPrice = tx.EffectiveGasPrice(big.NewInt(0), nil)
// if the transaction created a contract, store the creation address in the receipt.
if msg.To() == nil {
receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
Expand Down
11 changes: 8 additions & 3 deletions core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"fmt"
"io"
"math/big"
"unsafe"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -54,9 +55,10 @@ type Receipt struct {
Logs []*Log `json:"logs" gencodec:"required"`

// Implementation fields (don't reorder!)
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
ContractAddress common.Address `json:"contractAddress"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
ContractAddress common.Address `json:"contractAddress"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
EffectiveGasPrice *big.Int `json:"effectiveGasPrice"` // required, but tag omitted for backwards compatibility
}

type receiptMarshaling struct {
Expand All @@ -82,6 +84,7 @@ type receiptStorageRLP struct {
ContractAddress common.Address
Logs []*LogForStorage
GasUsed uint64
EffectiveGasPrice *big.Int `rlp:"optional"`
}

// NewReceipt creates a barebone transaction receipt, copying the init fields.
Expand Down Expand Up @@ -166,6 +169,7 @@ func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error {
ContractAddress: r.ContractAddress,
Logs: make([]*LogForStorage, len(r.Logs)),
GasUsed: r.GasUsed,
EffectiveGasPrice: r.EffectiveGasPrice,
}
for i, log := range r.Logs {
enc.Logs[i] = (*LogForStorage)(log)
Expand All @@ -191,6 +195,7 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error {
}
// Assign the implementation fields
r.TxHash, r.ContractAddress, r.GasUsed = dec.TxHash, dec.ContractAddress, dec.GasUsed
r.EffectiveGasPrice = dec.EffectiveGasPrice
return nil
}

Expand Down
68 changes: 67 additions & 1 deletion core/types/receipt_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package types

import (
"math/big"
"reflect"
"testing"

ethcommon "github.com/ethereum/go-ethereum/common"

"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/staking"
"github.com/stretchr/testify/require"
)

func TestFindLogsWithTopic(t *testing.T) {
Expand Down Expand Up @@ -112,3 +114,67 @@ func TestFindLogsWithTopic(t *testing.T) {
}
}
}

// Test we can still parse receipt without EffectiveGasPrice for backwards compatibility, even
// though it is required per the spec.
func TestEffectiveGasPriceNotRequired(t *testing.T) {
r := &Receipt{
Status: ReceiptStatusFailed,
CumulativeGasUsed: 1,
Logs: []*Log{},
// derived fields:
TxHash: ethcommon.BytesToHash([]byte{0x03, 0x14}),
ContractAddress: ethcommon.HexToAddress("0x5a443704dd4b594b382c22a083e2bd3090a6fef3"),
GasUsed: 1,
}

r.EffectiveGasPrice = nil
b, err := r.MarshalJSON()
if err != nil {
t.Fatal("error marshaling receipt to json:", err)
}
r2 := Receipt{}
err = r2.UnmarshalJSON(b)
if err != nil {
t.Fatal("error unmarshalling receipt from json:", err)
}
}

func TestReceiptEncDec(t *testing.T) {
r := ReceiptForStorage(Receipt{
Status: ReceiptStatusFailed,
CumulativeGasUsed: 1,
Logs: []*Log{},
// derived fields:
TxHash: ethcommon.BytesToHash([]byte{0x03, 0x14}),
ContractAddress: ethcommon.HexToAddress("0x5a443704dd4b594b382c22a083e2bd3090a6fef3"),
GasUsed: 1,
EffectiveGasPrice: big.NewInt(1),
})

bytes, err := rlp.EncodeToBytes(&r)
if err != nil {
t.Fatal("error encoding receipt to bytes:", err)
}

r2 := ReceiptForStorage{}
err = rlp.DecodeBytes(bytes, &r2)
if err != nil {
t.Fatal("error decoding receipt from bytes:", err)
}

require.Equal(t, r, r2)
}

func TestReceiptDecodeEmptyEffectiveGasPrice(t *testing.T) {
r := ReceiptForStorage(Receipt{})

bytes, err := rlp.EncodeToBytes(&r)
require.NoError(t, err, "error encoding receipt to bytes")

r2 := ReceiptForStorage{}
err = rlp.DecodeBytes(bytes, &r2)
require.NoError(t, err, "error decoding receipt from bytes")

require.EqualValues(t, r.EffectiveGasPrice, r2.EffectiveGasPrice)
}
9 changes: 9 additions & 0 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ func (d *txdata) CopyFrom(d2 *txdata) {
d.Hash = copyHash(d2.Hash)
}

func (d *txdata) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
return dst.Set(d.Price)
}

type txdataMarshaling struct {
AccountNonce hexutil.Uint64
Price *hexutil.Big
Expand Down Expand Up @@ -532,6 +536,11 @@ func (tx *Transaction) SenderAddress() (common.Address, error) {
return addr, nil
}

// EffectiveGasPrice returns the effective gas price of the transaction.
func (tx *Transaction) EffectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
return tx.data.effectiveGasPrice(dst, baseFee)
}

// TxByNonce implements the sort interface to allow sorting a list of transactions
// by their nonces. This is usually only useful for sorting transactions from a
// single account, otherwise a nonce comparison doesn't make much sense.
Expand Down
1 change: 1 addition & 0 deletions rpc/harmony/eth/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ func NewReceipt(senderAddr common.Address, tx *types.EthTransaction, blockHash c
"contractAddress": nil,
"logs": receipt.Logs,
"logsBloom": receipt.Bloom,
"effectiveGasPrice": hexutil.Big(*receipt.EffectiveGasPrice),
}

// Assign receipt status or post state.
Expand Down
2 changes: 2 additions & 0 deletions rpc/harmony/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ type TxReceipt struct {
To string `json:"to"`
Root hexutil.Bytes `json:"root"`
Status hexutil.Uint `json:"status"`
EffectiveGasPrice hexutil.Big `json:"effectiveGasPrice"`
}

// StakingTxReceipt represents a staking transaction receipt that will serialize to the RPC representation.
Expand Down Expand Up @@ -359,6 +360,7 @@ func NewTxReceipt(
To: receiver,
Root: receipt.PostState,
Status: hexutil.Uint(receipt.Status),
EffectiveGasPrice: hexutil.Big(*receipt.EffectiveGasPrice),
}

// Set empty array for empty logs
Expand Down
2 changes: 2 additions & 0 deletions rpc/harmony/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ type TxReceipt struct {
To string `json:"to"`
Root hexutil.Bytes `json:"root"`
Status uint `json:"status"`
EffectiveGasPrice hexutil.Big `json:"effectiveGasPrice"`
}

// StakingTxReceipt represents a staking transaction receipt that will serialize to the RPC representation.
Expand Down Expand Up @@ -388,6 +389,7 @@ func NewTxReceipt(
To: receiver,
Root: receipt.PostState,
Status: uint(receipt.Status),
EffectiveGasPrice: hexutil.Big(*receipt.EffectiveGasPrice),
}

// Set optionals
Expand Down