From 043d3a58588a02612f513939c4f82c543242c1dc Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 26 Jan 2023 10:51:57 +0800 Subject: [PATCH 01/10] add future height check for get_transaction_count --- rpc/backend/account_info.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/rpc/backend/account_info.go b/rpc/backend/account_info.go index 66f1a1d24d..747b641a56 100644 --- a/rpc/backend/account_info.go +++ b/rpc/backend/account_info.go @@ -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" @@ -187,14 +188,26 @@ 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.Wrap( + sdkerrors.ErrInvalidHeight, + "cannot query with height in the future; please provide a valid 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 } @@ -204,6 +217,6 @@ func (b *Backend) GetTransactionCount(address common.Address, blockNum rpctypes. return nil, err } - n := hexutil.Uint64(nonce) + n = hexutil.Uint64(nonce) return &n, nil } From 99bb365c0d9c724a59c7cf183fbf9f3eaf7a8b4f Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 26 Jan 2023 10:51:18 +0800 Subject: [PATCH 02/10] add query future account test --- tests/integration_tests/test_account.py | 49 +++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/tests/integration_tests/test_account.py b/tests/integration_tests/test_account.py index 612307c5c7..26ee51bd4e 100644 --- a/tests/integration_tests/test_account.py +++ b/tests/integration_tests/test_account.py @@ -1,20 +1,50 @@ 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 +@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(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 + 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) @@ -30,3 +60,14 @@ def test_get_transaction_count(ethermint_rpc_ws, geth): [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) From 70077913e338f61b694e29193eda79b76e6b5809 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 26 Jan 2023 10:51:35 +0800 Subject: [PATCH 03/10] fasten get_transaction_count test --- tests/integration_tests/test_account.py | 56 ++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/integration_tests/test_account.py b/tests/integration_tests/test_account.py index 26ee51bd4e..d1af096963 100644 --- a/tests/integration_tests/test_account.py +++ b/tests/integration_tests/test_account.py @@ -38,36 +38,36 @@ def derive_new_address(n=1): mnemonic = os.getenv("COMMUNITY_MNEMONIC") return (Account.from_mnemonic(mnemonic, account_path=account_path)).address -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"] - 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_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) + 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) From 1ffb6221cf8226469402a4ccdf2cdc2b6421fb0d Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 26 Jan 2023 11:13:34 +0800 Subject: [PATCH 04/10] add change doc --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0696aa0beb..45c3bb7fe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,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 query result of future block for `eth_getTransactionCount`. ## [v0.20.0] - 2022-12-28 From 61d59bac6ee63c8d55623d48e8838b2bbf919375 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 26 Jan 2023 11:45:17 +0800 Subject: [PATCH 05/10] fix test --- rpc/backend/account_info_test.go | 7 ++++++- rpc/backend/node_info_test.go | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/rpc/backend/account_info_test.go b/rpc/backend/account_info_test.go index 4382c54a12..75504b3252 100644 --- a/rpc/backend/account_info_test.go +++ b/rpc/backend/account_info_test.go @@ -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" @@ -359,7 +360,11 @@ 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), }, diff --git a/rpc/backend/node_info_test.go b/rpc/backend/node_info_test.go index fcb4a9f0c9..b5ef6bd20e 100644 --- a/rpc/backend/node_info_test.go +++ b/rpc/backend/node_info_test.go @@ -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() { @@ -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() From 15ef48e7d953843183f5c01d41ce1ffcd008e067 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 26 Jan 2023 11:48:59 +0800 Subject: [PATCH 06/10] update nix --- gomod2nix.toml | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/gomod2nix.toml b/gomod2nix.toml index fc5411b740..c486537fd0 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -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=" @@ -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=" @@ -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=" @@ -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=" @@ -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=" @@ -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=" From be16cf8c4818f72068dae7293cc946240869b8b2 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 27 Jan 2023 19:33:24 +0800 Subject: [PATCH 07/10] Update CHANGELOG.md Co-authored-by: MalteHerrmann <42640438+MalteHerrmann@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6d6b8a729..0904e251f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,7 +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 query result of future block for `eth_getTransactionCount`. +* (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 From 531af008c996c4ce4d25159bb8f47bec93bdec6f Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 27 Jan 2023 19:33:31 +0800 Subject: [PATCH 08/10] Update rpc/backend/account_info.go Co-authored-by: MalteHerrmann <42640438+MalteHerrmann@users.noreply.github.com> --- rpc/backend/account_info.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rpc/backend/account_info.go b/rpc/backend/account_info.go index 747b641a56..9c921a4c90 100644 --- a/rpc/backend/account_info.go +++ b/rpc/backend/account_info.go @@ -196,9 +196,10 @@ func (b *Backend) GetTransactionCount(address common.Address, blockNum rpctypes. height := blockNum.Int64() currentHeight := int64(bn) if height > currentHeight { - return &n, sdkerrors.Wrap( + return &n, sdkerrors.Wrapf( sdkerrors.ErrInvalidHeight, - "cannot query with height in the future; please provide a valid height", + "cannot query with height in the future (current: %d, queried: %d); please provide a valid height", + currentHeight, height, ) } // Get nonce (sequence) from account From 95c3b94419f266be0952599ee514073dd157a853 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 27 Jan 2023 20:15:43 +0800 Subject: [PATCH 09/10] update nix --- gomod2nix.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gomod2nix.toml b/gomod2nix.toml index 7abb6e5d59..65ab566060 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -520,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=" From ef5bdaf78f4e605fe43e6b82777d7a4233fc063d Mon Sep 17 00:00:00 2001 From: MalteHerrmann Date: Fri, 27 Jan 2023 14:41:15 +0100 Subject: [PATCH 10/10] add test for block height in future --- rpc/backend/account_info_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rpc/backend/account_info_test.go b/rpc/backend/account_info_test.go index 5a6d43ceaa..ac6d210393 100644 --- a/rpc/backend/account_info_test.go +++ b/rpc/backend/account_info_test.go @@ -368,6 +368,18 @@ func (suite *BackendTestSuite) TestGetTransactionCount() { 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",