rpc: support fetching pending nonce (#191)
* consider mempool tx when computing account nonce * fix lint * add condition on blocknbr * add log * update changelog : * cleanup
This commit is contained in:
parent
dcc9585595
commit
3b3daa4b48
@ -60,6 +60,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
* (evm) [tharsis#24](https://github.com/tharsis/ethermint/pull/24) Implement metrics for `MsgEthereumTx`, state transitions, `BeginBlock` and `EndBlock`.
|
* (evm) [tharsis#24](https://github.com/tharsis/ethermint/pull/24) Implement metrics for `MsgEthereumTx`, state transitions, `BeginBlock` and `EndBlock`.
|
||||||
* (rpc) [#124](https://github.com/tharsis/ethermint/issues/124) Implement `txpool_content`, `txpool_inspect` and `txpool_status` RPC methods
|
* (rpc) [#124](https://github.com/tharsis/ethermint/issues/124) Implement `txpool_content`, `txpool_inspect` and `txpool_status` RPC methods
|
||||||
* (rpc) [tharsis#112](https://github.com/tharsis/ethermint/pull/153) Fix `eth_coinbase` to return the ethereum address of the validator
|
* (rpc) [tharsis#112](https://github.com/tharsis/ethermint/pull/153) Fix `eth_coinbase` to return the ethereum address of the validator
|
||||||
|
* (rpc) [tharsis#176](https://github.com/tharsis/ethermint/issues/176) Support fetching pending nonce
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
@ -256,7 +256,8 @@ func (e *PublicAPI) GetTransactionCount(address common.Address, blockNum rpctype
|
|||||||
return &n, nil
|
return &n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, nonce, err := accRet.GetAccountNumberSequence(e.clientCtx, from)
|
includePending := blockNum == rpctypes.EthPendingBlockNumber
|
||||||
|
nonce, err := getAccountNonce(e.clientCtx, e.backend, address, includePending, e.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -565,16 +566,12 @@ func (e *PublicAPI) doCall(
|
|||||||
accessList = args.AccessList
|
accessList = args.AccessList
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set destination address for call
|
if args.From == nil {
|
||||||
var fromAddr sdk.AccAddress
|
|
||||||
if args.From != nil {
|
|
||||||
fromAddr = sdk.AccAddress(args.From.Bytes())
|
|
||||||
} else {
|
|
||||||
fromAddr = sdk.AccAddress(common.Address{}.Bytes())
|
|
||||||
args.From = &common.Address{}
|
args.From = &common.Address{}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, seq, err := e.clientCtx.AccountRetriever.GetAccountNumberSequence(e.clientCtx, fromAddr)
|
includePending := blockNr == rpctypes.EthPendingBlockNumber
|
||||||
|
seq, err := getAccountNonce(e.clientCtx, e.backend, *args.From, includePending, e.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1018,9 +1015,6 @@ func (e *PublicAPI) GetProof(address common.Address, storageKeys []string, block
|
|||||||
// provided on the args
|
// provided on the args
|
||||||
func (e *PublicAPI) setTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs, error) {
|
func (e *PublicAPI) setTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs, error) {
|
||||||
|
|
||||||
// Get nonce (sequence) from sender account
|
|
||||||
from := sdk.AccAddress(args.From.Bytes())
|
|
||||||
|
|
||||||
if args.GasPrice == nil {
|
if args.GasPrice == nil {
|
||||||
// TODO: Change to either:
|
// TODO: Change to either:
|
||||||
// - min gas price from context once available through server/daemon, or
|
// - min gas price from context once available through server/daemon, or
|
||||||
@ -1031,7 +1025,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.clientCtx.AccountRetriever.GetAccountNumberSequence(e.clientCtx, from)
|
nonce, _ := getAccountNonce(e.clientCtx, e.backend, args.From, true, e.logger)
|
||||||
args.Nonce = (*hexutil.Uint64)(&nonce)
|
args.Nonce = (*hexutil.Uint64)(&nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,3 +1078,40 @@ func (e *PublicAPI) setTxDefaults(args rpctypes.SendTxArgs) (rpctypes.SendTxArgs
|
|||||||
|
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getAccountNonce returns the account nonce for the given account address.
|
||||||
|
// If the pending value is true, it will iterate over the mempool (pending)
|
||||||
|
// txs in order to compute and return the pending tx sequence.
|
||||||
|
// Todo: include the ability to specify a blockNumber
|
||||||
|
func getAccountNonce(ctx client.Context, backend backend.Backend, accAddr common.Address, pending bool, logger log.Logger) (uint64, error) {
|
||||||
|
_, nonce, err := ctx.AccountRetriever.GetAccountNumberSequence(ctx, accAddr.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !pending {
|
||||||
|
return nonce, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// the account retriever doesn't include the uncommitted transactions on the nonce so we need to
|
||||||
|
// to manually add them.
|
||||||
|
pendingTxs, err := backend.PendingTransactions()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorln("fails to fetch pending transactions")
|
||||||
|
return nonce, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the uncommitted txs to the nonce counter
|
||||||
|
if len(pendingTxs) != 0 {
|
||||||
|
for i := range pendingTxs {
|
||||||
|
if pendingTxs[i] == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pendingTxs[i].From == accAddr {
|
||||||
|
nonce++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nonce, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user