tests(rpc): add filter tests (#1233)
* tests(rpc): add pending transaction filter test * tests(rpc): add block filter and event log test * tests(rpc): simplify to cluster instead of comparing types * tests(rpc): wip filter by address * tests(rpc): add get_logs test * fix flake8 linter * fix flake8 linter * add caching to readme * add caching to readme Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
94cab52ca1
commit
9bbf356c6b
@ -25,13 +25,13 @@ import (
|
||||
|
||||
// FilterAPI gathers
|
||||
type FilterAPI interface {
|
||||
GetLogs(ctx context.Context, crit filters.FilterCriteria) ([]*ethtypes.Log, error)
|
||||
GetFilterChanges(id rpc.ID) (interface{}, error)
|
||||
GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ethtypes.Log, error)
|
||||
NewPendingTransactionFilter() rpc.ID
|
||||
NewBlockFilter() rpc.ID
|
||||
NewFilter(criteria filters.FilterCriteria) (rpc.ID, error)
|
||||
NewPendingTransactionFilter() rpc.ID
|
||||
GetFilterChanges(id rpc.ID) (interface{}, error)
|
||||
GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ethtypes.Log, error)
|
||||
UninstallFilter(id rpc.ID) bool
|
||||
GetLogs(ctx context.Context, crit filters.FilterCriteria) ([]*ethtypes.Log, error)
|
||||
}
|
||||
|
||||
// Backend defines the methods requided by the PublicFilterAPI backend
|
||||
|
55
tests/integration_tests/README.md
Normal file
55
tests/integration_tests/README.md
Normal file
@ -0,0 +1,55 @@
|
||||
# RPC Integration tests
|
||||
|
||||
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
|
||||
|
||||
Nix 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
|
||||
|
||||
First time run (can take a while):
|
||||
|
||||
```
|
||||
make run-integration-tests
|
||||
```
|
||||
|
||||
Once you've run them once and, you can run:
|
||||
|
||||
```
|
||||
nix-shell tests/integration_tests/shell.nix
|
||||
cd tests/integration_tests
|
||||
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
|
||||
```
|
20
tests/integration_tests/contracts/contracts/Greeter.sol
Normal file
20
tests/integration_tests/contracts/contracts/Greeter.sol
Normal file
@ -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;
|
||||
}
|
||||
}
|
118
tests/integration_tests/test_filters.py
Normal file
118
tests/integration_tests/test_filters.py
Normal file
@ -0,0 +1,118 @@
|
||||
import pytest
|
||||
from web3 import Web3
|
||||
|
||||
from .utils import (
|
||||
ADDRS,
|
||||
CONTRACTS,
|
||||
deploy_contract,
|
||||
send_successful_transaction,
|
||||
send_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")
|
||||
|
||||
# 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() == []
|
||||
|
||||
|
||||
def test_event_log_filter_by_contract(cluster):
|
||||
w3: Web3 = cluster.w3
|
||||
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 = contract.events.ChangeGreeting.createFilter(fromBlock=current_height)
|
||||
|
||||
# without tx
|
||||
assert flt.get_new_entries() == [] # GetFilterChanges
|
||||
assert flt.get_all_entries() == [] # GetFilterLogs
|
||||
|
||||
# with tx
|
||||
tx = contract.functions.setGreeting("world").buildTransaction()
|
||||
tx_receipt = send_transaction(w3, tx)
|
||||
assert tx_receipt.status == 1
|
||||
|
||||
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 contract.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)
|
||||
assert not w3.eth.uninstall_filter(flt.filter_id)
|
||||
with pytest.raises(Exception):
|
||||
flt.get_all_entries()
|
||||
|
||||
|
||||
def test_event_log_filter_by_address(cluster):
|
||||
w3: Web3 = cluster.w3
|
||||
|
||||
contract = deploy_contract(w3, CONTRACTS["Greeter"])
|
||||
assert contract.caller.greet() == "Hello"
|
||||
|
||||
flt = w3.eth.filter({"address": contract.address})
|
||||
flt2 = w3.eth.filter({"address": ADDRS["validator"]})
|
||||
|
||||
# without tx
|
||||
assert flt.get_new_entries() == [] # GetFilterChanges
|
||||
assert flt.get_all_entries() == [] # GetFilterLogs
|
||||
|
||||
# with tx
|
||||
tx = contract.functions.setGreeting("world").buildTransaction()
|
||||
receipt = send_transaction(w3, tx)
|
||||
assert receipt.status == 1
|
||||
|
||||
assert len(flt.get_new_entries()) == 1
|
||||
assert len(flt2.get_new_entries()) == 0
|
||||
|
||||
|
||||
def test_get_logs(cluster):
|
||||
w3: Web3 = cluster.w3
|
||||
|
||||
contract = deploy_contract(w3, CONTRACTS["Greeter"])
|
||||
|
||||
# without tx
|
||||
assert w3.eth.get_logs({"address": contract.address}) == []
|
||||
assert w3.eth.get_logs({"address": ADDRS["validator"]}) == []
|
||||
|
||||
# with tx
|
||||
tx = contract.functions.setGreeting("world").buildTransaction()
|
||||
receipt = send_transaction(w3, tx)
|
||||
assert receipt.status == 1
|
||||
|
||||
assert len(w3.eth.get_logs({"address": contract.address})) == 1
|
||||
assert len(w3.eth.get_logs({"address": ADDRS["validator"]})) == 0
|
@ -24,6 +24,7 @@ ADDRS = {name: account.address for name, account in ACCOUNTS.items()}
|
||||
ETHERMINT_ADDRESS_PREFIX = "ethm"
|
||||
TEST_CONTRACTS = {
|
||||
"TestERC20A": "TestERC20A.sol",
|
||||
"Greeter": "Greeter.sol",
|
||||
}
|
||||
|
||||
|
||||
@ -140,6 +141,14 @@ def send_transaction(w3, tx, key=KEYS["validator"]):
|
||||
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
|
||||
|
||||
|
||||
def eth_to_bech32(addr, prefix=ETHERMINT_ADDRESS_PREFIX):
|
||||
bz = bech32.convertbits(HexBytes(addr), 8, 5)
|
||||
return bech32.bech32_encode(prefix, bz)
|
||||
|
Loading…
Reference in New Issue
Block a user