Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
fix(rpc): align query result of future block for eth_getTransactionCo…
Browse files Browse the repository at this point in the history
…unt (#1638)

* add future height check for get_transaction_count

* add query future account test

* fasten get_transaction_count test

* add change doc

* fix test

* update nix

* Update CHANGELOG.md

Co-authored-by: MalteHerrmann <[email protected]>

* Update rpc/backend/account_info.go

Co-authored-by: MalteHerrmann <[email protected]>

* update nix

* add test for block height in future

Co-authored-by: MalteHerrmann <[email protected]>
Co-authored-by: MalteHerrmann <[email protected]>
  • Loading branch information
3 people authored Jan 27, 2023
1 parent 83d4a2e commit 1a2ee06
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 49 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (rpc) [#1613](https://github.com/evmos/ethermint/pull/1613) Change the default json-rpc listen address to localhost.
* (rpc) [#1611](https://github.com/evmos/ethermint/pull/1611) Add missing next fee in fee history, fix wrong oldestBlock and align earliest input as ethereum.
* (proto) [#1586](https://github.com/evmos/ethermint/pull/1586) Avoid duplicate register proto type in `evm` & `feemarket`
* (rpc) [#1638](https://github.com/evmos/ethermint/pull/1638) Align results when querying `eth_getTransactionCount` for future blocks for accounts with zero and non-zero transaction counts.
* (rpc) [#1639](https://github.com/evmos/ethermint/pull/1639) Align block number input behaviour for `eth_getProof` as Ethereum.

## [v0.20.0] - 2022-12-28
Expand Down
37 changes: 17 additions & 20 deletions gomod2nix.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ schema = 3
version = "v0.0.0-20140422174119-9fd32a8b3d3d"
hash = "sha256-NDxQzO5C5M/aDz5/pjUHfZUh4VwIXovbb3irtxWCwjY="
[mod."github.com/bgentry/speakeasy"]
version = "v0.1.0"
hash = "sha256-Gt1vj6CFovLnO6wX5u2O4UfecY9V2J9WGw1ez4HMrgk="
version = "v0.1.1-0.20220910012023-760eaf8b6816"
hash = "sha256-Tx3sPuhsoVwrCfJdIwf4ipn7pD92OQNYvpCxl1Z9Wt0="
[mod."github.com/btcsuite/btcd"]
version = "v0.22.1"
hash = "sha256-hBU+roIELcmbW2Gz7eGZzL9qNA1bakq5wNxqCgs4TKc="
version = "v0.22.2"
hash = "sha256-TPX7GIArd+bwOdwgPnkHyptpEVGhpkqiAydsO4srOCQ="
[mod."github.com/btcsuite/btcd/btcec/v2"]
version = "v2.3.2"
hash = "sha256-natWs+yIAuD1UI07iZtjPilroQLfXizFn3lNOiOT83U="
Expand Down Expand Up @@ -96,8 +96,8 @@ schema = 3
version = "v1.0.0-beta.1"
hash = "sha256-oATkuj+fM5eBn+ywO+w/tL0AFSIEkx0J3Yz+VhVe0QA="
[mod."github.com/cosmos/cosmos-sdk"]
version = "v0.46.7"
hash = "sha256-54DCF8lrnA1oUmBJlbUlWXOP5UbenRInUROn5P5I9qI="
version = "v0.46.8"
hash = "sha256-jETbixsZq5XJ1pl1XaVJvD5jkcygBrEcHRK/L0+XI68="
[mod."github.com/cosmos/go-bip39"]
version = "v1.0.0"
hash = "sha256-Qm2aC2vaS8tjtMUbHmlBSagOSqbduEEDwc51qvQaBmA="
Expand All @@ -114,8 +114,8 @@ schema = 3
version = "v6.1.0"
hash = "sha256-mHYCqLedcveDjfm1EiO2EMMNJqLm9u4WHwQTy1muOoc="
[mod."github.com/cosmos/ledger-cosmos-go"]
version = "v0.12.1"
hash = "sha256-9+nr+/r4MyiogddS0JcXOuriPqXP4nxln8ts+mYQRcg="
version = "v0.12.2"
hash = "sha256-fLkveUWxn0nZzvgsY0KTU/T1TUUQ8Ap6XTYSnJs6XXo="
[mod."github.com/creachadair/taskgroup"]
version = "v0.3.2"
hash = "sha256-Y261IO/d9xjV0UScqHvo31broxvnKn4IQQC9Mu6jNkE="
Expand Down Expand Up @@ -361,8 +361,8 @@ schema = 3
version = "v2.7.0"
hash = "sha256-BKqQKCsPA73FaQwYpAY+QsWFHIncrG5jgRhC2IiNmCk="
[mod."github.com/onsi/gomega"]
version = "v1.25.0"
hash = "sha256-knaJppfBzKSMD4Gsqzx22SGrti7G5UyDBYrothAqsrs="
version = "v1.26.0"
hash = "sha256-B18jsoJHK/oE+wudT0dOsUb41s5+ZIAu/ZBzQ5djOLE="
[mod."github.com/pelletier/go-toml/v2"]
version = "v2.0.6"
hash = "sha256-BxAeApnn5H+OLlH3TXGvIbtC6LmbRnjwbcfT1qMZ4PE="
Expand Down Expand Up @@ -447,12 +447,6 @@ schema = 3
[mod."github.com/syndtr/goleveldb"]
version = "v1.0.1-0.20210819022825-2ae1ddf74ef7"
hash = "sha256-36a4hgVQfwtS2zhylKpQuFhrjdc/Y8pF0dxc26jcZIU="
[mod."github.com/tendermint/btcd"]
version = "v0.1.1"
hash = "sha256-QQl2GWZaKQtd+LQrgx2unkTLI1qye57fCWwJcmCXT/0="
[mod."github.com/tendermint/crypto"]
version = "v0.0.0-20191022145703-50d29ede1e15"
hash = "sha256-NkoZ3hKWZt5Hca49I+1g81x1m6aQGELZ/QGLdb3uHm4="
[mod."github.com/tendermint/go-amino"]
version = "v0.16.0"
hash = "sha256-JW4zO/0vMzf1dXLePOqaMtiLUZgNbuIseh9GV+jQlf0="
Expand All @@ -462,6 +456,9 @@ schema = 3
[mod."github.com/tendermint/tm-db"]
version = "v0.6.7"
hash = "sha256-hl/3RrBrpkk2zA6dmrNlIYKs1/GfqegSscDSkA5Pjlo="
[mod."github.com/tidwall/btree"]
version = "v1.5.0"
hash = "sha256-iWll4/+ADLVse3VAHxXYLprILugX/+3u0ZIk0YlLv/Q="
[mod."github.com/tklauser/go-sysconf"]
version = "v0.3.10"
hash = "sha256-Zf2NsgM9+HeM949vCce4HQtSbfUiFpeiQ716yKcFyx4="
Expand All @@ -478,8 +475,8 @@ schema = 3
version = "v0.9.1"
hash = "sha256-hSVmN/f/lQHFhF60o6ej78ELC0MMoqQgqIX2hHjdTXg="
[mod."github.com/zondax/ledger-go"]
version = "v0.14.0"
hash = "sha256-RozTPSNs4RerZ4DQMBcGmvREjoRtH1G69xjhccYjIOk="
version = "v0.14.1"
hash = "sha256-iQmShSaty50yYTbYPNd4fnOyrcEG7P2fWmj+fLJQW4s="
[mod."go.etcd.io/bbolt"]
version = "v1.3.6"
hash = "sha256-DenVAmyN22xUiivk6fdJp4C9ZnUJXCMDUf8E0goRRV4="
Expand Down Expand Up @@ -523,8 +520,8 @@ schema = 3
version = "v0.0.0-20221227171554-f9683d7f8bef"
hash = "sha256-vvYjJcG73odJwPUb3sZIz4MSHnzK1Jj2uo0CwZ8S8rQ="
[mod."google.golang.org/grpc"]
version = "v1.52.0"
hash = "sha256-wYJ/ysugKxz1O9u6BxECTIGFJ3sv0XmxOfM+Y0jW3KQ="
version = "v1.52.3"
hash = "sha256-vVkuG0kKgnh62f63unpk4JDa9rIu6kk0qtnPJOiew2M="
[mod."google.golang.org/protobuf"]
version = "v1.28.2-0.20220831092852-f930b1dc76e8"
hash = "sha256-li5hXlXwTJ5LIZ8bVki1AZ6UFI2gXHl33JwdX1dOrtM="
Expand Down
20 changes: 17 additions & 3 deletions rpc/backend/account_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -187,14 +188,27 @@ func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpctypes.Bloc

// GetTransactionCount returns the number of transactions at the given address up to the given block number.
func (b *Backend) GetTransactionCount(address common.Address, blockNum rpctypes.BlockNumber) (*hexutil.Uint64, error) {
n := hexutil.Uint64(0)
bn, err := b.BlockNumber()
if err != nil {
return &n, err
}
height := blockNum.Int64()
currentHeight := int64(bn)
if height > currentHeight {
return &n, sdkerrors.Wrapf(
sdkerrors.ErrInvalidHeight,
"cannot query with height in the future (current: %d, queried: %d); please provide a valid height",
currentHeight, height,
)
}
// Get nonce (sequence) from account
from := sdk.AccAddress(address.Bytes())
accRet := b.clientCtx.AccountRetriever

err := accRet.EnsureExists(b.clientCtx, from)
err = accRet.EnsureExists(b.clientCtx, from)
if err != nil {
// account doesn't exist yet, return 0
n := hexutil.Uint64(0)
return &n, nil
}

Expand All @@ -204,6 +218,6 @@ func (b *Backend) GetTransactionCount(address common.Address, blockNum rpctypes.
return nil, err
}

n := hexutil.Uint64(nonce)
n = hexutil.Uint64(nonce)
return &n, nil
}
19 changes: 18 additions & 1 deletion rpc/backend/account_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
tmrpcclient "github.com/tendermint/tendermint/rpc/client"
"google.golang.org/grpc/metadata"

"github.com/evmos/ethermint/rpc/backend/mocks"
rpctypes "github.com/evmos/ethermint/rpc/types"
Expand Down Expand Up @@ -359,10 +360,26 @@ func (suite *BackendTestSuite) TestGetTransactionCount() {
"pass - account doesn't exist",
false,
rpctypes.NewBlockNumber(big.NewInt(1)),
func(addr common.Address, bn rpctypes.BlockNumber) {},
func(addr common.Address, bn rpctypes.BlockNumber) {
var header metadata.MD
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterParams(queryClient, &header, 1)
},
true,
hexutil.Uint64(0),
},
{
"fail - block height is in the future",
false,
rpctypes.NewBlockNumber(big.NewInt(10000)),
func(addr common.Address, bn rpctypes.BlockNumber) {
var header metadata.MD
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterParams(queryClient, &header, 1)
},
false,
hexutil.Uint64(0),
},
// TODO: Error mocking the GetAccount call - problem with Any type
//{
// "pass - returns the number of transactions at the given address up to the given block number",
Expand Down
3 changes: 3 additions & 0 deletions rpc/backend/node_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
ethermint "github.com/evmos/ethermint/types"
"github.com/spf13/viper"
tmrpcclient "github.com/tendermint/tendermint/rpc/client"
"google.golang.org/grpc/metadata"
)

func (suite *BackendTestSuite) TestRPCMinGasPrice() {
Expand Down Expand Up @@ -247,10 +248,12 @@ func (suite *BackendTestSuite) TestSetEtherbase() {
{
"fail - error querying for account ",
func() {
var header metadata.MD
client := suite.backend.clientCtx.Client.(*mocks.Client)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterStatus(client)
RegisterValidatorAccount(queryClient, suite.acc)
RegisterParams(queryClient, &header, 1)
c := sdk.NewDecCoin("aphoton", sdk.NewIntFromBigInt(big.NewInt(1)))
suite.backend.cfg.SetMinGasPrices(sdk.DecCoins{c})
delAddr, _ := suite.backend.GetCoinbase()
Expand Down
91 changes: 66 additions & 25 deletions tests/integration_tests/test_account.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,73 @@
import os

import pytest
from eth_account import Account
from web3 import Web3

from .network import setup_ethermint
from .utils import ADDRS, w3_wait_for_new_blocks


def test_get_transaction_count(ethermint_rpc_ws, geth):
for p in [ethermint_rpc_ws, geth]:
w3 = p.w3
blk = hex(w3.eth.block_number)
sender = ADDRS["validator"]

# derive a new address
account_path = "m/44'/60'/0'/0/1"
mnemonic = os.getenv("COMMUNITY_MNEMONIC")
receiver = (Account.from_mnemonic(mnemonic, account_path=account_path)).address
n0 = w3.eth.get_transaction_count(receiver, blk)
# ensure transaction send in new block
w3_wait_for_new_blocks(w3, 1, sleep=0.1)
txhash = w3.eth.send_transaction(
{
"from": sender,
"to": receiver,
"value": 1000,
}
)
receipt = w3.eth.wait_for_transaction_receipt(txhash)
assert receipt.status == 1
[n1, n2] = [w3.eth.get_transaction_count(receiver, b) for b in [blk, "latest"]]
assert n0 == n1
assert n0 == n2
@pytest.fixture(scope="module")
def custom_ethermint(tmp_path_factory):
path = tmp_path_factory.mktemp("account")
yield from setup_ethermint(path, 26700, long_timeout_commit=True)


@pytest.fixture(scope="module", params=["ethermint", "ethermint-ws", "geth"])
def cluster(request, custom_ethermint, geth):
"""
run on ethermint, ethermint websocket and geth
"""
provider = request.param
if provider == "ethermint":
yield custom_ethermint
elif provider == "ethermint-ws":
ethermint_ws = custom_ethermint.copy()
ethermint_ws.use_websocket()
yield ethermint_ws
elif provider == "geth":
yield geth
else:
raise NotImplementedError


def derive_new_address(n=1):
# derive a new address
account_path = f"m/44'/60'/0'/0/{n}"
mnemonic = os.getenv("COMMUNITY_MNEMONIC")
return (Account.from_mnemonic(mnemonic, account_path=account_path)).address


def test_get_transaction_count(cluster):
w3: Web3 = cluster.w3
blk = hex(w3.eth.block_number)
sender = ADDRS["validator"]

receiver = derive_new_address()
n0 = w3.eth.get_transaction_count(receiver, blk)
# ensure transaction send in new block
w3_wait_for_new_blocks(w3, 1, sleep=0.1)
txhash = w3.eth.send_transaction(
{
"from": sender,
"to": receiver,
"value": 1000,
}
)
receipt = w3.eth.wait_for_transaction_receipt(txhash)
assert receipt.status == 1
[n1, n2] = [w3.eth.get_transaction_count(receiver, b) for b in [blk, "latest"]]
assert n0 == n1
assert n0 == n2


def test_query_future_blk(cluster):
w3: Web3 = cluster.w3
acc = derive_new_address(2)
current = w3.eth.block_number
future = current + 1000
with pytest.raises(ValueError) as exc:
w3.eth.get_transaction_count(acc, hex(future))
print(acc, str(exc))
assert "-32000" in str(exc)

0 comments on commit 1a2ee06

Please sign in to comment.