diff --git a/core/error.go b/core/error.go index 4214ed207a..ff8c75ad48 100644 --- a/core/error.go +++ b/core/error.go @@ -104,4 +104,8 @@ var ( // ErrBlobFeeCapTooLow is returned if the transaction fee cap is less than the // blob gas fee of the block. ErrBlobFeeCapTooLow = errors.New("max fee per blob gas less than block blob gas fee") + + // ErrMissingBlobHashes is returned if a blob transaction has 0 blob hashes. + ErrMissingBlobHashes = errors.New("blob transaction missing blob hashes") + ErrBlobTxCreate = errors.New("blob transaction of type create") ) diff --git a/core/state_transition.go b/core/state_transition.go index 540f63fda7..fa121741d2 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -17,7 +17,6 @@ package core import ( - "errors" "fmt" "math" "math/big" @@ -315,8 +314,11 @@ func (st *StateTransition) preCheck() error { } // Check the blob version validity if msg.BlobHashes != nil { + if msg.To == nil { + return ErrBlobTxCreate + } if len(msg.BlobHashes) == 0 { - return errors.New("blob transaction missing blob hashes") + return ErrMissingBlobHashes } for i, hash := range msg.BlobHashes { if hash[0] != params.BlobTxHashVersion { diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 3738769ecb..8932b12734 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -747,7 +747,7 @@ func TestCall(t *testing.T) { var ( accounts = newAccounts(3) genesis = &core.Genesis{ - Config: params.TestChainConfig, + Config: params.MergedTestChainConfig, Alloc: core.GenesisAlloc{ accounts[0].addr: {Balance: big.NewInt(params.Ether)}, accounts[1].addr: {Balance: big.NewInt(params.Ether)}, @@ -757,12 +757,13 @@ func TestCall(t *testing.T) { genBlocks = 10 signer = types.HomesteadSigner{} ) - api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) { + api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) { // Transfer from account[0] to account[1] // value: 1000 wei // fee: 0 wei tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, accounts[0].key) b.AddTx(tx) + b.SetPoS() })) randomAccounts := newAccounts(3) var testSuite = []struct { @@ -884,6 +885,32 @@ func TestCall(t *testing.T) { blockOverrides: BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))}, want: "0x000000000000000000000000000000000000000000000000000000000000000b", }, + // Invalid blob-tx + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[1].addr, + Input: &hexutil.Bytes{0x00}, + BlobVersionedHashes: []common.Hash{}, + }, + expectErr: core.ErrBlobTxCreate, + }, + // BLOBHASH opcode + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[1].addr, + To: &randomAccounts[2].addr, + BlobVersionedHashes: []common.Hash{common.Hash{0x01, 0x22}}, + MaxFeePerBlobGas: (*hexutil.Big)(big.NewInt(1)), + }, + overrides: StateOverride{ + randomAccounts[2].addr: { + Code: hex2Bytes("60004960005260206000f3"), + }, + }, + want: "0x0122000000000000000000000000000000000000000000000000000000000000", + }, } for i, tc := range testSuite { result, err := api.Call(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides) diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index a62eb1821a..730021aa87 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -311,6 +311,8 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (* } if args.MaxFeePerBlobGas != nil { blobGasFeeCap = args.MaxFeePerBlobGas.ToInt() + } else if args.BlobVersionedHashes != nil { + blobGasFeeCap = new(big.Int) } value := new(big.Int) if args.Value != nil {