def test_filter_log_before_from_block(session): construct_log(session, block_number=0) params = FilterParams(from_block=1) results = filter_logs(session, params) assert not results
def test_filter_log_after_to_block(session): construct_log(session, block_number=2) params = FilterParams(to_block=1) results = filter_logs(session, params) assert not results
def test_filter_log_single_topic_out_of_position(session): topic = Hash32Factory() wrong_topic = Hash32Factory() construct_log(session, topics=(wrong_topic, topic)) params = FilterParams(topics=(topic, )) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 0
def test_filter_log_null_from_block_before_to_block(session): log = construct_log(session, block_number=2) construct_log(session, block_number=6) # another log that doesn't match params = FilterParams(to_block=5) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 1 assert results[0].id == log.id
def test_filter_log_empty_params(session): log = construct_log(session) params = FilterParams() results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 1 assert results[0].id == log.id
def test_filter_log_after_from_block_null_to_block(session): log = construct_log(session, block_number=2) construct_log(session, block_number=0) # another log that doesn't match params = FilterParams(from_block=1) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 1 assert results[0].idx == log.idx assert results[0].receipt_hash == log.receipt_hash
def test_filter_log_single_topic(session): topic = Hash32Factory() log = construct_log(session, topics=(topic, )) construct_log(session) # another log that doesn't match params = FilterParams(topics=(topic, )) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 1 assert results[0].id == log.id assert results[0].topics[0].topic == topic
def test_filter_log_single_address_match(session): address = AddressFactory() log = construct_log(session, address=address) params = FilterParams(address=address) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 1 assert results[0].id == log.id assert results[0].address == address
def test_filter_log_single_topic_second_position(session): topic = Hash32Factory() log = construct_log(session, topics=(Hash32Factory(), topic)) construct_log(session) # another log that doesn't match params = FilterParams(topics=(None, topic)) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 1 assert results[0].idx == log.idx assert results[0].receipt_hash == log.receipt_hash assert results[0].topics[1].topic == topic
def _rpc_request_to_filter_params(raw_params: RawFilterParams) -> FilterParams: address: Union[None, Address, Tuple[Address, ...]] if "address" not in raw_params: address = None elif raw_params["address"] is None: address = None elif is_address(raw_params["address"]): address = to_canonical_address(raw_params["address"]) # type: ignore elif isinstance(raw_params["address"], list): address = tuple( to_canonical_address(sub_address) for sub_address in raw_params["address"]) else: raise TypeError(f"Unsupported address: {raw_params['address']!r}") topics: FilterTopics if "topics" not in raw_params: topics = () elif raw_params["topics"] is None: topics = () elif isinstance(raw_params["topics"], Sequence): topics = _normalize_topics(raw_params["topics"]) # type: ignore else: raise TypeError(f"Unsupported topics: {raw_params['topics']!r}") from_block: Optional[BlockNumber] if "fromBlock" not in raw_params: from_block = None elif raw_params["fromBlock"] is None: from_block = None elif isinstance(raw_params["fromBlock"], str): from_block = BlockNumber(to_int(hexstr=raw_params["fromBlock"])) else: raise TypeError(f"Unsupported fromBlock: {raw_params['fromBlock']!r}") to_block: Optional[BlockNumber] if "toBlock" not in raw_params: to_block = None elif raw_params["toBlock"] is None: to_block = None elif isinstance(raw_params["toBlock"], str): to_block = BlockNumber(to_int(hexstr=raw_params["toBlock"])) else: raise TypeError(f"Unsupported toBlock: {raw_params['toBlock']!r}") return FilterParams(from_block, to_block, address, topics)
def test_filter_log_multiple_topics(session): topic_0 = Hash32Factory() topic_1 = Hash32Factory() log = construct_log(session, topics=(topic_0, topic_1)) construct_log(session) # another log that doesn't match params = FilterParams(topics=(topic_0, topic_1)) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 1 assert results[0].idx == log.idx assert results[0].receipt_hash == log.receipt_hash assert results[0].topics[0].topic == topic_0 assert results[0].topics[1].topic == topic_1
def test_filter_log_multiple_addresses(session): address = AddressFactory() other = AddressFactory() log = construct_log(session, address=address) construct_log(session) # another log that doesn't match params = FilterParams(address=(other, address)) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 1 assert results[0].id == log.id assert results[0].address == address
def test_filter_params_with_multiple_options_for_topic(session): topic_a = Hash32Factory() topic_b = Hash32Factory() log_a = construct_log(session, topics=(topic_a, )) log_b = construct_log(session, topics=(topic_b, )) construct_log(session) # another log that doesn't match params = FilterParams(topics=((topic_a, topic_b), )) results = filter_logs(session, params) check_filter_results(params, results) assert len(results) == 2 assert results[0].id in {log_a.id, log_b.id} assert results[1].id in {log_a.id, log_b.id} assert results[0].topics[0].topic in {topic_a, topic_b} assert results[1].topics[0].topic in {topic_a, topic_b}
def build_filter(topic_factory: ThingGenerator[Address], address_factory: ThingGenerator[Address]) -> FilterParams: num_topics = int(random.expovariate(0.1)) topics = tuple(topic_factory() for _ in range(num_topics)) address = address_factory() from_block, to_block = sorted( (int(random.expovariate(0.05)), int(random.expovariate(0.01)))) if random.randint(0, 20) == 0: from_block = None if random.randint(0, 2) == 0: to_block = None return FilterParams(from_block=from_block, to_block=to_block, address=address, topics=topics)
@to_dict def _params_to_rpc_request(params): if params.address is not None: yield "address", params.address if params.from_block is not None: yield "fromBlock", params.from_block if params.to_block is not None: yield "toBlock", params.to_block yield "topics", [_rpc_friendly_topic(topic) for topic in params.topics] @pytest.mark.parametrize( "params", ( FilterParams(None, None, None, ()), FilterParams(0, None, None, ()), FilterParams(None, 4, None, ()), FilterParams(0, 4, None, ()), FilterParams(0, 4, None, ()), FilterParams(None, None, LOG_ADDRESS, ()), FilterParams(0, 4, LOG_ADDRESS, ()), FilterParams(None, None, (LOG_ADDRESS, OTHER_ADDRESS), ()), FilterParams(None, None, None, (LOG_TOPIC_0, )), FilterParams(None, None, None, (LOG_TOPIC_0, LOG_TOPIC_1)), FilterParams(None, None, None, (None, LOG_TOPIC_1)), FilterParams(None, None, None, ((LOG_TOPIC_0, OTHER_TOPIC), LOG_TOPIC_1)), FilterParams(None, None, None, (None, (OTHER_TOPIC, LOG_TOPIC_1))), ), )