internal/ethapi: handle blobs in API methods (#28786)
EIP-4844 adds a new transaction type for blobs. Users can submit such transactions via `eth_sendRawTransaction`. In this PR we refrain from adding support to `eth_sendTransaction` and in fact it will fail if the user passes in a blob hash. However since the chain can handle such transactions it makes sense to allow simulating them. E.g. an L2 operator should be able to simulate submitting a rollup blob and updating the L2 state. Most methods that take in a transaction object should recognize blobs. The change boils down to adding `blobVersionedHashes` and `maxFeePerBlobGas` to `TransactionArgs`. In summary: - `eth_sendTransaction`: will fail for blob txes - `eth_signTransaction`: will fail for blob txes The methods that sign txes does not, as of this PR, add support the for new EIP-4844 transaction types. Resuming the summary: - `eth_sendRawTransaction`: can send blob txes - `eth_fillTransaction`: will fill in a blob tx. Note: here we simply fill in normal transaction fields + possibly `maxFeePerBlobGas` when blobs are present. One can imagine a more elaborate set-up where users can submit blobs themselves and we fill in proofs and commitments and such. Left for future PRs if desired. - `eth_call`: can simulate blob messages - `eth_estimateGas`: blobs have no effect here. They have a separate unit of gas which is not tunable in the transaction.
This commit is contained in:
@@ -55,6 +55,8 @@ import (
|
||||
// allowed to produce in order to speed up calculations.
|
||||
const estimateGasErrorRatio = 0.015
|
||||
|
||||
var errBlobTxNotSupported = errors.New("signing blob transactions not supported")
|
||||
|
||||
// EthereumAPI provides an API to access Ethereum related information.
|
||||
type EthereumAPI struct {
|
||||
b Backend
|
||||
@@ -468,6 +470,9 @@ func (s *PersonalAccountAPI) SendTransaction(ctx context.Context, args Transacti
|
||||
s.nonceLock.LockAddr(args.from())
|
||||
defer s.nonceLock.UnlockAddr(args.from())
|
||||
}
|
||||
if args.IsEIP4844() {
|
||||
return common.Hash{}, errBlobTxNotSupported
|
||||
}
|
||||
signed, err := s.signTransaction(ctx, &args, passwd)
|
||||
if err != nil {
|
||||
log.Warn("Failed transaction send attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err)
|
||||
@@ -492,6 +497,9 @@ func (s *PersonalAccountAPI) SignTransaction(ctx context.Context, args Transacti
|
||||
if args.GasPrice == nil && (args.MaxFeePerGas == nil || args.MaxPriorityFeePerGas == nil) {
|
||||
return nil, errors.New("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas")
|
||||
}
|
||||
if args.IsEIP4844() {
|
||||
return nil, errBlobTxNotSupported
|
||||
}
|
||||
if args.Nonce == nil {
|
||||
return nil, errors.New("nonce not specified")
|
||||
}
|
||||
@@ -1219,6 +1227,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
|
||||
// returns error if the transaction would revert or if there are unexpected failures. The returned
|
||||
// value is capped by both `args.Gas` (if non-nil & non-zero) and the backend's RPCGasCap
|
||||
// configuration (if non-zero).
|
||||
// Note: Required blob gas is not computed in this method.
|
||||
func (s *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Uint64, error) {
|
||||
bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
|
||||
if blockNrOrHash != nil {
|
||||
@@ -1809,6 +1818,9 @@ func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionAr
|
||||
s.nonceLock.LockAddr(args.from())
|
||||
defer s.nonceLock.UnlockAddr(args.from())
|
||||
}
|
||||
if args.IsEIP4844() {
|
||||
return common.Hash{}, errBlobTxNotSupported
|
||||
}
|
||||
|
||||
// Set some sanity defaults and terminate on failure
|
||||
if err := args.setDefaults(ctx, s.b); err != nil {
|
||||
@@ -1834,6 +1846,7 @@ func (s *TransactionAPI) FillTransaction(ctx context.Context, args TransactionAr
|
||||
}
|
||||
// Assemble the transaction and obtain rlp
|
||||
tx := args.toTransaction()
|
||||
// TODO(s1na): fill in blob proofs, commitments
|
||||
data, err := tx.MarshalBinary()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1892,6 +1905,9 @@ func (s *TransactionAPI) SignTransaction(ctx context.Context, args TransactionAr
|
||||
if args.GasPrice == nil && (args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil) {
|
||||
return nil, errors.New("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas")
|
||||
}
|
||||
if args.IsEIP4844() {
|
||||
return nil, errBlobTxNotSupported
|
||||
}
|
||||
if args.Nonce == nil {
|
||||
return nil, errors.New("nonce not specified")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user