rpc: implement pending nonce with UnconfirmedTx
(#243)
* implement pending nonce with UnconfirmedTx Closes #242 fix lint * return early on error
This commit is contained in:
parent
d0b890b794
commit
7951852bb0
@ -13,6 +13,7 @@ import (
|
|||||||
log "github.com/xlab/suplog"
|
log "github.com/xlab/suplog"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
@ -36,7 +37,7 @@ type Backend interface {
|
|||||||
GetLogs(blockHash common.Hash) ([][]*ethtypes.Log, error)
|
GetLogs(blockHash common.Hash) ([][]*ethtypes.Log, error)
|
||||||
|
|
||||||
// Used by pending transaction filter
|
// Used by pending transaction filter
|
||||||
PendingTransactions() ([]*types.RPCTransaction, error)
|
PendingTransactions() ([]*sdk.Tx, error)
|
||||||
|
|
||||||
// Used by log filter
|
// Used by log filter
|
||||||
GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error)
|
GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error)
|
||||||
@ -294,8 +295,22 @@ func (e *EVMBackend) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, er
|
|||||||
|
|
||||||
// PendingTransactions returns the transactions that are in the transaction pool
|
// PendingTransactions returns the transactions that are in the transaction pool
|
||||||
// and have a from address that is one of the accounts this node manages.
|
// and have a from address that is one of the accounts this node manages.
|
||||||
func (e *EVMBackend) PendingTransactions() ([]*types.RPCTransaction, error) {
|
func (e *EVMBackend) PendingTransactions() ([]*sdk.Tx, error) {
|
||||||
return []*types.RPCTransaction{}, nil
|
res, err := e.clientCtx.Client.UnconfirmedTxs(e.ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]*sdk.Tx, 0, len(res.Txs))
|
||||||
|
for _, txBz := range res.Txs {
|
||||||
|
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result = append(result, &tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLogs returns all the logs from all the ethereum transactions in a block.
|
// GetLogs returns all the logs from all the ethereum transactions in a block.
|
||||||
|
@ -5,21 +5,18 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gogo/protobuf/jsonpb"
|
"github.com/gogo/protobuf/jsonpb"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
log "github.com/xlab/suplog"
|
log "github.com/xlab/suplog"
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
|
||||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
|
|
||||||
@ -260,7 +257,7 @@ func (e *PublicAPI) GetTransactionCount(address common.Address, blockNum rpctype
|
|||||||
}
|
}
|
||||||
|
|
||||||
includePending := blockNum == rpctypes.EthPendingBlockNumber
|
includePending := blockNum == rpctypes.EthPendingBlockNumber
|
||||||
nonce, err := e.getAccountNonce(address, includePending, blockNum.TmHeight(), e.logger)
|
nonce, err := e.getAccountNonce(address, includePending, blockNum.Int64(), e.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -585,7 +582,7 @@ func (e *PublicAPI) doCall(
|
|||||||
}
|
}
|
||||||
|
|
||||||
includePending := blockNr == rpctypes.EthPendingBlockNumber
|
includePending := blockNr == rpctypes.EthPendingBlockNumber
|
||||||
seq, err := e.getAccountNonce(*args.From, includePending, blockNr.TmHeight(), e.logger)
|
seq, err := e.getAccountNonce(*args.From, includePending, 0, e.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -985,7 +982,9 @@ func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interfac
|
|||||||
// and have a from address that is one of the accounts this node manages.
|
// and have a from address that is one of the accounts this node manages.
|
||||||
func (e *PublicAPI) PendingTransactions() ([]*rpctypes.RPCTransaction, error) {
|
func (e *PublicAPI) PendingTransactions() ([]*rpctypes.RPCTransaction, error) {
|
||||||
e.logger.Debugln("eth_getPendingTransactions")
|
e.logger.Debugln("eth_getPendingTransactions")
|
||||||
return e.backend.PendingTransactions()
|
|
||||||
|
// FIXME https://github.com/tharsis/ethermint/issues/244
|
||||||
|
return []*rpctypes.RPCTransaction{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUncleByBlockHashAndIndex returns the uncle identified by hash and index. Always returns nil.
|
// GetUncleByBlockHashAndIndex returns the uncle identified by hash and index. Always returns nil.
|
||||||
@ -1082,7 +1081,7 @@ func (e *PublicAPI) setTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs
|
|||||||
if args.Nonce == nil {
|
if args.Nonce == nil {
|
||||||
// get the nonce from the account retriever
|
// get the nonce from the account retriever
|
||||||
// ignore error in case tge account doesn't exist yet
|
// ignore error in case tge account doesn't exist yet
|
||||||
nonce, _ := e.getAccountNonce(args.From, true, nil, e.logger)
|
nonce, _ := e.getAccountNonce(args.From, true, 0, e.logger)
|
||||||
args.Nonce = (*hexutil.Uint64)(&nonce)
|
args.Nonce = (*hexutil.Uint64)(&nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1140,13 +1139,9 @@ func (e *PublicAPI) setTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs
|
|||||||
// If the pending value is true, it will iterate over the mempool (pending)
|
// If the pending value is true, it will iterate over the mempool (pending)
|
||||||
// txs in order to compute and return the pending tx sequence.
|
// txs in order to compute and return the pending tx sequence.
|
||||||
// Todo: include the ability to specify a blockNumber
|
// Todo: include the ability to specify a blockNumber
|
||||||
func (e *PublicAPI) getAccountNonce(accAddr common.Address, pending bool, height *int64, logger log.Logger) (uint64, error) {
|
func (e *PublicAPI) getAccountNonce(accAddr common.Address, pending bool, height int64, logger log.Logger) (uint64, error) {
|
||||||
ctx := e.ctx
|
|
||||||
if height != nil {
|
|
||||||
ctx = metadata.AppendToOutgoingContext(e.ctx, grpctypes.GRPCBlockHeightHeader, strconv.FormatInt(*height, 10))
|
|
||||||
}
|
|
||||||
queryClient := authtypes.NewQueryClient(e.clientCtx)
|
queryClient := authtypes.NewQueryClient(e.clientCtx)
|
||||||
res, err := queryClient.Account(ctx, &authtypes.QueryAccountRequest{Address: sdk.AccAddress(accAddr.Bytes()).String()})
|
res, err := queryClient.Account(rpctypes.ContextWithHeight(height), &authtypes.QueryAccountRequest{Address: sdk.AccAddress(accAddr.Bytes()).String()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -1165,19 +1160,29 @@ func (e *PublicAPI) getAccountNonce(accAddr common.Address, pending bool, height
|
|||||||
// to manually add them.
|
// to manually add them.
|
||||||
pendingTxs, err := e.backend.PendingTransactions()
|
pendingTxs, err := e.backend.PendingTransactions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorln("fails to fetch pending transactions")
|
logger.WithError(err).Errorln("fails to fetch pending transactions")
|
||||||
return nonce, nil
|
return nonce, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the uncommitted txs to the nonce counter
|
// add the uncommitted txs to the nonce counter
|
||||||
if len(pendingTxs) != 0 {
|
// only supports `MsgEthereumTx` style tx
|
||||||
for i := range pendingTxs {
|
for _, tx := range pendingTxs {
|
||||||
if pendingTxs[i] == nil {
|
if tx == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if pendingTxs[i].From == accAddr {
|
if len((*tx).GetMsgs()) != 1 {
|
||||||
nonce++
|
continue
|
||||||
}
|
}
|
||||||
|
msg, ok := (*tx).GetMsgs()[0].(*evmtypes.MsgEthereumTx)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sender, err := msg.GetSender(e.chainIDEpoch)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if sender == accAddr {
|
||||||
|
nonce++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user