Skip to content

Commit

Permalink
core/types: add 4844 data gas fields in Receipt (#27743)
Browse files Browse the repository at this point in the history
* core/types: add data gas fields in Receipt

* core/types: use BlobGas method of tx

* core: fix test

* core/types: fix receipt tests, add data gas used field test

---------

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
  • Loading branch information
fjl and karalabe committed Jul 27, 2023
1 parent 1662228 commit 393d4db
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 14 deletions.
3 changes: 2 additions & 1 deletion consensus/beacon/consensus.go
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -277,7 +278,7 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa
return fmt.Errorf("invalid dataGasUsed: have %d, expected nil", header.DataGasUsed)
}
if cancun {
if err := misc.VerifyEIP4844Header(parent, header); err != nil {
if err := eip4844.VerifyEIP4844Header(parent, header); err != nil {
return err
}
}
Expand Down
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package misc
package eip4844

import (
"errors"
Expand Down
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package misc
package eip4844

import (
"fmt"
Expand Down
9 changes: 8 additions & 1 deletion core/blockchain.go
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/common/prque"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state/snapshot"
Expand Down Expand Up @@ -2027,8 +2028,14 @@ func (bc *BlockChain) recoverAncestors(block *types.Block) (common.Hash, error)
// collectLogs collects the logs that were generated or removed during
// the processing of a block. These logs are later announced as deleted or reborn.
func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log {
var dataGasPrice *big.Int
excessDataGas := b.ExcessDataGas()
if excessDataGas != nil {
dataGasPrice = eip4844.CalcBlobFee(*excessDataGas)
}

receipts := rawdb.ReadRawReceipts(bc.db, b.Hash(), b.NumberU64())
if err := receipts.DeriveFields(bc.chainConfig, b.Hash(), b.NumberU64(), b.Time(), b.BaseFee(), b.Transactions()); err != nil {
if err := receipts.DeriveFields(bc.chainConfig, b.Hash(), b.NumberU64(), b.Time(), b.BaseFee(), dataGasPrice, b.Transactions()); err != nil {
log.Error("Failed to derive block receipts fields", "hash", b.Hash(), "number", b.NumberU64(), "err", err)
}

Expand Down
11 changes: 10 additions & 1 deletion core/rawdb/accessors_chain.go
Expand Up @@ -24,6 +24,7 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
Expand Down Expand Up @@ -637,13 +638,21 @@ func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64,
return nil
}
header := ReadHeader(db, hash, number)

var baseFee *big.Int
if header == nil {
baseFee = big.NewInt(0)
} else {
baseFee = header.BaseFee
}
if err := receipts.DeriveFields(config, hash, number, time, baseFee, body.Transactions); err != nil {

// Compute effective data gas price.
var dataGasPrice *big.Int
if header != nil && header.ExcessDataGas != nil {
dataGasPrice = eip4844.CalcBlobFee(*header.ExcessDataGas)
}

if err := receipts.DeriveFields(config, hash, number, time, baseFee, dataGasPrice, body.Transactions); err != nil {
log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion core/state_processor_test.go
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/beacon"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
Expand Down Expand Up @@ -405,7 +406,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
pExcess = *parent.ExcessDataGas()
pUsed = *parent.DataGasUsed()
}
excess := misc.CalcExcessDataGas(pExcess, pUsed)
excess := eip4844.CalcExcessDataGas(pExcess, pUsed)
used := uint64(nBlobs * params.BlobTxDataGasPerBlob)
header.ExcessDataGas = &excess
header.DataGasUsed = &used
Expand Down
9 changes: 5 additions & 4 deletions core/state_transition.go
Expand Up @@ -24,7 +24,7 @@ import (

"github.com/ethereum/go-ethereum/common"
cmath "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -252,7 +252,7 @@ func (st *StateTransition) buyGas() error {
balanceCheck.Add(balanceCheck, blobBalanceCheck)
// Pay for dataGasUsed * actual blob fee
blobFee := new(big.Int).SetUint64(dataGas)
blobFee.Mul(blobFee, misc.CalcBlobFee(*st.evm.Context.ExcessDataGas))
blobFee.Mul(blobFee, eip4844.CalcBlobFee(*st.evm.Context.ExcessDataGas))
mgval.Add(mgval, blobFee)
}
}
Expand Down Expand Up @@ -333,8 +333,9 @@ func (st *StateTransition) preCheck() error {
if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) {
if st.dataGasUsed() > 0 {
// Check that the user is paying at least the current blob fee
if have, want := st.msg.BlobGasFeeCap, misc.CalcBlobFee(*st.evm.Context.ExcessDataGas); have.Cmp(want) < 0 {
return fmt.Errorf("%w: address %v have %v want %v", ErrBlobFeeCapTooLow, st.msg.From.Hex(), have, want)
blobFee := eip4844.CalcBlobFee(*st.evm.Context.ExcessDataGas)
if st.msg.BlobGasFeeCap.Cmp(blobFee) < 0 {
return fmt.Errorf("%w: address %v have %v want %v", ErrBlobFeeCapTooLow, st.msg.From.Hex(), st.msg.BlobGasFeeCap, blobFee)
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions core/types/gen_receipt_json.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions core/types/receipt.go
Expand Up @@ -63,6 +63,8 @@ type Receipt struct {
ContractAddress common.Address `json:"contractAddress"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
EffectiveGasPrice *big.Int `json:"effectiveGasPrice"` // required, but tag omitted for backwards compatibility
DataGasUsed uint64 `json:"dataGasUsed,omitempty"`
DataGasPrice *big.Int `json:"dataGasPrice,omitempty"`

// Inclusion information: These fields provide information about the inclusion of the
// transaction corresponding to this receipt.
Expand Down Expand Up @@ -313,7 +315,7 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) {

// DeriveFields fills the receipts with their computed fields based on consensus
// data and contextual infos like containing block and transactions.
func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, number uint64, time uint64, baseFee *big.Int, txs []*Transaction) error {
func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, number uint64, time uint64, baseFee *big.Int, dataGasPrice *big.Int, txs []*Transaction) error {
signer := MakeSigner(config, new(big.Int).SetUint64(number), time)

logIndex := uint(0)
Expand All @@ -324,9 +326,14 @@ func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, nu
// The transaction type and hash can be retrieved from the transaction itself
rs[i].Type = txs[i].Type()
rs[i].TxHash = txs[i].Hash()

rs[i].EffectiveGasPrice = txs[i].inner.effectiveGasPrice(new(big.Int), baseFee)

// EIP-4844 blob transaction fields
if txs[i].Type() == BlobTxType {
rs[i].DataGasUsed = txs[i].BlobGas()
rs[i].DataGasPrice = dataGasPrice
}

// block location fields
rs[i].BlockHash = hash
rs[i].BlockNumber = new(big.Int).SetUint64(number)
Expand Down
12 changes: 11 additions & 1 deletion core/types/receipt_test.go
Expand Up @@ -137,6 +137,7 @@ var (
GasTipCap: uint256.NewInt(66),
GasFeeCap: uint256.NewInt(1066),
BlobFeeCap: uint256.NewInt(100066),
BlobHashes: []common.Hash{{}},
}),
NewTx(&BlobTx{
To: to7,
Expand All @@ -146,6 +147,7 @@ var (
GasTipCap: uint256.NewInt(77),
GasFeeCap: uint256.NewInt(1077),
BlobFeeCap: uint256.NewInt(100077),
BlobHashes: []common.Hash{{}, {}, {}},
}),
}

Expand Down Expand Up @@ -270,6 +272,8 @@ var (
TxHash: txs[5].Hash(),
GasUsed: 6,
EffectiveGasPrice: big.NewInt(1066),
DataGasUsed: params.BlobTxDataGasPerBlob,
DataGasPrice: big.NewInt(920),
BlockHash: blockHash,
BlockNumber: blockNumber,
TransactionIndex: 5,
Expand All @@ -283,6 +287,8 @@ var (
TxHash: txs[6].Hash(),
GasUsed: 7,
EffectiveGasPrice: big.NewInt(1077),
DataGasUsed: 3 * params.BlobTxDataGasPerBlob,
DataGasPrice: big.NewInt(920),
BlockHash: blockHash,
BlockNumber: blockNumber,
TransactionIndex: 6,
Expand All @@ -303,8 +309,9 @@ func TestDecodeEmptyTypedReceipt(t *testing.T) {
func TestDeriveFields(t *testing.T) {
// Re-derive receipts.
basefee := big.NewInt(1000)
dataGasPrice := big.NewInt(920)
derivedReceipts := clearComputedFieldsOnReceipts(receipts)
err := Receipts(derivedReceipts).DeriveFields(params.TestChainConfig, blockHash, blockNumber.Uint64(), blockTime, basefee, txs)
err := Receipts(derivedReceipts).DeriveFields(params.TestChainConfig, blockHash, blockNumber.Uint64(), blockTime, basefee, dataGasPrice, txs)
if err != nil {
t.Fatalf("DeriveFields(...) = %v, want <nil>", err)
}
Expand Down Expand Up @@ -501,6 +508,9 @@ func clearComputedFieldsOnReceipt(receipt *Receipt) *Receipt {
cpy.ContractAddress = common.Address{0xff, 0xff, 0x33}
cpy.GasUsed = 0xffffffff
cpy.Logs = clearComputedFieldsOnLogs(receipt.Logs)
cpy.EffectiveGasPrice = big.NewInt(0)
cpy.DataGasUsed = 0
cpy.DataGasPrice = nil
return &cpy
}

Expand Down
9 changes: 8 additions & 1 deletion light/odr_util.go
Expand Up @@ -23,6 +23,7 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -175,7 +176,13 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
genesis := rawdb.ReadCanonicalHash(odr.Database(), 0)
config := rawdb.ReadChainConfig(odr.Database(), genesis)

if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), block.Transactions()); err != nil {
var dataGasPrice *big.Int
excessDataGas := block.ExcessDataGas()
if excessDataGas != nil {
dataGasPrice = eip4844.CalcBlobFee(*excessDataGas)
}

if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), dataGasPrice, block.Transactions()); err != nil {
return nil, err
}
rawdb.WriteReceipts(odr.Database(), hash, number, receipts)
Expand Down

0 comments on commit 393d4db

Please sign in to comment.