Evm_node_lib_dev.Filter_helpers
A bloom filter can be seen as a probabilistic set. As such, the order of its elements is not important.
Blocks contain a bloom filter with the union of all topics in their logs, together with the address of the contract that produced them. The getLogs
RPC defines a filter (not to be confused with bloom filter) which may contain a pattern of topics to be matched with a log.
A pattern is defined as: pattern := TOPIC | NULL | TOPIC list
Where NULL
is a wildcard, and a list of topics matches against any of the elements in the list (Or
).
To speed up the filtering, we compute a bloom filter corresponding to the filter's pattern. The goal is to check if this bloom is contained in the block's bloom, and only fetching the block in that case. Therefore, our filter must always be included in filters corresponding to blocks that have at least a log that matches with the pattern. For this reason, we decide to ignore Or
patterns in the bloom filter "heuristic" (including all topics would break the previous property). The same is done for addresses, as a filter can match against a list of them. If this becomes a serious bottleneck, we could keep a collection of bloom filters to represent the disjunction.
type valid_filter = {
from_block : Evm_node_lib_dev_encoding.Ethereum_types.quantity;
to_block : Evm_node_lib_dev_encoding.Ethereum_types.quantity;
bloom : Ethbloom.t;
topics : Evm_node_lib_dev_encoding.Ethereum_types.Filter.topic option list;
address : Evm_node_lib_dev_encoding.Ethereum_types.address list;
}
Saner representation of an input filter: from_block
and to_block
are defined by: A filter's from_block
and to_block
if provided, or a filter's block_hash
if provided (from_block = to_block = block_n
), or from_block = to_block = latest block's number
.
A bloom
filter is computed using the topics and address.
type bloom_filter = {
bloom : Ethbloom.t;
topics : Evm_node_lib_dev_encoding.Ethereum_types.Filter.topic option list;
address : Evm_node_lib_dev_encoding.Ethereum_types.address list;
}
type Tezos_base.TzPervasives.error +=
| Incompatible_block_params
| Block_range_too_large of {
}
| Topic_list_too_large
| Receipt_not_found of Evm_node_lib_dev_encoding.Ethereum_types.hash
| Too_many_logs of {
}
val emit_and_return_none :
'a Tezos_base.TzPervasives.Internal_event.Simple.t ->
'a ->
('b option, 'c) Stdlib.result Lwt.t
val validate_range :
Evm_node_config.Configuration.log_filter_config ->
(module Services_backend_sig.S) ->
Evm_node_lib_dev_encoding.Ethereum_types.Filter.t ->
((Evm_node_lib_dev_encoding.Ethereum_types.quantity
* Evm_node_lib_dev_encoding.Ethereum_types.quantity)
option,
Tezos_base.TzPervasives.error list)
Stdlib.result
Lwt.t
val make_bloom_address_topics :
Evm_node_lib_dev_encoding.Ethereum_types.Filter.filter_address option ->
Evm_node_lib_dev_encoding.Ethereum_types.Filter.topic option list option ->
Ethbloom.t
val make_bloom :
Evm_node_lib_dev_encoding.Ethereum_types.Filter.t ->
Ethbloom.t
val validate_topics :
Evm_node_lib_dev_encoding.Ethereum_types.Filter.t ->
(unit, Tezos_base.TzPervasives.error list) Stdlib.result Lwt.t
val validate_bloom_filter :
Evm_node_lib_dev_encoding.Ethereum_types.Filter.t ->
(bloom_filter, Tezos_base.TzPervasives.error list) Stdlib.result Lwt.t
val validate_filter :
Evm_node_config.Configuration.log_filter_config ->
(module Services_backend_sig.S) ->
Evm_node_lib_dev_encoding.Ethereum_types.Filter.t ->
(valid_filter option, Tezos_base.TzPervasives.error list) Stdlib.result Lwt.t
val hex_to_bytes : Evm_node_lib_dev_encoding.Ethereum_types.hex -> bytes
val match_filter_topics :
bloom_filter ->
Evm_node_lib_dev_encoding.Ethereum_types.hash list ->
bool
val match_filter_address :
bloom_filter ->
Evm_node_lib_dev_encoding.Ethereum_types.address ->
bool
val filter_one_log :
bloom_filter ->
Evm_node_lib_dev_encoding.Ethereum_types.transaction_log ->
Evm_node_lib_dev_encoding.Ethereum_types.Filter.changes option
val filter_receipt :
bloom_filter ->
Evm_node_lib_dev_encoding.Transaction_receipt.t ->
Evm_node_lib_dev_encoding.Ethereum_types.Filter.changes list option
val filter_one_tx :
(module Services_backend_sig.S) ->
bloom_filter ->
Evm_node_lib_dev_encoding.Ethereum_types.hash ->
Evm_node_lib_dev_encoding.Ethereum_types.Filter.changes list option
Tezos_base.TzPervasives.tzresult
Lwt.t
val filter_one_block :
(module Services_backend_sig.S) ->
valid_filter ->
Z.t ->
Evm_node_lib_dev_encoding.Ethereum_types.Filter.changes list option
Tezos_base.TzPervasives.tzresult
Lwt.t
split_in_chunks ~chunk_size ~base ~length
returns a list of lists (chunks) containing the consecutive numbers from base
to base + length - 1
. Each chunk is at most of length chunk_size
. Only the last chunk can be shorter than chunk_size
.
Example split_in_chunks ~chunk_size:2 ~base:1 ~length:5
is <<1, 2>, <3,4>, <5>>.
val get_logs :
Evm_node_config.Configuration.log_filter_config ->
(module Services_backend_sig.S) ->
Evm_node_lib_dev_encoding.Ethereum_types.Filter.t ->
(Evm_node_lib_dev_encoding.Ethereum_types.Filter.changes list,
Tezos_base.TzPervasives.error list)
Stdlib.result
Lwt.t