Skip to content

Commit

Permalink
Add tests for indexed and nonindexed arg filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
fselmo committed Aug 16, 2023
1 parent 111ddbc commit 6fdb44e
Show file tree
Hide file tree
Showing 10 changed files with 351 additions and 83 deletions.
3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ def emitter_contract_data():


class LogFunctions:
# These appear to be for a very specific test and this doesn't need to be updated
# for every event in the emitter contract. That ends up breaking that test.
LogAnonymous = 0
LogNoArguments = 1
LogSingleArg = 2
Expand Down Expand Up @@ -99,6 +101,7 @@ class LogTopics:
"LogAddressNotIndexed(address,address)"
)
LogStructArgs = event_signature_to_log_topic("LogStructArgs(uint256,tuple)")
LogIndexedAndNotIndexed = event_signature_to_log_topic("LogIndexedAndNotIndexed()")


@pytest.fixture(scope="session")
Expand Down
173 changes: 171 additions & 2 deletions tests/core/filtering/test_contract_get_logs.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import pytest

from web3._utils.contract_sources.contract_data._custom_contract_data import (
EMITTER_ENUM,
)


def test_contract_get_available_events(
emitter,
):
"""We can iterate over available contract events"""
contract = emitter
events = list(contract.events)
assert len(events) == 19
assert len(events) == len(EMITTER_ENUM)


def test_contract_get_logs_all(
Expand Down Expand Up @@ -87,6 +91,81 @@ def test_contract_get_logs_argument_filter(
assert len(partial_logs) == 4


def test_get_logs_argument_filters_indexed_and_non_indexed_args(emitter):
emitter.functions.logIndexedAndNotIndexedArgs(
f"0xdead{'00' * 17}01", # indexed address
101, # indexed uint256
f"0xBEEf{'00' * 17}01", # non-indexed address
201, # non-indexed uint256
"This is the FIRST string arg.", # non-indexed string
).transact()
emitter.functions.logIndexedAndNotIndexedArgs(
f"0xdEaD{'00' * 17}02",
102,
f"0xbeeF{'00' * 17}02",
202,
"This is the SECOND string arg.",
).transact()

# get all logs
logs_no_filter = emitter.events.LogIndexedAndNotIndexed.get_logs(fromBlock=1)
assert len(logs_no_filter) == 2

# filter for the second log by each of the indexed args and compare
logs_filter_indexed_address = emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"indexedAddress": f"0xdEaD{'00' * 17}02"},
)
logs_filter_indexed_uint256 = emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"indexedUint256": 102},
)
assert len(logs_filter_indexed_address) == len(logs_filter_indexed_uint256) == 1
assert (
logs_filter_indexed_address[0]
== logs_filter_indexed_uint256[0]
== logs_no_filter[1]
)

# filter for the first log by non-indexed address
logs_filter_non_indexed_address = emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"nonIndexedAddress": f"0xBEEf{'00' * 17}01"},
)
assert len(logs_filter_non_indexed_address) == 1
assert logs_filter_non_indexed_address[0] == logs_no_filter[0]

# filter for the second log by non-indexed uint256 and string separately
logs_filter_non_indexed_uint256 = emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"nonIndexedUint256": 202},
)
logs_filter_non_indexed_string = emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"nonIndexedString": "SECOND"},
)
assert len(logs_filter_non_indexed_uint256) == 1
assert len(logs_filter_non_indexed_string) == 1
assert (
logs_filter_non_indexed_uint256[0]
== logs_filter_non_indexed_string[0]
== logs_no_filter[1]
)

# filter by both string and uint256, non-indexed
logs_filter_non_indexed_uint256_and_string = (
emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={
"nonIndexedUint256": 201,
"nonIndexedString": "FIRST",
},
)
)
assert len(logs_filter_non_indexed_uint256_and_string) == 1
assert logs_filter_non_indexed_uint256_and_string[0] == logs_no_filter[0]


# --- async --- #


