Skip to content

Commit

Permalink
Get events filter bugfix (0xSpaceShard#386)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikiw committed Jan 23, 2023
1 parent a5296e5 commit 4e567d9
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 28 deletions.
35 changes: 23 additions & 12 deletions starknet_devnet/blueprints/rpc/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

from __future__ import annotations

from typing import List, Union
from typing import Union

from starknet_devnet.blueprints.rpc.structures.responses import RpcEventsResult
from starknet_devnet.blueprints.rpc.structures.types import (
Address,
BlockId,
Felt,
RpcError,
RpcErrorCode,
)
from starknet_devnet.blueprints.rpc.utils import (
assert_block_id_is_latest_or_pending,
Expand Down Expand Up @@ -63,15 +64,9 @@ async def syncing() -> Union[dict, bool]:
return False


# pylint: disable=too-many-arguments
async def get_events(
from_block: BlockId,
to_block: BlockId,
chunk_size: int,
address: Address = None,
keys: List[Address] = None,
continuation_token: str = "0",
) -> str:
# pylint: disable=redefined-builtin
# filter name is determined by current RPC implementation and starknet specification
async def get_events(filter) -> RpcEventsResult:
"""
Returns all events matching the given filters.
Expand All @@ -81,6 +76,22 @@ async def get_events(
This is why we need to iterate block by block, take all events,
and chunk it later which is not an optimal solution.
"""
# Required parameters
from_block = filter.get("from_block")
to_block = filter.get("to_block")
try:
chunk_size = int(filter.get("chunk_size"))
except ValueError as ex:
raise RpcError(
code=RpcErrorCode.INVALID_PARAMS.value,
message=f"invalid chunk_size: '{filter.get('chunk_size')}'",
) from ex

# Optional parameters
address = filter.get("address")
keys = filter.get("keys")
continuation_token = filter.get("continuation_token", "0")

events = []
keys = [] if keys is None else [int(k, 0) for k in keys]
to_block = (
Expand All @@ -93,12 +104,12 @@ async def get_events(
if block.transaction_receipts:
events.extend(get_events_from_block(block, address, keys))

# chunking
# Chunking
continuation_token = int(continuation_token)
start_index = continuation_token * chunk_size
events = events[start_index : start_index + chunk_size]

# continuation_token should be increased only if events are not empty
# Continuation_token should be increased only if events are not empty
if events:
continuation_token = continuation_token + 1

Expand Down
41 changes: 30 additions & 11 deletions test/rpc/test_data/get_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"chunk_size": 10,
}

BLOCK_FROM_0_TO_LATEST_MALFORMED_REQUEST = {
"from_block": "0",
"to_block": "latest",
"chunk_size": "test",
}

BLOCK_FROM_0_TO_2 = {
"from_block": "0",
"to_block": "2",
Expand Down Expand Up @@ -105,10 +111,23 @@
0,
]


def create_get_events_rpc(filter_data):
"""
Construct JSON RPC call with filter data
"""
return {
"jsonrpc": "2.0",
"method": "starknet_getEvents",
"params": {"filter": filter_data},
"id": 0,
}


GET_EVENTS_TEST_DATA = [
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_LATEST,
create_get_events_rpc(BLOCK_FROM_0_TO_LATEST),
[
INCREASE_BALANCE_BY_0_EVENT,
FEE_CHARGING_IN_BLOCK_2_EVENT,
Expand All @@ -118,17 +137,17 @@
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_2,
create_get_events_rpc(BLOCK_FROM_0_TO_2),
[INCREASE_BALANCE_BY_0_EVENT, FEE_CHARGING_IN_BLOCK_2_EVENT],
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_3_TO_3,
create_get_events_rpc(BLOCK_FROM_3_TO_3),
[INCREASE_BALANCE_BY_1_EVENT, FEE_CHARGING_IN_BLOCK_3_EVENT],
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_2_TO_3,
create_get_events_rpc(BLOCK_FROM_2_TO_3),
[
INCREASE_BALANCE_BY_0_EVENT,
FEE_CHARGING_IN_BLOCK_2_EVENT,
Expand All @@ -138,7 +157,7 @@
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_LATEST_CHUNK_SIZE_3,
create_get_events_rpc(BLOCK_FROM_0_TO_LATEST_CHUNK_SIZE_3),
[
INCREASE_BALANCE_BY_0_EVENT,
FEE_CHARGING_IN_BLOCK_2_EVENT,
Expand All @@ -147,27 +166,27 @@
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_LATEST_CHUNK_3_CONTINUATION_TOKEN,
create_get_events_rpc(BLOCK_FROM_0_TO_LATEST_CHUNK_3_CONTINUATION_TOKEN),
[FEE_CHARGING_IN_BLOCK_3_EVENT],
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_1_CHUNK_3_CONTINUATION_TOKEN,
create_get_events_rpc(BLOCK_FROM_0_TO_1_CHUNK_3_CONTINUATION_TOKEN),
[],
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_LATEST_WITH_ADDRESS,
create_get_events_rpc(BLOCK_FROM_0_TO_LATEST_WITH_ADDRESS),
[FEE_CHARGING_IN_BLOCK_2_EVENT, FEE_CHARGING_IN_BLOCK_3_EVENT],
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_LATEST_WITH_KEY,
create_get_events_rpc(BLOCK_FROM_0_TO_LATEST_WITH_KEY),
[FEE_CHARGING_IN_BLOCK_2_EVENT, FEE_CHARGING_IN_BLOCK_3_EVENT],
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_LATEST_WITH_KEYS,
create_get_events_rpc(BLOCK_FROM_0_TO_LATEST_WITH_KEYS),
[
INCREASE_BALANCE_BY_0_EVENT,
FEE_CHARGING_IN_BLOCK_2_EVENT,
Expand All @@ -177,7 +196,7 @@
),
(
[*PREDEPLOY_ACCOUNT_CLI_ARGS],
BLOCK_FROM_0_TO_LATEST_WITH_ADDRESS_AND_KEYS,
create_get_events_rpc(BLOCK_FROM_0_TO_LATEST_WITH_ADDRESS_AND_KEYS),
[FEE_CHARGING_IN_BLOCK_2_EVENT, FEE_CHARGING_IN_BLOCK_3_EVENT],
),
]
30 changes: 25 additions & 5 deletions test/rpc/test_rpc_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@

from test.account import declare, invoke
from test.rpc.rpc_utils import deploy_and_invoke_storage_contract, rpc_call
from test.rpc.test_data.get_events import GET_EVENTS_TEST_DATA
from test.rpc.test_data.get_events import (
BLOCK_FROM_0_TO_LATEST_MALFORMED_REQUEST,
GET_EVENTS_TEST_DATA,
create_get_events_rpc,
)
from test.shared import (
CONTRACT_PATH,
DEPLOYER_CONTRACT_PATH,
Expand All @@ -23,6 +27,7 @@
import pytest
from starkware.starknet.public.abi import get_storage_var_address

from starknet_devnet.blueprints.rpc.structures.types import RpcErrorCode
from starknet_devnet.blueprints.rpc.utils import rpc_felt
from starknet_devnet.general_config import DEFAULT_GENERAL_CONFIG

Expand Down Expand Up @@ -148,6 +153,20 @@ def test_call_with_invalid_params(params):
assert ex["error"] == {"code": -32602, "message": "Invalid params"}


@pytest.mark.usefixtures("run_devnet_in_background")
def test_get_events_malformed_request():
"""
Test RPC get_events with malformed request.
"""
resp = rpc_call(
"starknet_getEvents",
params=create_get_events_rpc(BLOCK_FROM_0_TO_LATEST_MALFORMED_REQUEST)[
"params"
],
)
assert resp["error"]["code"] == RpcErrorCode.INVALID_PARAMS.value


@pytest.mark.usefixtures("run_devnet_in_background")
@pytest.mark.parametrize(
"run_devnet_in_background, input_data, expected_data",
Expand All @@ -165,14 +184,15 @@ def test_get_events(input_data, expected_data):
account_address=PREDEPLOYED_ACCOUNT_ADDRESS,
private_key=PREDEPLOYED_ACCOUNT_PRIVATE_KEY,
)
resp = rpc_call("starknet_getEvents", params=input_data)
resp = rpc_call("starknet_getEvents", params=input_data["params"])
assert len(expected_data) == len(resp["result"]["events"])
for i, data in enumerate(expected_data):
assert str(resp["result"]["events"][i]["data"]) == str(data)

if "continuation_token" in input_data:
expected_continuation_token = int(input_data["continuation_token"])

if "continuation_token" in input_data["params"]["filter"]:
expected_continuation_token = int(
input_data["params"]["filter"]["continuation_token"]
)
# increase continuation_token when events are not empty
if resp["result"]["events"]:
expected_continuation_token += 1
Expand Down

0 comments on commit 4e567d9

Please sign in to comment.