filter.rs
Overview
This file defines input filter structures used for querying blocks and their referenced external blocks within a system that processes blockchain-like data. It provides flexible, composable criteria to filter blocks based on various fields such as IDs, flags, timestamps, references to previous blocks, and logical OR combinations. These filters are designed for use within GraphQL APIs, leveraging the async_graphql crate for input objects, and support serialization via serde.
The primary purpose is to enable expressive and type-safe construction of query filters that can be converted into SQL-like WHERE clauses or similar query predicates, facilitating querying and retrieval of blocks with complex conditions.
Key Structures
ExtBlkRefFilter
Represents filtering criteria for external block references. External block references are metadata pointers to other blocks, identified by hashes and sequence numbers.
Fields
Field | Type | Description |
|---|---|---|
|
| Filter by a string field named |
|
| Filter by the hash of the file associated with the block reference. |
|
| Filter by the root hash of the referenced block. |
|
| Filter by the sequence number of the block reference. |
|
| Optional logical OR combination with another |
Usage Example
let ext_filter = ExtBlkRefFilter {
root_hash: Some(StringFilter { eq: Some("abc123".into()), ..Default::default() }),
..Default::default()
};
This example filters external block references where the root hash exactly matches "abc123".
BlockFilter
Represents filtering criteria for blocks themselves. This struct aggregates multiple optional filters on block fields, previous block references, and supports nested OR conditions.
Fields
Field | Type | Description |
|---|---|---|
|
| Filter by the block's unique identifier. |
|
| Filter for blocks after a merge event. |
|
| Filter for blocks after a split event. |
|
| Filter based on integer flags associated with the block. |
|
| Filter by generation Unix time of the block. |
|
| Filter for blocks designated as key blocks. |
|
| Filter on an alternative previous block reference, with fields prefixed by |
|
| Filter on the previous block reference, with fields prefixed by |
|
| Filter by shard string identifier. |
|
| Filter by the status integer code of the block. |
|
| Filter by transaction count in the block. |
|
| Filter by associated workchain ID. |
|
| Logical OR combination with another |
Prefixing Previous References
The fields within prev_ref and prev_alt_ref are serialized and deserialized with prefixes (prev_ref_ and prev_alt_ref_ respectively) using the serde_with::with_prefix macro. This allows nested filters on previous block references to be flattened into a single-level structure with clear namespacing.
Trait Implementation
Implements the
WhereOptrait which provides the methodto_where()for converting filter conditions intoWHEREclause strings.
Usage Example
let block_filter = BlockFilter {
key_block: Some(BooleanFilter { eq: Some(true), ne: None }),
workchain_id: Some(IntFilter { eq: Some(-1), ..Default::default() }),
..Default::default()
};
This filter matches blocks that are key blocks and belong to workchain -1.
Important Implementation Details
Trait
WhereOp: Both filters implement or derive theWhereOptrait (defined elsewhere), enabling them to translate the filter criteria into query predicates. This trait is critical for integrating these filters into the querying mechanism of the system.Logical OR Support: Both
ExtBlkRefFilterandBlockFilterinclude anorfield which allows combining multiple filter criteria with logical OR operations. This is implemented recursively by boxing an optional filter of the same type.Field Name Renaming: The
#[graphql(rename_fields = "snake_case")]attribute ensures that GraphQL input fields use snake case naming conventions, aligning with typical API expectations.Serde Flattening with Prefixes: The
prev_refandprev_alt_reffields useserde(flatten)with custom prefixes to serialize nested filters in a flattened, prefixed manner. This design simplifies GraphQL input structures and downstream query construction.Default Implementations: Both filters implement
Defaultto allow constructing empty filters which represent no filtering.
Interaction with Other Parts of the System
GraphQL Schema Integration: These filter structs are exposed as input objects in the GraphQL schema (
async_graphql::InputObject), enabling clients to specify complex filtering criteria when querying block data.Filter Submodules: The filters make use of auxiliary filter types like
OptBooleanFilter,OptFloatFilter,OptIntFilter, andOptStringFilterfrom thecrate::schema::graphql::filtermodule. These types encapsulate optional filtering operations such as equality, inequality, and range comparisons.Where Clause Generation: The
to_where()method (from theWhereOptrait) used in tests demonstrates how these filters convert themselves to SQL-likeWHEREclauses, which can then be used by the query execution layer to fetch matching blocks from a database.Test Coverage: The
testsmodule contains unit tests verifying that the filters produce correctWHEREclauses for various filtering scenarios, including nested filters and OR combinations.
Tests Overview
The tests module contains four unit tests illustrating usage and verifying correctness of the BlockFilter's to_where() method:
test_block_filter_1: Filters blocks where
key_blockis true andworkchain_idequals -1, expecting a combinedWHEREclause with AND.test_block_filter_2: Tests empty filter returns no
WHEREclause.test_block_filter_3: Filters by a nested
prev_ref.root_hashfield, expecting the prefixed field name in the output.test_block_filter_4: Combines nested filters with an OR condition between
prev_refandprev_alt_reffilters, demonstrating recursive OR clause generation.
Mermaid Diagram
classDiagram
class ExtBlkRefFilter {
+end_lt: OptStringFilter
+file_hash: OptStringFilter
+root_hash: OptStringFilter
+seq_no: OptFloatFilter
+or: Option<Box<ExtBlkRefFilter>>
}
class BlockFilter {
+id: OptStringFilter
+after_merge: OptBooleanFilter
+after_split: OptBooleanFilter
+flags: OptIntFilter
+gen_utime: OptFloatFilter
+key_block: OptBooleanFilter
+prev_alt_ref: Option<ExtBlkRefFilter>
+prev_ref: Option<ExtBlkRefFilter>
+shard: OptStringFilter
+status: OptIntFilter
+tr_count: OptIntFilter
+workchain_id: OptIntFilter
+or: Option<Box<BlockFilter>>
}
BlockFilter --> ExtBlkRefFilter : prev_ref
BlockFilter --> ExtBlkRefFilter : prev_alt_ref
BlockFilter o-- BlockFilter : or
ExtBlkRefFilter o-- ExtBlkRefFilter : or
This class diagram illustrates the two main filter structs and their recursive relationships: BlockFilter contains optional references to ExtBlkRefFilter for previous block references and supports recursive OR combinations with itself; ExtBlkRefFilter supports recursive OR combinations with itself.
References
OptBooleanFilter,OptFloatFilter,OptIntFilter,OptStringFilter,WhereOp: See Filter Types for detailed descriptions of these filter abstractions.serde_with::with_prefix: See Serde With Prefix for details on how field prefixing and flattening works with Serde serialization.async_graphql::InputObject: See GraphQL Input Object for information on defining GraphQL input types.WhereOptrait and itsto_where()method: See Where Operation Trait for how filters convert to query predicates.