Expand All @@ -96,7 +175,7 @@ def test_async_contract_get_available_events(
"""We can iterate over available contract events"""
contract = async_emitter
events = list(contract.events)
assert len(events) == 19
assert len(events) == len(EMITTER_ENUM)


@pytest.mark.asyncio
Expand Down Expand Up @@ -195,3 +274,93 @@ async def test_async_contract_get_logs_argument_filter(
argument_filters={"arg0": 1},
)
assert len(partial_logs) == 4


@pytest.mark.asyncio
async def test_async_get_logs_argument_filters_indexed_and_non_indexed_args(
async_emitter
):
await async_emitter.functions.logIndexedAndNotIndexedArgs(
f"0xdead{'00' * 17}01", # indexed address
101, # indexed uint256
f"0xBEEf{'00' * 17}01", # non-indexed address
201, # non-indexed uint256
"This is the FIRST string arg.", # non-indexed string
).transact()
await async_emitter.functions.logIndexedAndNotIndexedArgs(
f"0xdEaD{'00' * 17}02",
102,
f"0xbeeF{'00' * 17}02",
202,
"This is the SECOND string arg.",
).transact()

# get all logs
logs_no_filter = await async_emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1
)
assert len(logs_no_filter) == 2

# filter for the second log by each of the indexed args and compare
logs_filter_indexed_address = (
await async_emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"indexedAddress": f"0xdEaD{'00' * 17}02"},
)
)
logs_filter_indexed_uint256 = (
await async_emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"indexedUint256": 102},
)
)
assert len(logs_filter_indexed_address) == len(logs_filter_indexed_uint256) == 1
assert (
logs_filter_indexed_address[0]
== logs_filter_indexed_uint256[0]
== logs_no_filter[1]
)

# filter for the first log by non-indexed address
logs_filter_non_indexed_address = (
await async_emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"nonIndexedAddress": f"0xBEEf{'00' * 17}01"},
)
)
assert len(logs_filter_non_indexed_address) == 1
assert logs_filter_non_indexed_address[0] == logs_no_filter[0]

# filter for the second log by non-indexed uint256 and string separately
logs_filter_non_indexed_uint256 = (
await async_emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"nonIndexedUint256": 202},
)
)
logs_filter_non_indexed_string = (
await async_emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={"nonIndexedString": "SECOND"},
)
)
assert len(logs_filter_non_indexed_uint256) == 1
assert len(logs_filter_non_indexed_string) == 1
assert (
logs_filter_non_indexed_uint256[0]
== logs_filter_non_indexed_string[0]
== logs_no_filter[1]
)

# filter by both string and uint256, non-indexed
logs_filter_non_indexed_uint256_and_string = (
await async_emitter.events.LogIndexedAndNotIndexed.get_logs(
fromBlock=1,
argument_filters={
"nonIndexedUint256": 201,
"nonIndexedString": "FIRST",
},
)
)
assert len(logs_filter_non_indexed_uint256_and_string) == 1
assert logs_filter_non_indexed_uint256_and_string[0] == logs_no_filter[0]
51 changes: 38 additions & 13 deletions web3/_utils/contract_sources/EmitterContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ contract EmitterContract {
}
event LogStructArgs(uint arg0, TestTuple arg1);

event LogIndexedAndNotIndexed(
address indexed indexedAddress,
uint256 indexed indexedUint256,
address nonIndexedAddress,
uint256 nonIndexedUint256,
string nonIndexedString
);

