From edbcfcabb93576037d7469f6486d0c423122951d Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Wed, 10 Aug 2022 13:12:58 +0200 Subject: [PATCH 1/9] tests(rpc): add pending transaction filter test --- tests/integration_tests/README.md | 43 +++++++++++++++++++++++++ tests/integration_tests/test_filters.py | 31 ++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/integration_tests/README.md create mode 100644 tests/integration_tests/test_filters.py diff --git a/tests/integration_tests/README.md b/tests/integration_tests/README.md new file mode 100644 index 0000000000..00dc2ee6e1 --- /dev/null +++ b/tests/integration_tests/README.md @@ -0,0 +1,43 @@ +# RPC Integration tests + +The RPC integration test suite uses nix and python to send identical queries to both an Ethermint and a [Geth](https://github.com/ethereum/go-ethereum) client and compare the responses. It allows for quickly assessing the compatibility with Geth. + +## Installation + +Multi-user installation: + +``` +sh <(curl -L https://nixos.org/nix/install) --daemon +``` + +Make sure the following line has been added to your shell profile (e.g. ~/.profile): + +``` +source ~/.nix-profile/etc/profile.d/nix.sh +``` + +Then re-login shell, the nix installation is completed. + +For linux: + +``` +sh <(curl -L https://nixos.org/nix/install) --no-daemon +``` + + + +## Run Local + +Fist time run (can take a while): + +``` +make run-integration-tests +``` + +Once you've run them once, you can run. + +``` +nix-shell tests/integration_tests/shell.nix +cd tests/integration_tests +pytest -s -vv +``` \ No newline at end of file diff --git a/tests/integration_tests/test_filters.py b/tests/integration_tests/test_filters.py new file mode 100644 index 0000000000..d373ce445a --- /dev/null +++ b/tests/integration_tests/test_filters.py @@ -0,0 +1,31 @@ +from web3 import Web3 + +from .utils import ADDRS, CONTRACTS, deploy_contract, send_transaction, sign_transaction + +def test_pending_transaction_filter(ethermint, geth): + w3_eth: Web3 = ethermint.w3 + w3_geth: Web3 = geth.w3 + + flt_eth = w3_eth.eth.filter("pending") + flt_geth = w3_geth.eth.filter("pending") + + # without tx + assert flt_eth.get_new_entries() == [] + assert flt_eth.get_new_entries() == flt_geth.get_new_entries() + + # with tx + txhash1, receipt1 = send_transaction(w3_eth) + txhash2, receipt2 = send_transaction(w3_geth) + + assert receipt1, receipt2 + assert txhash1, txhash2 + assert txhash1 in flt_eth.get_new_entries() + assert txhash2 in flt_geth.get_new_entries() + +def send_transaction(w3): + signed = sign_transaction(w3, {"to": ADDRS["community"], "value": 1000}) + txhash = w3.eth.send_raw_transaction(signed.rawTransaction) + receipt = w3.eth.wait_for_transaction_receipt(txhash) + assert receipt.status == 1 + + return txhash, receipt From e3f5b575f27c97744ab733d53dd75d3bf62068e5 Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Wed, 10 Aug 2022 16:25:11 +0200 Subject: [PATCH 2/9] tests(rpc): add block filter and event log test --- tests/integration_tests/README.md | 2 - .../contracts/contracts/Greeter.sol | 20 ++++++ tests/integration_tests/test_filters.py | 72 ++++++++++++++++--- tests/integration_tests/utils.py | 2 +- 4 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 tests/integration_tests/contracts/contracts/Greeter.sol diff --git a/tests/integration_tests/README.md b/tests/integration_tests/README.md index 00dc2ee6e1..bd9275db82 100644 --- a/tests/integration_tests/README.md +++ b/tests/integration_tests/README.md @@ -24,8 +24,6 @@ For linux: sh <(curl -L https://nixos.org/nix/install) --no-daemon ``` - - ## Run Local Fist time run (can take a while): diff --git a/tests/integration_tests/contracts/contracts/Greeter.sol b/tests/integration_tests/contracts/contracts/Greeter.sol new file mode 100644 index 0000000000..2f5dbda54f --- /dev/null +++ b/tests/integration_tests/contracts/contracts/Greeter.sol @@ -0,0 +1,20 @@ +pragma solidity >0.5.0; + +contract Greeter { + string public greeting; + + event ChangeGreeting(address from, string value); + + constructor() public { + greeting = "Hello"; + } + + function setGreeting(string memory _greeting) public { + greeting = _greeting; + emit ChangeGreeting(msg.sender, _greeting); + } + + function greet() public view returns (string memory) { + return greeting; + } +} diff --git a/tests/integration_tests/test_filters.py b/tests/integration_tests/test_filters.py index d373ce445a..863a3a1e27 100644 --- a/tests/integration_tests/test_filters.py +++ b/tests/integration_tests/test_filters.py @@ -3,10 +3,9 @@ from .utils import ADDRS, CONTRACTS, deploy_contract, send_transaction, sign_transaction def test_pending_transaction_filter(ethermint, geth): - w3_eth: Web3 = ethermint.w3 + w3_ethm: Web3 = ethermint.w3 w3_geth: Web3 = geth.w3 - - flt_eth = w3_eth.eth.filter("pending") + flt_eth = w3_ethm.eth.filter("pending") flt_geth = w3_geth.eth.filter("pending") # without tx @@ -14,18 +13,75 @@ def test_pending_transaction_filter(ethermint, geth): assert flt_eth.get_new_entries() == flt_geth.get_new_entries() # with tx - txhash1, receipt1 = send_transaction(w3_eth) - txhash2, receipt2 = send_transaction(w3_geth) - + txhash1, receipt1 = send_successful_transaction(w3_ethm) + txhash2, receipt2 = send_successful_transaction(w3_geth) assert receipt1, receipt2 assert txhash1, txhash2 assert txhash1 in flt_eth.get_new_entries() assert txhash2 in flt_geth.get_new_entries() -def send_transaction(w3): +def test_block_filter(ethermint, geth): + w3_ethm: Web3 = ethermint.w3 + w3_geth: Web3 = geth.w3 + flt_eth = w3_ethm.eth.filter("latest") + flt_geth = w3_geth.eth.filter("latest") + + # without tx + assert flt_eth.get_new_entries() == [] + assert flt_eth.get_new_entries() == flt_geth.get_new_entries() + + # with tx + send_successful_transaction(w3_ethm) + send_successful_transaction(w3_geth) + blocks1 = flt_eth.get_new_entries() + blocks2 = flt_geth.get_new_entries() + + assert len(blocks1) >= 1 + assert len(blocks2) >= 1 + assert blocks1, blocks2 + +def send_successful_transaction(w3): signed = sign_transaction(w3, {"to": ADDRS["community"], "value": 1000}) txhash = w3.eth.send_raw_transaction(signed.rawTransaction) receipt = w3.eth.wait_for_transaction_receipt(txhash) assert receipt.status == 1 - return txhash, receipt + +def test_event_log_filter(ethermint, geth): + w3_ethm: Web3 = ethermint.w3 + w3_geth: Web3 = geth.w3 + + contract1 = deploy_contract(w3_ethm, CONTRACTS["Greeter"]) + contract2 = deploy_contract(w3_geth, CONTRACTS["Greeter"]) + + assert contract1.caller.greet() == "Hello" + assert contract1.caller.greet() == contract2.caller.greet() + + current_height1 = hex(w3_ethm.eth.get_block_number()) + event_filter1 = contract1.events.ChangeGreeting.createFilter( + fromBlock=current_height1 + ) + + current_height2 = hex(w3_ethm.eth.get_block_number()) + event_filter2 = contract1.events.ChangeGreeting.createFilter( + fromBlock=current_height2 + ) + + tx1 = contract1.functions.setGreeting("world").buildTransaction() + tx2 = contract2.functions.setGreeting("world").buildTransaction() + tx_receipt1 = send_transaction(w3_ethm, tx1) + tx_receipt2 = send_transaction(w3_geth, tx2) + assert tx_receipt1.status == 1 + assert tx_receipt2.status == 1 + + log1 = contract1.events.ChangeGreeting().processReceipt(tx_receipt1)[0] + log2 = contract1.events.ChangeGreeting().processReceipt(tx_receipt1)[0] + assert log1["event"] == log2["event"] + + new_entries1 = event_filter1.get_new_entries() + new_entries2 = event_filter2.get_new_entries() + assert len(new_entries1) == len(new_entries2) + # print(f"get event: {new_entries}") + assert new_entries1[0] == new_entries2[0] + assert contract1.caller.greet() == "world" + assert contract2.caller.greet() == "world" \ No newline at end of file diff --git a/tests/integration_tests/utils.py b/tests/integration_tests/utils.py index ed15b35cdd..bf9861ff9e 100644 --- a/tests/integration_tests/utils.py +++ b/tests/integration_tests/utils.py @@ -21,9 +21,9 @@ ETHERMINT_ADDRESS_PREFIX = "ethm" TEST_CONTRACTS = { "TestERC20A": "TestERC20A.sol", + "Greeter": "Greeter.sol", } - def contract_path(name, filename): return ( Path(__file__).parent From 9ef37d2b7a3eba1170d5975a6ffb59844f3e25a3 Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Wed, 10 Aug 2022 18:40:23 +0200 Subject: [PATCH 3/9] tests(rpc): simplify to cluster instead of comparing types --- rpc/namespaces/ethereum/eth/filters/api.go | 4 +- tests/integration_tests/test_filters.py | 99 +++++++--------------- 2 files changed, 33 insertions(+), 70 deletions(-) diff --git a/rpc/namespaces/ethereum/eth/filters/api.go b/rpc/namespaces/ethereum/eth/filters/api.go index 669580a5c2..994e808fe0 100644 --- a/rpc/namespaces/ethereum/eth/filters/api.go +++ b/rpc/namespaces/ethereum/eth/filters/api.go @@ -25,11 +25,11 @@ import ( // FilterAPI gathers type FilterAPI interface { - GetLogs(ctx context.Context, crit filters.FilterCriteria) ([]*ethtypes.Log, error) + NewFilter(criteria filters.FilterCriteria) (rpc.ID, error) GetFilterChanges(id rpc.ID) (interface{}, error) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ethtypes.Log, error) + GetLogs(ctx context.Context, crit filters.FilterCriteria) ([]*ethtypes.Log, error) NewBlockFilter() rpc.ID - NewFilter(criteria filters.FilterCriteria) (rpc.ID, error) NewPendingTransactionFilter() rpc.ID UninstallFilter(id rpc.ID) bool } diff --git a/tests/integration_tests/test_filters.py b/tests/integration_tests/test_filters.py index 863a3a1e27..1de1b9529f 100644 --- a/tests/integration_tests/test_filters.py +++ b/tests/integration_tests/test_filters.py @@ -2,86 +2,49 @@ from .utils import ADDRS, CONTRACTS, deploy_contract, send_transaction, sign_transaction -def test_pending_transaction_filter(ethermint, geth): - w3_ethm: Web3 = ethermint.w3 - w3_geth: Web3 = geth.w3 - flt_eth = w3_ethm.eth.filter("pending") - flt_geth = w3_geth.eth.filter("pending") +def test_pending_transaction_filter(cluster): + w3: Web3 = cluster.w3 + flt = w3.eth.filter("pending") + assert flt.get_new_entries() == [] - # without tx - assert flt_eth.get_new_entries() == [] - assert flt_eth.get_new_entries() == flt_geth.get_new_entries() + txhash = send_successful_transaction(w3) + assert txhash in flt.get_new_entries() - # with tx - txhash1, receipt1 = send_successful_transaction(w3_ethm) - txhash2, receipt2 = send_successful_transaction(w3_geth) - assert receipt1, receipt2 - assert txhash1, txhash2 - assert txhash1 in flt_eth.get_new_entries() - assert txhash2 in flt_geth.get_new_entries() +def test_block_filter(cluster): + w3: Web3 = cluster.w3 + flt = w3.eth.filter("latest") + assert flt.get_new_entries() == [] -def test_block_filter(ethermint, geth): - w3_ethm: Web3 = ethermint.w3 - w3_geth: Web3 = geth.w3 - flt_eth = w3_ethm.eth.filter("latest") - flt_geth = w3_geth.eth.filter("latest") - - # without tx - assert flt_eth.get_new_entries() == [] - assert flt_eth.get_new_entries() == flt_geth.get_new_entries() - - # with tx - send_successful_transaction(w3_ethm) - send_successful_transaction(w3_geth) - blocks1 = flt_eth.get_new_entries() - blocks2 = flt_geth.get_new_entries() - - assert len(blocks1) >= 1 - assert len(blocks2) >= 1 - assert blocks1, blocks2 + send_successful_transaction(w3) + blocks = flt.get_new_entries() + assert len(blocks) >= 1 +# TODO replace with send_and_get_hash def send_successful_transaction(w3): signed = sign_transaction(w3, {"to": ADDRS["community"], "value": 1000}) txhash = w3.eth.send_raw_transaction(signed.rawTransaction) receipt = w3.eth.wait_for_transaction_receipt(txhash) assert receipt.status == 1 - return txhash, receipt - -def test_event_log_filter(ethermint, geth): - w3_ethm: Web3 = ethermint.w3 - w3_geth: Web3 = geth.w3 + return txhash - contract1 = deploy_contract(w3_ethm, CONTRACTS["Greeter"]) - contract2 = deploy_contract(w3_geth, CONTRACTS["Greeter"]) - - assert contract1.caller.greet() == "Hello" - assert contract1.caller.greet() == contract2.caller.greet() - - current_height1 = hex(w3_ethm.eth.get_block_number()) - event_filter1 = contract1.events.ChangeGreeting.createFilter( - fromBlock=current_height1 - ) +def test_event_log_filter(cluster): + w3: Web3 = cluster.w3 + myContract = deploy_contract(w3, CONTRACTS["Greeter"]) + assert myContract.caller.greet() == "Hello" - current_height2 = hex(w3_ethm.eth.get_block_number()) - event_filter2 = contract1.events.ChangeGreeting.createFilter( - fromBlock=current_height2 + current_height = hex(w3.eth.get_block_number()) + event_filter = myContract.events.ChangeGreeting.createFilter( + fromBlock=current_height ) - tx1 = contract1.functions.setGreeting("world").buildTransaction() - tx2 = contract2.functions.setGreeting("world").buildTransaction() - tx_receipt1 = send_transaction(w3_ethm, tx1) - tx_receipt2 = send_transaction(w3_geth, tx2) - assert tx_receipt1.status == 1 - assert tx_receipt2.status == 1 + tx = myContract.functions.setGreeting("world").buildTransaction() + tx_receipt = send_transaction(w3, tx) + assert tx_receipt.status == 1 - log1 = contract1.events.ChangeGreeting().processReceipt(tx_receipt1)[0] - log2 = contract1.events.ChangeGreeting().processReceipt(tx_receipt1)[0] - assert log1["event"] == log2["event"] + log = myContract.events.ChangeGreeting().processReceipt(tx_receipt)[0] + assert log["event"] == "ChangeGreeting" - new_entries1 = event_filter1.get_new_entries() - new_entries2 = event_filter2.get_new_entries() - assert len(new_entries1) == len(new_entries2) - # print(f"get event: {new_entries}") - assert new_entries1[0] == new_entries2[0] - assert contract1.caller.greet() == "world" - assert contract2.caller.greet() == "world" \ No newline at end of file + new_entries = event_filter.get_new_entries() + assert len(new_entries) == 1 + assert new_entries[0] == log + assert myContract.caller.greet() == "world" From 624f887d45a1deab8f8803f8b7e3d649e2c7954e Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Thu, 11 Aug 2022 17:55:46 +0200 Subject: [PATCH 4/9] tests(rpc): wip filter by address --- rpc/namespaces/ethereum/eth/filters/api.go | 6 +- tests/integration_tests/test_filters.py | 157 +++++++++++++++------ 2 files changed, 118 insertions(+), 45 deletions(-) diff --git a/rpc/namespaces/ethereum/eth/filters/api.go b/rpc/namespaces/ethereum/eth/filters/api.go index 994e808fe0..0f6cf05df0 100644 --- a/rpc/namespaces/ethereum/eth/filters/api.go +++ b/rpc/namespaces/ethereum/eth/filters/api.go @@ -25,13 +25,13 @@ import ( // FilterAPI gathers type FilterAPI interface { + NewPendingTransactionFilter() rpc.ID + NewBlockFilter() rpc.ID NewFilter(criteria filters.FilterCriteria) (rpc.ID, error) GetFilterChanges(id rpc.ID) (interface{}, error) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ethtypes.Log, error) - GetLogs(ctx context.Context, crit filters.FilterCriteria) ([]*ethtypes.Log, error) - NewBlockFilter() rpc.ID - NewPendingTransactionFilter() rpc.ID UninstallFilter(id rpc.ID) bool + GetLogs(ctx context.Context, crit filters.FilterCriteria) ([]*ethtypes.Log, error) } // Backend defines the methods requided by the PublicFilterAPI backend diff --git a/tests/integration_tests/test_filters.py b/tests/integration_tests/test_filters.py index 1de1b9529f..a68f3e17fa 100644 --- a/tests/integration_tests/test_filters.py +++ b/tests/integration_tests/test_filters.py @@ -1,50 +1,123 @@ from web3 import Web3 -from .utils import ADDRS, CONTRACTS, deploy_contract, send_transaction, sign_transaction +import pytest +from .utils import ( + ADDRS, + CONTRACTS, + deploy_contract, + send_transaction, + sign_transaction, +) -def test_pending_transaction_filter(cluster): - w3: Web3 = cluster.w3 - flt = w3.eth.filter("pending") - assert flt.get_new_entries() == [] +# def test_pending_transaction_filter(cluster): +# w3: Web3 = cluster.w3 +# flt = w3.eth.filter("pending") - txhash = send_successful_transaction(w3) - assert txhash in flt.get_new_entries() +# # without tx +# assert flt.get_new_entries() == [] # GetFilterChanges -def test_block_filter(cluster): - w3: Web3 = cluster.w3 - flt = w3.eth.filter("latest") - assert flt.get_new_entries() == [] +# # with tx +# txhash = send_successful_transaction(w3) +# assert txhash in flt.get_new_entries() + +# # without new txs since last call +# assert flt.get_new_entries() == [] + + +# def test_block_filter(cluster): +# w3: Web3 = cluster.w3 +# flt = w3.eth.filter("latest") + +# # without tx +# assert flt.get_new_entries() == [] + +# # with tx +# send_successful_transaction(w3) +# blocks = flt.get_new_entries() +# assert len(blocks) >= 1 + +# # without new txs since last call +# assert flt.get_new_entries() == [] + + +# # Event Logs + +# # # through contract +# # event_filter = mycontract.events.myEvent.createFilter(fromBlock='latest', argument_filters={'arg1':10}) + +# # # manual +# # event_filter = w3.eth.filter({"address": contract_address}) + +# # # with existing filter id +# # existing_filter = w3.eth.filter(filter_id="0x0") + + +def test_event_log_filter_from_contract(cluster): + w3: Web3 = cluster.w3 + myContract = deploy_contract(w3, CONTRACTS["Greeter"]) + assert myContract.caller.greet() == "Hello" + + # Create new filter from contract + current_height = hex(w3.eth.get_block_number()) + flt = myContract.events.ChangeGreeting.createFilter( + fromBlock=current_height + ) + + # without tx + assert flt.get_new_entries() == [] # GetFilterChanges + assert flt.get_all_entries() == [] # GetFilterLogs + + # with tx + tx = myContract.functions.setGreeting("world").buildTransaction() + tx_receipt = send_transaction(w3, tx) + assert tx_receipt.status == 1 + + log = myContract.events.ChangeGreeting().processReceipt(tx_receipt)[0] + assert log["event"] == "ChangeGreeting" + + new_entries = flt.get_new_entries() + assert len(new_entries) == 1 + assert new_entries[0] == log + assert myContract.caller.greet() == "world" + + # without new txs since last call + assert flt.get_new_entries() == [] + assert flt.get_all_entries() == new_entries + + # Uninstall + assert w3.eth.uninstall_filter(flt.filter_id) == True + assert w3.eth.uninstall_filter(flt.filter_id) == False + with pytest.raises(Exception): + flt.get_all_entries() + +def test_event_log_filter_by_address(cluster): + w3: Web3 = cluster.w3 + # TODO how to get the addr? + myContract = deploy_contract(w3, CONTRACTS["Greeter"]) + assert myContract.caller.greet() == "Hello" + + flt = w3.eth.filter({"address": addr}) + + # without tx + assert flt.get_new_entries() == [] # GetFilterChanges + assert flt.get_all_entries() == [] # GetFilterLogs + + # with tx + tx = myContract.functions.setGreeting("world").buildTransaction() + tx_receipt = send_transaction(w3, tx) + assert tx_receipt.status == 1 + + new_entries = flt.get_new_entries() + assert len(new_entries) == 1 - send_successful_transaction(w3) - blocks = flt.get_new_entries() - assert len(blocks) >= 1 # TODO replace with send_and_get_hash -def send_successful_transaction(w3): - signed = sign_transaction(w3, {"to": ADDRS["community"], "value": 1000}) - txhash = w3.eth.send_raw_transaction(signed.rawTransaction) - receipt = w3.eth.wait_for_transaction_receipt(txhash) - assert receipt.status == 1 - return txhash - -def test_event_log_filter(cluster): - w3: Web3 = cluster.w3 - myContract = deploy_contract(w3, CONTRACTS["Greeter"]) - assert myContract.caller.greet() == "Hello" - - current_height = hex(w3.eth.get_block_number()) - event_filter = myContract.events.ChangeGreeting.createFilter( - fromBlock=current_height - ) - - tx = myContract.functions.setGreeting("world").buildTransaction() - tx_receipt = send_transaction(w3, tx) - assert tx_receipt.status == 1 - - log = myContract.events.ChangeGreeting().processReceipt(tx_receipt)[0] - assert log["event"] == "ChangeGreeting" - - new_entries = event_filter.get_new_entries() - assert len(new_entries) == 1 - assert new_entries[0] == log - assert myContract.caller.greet() == "world" +def send_successful_transaction(w3, addr=ADDRS["community"]): + signed = sign_transaction(w3, {"to": addr, "value": 1000}) + txhash = w3.eth.send_raw_transaction(signed.rawTransaction) + receipt = w3.eth.wait_for_transaction_receipt(txhash) + assert receipt.status == 1 + return txhash + + + From 539926aaf752bedec8a693ba90019bd9004813bf Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Thu, 11 Aug 2022 22:20:12 +0200 Subject: [PATCH 5/9] tests(rpc): add get_logs test --- tests/integration_tests/README.md | 10 +-- tests/integration_tests/test_filters.py | 93 ++++++++++++------------- tests/integration_tests/utils.py | 8 +++ 3 files changed, 58 insertions(+), 53 deletions(-) diff --git a/tests/integration_tests/README.md b/tests/integration_tests/README.md index bd9275db82..476c99302a 100644 --- a/tests/integration_tests/README.md +++ b/tests/integration_tests/README.md @@ -4,7 +4,7 @@ The RPC integration test suite uses nix and python to send identical queries to ## Installation -Multi-user installation: +Nix Multi-user installation: ``` sh <(curl -L https://nixos.org/nix/install) --daemon @@ -26,16 +26,18 @@ sh <(curl -L https://nixos.org/nix/install) --no-daemon ## Run Local -Fist time run (can take a while): +First time run (can take a while): ``` make run-integration-tests ``` -Once you've run them once, you can run. +Once you've run them once and, you can run: ``` nix-shell tests/integration_tests/shell.nix cd tests/integration_tests pytest -s -vv -``` \ No newline at end of file +``` + +If you're changing anything on the ethermint rpc, rerun the first command. diff --git a/tests/integration_tests/test_filters.py b/tests/integration_tests/test_filters.py index a68f3e17fa..339078a67a 100644 --- a/tests/integration_tests/test_filters.py +++ b/tests/integration_tests/test_filters.py @@ -2,57 +2,44 @@ import pytest from .utils import ( - ADDRS, CONTRACTS, deploy_contract, send_transaction, - sign_transaction, + send_successful_transaction, ) -# def test_pending_transaction_filter(cluster): -# w3: Web3 = cluster.w3 -# flt = w3.eth.filter("pending") - -# # without tx -# assert flt.get_new_entries() == [] # GetFilterChanges - -# # with tx -# txhash = send_successful_transaction(w3) -# assert txhash in flt.get_new_entries() - -# # without new txs since last call -# assert flt.get_new_entries() == [] - - -# def test_block_filter(cluster): -# w3: Web3 = cluster.w3 -# flt = w3.eth.filter("latest") +def test_pending_transaction_filter(cluster): + w3: Web3 = cluster.w3 + flt = w3.eth.filter("pending") -# # without tx -# assert flt.get_new_entries() == [] + # without tx + assert flt.get_new_entries() == [] # GetFilterChanges -# # with tx -# send_successful_transaction(w3) -# blocks = flt.get_new_entries() -# assert len(blocks) >= 1 + # with tx + txhash = send_successful_transaction(w3) + assert txhash in flt.get_new_entries() -# # without new txs since last call -# assert flt.get_new_entries() == [] + # without new txs since last call + assert flt.get_new_entries() == [] -# # Event Logs +def test_block_filter(cluster): + w3: Web3 = cluster.w3 + flt = w3.eth.filter("latest") -# # # through contract -# # event_filter = mycontract.events.myEvent.createFilter(fromBlock='latest', argument_filters={'arg1':10}) + # without tx + assert flt.get_new_entries() == [] -# # # manual -# # event_filter = w3.eth.filter({"address": contract_address}) + # with tx + send_successful_transaction(w3) + blocks = flt.get_new_entries() + assert len(blocks) >= 1 -# # # with existing filter id -# # existing_filter = w3.eth.filter(filter_id="0x0") + # without new txs since last call + assert flt.get_new_entries() == [] -def test_event_log_filter_from_contract(cluster): +def test_event_log_filter_by_contract(cluster): w3: Web3 = cluster.w3 myContract = deploy_contract(w3, CONTRACTS["Greeter"]) assert myContract.caller.greet() == "Hello" @@ -90,13 +77,15 @@ def test_event_log_filter_from_contract(cluster): with pytest.raises(Exception): flt.get_all_entries() + def test_event_log_filter_by_address(cluster): w3: Web3 = cluster.w3 - # TODO how to get the addr? + myContract = deploy_contract(w3, CONTRACTS["Greeter"]) assert myContract.caller.greet() == "Hello" - flt = w3.eth.filter({"address": addr}) + flt = w3.eth.filter({"address": myContract.address}) + flt2 = w3.eth.filter({"address": "0x0000000000000000000000000000000000000000"}) # without tx assert flt.get_new_entries() == [] # GetFilterChanges @@ -104,20 +93,26 @@ def test_event_log_filter_by_address(cluster): # with tx tx = myContract.functions.setGreeting("world").buildTransaction() - tx_receipt = send_transaction(w3, tx) - assert tx_receipt.status == 1 + receipt = send_transaction(w3, tx) + assert receipt.status == 1 - new_entries = flt.get_new_entries() - assert len(new_entries) == 1 + assert len(flt.get_new_entries()) == 1 + assert len(flt2.get_new_entries()) == 0 -# TODO replace with send_and_get_hash -def send_successful_transaction(w3, addr=ADDRS["community"]): - signed = sign_transaction(w3, {"to": addr, "value": 1000}) - txhash = w3.eth.send_raw_transaction(signed.rawTransaction) - receipt = w3.eth.wait_for_transaction_receipt(txhash) - assert receipt.status == 1 - return txhash +def test_get_logs(cluster): + w3: Web3 = cluster.w3 + + myContract = deploy_contract(w3, CONTRACTS["Greeter"]) + # without tx + assert w3.eth.get_logs({"address": myContract.address}) == [] + assert w3.eth.get_logs({"address": "0x0000000000000000000000000000000000000000"}) == [] + # with tx + tx = myContract.functions.setGreeting("world").buildTransaction() + receipt = send_transaction(w3, tx) + assert receipt.status == 1 + assert len(w3.eth.get_logs({"address": myContract.address})) == 1 + assert len(w3.eth.get_logs({"address": "0x0000000000000000000000000000000000000000"})) == 0 \ No newline at end of file diff --git a/tests/integration_tests/utils.py b/tests/integration_tests/utils.py index bf9861ff9e..2ac6d9bb85 100644 --- a/tests/integration_tests/utils.py +++ b/tests/integration_tests/utils.py @@ -95,3 +95,11 @@ def send_transaction(w3, tx, key=KEYS["validator"]): signed = sign_transaction(w3, tx, key) txhash = w3.eth.send_raw_transaction(signed.rawTransaction) return w3.eth.wait_for_transaction_receipt(txhash) + + +def send_successful_transaction(w3): + signed = sign_transaction(w3, {"to": ADDRS["community"], "value": 1000}) + txhash = w3.eth.send_raw_transaction(signed.rawTransaction) + receipt = w3.eth.wait_for_transaction_receipt(txhash) + assert receipt.status == 1 + return txhash From 971f9bcf155db001a69e088eb9c9c6d97fe2a707 Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Thu, 11 Aug 2022 22:29:38 +0200 Subject: [PATCH 6/9] fix flake8 linter --- tests/integration_tests/test_filters.py | 22 ++++++++++++---------- tests/integration_tests/utils.py | 1 + 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/integration_tests/test_filters.py b/tests/integration_tests/test_filters.py index 339078a67a..4a458dc7bc 100644 --- a/tests/integration_tests/test_filters.py +++ b/tests/integration_tests/test_filters.py @@ -2,18 +2,20 @@ import pytest from .utils import ( + ADDRS, CONTRACTS, deploy_contract, send_transaction, send_successful_transaction, ) + def test_pending_transaction_filter(cluster): w3: Web3 = cluster.w3 flt = w3.eth.filter("pending") # without tx - assert flt.get_new_entries() == [] # GetFilterChanges + assert flt.get_new_entries() == [] # GetFilterChanges # with tx txhash = send_successful_transaction(w3) @@ -51,8 +53,8 @@ def test_event_log_filter_by_contract(cluster): ) # without tx - assert flt.get_new_entries() == [] # GetFilterChanges - assert flt.get_all_entries() == [] # GetFilterLogs + assert flt.get_new_entries() == [] # GetFilterChanges + assert flt.get_all_entries() == [] # GetFilterLogs # with tx tx = myContract.functions.setGreeting("world").buildTransaction() @@ -72,8 +74,8 @@ def test_event_log_filter_by_contract(cluster): assert flt.get_all_entries() == new_entries # Uninstall - assert w3.eth.uninstall_filter(flt.filter_id) == True - assert w3.eth.uninstall_filter(flt.filter_id) == False + assert w3.eth.uninstall_filter(flt.filter_id) + assert not w3.eth.uninstall_filter(flt.filter_id) with pytest.raises(Exception): flt.get_all_entries() @@ -85,11 +87,11 @@ def test_event_log_filter_by_address(cluster): assert myContract.caller.greet() == "Hello" flt = w3.eth.filter({"address": myContract.address}) - flt2 = w3.eth.filter({"address": "0x0000000000000000000000000000000000000000"}) + flt2 = w3.eth.filter({"address": ADDRS["validator"]}) # without tx - assert flt.get_new_entries() == [] # GetFilterChanges - assert flt.get_all_entries() == [] # GetFilterLogs + assert flt.get_new_entries() == [] # GetFilterChanges + assert flt.get_all_entries() == [] # GetFilterLogs # with tx tx = myContract.functions.setGreeting("world").buildTransaction() @@ -107,7 +109,7 @@ def test_get_logs(cluster): # without tx assert w3.eth.get_logs({"address": myContract.address}) == [] - assert w3.eth.get_logs({"address": "0x0000000000000000000000000000000000000000"}) == [] + assert w3.eth.get_logs({"address": ADDRS["validator"]}) == [] # with tx tx = myContract.functions.setGreeting("world").buildTransaction() @@ -115,4 +117,4 @@ def test_get_logs(cluster): assert receipt.status == 1 assert len(w3.eth.get_logs({"address": myContract.address})) == 1 - assert len(w3.eth.get_logs({"address": "0x0000000000000000000000000000000000000000"})) == 0 \ No newline at end of file + assert len(w3.eth.get_logs({"address": ADDRS["validator"]})) == 0 diff --git a/tests/integration_tests/utils.py b/tests/integration_tests/utils.py index 2ac6d9bb85..6ba098971f 100644 --- a/tests/integration_tests/utils.py +++ b/tests/integration_tests/utils.py @@ -24,6 +24,7 @@ "Greeter": "Greeter.sol", } + def contract_path(name, filename): return ( Path(__file__).parent From afb4c298afcceb257bd54ca990e07c115d8d4605 Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Fri, 12 Aug 2022 10:45:30 +0200 Subject: [PATCH 7/9] fix flake8 linter --- tests/integration_tests/test_filters.py | 34 ++++++++++++------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/tests/integration_tests/test_filters.py b/tests/integration_tests/test_filters.py index 4a458dc7bc..1f871eeebd 100644 --- a/tests/integration_tests/test_filters.py +++ b/tests/integration_tests/test_filters.py @@ -1,12 +1,12 @@ +import pytest from web3 import Web3 -import pytest from .utils import ( ADDRS, CONTRACTS, deploy_contract, - send_transaction, send_successful_transaction, + send_transaction, ) @@ -43,31 +43,29 @@ def test_block_filter(cluster): def test_event_log_filter_by_contract(cluster): w3: Web3 = cluster.w3 - myContract = deploy_contract(w3, CONTRACTS["Greeter"]) - assert myContract.caller.greet() == "Hello" + contract = deploy_contract(w3, CONTRACTS["Greeter"]) + assert contract.caller.greet() == "Hello" # Create new filter from contract current_height = hex(w3.eth.get_block_number()) - flt = myContract.events.ChangeGreeting.createFilter( - fromBlock=current_height - ) + flt = contract.events.ChangeGreeting.createFilter(fromBlock=current_height) # without tx assert flt.get_new_entries() == [] # GetFilterChanges assert flt.get_all_entries() == [] # GetFilterLogs # with tx - tx = myContract.functions.setGreeting("world").buildTransaction() + tx = contract.functions.setGreeting("world").buildTransaction() tx_receipt = send_transaction(w3, tx) assert tx_receipt.status == 1 - log = myContract.events.ChangeGreeting().processReceipt(tx_receipt)[0] + log = contract.events.ChangeGreeting().processReceipt(tx_receipt)[0] assert log["event"] == "ChangeGreeting" new_entries = flt.get_new_entries() assert len(new_entries) == 1 assert new_entries[0] == log - assert myContract.caller.greet() == "world" + assert contract.caller.greet() == "world" # without new txs since last call assert flt.get_new_entries() == [] @@ -83,10 +81,10 @@ def test_event_log_filter_by_contract(cluster): def test_event_log_filter_by_address(cluster): w3: Web3 = cluster.w3 - myContract = deploy_contract(w3, CONTRACTS["Greeter"]) - assert myContract.caller.greet() == "Hello" + contract = deploy_contract(w3, CONTRACTS["Greeter"]) + assert contract.caller.greet() == "Hello" - flt = w3.eth.filter({"address": myContract.address}) + flt = w3.eth.filter({"address": contract.address}) flt2 = w3.eth.filter({"address": ADDRS["validator"]}) # without tx @@ -94,7 +92,7 @@ def test_event_log_filter_by_address(cluster): assert flt.get_all_entries() == [] # GetFilterLogs # with tx - tx = myContract.functions.setGreeting("world").buildTransaction() + tx = contract.functions.setGreeting("world").buildTransaction() receipt = send_transaction(w3, tx) assert receipt.status == 1 @@ -105,16 +103,16 @@ def test_event_log_filter_by_address(cluster): def test_get_logs(cluster): w3: Web3 = cluster.w3 - myContract = deploy_contract(w3, CONTRACTS["Greeter"]) + contract = deploy_contract(w3, CONTRACTS["Greeter"]) # without tx - assert w3.eth.get_logs({"address": myContract.address}) == [] + assert w3.eth.get_logs({"address": contract.address}) == [] assert w3.eth.get_logs({"address": ADDRS["validator"]}) == [] # with tx - tx = myContract.functions.setGreeting("world").buildTransaction() + tx = contract.functions.setGreeting("world").buildTransaction() receipt = send_transaction(w3, tx) assert receipt.status == 1 - assert len(w3.eth.get_logs({"address": myContract.address})) == 1 + assert len(w3.eth.get_logs({"address": contract.address})) == 1 assert len(w3.eth.get_logs({"address": ADDRS["validator"]})) == 0 From 34dff980b223916a78b69cabd4cfe29ef1f8eb5e Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Fri, 12 Aug 2022 14:52:42 +0200 Subject: [PATCH 8/9] add caching to readme --- tests/integration_tests/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/integration_tests/README.md b/tests/integration_tests/README.md index 476c99302a..efa860a2c0 100644 --- a/tests/integration_tests/README.md +++ b/tests/integration_tests/README.md @@ -41,3 +41,13 @@ pytest -s -vv ``` If you're changing anything on the ethermint rpc, rerun the first command. + + +## Caching + +You can enable Binary Cache to speed up the tests: + +``` +$ nix-env -iA cachix -f https://cachix.org/api/v1/install +$ cachix use ethermint +``` \ No newline at end of file From ef330579769d7d5f51d70897aafe14fd379dbaaf Mon Sep 17 00:00:00 2001 From: Daniel Burckhardt Date: Fri, 12 Aug 2022 14:53:42 +0200 Subject: [PATCH 9/9] add caching to readme --- tests/integration_tests/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/integration_tests/README.md b/tests/integration_tests/README.md index efa860a2c0..d321b7fb72 100644 --- a/tests/integration_tests/README.md +++ b/tests/integration_tests/README.md @@ -1,6 +1,8 @@ # RPC Integration tests -The RPC integration test suite uses nix and python to send identical queries to both an Ethermint and a [Geth](https://github.com/ethereum/go-ethereum) client and compare the responses. It allows for quickly assessing the compatibility with Geth. +The RPC integration test suite uses nix for reproducible and configurable +builds allowing to run integration tests using python web3 library against +different Ethermint and [Geth](https://github.com/ethereum/go-ethereum) clients with multiple configurations. ## Installation