From 55f811fb17db59e339bb319c1bc8c60b4b27fb90 Mon Sep 17 00:00:00 2001 From: devopsbo3 <69951731+devopsbo3@users.noreply.github.com> Date: Fri, 10 Nov 2023 12:31:54 -0600 Subject: [PATCH] Revert "core, tests: EIP-4844 transaction processing logic (#27721)" This reverts commit 1481df630b47a1161d068a9e3ae4bd2824170aff. --- cmd/evm/staterunner.go | 1 - core/block_validator.go | 14 +++- core/error.go | 4 - core/evm.go | 21 +++-- core/gen_genesis.go | 64 ++++++--------- core/genesis.go | 52 ++++-------- core/state_processor.go | 2 +- core/state_processor_test.go | 154 +++++++++++++++++++---------------- core/state_transition.go | 73 +++-------------- core/vm/evm.go | 15 ++-- tests/gen_sttransaction.go | 13 --- tests/state_test.go | 13 ++- tests/state_test_util.go | 25 +++--- tests/testdata | 2 +- 14 files changed, 185 insertions(+), 268 deletions(-) diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 231830f6d78bf..ed102e6054da9 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -117,7 +117,6 @@ func runStateTest(fname string, cfg vm.Config, jsonOut, dump bool) error { // Test failed, mark as so and dump any state to aid debugging result.Pass, result.Error = false, err.Error() if dump && s != nil { - s, _ = state.New(*result.Root, s.Database(), nil) dump := s.RawDump(nil) result.State = &dump } diff --git a/core/block_validator.go b/core/block_validator.go index 4ea623cf47fc1..1bca444451275 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -86,8 +86,18 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { for _, tx := range block.Transactions() { // Count the number of blobs to validate against the header's dataGasUsed blobs += len(tx.BlobHashes()) - // The individual checks for blob validity (version-check + not empty) - // happens in the state_transition check. + + // Validate the data blobs individually too + if tx.Type() == types.BlobTxType { + if len(tx.BlobHashes()) == 0 { + return errors.New("no-blob blob transaction present in block body") + } + for _, hash := range tx.BlobHashes() { + if hash[0] != params.BlobTxHashVersion { + return fmt.Errorf("blob hash version mismatch (have %d, supported %d)", hash[0], params.BlobTxHashVersion) + } + } + } } if header.DataGasUsed != nil { if want := *header.DataGasUsed / params.BlobTxDataGasPerBlob; uint64(blobs) != want { // div because the header is surely good vs the body might be bloated diff --git a/core/error.go b/core/error.go index 8967432a40f53..872ba8d365d8c 100644 --- a/core/error.go +++ b/core/error.go @@ -100,8 +100,4 @@ var ( // ErrSenderNoEOA is returned if the sender of a transaction is a contract. ErrSenderNoEOA = errors.New("sender not an eoa") - - // ErrBlobFeeCapTooLow is returned if the transaction fee cap is less than the - // data gas fee of the block. - ErrBlobFeeCapTooLow = errors.New("max fee per data gas less than block data gas fee") ) diff --git a/core/evm.go b/core/evm.go index f4e6aa43f4271..b7ff7790295be 100644 --- a/core/evm.go +++ b/core/evm.go @@ -56,17 +56,16 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common random = &header.MixDigest } return vm.BlockContext{ - CanTransfer: CanTransfer, - Transfer: Transfer, - GetHash: GetHashFn(header, chain), - Coinbase: beneficiary, - BlockNumber: new(big.Int).Set(header.Number), - Time: header.Time, - Difficulty: new(big.Int).Set(header.Difficulty), - BaseFee: baseFee, - GasLimit: header.GasLimit, - Random: random, - ExcessDataGas: header.ExcessDataGas, + CanTransfer: CanTransfer, + Transfer: Transfer, + GetHash: GetHashFn(header, chain), + Coinbase: beneficiary, + BlockNumber: new(big.Int).Set(header.Number), + Time: header.Time, + Difficulty: new(big.Int).Set(header.Difficulty), + BaseFee: baseFee, + GasLimit: header.GasLimit, + Random: random, } } diff --git a/core/gen_genesis.go b/core/gen_genesis.go index 9a8b279d257bf..4e0844e889ab4 100644 --- a/core/gen_genesis.go +++ b/core/gen_genesis.go @@ -18,21 +18,19 @@ var _ = (*genesisSpecMarshaling)(nil) // MarshalJSON marshals as JSON. func (g Genesis) MarshalJSON() ([]byte, error) { type Genesis struct { - Config *params.ChainConfig `json:"config"` - Nonce math.HexOrDecimal64 `json:"nonce"` - Timestamp math.HexOrDecimal64 `json:"timestamp"` - ExtraData hexutil.Bytes `json:"extraData"` - GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash common.Hash `json:"mixHash"` - Coinbase common.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` - Number math.HexOrDecimal64 `json:"number"` - GasUsed math.HexOrDecimal64 `json:"gasUsed"` - ParentHash common.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` - ExcessDataGas *math.HexOrDecimal64 `json:"excessDataGas"` - DataGasUsed *math.HexOrDecimal64 `json:"dataGasUsed"` + Config *params.ChainConfig `json:"config"` + Nonce math.HexOrDecimal64 `json:"nonce"` + Timestamp math.HexOrDecimal64 `json:"timestamp"` + ExtraData hexutil.Bytes `json:"extraData"` + GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` + Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` + Mixhash common.Hash `json:"mixHash"` + Coinbase common.Address `json:"coinbase"` + Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` + Number math.HexOrDecimal64 `json:"number"` + GasUsed math.HexOrDecimal64 `json:"gasUsed"` + ParentHash common.Hash `json:"parentHash"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` } var enc Genesis enc.Config = g.Config @@ -53,29 +51,25 @@ func (g Genesis) MarshalJSON() ([]byte, error) { enc.GasUsed = math.HexOrDecimal64(g.GasUsed) enc.ParentHash = g.ParentHash enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee) - enc.ExcessDataGas = (*math.HexOrDecimal64)(g.ExcessDataGas) - enc.DataGasUsed = (*math.HexOrDecimal64)(g.DataGasUsed) return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (g *Genesis) UnmarshalJSON(input []byte) error { type Genesis struct { - Config *params.ChainConfig `json:"config"` - Nonce *math.HexOrDecimal64 `json:"nonce"` - Timestamp *math.HexOrDecimal64 `json:"timestamp"` - ExtraData *hexutil.Bytes `json:"extraData"` - GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash *common.Hash `json:"mixHash"` - Coinbase *common.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` - Number *math.HexOrDecimal64 `json:"number"` - GasUsed *math.HexOrDecimal64 `json:"gasUsed"` - ParentHash *common.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` - ExcessDataGas *math.HexOrDecimal64 `json:"excessDataGas"` - DataGasUsed *math.HexOrDecimal64 `json:"dataGasUsed"` + Config *params.ChainConfig `json:"config"` + Nonce *math.HexOrDecimal64 `json:"nonce"` + Timestamp *math.HexOrDecimal64 `json:"timestamp"` + ExtraData *hexutil.Bytes `json:"extraData"` + GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` + Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` + Mixhash *common.Hash `json:"mixHash"` + Coinbase *common.Address `json:"coinbase"` + Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` + Number *math.HexOrDecimal64 `json:"number"` + GasUsed *math.HexOrDecimal64 `json:"gasUsed"` + ParentHash *common.Hash `json:"parentHash"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` } var dec Genesis if err := json.Unmarshal(input, &dec); err != nil { @@ -126,11 +120,5 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.BaseFee != nil { g.BaseFee = (*big.Int)(dec.BaseFee) } - if dec.ExcessDataGas != nil { - g.ExcessDataGas = (*uint64)(dec.ExcessDataGas) - } - if dec.DataGasUsed != nil { - g.DataGasUsed = (*uint64)(dec.DataGasUsed) - } return nil } diff --git a/core/genesis.go b/core/genesis.go index 0b255a8d37371..013ef78601fce 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -59,12 +59,10 @@ type Genesis struct { // These fields are used for consensus tests. Please don't use them // in actual genesis blocks. - Number uint64 `json:"number"` - GasUsed uint64 `json:"gasUsed"` - ParentHash common.Hash `json:"parentHash"` - BaseFee *big.Int `json:"baseFeePerGas"` // EIP-1559 - ExcessDataGas *uint64 `json:"excessDataGas"` // EIP-4844 - DataGasUsed *uint64 `json:"dataGasUsed"` // EIP-4844 + Number uint64 `json:"number"` + GasUsed uint64 `json:"gasUsed"` + ParentHash common.Hash `json:"parentHash"` + BaseFee *big.Int `json:"baseFeePerGas"` } func ReadGenesis(db ethdb.Database) (*Genesis, error) { @@ -98,9 +96,6 @@ func ReadGenesis(db ethdb.Database) (*Genesis, error) { genesis.Difficulty = genesisHeader.Difficulty genesis.Mixhash = genesisHeader.MixDigest genesis.Coinbase = genesisHeader.Coinbase - genesis.BaseFee = genesisHeader.BaseFee - genesis.ExcessDataGas = genesisHeader.ExcessDataGas - genesis.DataGasUsed = genesisHeader.DataGasUsed return &genesis, nil } @@ -219,17 +214,15 @@ type GenesisAccount struct { // field type overrides for gencodec type genesisSpecMarshaling struct { - Nonce math.HexOrDecimal64 - Timestamp math.HexOrDecimal64 - ExtraData hexutil.Bytes - GasLimit math.HexOrDecimal64 - GasUsed math.HexOrDecimal64 - Number math.HexOrDecimal64 - Difficulty *math.HexOrDecimal256 - Alloc map[common.UnprefixedAddress]GenesisAccount - BaseFee *math.HexOrDecimal256 - ExcessDataGas *math.HexOrDecimal64 - DataGasUsed *math.HexOrDecimal64 + Nonce math.HexOrDecimal64 + Timestamp math.HexOrDecimal64 + ExtraData hexutil.Bytes + GasLimit math.HexOrDecimal64 + GasUsed math.HexOrDecimal64 + Number math.HexOrDecimal64 + Difficulty *math.HexOrDecimal256 + BaseFee *math.HexOrDecimal256 + Alloc map[common.UnprefixedAddress]GenesisAccount } type genesisAccountMarshaling struct { @@ -470,22 +463,9 @@ func (g *Genesis) ToBlock() *types.Block { } } var withdrawals []*types.Withdrawal - if conf := g.Config; conf != nil { - num := big.NewInt(int64(g.Number)) - if conf.IsShanghai(num, g.Timestamp) { - head.WithdrawalsHash = &types.EmptyWithdrawalsHash - withdrawals = make([]*types.Withdrawal, 0) - } - if conf.IsCancun(num, g.Timestamp) { - head.ExcessDataGas = g.ExcessDataGas - head.DataGasUsed = g.DataGasUsed - if head.ExcessDataGas == nil { - head.ExcessDataGas = new(uint64) - } - if head.DataGasUsed == nil { - head.DataGasUsed = new(uint64) - } - } + if g.Config != nil && g.Config.IsShanghai(big.NewInt(int64(g.Number)), g.Timestamp) { + head.WithdrawalsHash = &types.EmptyWithdrawalsHash + withdrawals = make([]*types.Withdrawal, 0) } return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals) } diff --git a/core/state_processor.go b/core/state_processor.go index fcaf5a8ff3c9b..4837628e66021 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -157,6 +157,6 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo } // Create a new context to be used in the EVM environment blockContext := NewEVMBlockContext(header, bc, author) - vmenv := vm.NewEVM(blockContext, vm.TxContext{BlobHashes: tx.BlobHashes()}, statedb, config, cfg) + vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg) return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv) } diff --git a/core/state_processor_test.go b/core/state_processor_test.go index a8858ec7e3f9c..5dbeed97a00bd 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -33,7 +33,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" - "github.com/holiman/uint256" "golang.org/x/crypto/sha3" ) @@ -46,23 +45,19 @@ func u64(val uint64) *uint64 { return &val } func TestStateProcessorErrors(t *testing.T) { var ( config = ¶ms.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - Ethash: new(params.EthashConfig), - TerminalTotalDifficulty: big.NewInt(0), - TerminalTotalDifficultyPassed: true, - ShanghaiTime: new(uint64), - CancunTime: new(uint64), + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Ethash: new(params.EthashConfig), } signer = types.LatestSigner(config) key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") @@ -94,22 +89,6 @@ func TestStateProcessorErrors(t *testing.T) { }), signer, key1) return tx } - var mkBlobTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, hashes []common.Hash) *types.Transaction { - tx, err := types.SignTx(types.NewTx(&types.BlobTx{ - Nonce: nonce, - GasTipCap: uint256.MustFromBig(gasTipCap), - GasFeeCap: uint256.MustFromBig(gasFeeCap), - Gas: gasLimit, - To: to, - BlobHashes: hashes, - Value: new(uint256.Int), - }), signer, key1) - if err != nil { - t.Fatal(err) - } - return tx - } - { // Tests against a 'recent' chain definition var ( db = rawdb.NewMemoryDatabase() @@ -126,10 +105,8 @@ func TestStateProcessorErrors(t *testing.T) { }, }, } - blockchain, _ = NewBlockChain(db, nil, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil, nil) - tooBigInitCode = [params.MaxInitCodeSize + 1]byte{} + blockchain, _ = NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) ) - defer blockchain.Stop() bigNumber := new(big.Int).SetBytes(common.FromHex("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) tooBigNumber := new(big.Int).Set(bigNumber) @@ -232,26 +209,8 @@ func TestStateProcessorErrors(t *testing.T) { }, want: "could not apply tx 0 [0xd82a0c2519acfeac9a948258c47e784acd20651d9d80f9a1c67b4137651c3a24]: insufficient funds for gas * price + value: address 0x71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 2431633873983640103894990685182446064918669677978451844828609264166175722438635000", }, - { // ErrMaxInitCodeSizeExceeded - txs: []*types.Transaction{ - mkDynamicCreationTx(0, 500000, common.Big0, big.NewInt(params.InitialBaseFee), tooBigInitCode[:]), - }, - want: "could not apply tx 0 [0xd491405f06c92d118dd3208376fcee18a57c54bc52063ee4a26b1cf296857c25]: max initcode size exceeded: code size 49153 limit 49152", - }, - { // ErrIntrinsicGas: Not enough gas to cover init code - txs: []*types.Transaction{ - mkDynamicCreationTx(0, 54299, common.Big0, big.NewInt(params.InitialBaseFee), make([]byte, 320)), - }, - want: "could not apply tx 0 [0xfd49536a9b323769d8472fcb3ebb3689b707a349379baee3e2ee3fe7baae06a1]: intrinsic gas too low: have 54299, want 54300", - }, - { // ErrBlobFeeCapTooLow - txs: []*types.Transaction{ - mkBlobTx(0, common.Address{}, params.TxGas, big.NewInt(1), big.NewInt(1), []common.Hash{(common.Hash{1})}), - }, - want: "could not apply tx 0 [0x6c11015985ce82db691d7b2d017acda296db88b811c3c60dc71449c76256c716]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 1 baseFee: 875000000", - }, } { - block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config) + block := GenerateBadBlock(gspec.ToBlock(), ethash.NewFaker(), tt.txs, gspec.Config) _, err := blockchain.InsertChain(types.Blocks{block}) if err == nil { t.Fatal("block imported without errors") @@ -325,7 +284,7 @@ func TestStateProcessorErrors(t *testing.T) { }, }, } - blockchain, _ = NewBlockChain(db, nil, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil, nil) + blockchain, _ = NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) ) defer blockchain.Stop() for i, tt := range []struct { @@ -339,7 +298,73 @@ func TestStateProcessorErrors(t *testing.T) { want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: sender not an eoa: address 0x71562b71999873DB5b286dF957af199Ec94617F7, codehash: 0x9280914443471259d4570a8661015ae4a5b80186dbc619658fb494bebc3da3d1", }, } { - block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config) + block := GenerateBadBlock(gspec.ToBlock(), ethash.NewFaker(), tt.txs, gspec.Config) + _, err := blockchain.InsertChain(types.Blocks{block}) + if err == nil { + t.Fatal("block imported without errors") + } + if have, want := err.Error(), tt.want; have != want { + t.Errorf("test %d:\nhave \"%v\"\nwant \"%v\"\n", i, have, want) + } + } + } + + // ErrMaxInitCodeSizeExceeded, for this we need extra Shanghai (EIP-3860) enabled. + { + var ( + db = rawdb.NewMemoryDatabase() + gspec = &Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + GrayGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + TerminalTotalDifficultyPassed: true, + ShanghaiTime: u64(0), + }, + Alloc: GenesisAlloc{ + common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{ + Balance: big.NewInt(1000000000000000000), // 1 ether + Nonce: 0, + }, + }, + } + genesis = gspec.MustCommit(db) + blockchain, _ = NewBlockChain(db, nil, gspec, nil, beacon.New(ethash.NewFaker()), vm.Config{}, nil, nil) + tooBigInitCode = [params.MaxInitCodeSize + 1]byte{} + smallInitCode = [320]byte{} + ) + defer blockchain.Stop() + for i, tt := range []struct { + txs []*types.Transaction + want string + }{ + { // ErrMaxInitCodeSizeExceeded + txs: []*types.Transaction{ + mkDynamicCreationTx(0, 500000, common.Big0, misc.CalcBaseFee(config, genesis.Header()), tooBigInitCode[:]), + }, + want: "could not apply tx 0 [0x832b54a6c3359474a9f504b1003b2cc1b6fcaa18e4ef369eb45b5d40dad6378f]: max initcode size exceeded: code size 49153 limit 49152", + }, + { // ErrIntrinsicGas: Not enough gas to cover init code + txs: []*types.Transaction{ + mkDynamicCreationTx(0, 54299, common.Big0, misc.CalcBaseFee(config, genesis.Header()), smallInitCode[:]), + }, + want: "could not apply tx 0 [0x39b7436cb432d3662a25626474282c5c4c1a213326fd87e4e18a91477bae98b2]: intrinsic gas too low: have 54299, want 54300", + }, + } { + block := GenerateBadBlock(genesis, beacon.New(ethash.NewFaker()), tt.txs, gspec.Config) _, err := blockchain.InsertChain(types.Blocks{block}) if err == nil { t.Fatal("block imported without errors") @@ -387,7 +412,6 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr hasher := sha3.NewLegacyKeccak256() hasher.Write(header.Number.Bytes()) var cumulativeGas uint64 - var nBlobs int for _, tx := range txs { txh := tx.Hash() hasher.Write(txh[:]) @@ -396,20 +420,8 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr receipt.GasUsed = tx.Gas() receipts = append(receipts, receipt) cumulativeGas += tx.Gas() - nBlobs += len(tx.BlobHashes()) } header.Root = common.BytesToHash(hasher.Sum(nil)) - if config.IsCancun(header.Number, header.Time) { - var pExcess, pUsed = uint64(0), uint64(0) - if parent.ExcessDataGas() != nil { - pExcess = *parent.ExcessDataGas() - pUsed = *parent.DataGasUsed() - } - excess := misc.CalcExcessDataGas(pExcess, pUsed) - used := uint64(nBlobs * params.BlobTxDataGasPerBlob) - header.ExcessDataGas = &excess - header.DataGasUsed = &used - } // Assemble and return the final block for sealing if config.IsShanghai(header.Number, header.Time) { return types.NewBlockWithWithdrawals(header, txs, nil, receipts, []*types.Withdrawal{}, trie.NewStackTrie(nil)) diff --git a/core/state_transition.go b/core/state_transition.go index 9fcdb74458ba3..022238c8d640b 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -17,14 +17,12 @@ package core import ( - "errors" "fmt" "math" "math/big" "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/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" @@ -127,18 +125,17 @@ func toWordSize(size uint64) uint64 { // A Message contains the data derived from a single transaction that is relevant to state // processing. type Message struct { - To *common.Address - From common.Address - Nonce uint64 - Value *big.Int - GasLimit uint64 - GasPrice *big.Int - GasFeeCap *big.Int - GasTipCap *big.Int - Data []byte - AccessList types.AccessList - BlobGasFeeCap *big.Int - BlobHashes []common.Hash + To *common.Address + From common.Address + Nonce uint64 + Value *big.Int + GasLimit uint64 + GasPrice *big.Int + GasFeeCap *big.Int + GasTipCap *big.Int + Data []byte + AccessList types.AccessList + BlobHashes []common.Hash // When SkipAccountChecks is true, the message nonce is not checked against the // account nonce in state. It also disables checking that the sender is an EOA. @@ -160,7 +157,6 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In AccessList: tx.AccessList(), SkipAccountChecks: false, BlobHashes: tx.BlobHashes(), - BlobGasFeeCap: tx.BlobGasFeeCap(), } // If baseFee provided, set gasPrice to effectiveGasPrice. if baseFee != nil { @@ -234,28 +230,12 @@ func (st *StateTransition) to() common.Address { func (st *StateTransition) buyGas() error { mgval := new(big.Int).SetUint64(st.msg.GasLimit) mgval = mgval.Mul(mgval, st.msg.GasPrice) - balanceCheck := new(big.Int).Set(mgval) + balanceCheck := mgval if st.msg.GasFeeCap != nil { - balanceCheck.SetUint64(st.msg.GasLimit) + balanceCheck = new(big.Int).SetUint64(st.msg.GasLimit) balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap) balanceCheck.Add(balanceCheck, st.msg.Value) } - if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) { - if dataGas := st.dataGasUsed(); dataGas > 0 { - if st.evm.Context.ExcessDataGas == nil { - // programming error - panic("missing field excess data gas") - } - // Check that the user has enough funds to cover dataGasUsed * tx.BlobGasFeeCap - blobBalanceCheck := new(big.Int).SetUint64(dataGas) - blobBalanceCheck.Mul(blobBalanceCheck, st.msg.BlobGasFeeCap) - 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)) - mgval.Add(mgval, blobFee) - } - } if have, want := st.state.GetBalance(st.msg.From), balanceCheck; have.Cmp(want) < 0 { return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want) } @@ -317,28 +297,6 @@ func (st *StateTransition) preCheck() error { } } } - // Check the blob version validity - if msg.BlobHashes != nil { - if len(msg.BlobHashes) == 0 { - return errors.New("blob transaction missing blob hashes") - } - for i, hash := range msg.BlobHashes { - if hash[0] != params.BlobTxHashVersion { - return fmt.Errorf("blob %d hash version mismatch (have %d, supported %d)", - i, hash[0], params.BlobTxHashVersion) - } - } - } - - 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) - } - } - } - return st.buyGas() } @@ -469,8 +427,3 @@ func (st *StateTransition) refundGas(refundQuotient uint64) { func (st *StateTransition) gasUsed() uint64 { return st.initialGas - st.gasRemaining } - -// dataGasUsed returns the amount of data gas used by the message. -func (st *StateTransition) dataGasUsed() uint64 { - return uint64(len(st.msg.BlobHashes) * params.BlobTxDataGasPerBlob) -} diff --git a/core/vm/evm.go b/core/vm/evm.go index 54395136a4546..3f3c3751f88fb 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -67,14 +67,13 @@ type BlockContext struct { GetHash GetHashFunc // Block information - Coinbase common.Address // Provides information for COINBASE - GasLimit uint64 // Provides information for GASLIMIT - BlockNumber *big.Int // Provides information for NUMBER - Time uint64 // Provides information for TIME - Difficulty *big.Int // Provides information for DIFFICULTY - BaseFee *big.Int // Provides information for BASEFEE - Random *common.Hash // Provides information for PREVRANDAO - ExcessDataGas *uint64 // ExcessDataGas field in the header, needed to compute the data + Coinbase common.Address // Provides information for COINBASE + GasLimit uint64 // Provides information for GASLIMIT + BlockNumber *big.Int // Provides information for NUMBER + Time uint64 // Provides information for TIME + Difficulty *big.Int // Provides information for DIFFICULTY + BaseFee *big.Int // Provides information for BASEFEE + Random *common.Hash // Provides information for PREVRANDAO } // TxContext provides the EVM with information about a transaction. diff --git a/tests/gen_sttransaction.go b/tests/gen_sttransaction.go index 11278833157d8..7693a207a56cb 100644 --- a/tests/gen_sttransaction.go +++ b/tests/gen_sttransaction.go @@ -6,7 +6,6 @@ import ( "encoding/json" "math/big" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/types" @@ -27,8 +26,6 @@ func (s stTransaction) MarshalJSON() ([]byte, error) { GasLimit []math.HexOrDecimal64 `json:"gasLimit"` Value []string `json:"value"` PrivateKey hexutil.Bytes `json:"secretKey"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - BlobGasFeeCap *math.HexOrDecimal256 `json:"maxFeePerDataGas,omitempty"` } var enc stTransaction enc.GasPrice = (*math.HexOrDecimal256)(s.GasPrice) @@ -46,8 +43,6 @@ func (s stTransaction) MarshalJSON() ([]byte, error) { } enc.Value = s.Value enc.PrivateKey = s.PrivateKey - enc.BlobVersionedHashes = s.BlobVersionedHashes - enc.BlobGasFeeCap = (*math.HexOrDecimal256)(s.BlobGasFeeCap) return json.Marshal(&enc) } @@ -64,8 +59,6 @@ func (s *stTransaction) UnmarshalJSON(input []byte) error { GasLimit []math.HexOrDecimal64 `json:"gasLimit"` Value []string `json:"value"` PrivateKey *hexutil.Bytes `json:"secretKey"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - BlobGasFeeCap *math.HexOrDecimal256 `json:"maxFeePerDataGas,omitempty"` } var dec stTransaction if err := json.Unmarshal(input, &dec); err != nil { @@ -104,11 +97,5 @@ func (s *stTransaction) UnmarshalJSON(input []byte) error { if dec.PrivateKey != nil { s.PrivateKey = *dec.PrivateKey } - if dec.BlobVersionedHashes != nil { - s.BlobVersionedHashes = dec.BlobVersionedHashes - } - if dec.BlobGasFeeCap != nil { - s.BlobGasFeeCap = (*big.Int)(dec.BlobGasFeeCap) - } return nil } diff --git a/tests/state_test.go b/tests/state_test.go index 61ce8aab39568..9d3862e1dc7c2 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -48,24 +48,23 @@ func TestState(t *testing.T) { st.slow(`^stStaticCall/static_Return50000`) st.slow(`^stSystemOperationsTest/CallRecursiveBomb`) st.slow(`^stTransactionTest/Opcodes_TransactionInit`) + // Very time consuming st.skipLoad(`^stTimeConsuming/`) st.skipLoad(`.*vmPerformance/loop.*`) + // Uses 1GB RAM per tested fork st.skipLoad(`^stStaticCall/static_Call1MB`) // Broken tests: - // EOF is not part of cancun - st.skipLoad(`^stEOF/`) - + // + // The stEOF tests are generated with EOF as part of Shanghai, which + // is erroneous. Therefore, these tests are skipped. + st.skipLoad(`^EIPTests/stEOF/`) // Expected failures: - // These EIP-4844 tests need to be regenerated. - st.fails(`stEIP4844-blobtransactions/opcodeBlobhashOutOfRange.json`, "test has incorrect state root") - st.fails(`stEIP4844-blobtransactions/opcodeBlobhBounds.json`, "test has incorrect state root") // For Istanbul, older tests were moved into LegacyTests for _, dir := range []string{ - filepath.Join(baseDir, "EIPTests", "StateTests"), stateTestDir, legacyStateTestDir, benchmarksDir, diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 0958e248b4ca9..6956fe5b966de 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -113,8 +113,6 @@ type stTransaction struct { GasLimit []uint64 `json:"gasLimit"` Value []string `json:"value"` PrivateKey []byte `json:"secretKey"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - BlobGasFeeCap *big.Int `json:"maxFeePerDataGas,omitempty"` } type stTransactionMarshaling struct { @@ -124,7 +122,6 @@ type stTransactionMarshaling struct { Nonce math.HexOrDecimal64 GasLimit []math.HexOrDecimal64 PrivateKey hexutil.Bytes - BlobGasFeeCap *math.HexOrDecimal256 } // GetChainConfig takes a fork definition and returns a chain config. @@ -406,18 +403,16 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess } msg := &core.Message{ - From: from, - To: to, - Nonce: tx.Nonce, - Value: value, - GasLimit: gasLimit, - GasPrice: gasPrice, - GasFeeCap: tx.MaxFeePerGas, - GasTipCap: tx.MaxPriorityFeePerGas, - Data: data, - AccessList: accessList, - BlobHashes: tx.BlobVersionedHashes, - BlobGasFeeCap: tx.BlobGasFeeCap, + From: from, + To: to, + Nonce: tx.Nonce, + Value: value, + GasLimit: gasLimit, + GasPrice: gasPrice, + GasFeeCap: tx.MaxFeePerGas, + GasTipCap: tx.MaxPriorityFeePerGas, + Data: data, + AccessList: accessList, } return msg, nil } diff --git a/tests/testdata b/tests/testdata index ee3fa4c86d05f..bac70c50a5791 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit ee3fa4c86d05f99f2717f83a6ad08008490ddf07 +Subproject commit bac70c50a579197af68af5fc6d8c7b6163b92c52