mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
internal, eth, core: return RPC error
This commit is contained in:
parent
64196f9657
commit
4e0eb8b24d
7 changed files with 103 additions and 48 deletions
|
|
@ -279,7 +279,7 @@ func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLoo
|
|||
// The transaction indexing is not finished yet, returning an
|
||||
// error to explicitly indicate it.
|
||||
if !progress.done() {
|
||||
return nil, nil, errors.New("transaction is still indexing")
|
||||
return nil, nil, errors.New("transaction indexing still in progress")
|
||||
}
|
||||
// The transaction is already indexed, the transaction is either
|
||||
// not existent or not in the range of index, returning null.
|
||||
|
|
|
|||
|
|
@ -828,7 +828,7 @@ func containsTx(block *types.Block, hash common.Hash) bool {
|
|||
func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
|
||||
found, _, blockHash, blockNumber, index, err := api.backend.GetTransaction(ctx, hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, ethapi.NewTxIndexingError()
|
||||
}
|
||||
// Only mined txes are supported
|
||||
if !found {
|
||||
|
|
|
|||
|
|
@ -113,9 +113,9 @@ func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber)
|
|||
return b.chain.GetBlockByNumber(uint64(number)), nil
|
||||
}
|
||||
|
||||
func (b *testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
func (b *testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
tx, hash, blockNumber, index := rawdb.ReadTransaction(b.chaindb, txHash)
|
||||
return tx, hash, blockNumber, index, nil
|
||||
return true, tx, hash, blockNumber, index, nil
|
||||
}
|
||||
|
||||
func (b *testBackend) RPCGasCap() uint64 {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import (
|
|||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/accounts/scwallet"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -1133,37 +1132,6 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash
|
|||
return doCall(ctx, b, args, state, header, overrides, blockOverrides, timeout, globalGasCap)
|
||||
}
|
||||
|
||||
func newRevertError(revert []byte) *revertError {
|
||||
err := vm.ErrExecutionReverted
|
||||
|
||||
reason, errUnpack := abi.UnpackRevert(revert)
|
||||
if errUnpack == nil {
|
||||
err = fmt.Errorf("%w: %v", vm.ErrExecutionReverted, reason)
|
||||
}
|
||||
return &revertError{
|
||||
error: err,
|
||||
reason: hexutil.Encode(revert),
|
||||
}
|
||||
}
|
||||
|
||||
// revertError is an API error that encompasses an EVM revertal with JSON error
|
||||
// code and a binary data blob.
|
||||
type revertError struct {
|
||||
error
|
||||
reason string // revert reason hex encoded
|
||||
}
|
||||
|
||||
// ErrorCode returns the JSON error code for a revertal.
|
||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
||||
func (e *revertError) ErrorCode() int {
|
||||
return 3
|
||||
}
|
||||
|
||||
// ErrorData returns the hex encoded revert reason.
|
||||
func (e *revertError) ErrorData() interface{} {
|
||||
return e.reason
|
||||
}
|
||||
|
||||
// Call executes the given transaction on the state for the given block number.
|
||||
//
|
||||
// Additionally, the caller can specify a batch of contract for fields overriding.
|
||||
|
|
@ -1658,7 +1626,10 @@ func (s *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.H
|
|||
if tx := s.b.GetPoolTransaction(hash); tx != nil {
|
||||
return NewRPCPendingTransaction(tx, s.b.CurrentHeader(), s.b.ChainConfig()), nil
|
||||
}
|
||||
return nil, err
|
||||
if err == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, NewTxIndexingError()
|
||||
}
|
||||
header, err := s.b.HeaderByHash(ctx, blockHash)
|
||||
if err != nil {
|
||||
|
|
@ -1672,11 +1643,14 @@ func (s *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash commo
|
|||
// Retrieve a finalized transaction, or a pooled otherwise
|
||||
found, tx, _, _, _, err := s.b.GetTransaction(ctx, hash)
|
||||
if !found {
|
||||
if tx = s.b.GetPoolTransaction(hash); tx == nil {
|
||||
return nil, err
|
||||
if tx = s.b.GetPoolTransaction(hash); tx != nil {
|
||||
return tx.MarshalBinary()
|
||||
}
|
||||
if err == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, NewTxIndexingError()
|
||||
}
|
||||
// Serialize to RLP and return
|
||||
return tx.MarshalBinary()
|
||||
}
|
||||
|
||||
|
|
@ -1684,7 +1658,7 @@ func (s *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash commo
|
|||
func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
|
||||
found, tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash)
|
||||
if err != nil {
|
||||
return nil, err // transaction is not fully indexed
|
||||
return nil, NewTxIndexingError() // transaction is not fully indexed
|
||||
}
|
||||
if !found {
|
||||
return nil, nil // transaction is not existent or reachable
|
||||
|
|
@ -2079,10 +2053,13 @@ func (s *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hex
|
|||
// Retrieve a finalized transaction, or a pooled otherwise
|
||||
found, tx, _, _, _, err := s.b.GetTransaction(ctx, hash)
|
||||
if !found {
|
||||
if tx = s.b.GetPoolTransaction(hash); tx == nil {
|
||||
// Transaction not found anywhere, abort
|
||||
return nil, err
|
||||
if tx = s.b.GetPoolTransaction(hash); tx != nil {
|
||||
return tx.MarshalBinary()
|
||||
}
|
||||
if err == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, NewTxIndexingError()
|
||||
}
|
||||
return tx.MarshalBinary()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -583,9 +583,9 @@ func (b testBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) even
|
|||
func (b testBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||
panic("implement me")
|
||||
}
|
||||
func (b testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
func (b testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.db, txHash)
|
||||
return tx, blockHash, blockNumber, index, nil
|
||||
return true, tx, blockHash, blockNumber, index, nil
|
||||
}
|
||||
func (b testBackend) GetPoolTransactions() (types.Transactions, error) { panic("implement me") }
|
||||
func (b testBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { panic("implement me") }
|
||||
|
|
|
|||
78
internal/ethapi/errors.go
Normal file
78
internal/ethapi/errors.go
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright 2024 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// 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 ethapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
)
|
||||
|
||||
// revertError is an API error that encompasses an EVM revert with JSON error
|
||||
// code and a binary data blob.
|
||||
type revertError struct {
|
||||
error
|
||||
reason string // revert reason hex encoded
|
||||
}
|
||||
|
||||
// ErrorCode returns the JSON error code for a revert.
|
||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
||||
func (e *revertError) ErrorCode() int {
|
||||
return 3
|
||||
}
|
||||
|
||||
// ErrorData returns the hex encoded revert reason.
|
||||
func (e *revertError) ErrorData() interface{} {
|
||||
return e.reason
|
||||
}
|
||||
|
||||
// newRevertError creates a revertError instance with the provided revert data.
|
||||
func newRevertError(revert []byte) *revertError {
|
||||
err := vm.ErrExecutionReverted
|
||||
|
||||
reason, errUnpack := abi.UnpackRevert(revert)
|
||||
if errUnpack == nil {
|
||||
err = fmt.Errorf("%w: %v", vm.ErrExecutionReverted, reason)
|
||||
}
|
||||
return &revertError{
|
||||
error: err,
|
||||
reason: hexutil.Encode(revert),
|
||||
}
|
||||
}
|
||||
|
||||
// TxIndexingError is an API error that indicates the transaction indexing is not
|
||||
// fully finished yet with JSON error code and a binary data blob.
|
||||
type TxIndexingError struct{}
|
||||
|
||||
// NewTxIndexingError creates a TxIndexingError instance.
|
||||
func NewTxIndexingError() *TxIndexingError { return &TxIndexingError{} }
|
||||
|
||||
// Error implement error interface, returning the error message.
|
||||
func (e *TxIndexingError) Error() string {
|
||||
return "transaction indexing is in progress"
|
||||
}
|
||||
|
||||
// ErrorCode returns the JSON error code for a revert.
|
||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
||||
func (e *TxIndexingError) ErrorCode() int {
|
||||
return 3 // TODO tbd
|
||||
}
|
||||
|
||||
// ErrorData returns the hex encoded revert reason.
|
||||
func (e *TxIndexingError) ErrorData() interface{} { return "transaction indexing is in progress" }
|
||||
|
|
@ -379,8 +379,8 @@ func (b *backendMock) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) eve
|
|||
return nil
|
||||
}
|
||||
func (b *backendMock) SendTx(ctx context.Context, signedTx *types.Transaction) error { return nil }
|
||||
func (b *backendMock) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
return nil, [32]byte{}, 0, 0, nil
|
||||
func (b *backendMock) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
return false, nil, [32]byte{}, 0, 0, nil
|
||||
}
|
||||
func (b *backendMock) GetPoolTransactions() (types.Transactions, error) { return nil, nil }
|
||||
func (b *backendMock) GetPoolTransaction(txHash common.Hash) *types.Transaction { return nil }
|
||||
|
|
|
|||
Loading…
Reference in a new issue