From 0927b9c77fb790a4a2a126f7e909b23e084714cc Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Tue, 25 Apr 2023 10:47:43 -0600 Subject: [PATCH 1/3] Add blob length errors for engine api and transition tool. --- beacon/engine/types.go | 16 ++++++++++++++++ core/error.go | 4 ++++ core/state_transition.go | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/beacon/engine/types.go b/beacon/engine/types.go index afab0968195e..42f524f62b67 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -23,6 +23,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" + param "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" ) @@ -192,6 +193,21 @@ func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) { h := types.DeriveSha(types.Withdrawals(params.Withdrawals), trie.NewStackTrie(nil)) withdrawalsRoot = &h } + // Check that number of blobs are valid + numBlobsBlock := 0 + for _, tx := range txs { + if tx.Type() < 3 { + continue + } + numBlobsTx := len(tx.DataHashes()) + numBlobsBlock += numBlobsTx + if numBlobsTx == 0 || numBlobsTx > param.MaxBlobsPerBlock { + return nil, fmt.Errorf("invalid number of blobs in tx: %v", numBlobsTx) + } + if numBlobsBlock > param.MaxBlobsPerBlock { + return nil, fmt.Errorf("invalid number of blobs in block: %v", numBlobsBlock) + } + } header := &types.Header{ ParentHash: params.ParentHash, UncleHash: types.EmptyUncleHash, diff --git a/core/error.go b/core/error.go index 6782e3709373..a6e19f61ddee 100644 --- a/core/error.go +++ b/core/error.go @@ -63,6 +63,10 @@ var ( // transaction is higher than what's left in the block. ErrDataGasLimitReached = errors.New("data gas limit reached") + // ErrInvalidNumberBlobs is returned if the number of blobs in a transaction + // is zero or greater than MaxBlobsPerBlock + ErrInvalidNumberBlobs = errors.New("invalid number blobs") + // ErrInsufficientFundsForTransfer is returned if the transaction sender doesn't // have enough funds for transfer(topmost call only). ErrInsufficientFundsForTransfer = errors.New("insufficient funds for transfer") diff --git a/core/state_transition.go b/core/state_transition.go index 8424be7d8760..8cadeaf39be0 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -167,6 +167,13 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In } var err error msg.From, err = types.Sender(s, tx) + if err != nil { + return msg, err + } + numBlobsTx := len(tx.DataHashes()) + if numBlobsTx == 0 || numBlobsTx > params.MaxBlobsPerBlock { + return nil, ErrInvalidNumberBlobs + } return msg, err } From 674b2b194ceff4aa54a3025e69a14405860e964e Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Tue, 25 Apr 2023 10:55:12 -0600 Subject: [PATCH 2/3] Fix errors for engine api. --- core/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state_transition.go b/core/state_transition.go index 8cadeaf39be0..da073f14833e 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -171,7 +171,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In return msg, err } numBlobsTx := len(tx.DataHashes()) - if numBlobsTx == 0 || numBlobsTx > params.MaxBlobsPerBlock { + if tx.Type() >= 3 && (numBlobsTx == 0 || numBlobsTx > params.MaxBlobsPerBlock) { return nil, ErrInvalidNumberBlobs } return msg, err From 04bc0702be9541e8c63f78f90505077b17bc5e51 Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Wed, 26 Apr 2023 18:23:56 -0600 Subject: [PATCH 3/3] Update validation errors appropriately. --- beacon/engine/types.go | 14 ++------------ cmd/evm/internal/t8ntool/execution.go | 3 +++ core/error.go | 4 ---- core/state_transition.go | 7 ------- 4 files changed, 5 insertions(+), 23 deletions(-) diff --git a/beacon/engine/types.go b/beacon/engine/types.go index 42f524f62b67..61da5fe614c8 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -23,7 +23,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" - param "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" ) @@ -194,18 +193,9 @@ func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) { withdrawalsRoot = &h } // Check that number of blobs are valid - numBlobsBlock := 0 for _, tx := range txs { - if tx.Type() < 3 { - continue - } - numBlobsTx := len(tx.DataHashes()) - numBlobsBlock += numBlobsTx - if numBlobsTx == 0 || numBlobsTx > param.MaxBlobsPerBlock { - return nil, fmt.Errorf("invalid number of blobs in tx: %v", numBlobsTx) - } - if numBlobsBlock > param.MaxBlobsPerBlock { - return nil, fmt.Errorf("invalid number of blobs in block: %v", numBlobsBlock) + if tx.Type() == types.BlobTxType && len(tx.DataHashes()) == 0 { + return nil, fmt.Errorf("zero blobs within a blob transaction") } } header := &types.Header{ diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index c3d95fcea952..c4a6bc69dff0 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -177,6 +177,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, for i, tx := range txs { msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee) + if tx.Type() == types.BlobTxType && len(tx.DataHashes()) == 0 { + err = fmt.Errorf("blob transaction with zero blobs") + } if err != nil { log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) diff --git a/core/error.go b/core/error.go index a6e19f61ddee..6782e3709373 100644 --- a/core/error.go +++ b/core/error.go @@ -63,10 +63,6 @@ var ( // transaction is higher than what's left in the block. ErrDataGasLimitReached = errors.New("data gas limit reached") - // ErrInvalidNumberBlobs is returned if the number of blobs in a transaction - // is zero or greater than MaxBlobsPerBlock - ErrInvalidNumberBlobs = errors.New("invalid number blobs") - // ErrInsufficientFundsForTransfer is returned if the transaction sender doesn't // have enough funds for transfer(topmost call only). ErrInsufficientFundsForTransfer = errors.New("insufficient funds for transfer") diff --git a/core/state_transition.go b/core/state_transition.go index da073f14833e..8424be7d8760 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -167,13 +167,6 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In } var err error msg.From, err = types.Sender(s, tx) - if err != nil { - return msg, err - } - numBlobsTx := len(tx.DataHashes()) - if tx.Type() >= 3 && (numBlobsTx == 0 || numBlobsTx > params.MaxBlobsPerBlock) { - return nil, ErrInvalidNumberBlobs - } return msg, err }