enum WhichEvent {
LogAnonymous,
LogNoArguments,
Expand All @@ -50,67 +58,84 @@ contract EmitterContract {
LogListArgs,
LogAddressIndexed,
LogAddressNotIndexed,
LogStructArgs
LogStructArgs,
LogIndexedAndNotIndexed
}

function logNoArgs(WhichEvent which) public {
function logNoArgs(WhichEvent which) external {
if (which == WhichEvent.LogNoArguments) emit LogNoArguments();
else if (which == WhichEvent.LogAnonymous) emit LogAnonymous();
else revert("Didn't match any allowable event index");
}
function logSingle(WhichEvent which, uint arg0) public {
function logSingle(WhichEvent which, uint arg0) external {
if (which == WhichEvent.LogSingleArg) emit LogSingleArg(arg0);
else if (which == WhichEvent.LogSingleWithIndex) emit LogSingleWithIndex(arg0);
else if (which == WhichEvent.LogSingleAnonymous) emit LogSingleAnonymous(arg0);
else revert("Didn't match any allowable event index");
}

function logDouble(WhichEvent which, uint arg0, uint arg1) public {
function logDouble(WhichEvent which, uint arg0, uint arg1) external {
if (which == WhichEvent.LogDoubleArg) emit LogDoubleArg(arg0, arg1);
else if (which == WhichEvent.LogDoubleWithIndex) emit LogDoubleWithIndex(arg0, arg1);
else if (which == WhichEvent.LogDoubleAnonymous) emit LogDoubleAnonymous(arg0, arg1);
else revert("Didn't match any allowable event index");
}
function logTriple(WhichEvent which, uint arg0, uint arg1, uint arg2) public {
function logTriple(WhichEvent which, uint arg0, uint arg1, uint arg2) external {
if (which == WhichEvent.LogTripleArg) emit LogTripleArg(arg0, arg1, arg2);
else if (which == WhichEvent.LogTripleWithIndex) emit LogTripleWithIndex(arg0, arg1, arg2);
else revert("Didn't match any allowable event index");
}

function logQuadruple(WhichEvent which, uint arg0, uint arg1, uint arg2, uint arg3) public {
function logQuadruple(WhichEvent which, uint arg0, uint arg1, uint arg2, uint arg3) external {
if (which == WhichEvent.LogQuadrupleArg) emit LogQuadrupleArg(arg0, arg1, arg2, arg3);
else if (which == WhichEvent.LogQuadrupleWithIndex) emit LogQuadrupleWithIndex(arg0, arg1, arg2, arg3);
else revert("Didn't match any allowable event index");
}
function logDynamicArgs(string memory arg0, string memory arg1) public {
function logDynamicArgs(string memory arg0, string memory arg1) external {
emit LogDynamicArgs(arg0, arg1);
}
function logListArgs(bytes2[] memory arg0, bytes2[] memory arg1) public {
function logListArgs(bytes2[] memory arg0, bytes2[] memory arg1) external {
emit LogListArgs(arg0, arg1);
}
function logAddressIndexedArgs(address arg0, address arg1) public {
function logAddressIndexedArgs(address arg0, address arg1) external {
emit LogAddressIndexed(arg0, arg1);
}
function logAddressNotIndexedArgs(address arg0, address arg1) public {
function logAddressNotIndexedArgs(address arg0, address arg1) external {
emit LogAddressNotIndexed(arg0, arg1);
}
function logBytes(bytes memory v) public {
function logBytes(bytes memory v) external {
emit LogBytes(v);
}
function logString(string memory v) public {
function logString(string memory v) external {
emit LogString(v);
}
function logStruct(uint arg0, TestTuple memory arg1) public {
function logStruct(uint arg0, TestTuple memory arg1) external {
emit LogStructArgs(arg0, arg1);
}
function logIndexedAndNotIndexedArgs(
address indexedAddress,
uint256 indexedUint256,
address nonIndexedAddress,
uint256 nonIndexedUint256,
string memory nonIndexedString
) external {
emit LogIndexedAndNotIndexed(
indexedAddress,
indexedUint256,
nonIndexedAddress,
nonIndexedUint256,
nonIndexedString
);
}
}
4 changes: 2 additions & 2 deletions web3/_utils/contract_sources/EventContracts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ contract EventContract {
event LogSingleArg(uint256 arg0);
event LogSingleWithIndex(uint256 arg0);

function logTwoEvents(uint256 _arg0) public {
function logTwoEvents(uint256 _arg0) external {
emit LogSingleWithIndex(_arg0);
emit LogSingleArg(_arg0);
}
Expand All @@ -14,7 +14,7 @@ contract IndexedEventContract {
event LogSingleArg(uint256 arg0);
event LogSingleWithIndex(uint256 indexed arg0);

function logTwoEvents(uint256 _arg0) public {
function logTwoEvents(uint256 _arg0) external {
emit LogSingleWithIndex(_arg0);
emit LogSingleArg(_arg0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@
"LogAddressIndexed": 16,
"LogAddressNotIndexed": 17,
"LogStructArgs": 18,
"LogIndexedAndNotIndexed": 19,
}

0 comments on commit 6fdb44e

Please sign in to comment.