From 7458169b4dcd265d4786aacf1db805a92dcba549 Mon Sep 17 00:00:00 2001 From: MartianGreed Date: Mon, 23 Mar 2026 14:24:55 +0100 Subject: [PATCH 01/21] feat(grpc): gzip responses and preserve fixed-width primitive bytes --- Cargo.lock | 2 + Cargo.toml | 2 +- bins/torii-arcade/src/main.rs | 123 +- bins/torii-erc20/Cargo.toml | 2 +- bins/torii-erc20/src/main.rs | 8 +- bins/torii-introspect-bin/src/main.rs | 127 +- bins/torii-tokens/Cargo.toml | 2 +- bins/torii-tokens/src/main.rs | 55 +- crates/torii-ecs-sink/Cargo.toml | 1 + crates/torii-ecs-sink/proto/types.proto | 136 ++ crates/torii-ecs-sink/proto/world.proto | 127 ++ crates/torii-ecs-sink/src/grpc_service.rs | 1900 ++++++++++++++++++++- examples/multi_sink_example/main.rs | 20 +- examples/simple_sql_sink/main.rs | 8 +- src/grpc.rs | 3 +- src/lib.rs | 7 +- 16 files changed, 2303 insertions(+), 220 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 903c8688..61873410 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4517,6 +4517,7 @@ dependencies = [ "axum", "base64 0.22.1", "bytes", + "flate2", "h2", "http", "http-body", @@ -4749,6 +4750,7 @@ dependencies = [ "hex", "introspect-types", "metrics", + "num-bigint", "prost 0.13.5", "prost-types 0.13.5", "serde", diff --git a/Cargo.toml b/Cargo.toml index b8596143..954b4a71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ tokio-stream = { version = "0.1", features = ["sync"] } # gRPC and protobuf # Keep older version for now due to some compatibility issues with newer axum: https://github.com/hyperium/tonic/issues/1964. -tonic = "0.12" +tonic = { version = "0.12", features = ["gzip"] } tonic-reflection = "0.12" tonic-web = "0.12" prost = "0.13" diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index a9b611d7..f1ace2e0 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -9,6 +9,7 @@ use starknet::core::types::Felt; use std::collections::HashSet; use std::path::Path; use std::sync::Arc; +use tonic::codec::CompressionEncoding; use tonic_reflection::server::Builder as ReflectionBuilder; use torii::axum::Router; use torii::etl::decoder::DecoderId; @@ -476,89 +477,65 @@ async fn run_indexer(config: Config) -> Result<()> { let reflection = reflection_builder .build_v1() - .expect("failed to build Arcade reflection service"); + .expect("failed to build Arcade reflection service") + .accept_compressed(CompressionEncoding::Gzip); + + let world_server = + WorldServer::new((*ecs_grpc_service).clone()).accept_compressed(CompressionEncoding::Gzip); + let arcade_server = ArcadeServer::new((*arcade_grpc_service).clone()) + .accept_compressed(CompressionEncoding::Gzip); + let erc20_server = erc20_grpc_service + .map(|service| Erc20Server::new(service).accept_compressed(CompressionEncoding::Gzip)); + let erc721_server = erc721_grpc_service + .map(|service| Erc721Server::new(service).accept_compressed(CompressionEncoding::Gzip)); + let erc1155_server = erc1155_grpc_service + .map(|service| Erc1155Server::new(service).accept_compressed(CompressionEncoding::Gzip)); let mut grpc_builder = tonic::transport::Server::builder().accept_http1(true); - let grpc_router = match ( - erc20_grpc_service, - erc721_grpc_service, - erc1155_grpc_service, - ) { + let grpc_router = match (erc20_server, erc721_server, erc1155_server) { (Some(erc20), Some(erc721), Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(ArcadeServer::new( - (*arcade_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(world_server.clone())) + .add_service(tonic_web::enable(arcade_server.clone())) + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), Some(erc721), None) => grpc_builder - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(ArcadeServer::new( - (*arcade_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(world_server.clone())) + .add_service(tonic_web::enable(arcade_server.clone())) + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), None, Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(ArcadeServer::new( - (*arcade_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(world_server.clone())) + .add_service(tonic_web::enable(arcade_server.clone())) + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (None, Some(erc721), Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(ArcadeServer::new( - (*arcade_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(world_server.clone())) + .add_service(tonic_web::enable(arcade_server.clone())) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), None, None) => grpc_builder - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(ArcadeServer::new( - (*arcade_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(world_server.clone())) + .add_service(tonic_web::enable(arcade_server.clone())) + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(reflection.clone())), (None, Some(erc721), None) => grpc_builder - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(ArcadeServer::new( - (*arcade_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(world_server.clone())) + .add_service(tonic_web::enable(arcade_server.clone())) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(reflection.clone())), (None, None, Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(ArcadeServer::new( - (*arcade_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(world_server.clone())) + .add_service(tonic_web::enable(arcade_server.clone())) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (None, None, None) => grpc_builder - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(ArcadeServer::new( - (*arcade_grpc_service).clone(), - ))) + .add_service(tonic_web::enable(world_server)) + .add_service(tonic_web::enable(arcade_server)) .add_service(tonic_web::enable(reflection)), }; diff --git a/bins/torii-erc20/Cargo.toml b/bins/torii-erc20/Cargo.toml index 55ff3fce..9dd48af1 100644 --- a/bins/torii-erc20/Cargo.toml +++ b/bins/torii-erc20/Cargo.toml @@ -31,7 +31,7 @@ clap = { version = "4.5", features = ["derive", "env"] } anyhow = "1.0" # gRPC -tonic = "0.12" +tonic = { version = "0.12", features = ["gzip"] } tonic-reflection = "0.12" # Profiling (optional, enable with --features profiling) diff --git a/bins/torii-erc20/src/main.rs b/bins/torii-erc20/src/main.rs index ab7250b3..33b1272d 100644 --- a/bins/torii-erc20/src/main.rs +++ b/bins/torii-erc20/src/main.rs @@ -33,6 +33,7 @@ use starknet::core::types::Felt; use std::sync::Arc; #[cfg(feature = "profiling")] use std::time::{SystemTime, UNIX_EPOCH}; +use tonic::codec::CompressionEncoding; use torii::etl::decoder::DecoderId; use torii::etl::extractor::{BlockRangeConfig, BlockRangeExtractor}; use torii_runtime_common::database::resolve_single_db_setup; @@ -132,10 +133,13 @@ async fn main() -> Result<()> { .register_encoded_file_descriptor_set(torii::TORII_DESCRIPTOR_SET) .register_encoded_file_descriptor_set(FILE_DESCRIPTOR_SET) .build_v1() - .expect("Failed to build gRPC reflection service"); + .expect("Failed to build gRPC reflection service") + .accept_compressed(CompressionEncoding::Gzip); + + let grpc_service = Erc20Server::new(grpc_service).accept_compressed(CompressionEncoding::Gzip); let grpc_router = tonic::transport::Server::builder() - .add_service(Erc20Server::new(grpc_service)) + .add_service(grpc_service) .add_service(reflection); let mut torii_config = torii::ToriiConfig::builder() diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index 4e16a1d7..c7143f58 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -11,6 +11,7 @@ use starknet::core::types::Felt; use std::collections::{HashMap, HashSet}; use std::path::Path; use std::sync::Arc; +use tonic::codec::CompressionEncoding; use torii::etl::decoder::DecoderId; use torii::etl::extractor::{ ContractEventConfig, EventExtractor, EventExtractorConfig, Extractor, RetryPolicy, @@ -512,44 +513,51 @@ async fn run_with_postgres( let reflection = reflection_builder .build_v1() - .expect("failed to build reflection service"); + .expect("failed to build reflection service") + .accept_compressed(CompressionEncoding::Gzip); + + let world_server = + WorldServer::new((*ecs_grpc_service).clone()).accept_compressed(CompressionEncoding::Gzip); + let erc20_server = token_services + .erc20 + .map(|service| Erc20Server::new(service).accept_compressed(CompressionEncoding::Gzip)); + let erc721_server = token_services + .erc721 + .map(|service| Erc721Server::new(service).accept_compressed(CompressionEncoding::Gzip)); + let erc1155_server = token_services + .erc1155 + .map(|service| Erc1155Server::new(service).accept_compressed(CompressionEncoding::Gzip)); let grpc_builder = tonic::transport::Server::builder() .accept_http1(true) - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))); - let grpc_router = match ( - token_services.erc20, - token_services.erc721, - token_services.erc1155, - ) { + .add_service(tonic_web::enable(world_server)); + let grpc_router = match (erc20_server, erc721_server, erc1155_server) { (Some(erc20), Some(erc721), Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), Some(erc721), None) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), None, Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (None, Some(erc721), Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), None, None) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(reflection.clone())), (None, Some(erc721), None) => grpc_builder - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(reflection.clone())), (None, None, Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (None, None, None) => grpc_builder.add_service(tonic_web::enable(reflection)), }; @@ -651,44 +659,51 @@ async fn run_with_sqlite( let reflection = reflection_builder .build_v1() - .expect("failed to build reflection service"); + .expect("failed to build reflection service") + .accept_compressed(CompressionEncoding::Gzip); + + let world_server = + WorldServer::new((*ecs_grpc_service).clone()).accept_compressed(CompressionEncoding::Gzip); + let erc20_server = token_services + .erc20 + .map(|service| Erc20Server::new(service).accept_compressed(CompressionEncoding::Gzip)); + let erc721_server = token_services + .erc721 + .map(|service| Erc721Server::new(service).accept_compressed(CompressionEncoding::Gzip)); + let erc1155_server = token_services + .erc1155 + .map(|service| Erc1155Server::new(service).accept_compressed(CompressionEncoding::Gzip)); let grpc_builder = tonic::transport::Server::builder() .accept_http1(true) - .add_service(tonic_web::enable(WorldServer::new( - (*ecs_grpc_service).clone(), - ))); - let grpc_router = match ( - token_services.erc20, - token_services.erc721, - token_services.erc1155, - ) { + .add_service(tonic_web::enable(world_server)); + let grpc_router = match (erc20_server, erc721_server, erc1155_server) { (Some(erc20), Some(erc721), Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), Some(erc721), None) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), None, Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (None, Some(erc721), Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (Some(erc20), None, None) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(reflection.clone())), (None, Some(erc721), None) => grpc_builder - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(reflection.clone())), (None, None, Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(tonic_web::enable(reflection)), + .add_service(tonic_web::enable(erc1155)) + .add_service(tonic_web::enable(reflection.clone())), (None, None, None) => grpc_builder.add_service(tonic_web::enable(reflection)), }; diff --git a/bins/torii-tokens/Cargo.toml b/bins/torii-tokens/Cargo.toml index e5a40c0a..b6a98319 100644 --- a/bins/torii-tokens/Cargo.toml +++ b/bins/torii-tokens/Cargo.toml @@ -36,7 +36,7 @@ clap = { version = "4.5", features = ["derive", "env"] } anyhow = "1.0" # gRPC -tonic = "0.12" +tonic = { version = "0.12", features = ["gzip"] } tonic-web = "0.12" tonic-reflection = "0.12" diff --git a/bins/torii-tokens/src/main.rs b/bins/torii-tokens/src/main.rs index 89a1ef4b..f81d81ac 100644 --- a/bins/torii-tokens/src/main.rs +++ b/bins/torii-tokens/src/main.rs @@ -49,6 +49,7 @@ use std::path::Path; use std::sync::Arc; #[cfg(feature = "profiling")] use std::time::{SystemTime, UNIX_EPOCH}; +use tonic::codec::CompressionEncoding; use torii::etl::decoder::DecoderId; use torii::etl::extractor::{ BlockRangeConfig, BlockRangeExtractor, ContractEventConfig, EventExtractor, @@ -692,40 +693,44 @@ async fn run_indexer(config: Config) -> Result<()> { let reflection = reflection_builder .build_v1() - .expect("Failed to build gRPC reflection service"); + .expect("Failed to build gRPC reflection service") + .accept_compressed(CompressionEncoding::Gzip); + + let erc20_server = erc20_grpc_service + .map(|service| Erc20Server::new(service).accept_compressed(CompressionEncoding::Gzip)); + let erc721_server = erc721_grpc_service + .map(|service| Erc721Server::new(service).accept_compressed(CompressionEncoding::Gzip)); + let erc1155_server = erc1155_grpc_service + .map(|service| Erc1155Server::new(service).accept_compressed(CompressionEncoding::Gzip)); let mut grpc_builder = tonic::transport::Server::builder(); - let grpc_router = match ( - erc20_grpc_service, - erc721_grpc_service, - erc1155_grpc_service, - ) { + let grpc_router = match (erc20_server, erc721_server, erc1155_server) { (Some(erc20), Some(erc721), Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(reflection), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(erc1155)) + .add_service(reflection.clone()), (Some(erc20), Some(erc721), None) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(reflection), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc721)) + .add_service(reflection.clone()), (Some(erc20), None, Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(reflection), + .add_service(tonic_web::enable(erc20)) + .add_service(tonic_web::enable(erc1155)) + .add_service(reflection.clone()), (None, Some(erc721), Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(reflection), + .add_service(tonic_web::enable(erc721)) + .add_service(tonic_web::enable(erc1155)) + .add_service(reflection.clone()), (Some(erc20), None, None) => grpc_builder - .add_service(tonic_web::enable(Erc20Server::new(erc20))) - .add_service(reflection), + .add_service(tonic_web::enable(erc20)) + .add_service(reflection.clone()), (None, Some(erc721), None) => grpc_builder - .add_service(tonic_web::enable(Erc721Server::new(erc721))) - .add_service(reflection), + .add_service(tonic_web::enable(erc721)) + .add_service(reflection.clone()), (None, None, Some(erc1155)) => grpc_builder - .add_service(tonic_web::enable(Erc1155Server::new(erc1155))) - .add_service(reflection), + .add_service(tonic_web::enable(erc1155)) + .add_service(reflection.clone()), (None, None, None) => { // No token services, just reflection grpc_builder.add_service(reflection) diff --git a/crates/torii-ecs-sink/Cargo.toml b/crates/torii-ecs-sink/Cargo.toml index 0d402e5f..ae866f38 100644 --- a/crates/torii-ecs-sink/Cargo.toml +++ b/crates/torii-ecs-sink/Cargo.toml @@ -27,6 +27,7 @@ tonic.workspace = true tracing.workspace = true metrics.workspace = true hex.workspace = true +num-bigint = "0.4" [build-dependencies] tonic-build.workspace = true diff --git a/crates/torii-ecs-sink/proto/types.proto b/crates/torii-ecs-sink/proto/types.proto index b3e6d98a..cabfae3e 100644 --- a/crates/torii-ecs-sink/proto/types.proto +++ b/crates/torii-ecs-sink/proto/types.proto @@ -51,6 +51,23 @@ message EventQuery { Pagination pagination = 2; } +message Token { + optional bytes token_id = 1; + bytes contract_address = 2; + string name = 3; + string symbol = 4; + uint32 decimals = 5; + bytes metadata = 6; + optional bytes total_supply = 7; +} + +message TokenBalance { + bytes balance = 1; + bytes account_address = 2; + bytes contract_address = 3; + optional bytes token_id = 4; +} + message Clause { oneof clause_type { HashedKeysClause hashed_keys = 1; @@ -143,6 +160,91 @@ message Pagination { repeated OrderBy order_by = 4; } +message TokenAttributeFilter { + string trait_name = 1; + string trait_value = 2; +} + +message TokenQuery { + repeated bytes contract_addresses = 1; + repeated bytes token_ids = 2; + repeated TokenAttributeFilter attribute_filters = 3; + Pagination pagination = 4; +} + +message TokenBalanceQuery { + repeated bytes account_addresses = 1; + repeated bytes contract_addresses = 2; + repeated bytes token_ids = 3; + Pagination pagination = 4; +} + +message TokenContractQuery { + repeated bytes contract_addresses = 1; + repeated ContractType contract_types = 2; + Pagination pagination = 3; +} + +message TokenTransfer { + string id = 1; + bytes contract_address = 2; + bytes from_address = 3; + bytes to_address = 4; + bytes amount = 5; + optional bytes token_id = 6; + uint64 executed_at = 7; + optional string event_id = 8; +} + +message TokenTransferQuery { + repeated bytes account_addresses = 1; + repeated bytes contract_addresses = 2; + repeated bytes token_ids = 3; + Pagination pagination = 4; +} + +enum CallType { + EXECUTE = 0; + EXECUTE_FROM_OUTSIDE = 1; +} + +message TransactionCall { + bytes contract_address = 1; + string entrypoint = 2; + repeated bytes calldata = 3; + CallType call_type = 4; + bytes caller_address = 5; +} + +message Transaction { + bytes transaction_hash = 1; + bytes sender_address = 2; + repeated bytes calldata = 3; + bytes max_fee = 4; + repeated bytes signature = 5; + bytes nonce = 6; + uint64 block_number = 7; + string transaction_type = 8; + uint64 block_timestamp = 9; + repeated TransactionCall calls = 10; + repeated bytes unique_models = 11; +} + +message TransactionFilter { + repeated bytes transaction_hashes = 1; + repeated bytes caller_addresses = 2; + repeated bytes contract_addresses = 3; + repeated string entrypoints = 4; + repeated bytes model_selectors = 5; + optional uint64 from_block = 6; + optional uint64 to_block = 7; +} + +message TransactionQuery { + TransactionFilter filter = 1; + Pagination pagination = 2; +} + enum ContractType { WORLD = 0; ERC20 = 1; @@ -167,3 +269,37 @@ message ContractQuery { repeated bytes contract_addresses = 1; repeated ContractType contract_types = 2; } + +message SqlValue { + oneof value_type { + string text = 1; + int64 integer = 2; + double real = 3; + bytes blob = 4; + bool null = 5; + } +} + +message SqlRow { + map fields = 1; +} + +message SqlQueryRequest { + string query = 1; +} + +message SqlQueryResponse { + repeated SqlRow rows = 1; +} + +message TokenContract { + bytes contract_address = 1; + ContractType contract_type = 2; + string name = 3; + string symbol = 4; + uint32 decimals = 5; + bytes metadata = 6; + optional bytes total_supply = 7; + string traits = 8; + bytes token_metadata = 9; +} diff --git a/crates/torii-ecs-sink/proto/world.proto b/crates/torii-ecs-sink/proto/world.proto index 803c59ae..fc0c519f 100644 --- a/crates/torii-ecs-sink/proto/world.proto +++ b/crates/torii-ecs-sink/proto/world.proto @@ -12,9 +12,109 @@ service World { rpc RetrieveEntities (RetrieveEntitiesRequest) returns (RetrieveEntitiesResponse); rpc SubscribeEventMessages (SubscribeEntitiesRequest) returns (stream SubscribeEntityResponse); rpc UpdateEventMessagesSubscription (UpdateEntitiesSubscriptionRequest) returns (google.protobuf.Empty); + rpc SubscribeTokenBalances (SubscribeTokenBalancesRequest) returns (stream SubscribeTokenBalancesResponse); + rpc UpdateTokenBalancesSubscription (UpdateTokenBalancesSubscriptionRequest) returns (google.protobuf.Empty); + rpc SubscribeTokens (SubscribeTokensRequest) returns (stream SubscribeTokensResponse); + rpc UpdateTokensSubscription (UpdateTokenSubscriptionRequest) returns (google.protobuf.Empty); + rpc SubscribeTokenTransfers (SubscribeTokenTransfersRequest) returns (stream SubscribeTokenTransfersResponse); + rpc UpdateTokenTransfersSubscription (UpdateTokenTransfersSubscriptionRequest) returns (google.protobuf.Empty); rpc RetrieveEventMessages (RetrieveEntitiesRequest) returns (RetrieveEntitiesResponse); rpc RetrieveEvents (RetrieveEventsRequest) returns (RetrieveEventsResponse); rpc SubscribeEvents (SubscribeEventsRequest) returns (stream SubscribeEventsResponse); + rpc RetrieveTokens (RetrieveTokensRequest) returns (RetrieveTokensResponse); + rpc RetrieveTokenTransfers (RetrieveTokenTransfersRequest) returns (RetrieveTokenTransfersResponse); + rpc RetrieveTokenBalances (RetrieveTokenBalancesRequest) returns (RetrieveTokenBalancesResponse); + rpc RetrieveTransactions (RetrieveTransactionsRequest) returns (RetrieveTransactionsResponse); + rpc SubscribeTransactions (SubscribeTransactionsRequest) returns (stream SubscribeTransactionsResponse); + rpc RetrieveContracts (RetrieveContractsRequest) returns (RetrieveContractsResponse); + rpc RetrieveTokenContracts (RetrieveTokenContractsRequest) returns (RetrieveTokenContractsResponse); + rpc ExecuteSql (types.SqlQueryRequest) returns (types.SqlQueryResponse); +} + +message SubscribeTransactionsRequest { + types.TransactionFilter filter = 1; +} + +message SubscribeTransactionsResponse { + types.Transaction transaction = 1; +} + +message RetrieveContractsRequest { + types.ContractQuery query = 1; +} + +message RetrieveContractsResponse { + repeated types.Contract contracts = 1; +} + +message UpdateTokenBalancesSubscriptionRequest { + uint64 subscription_id = 1; + repeated bytes contract_addresses = 2; + repeated bytes account_addresses = 3; + repeated bytes token_ids = 4; +} + +message SubscribeTokenBalancesResponse { + uint64 subscription_id = 1; + types.TokenBalance balance = 2; +} + +message RetrieveTokensRequest { + types.TokenQuery query = 1; +} + +message SubscribeTokensRequest { + repeated bytes contract_addresses = 1; + repeated bytes token_ids = 2; +} + +message RetrieveTokensResponse { + string next_cursor = 1; + repeated types.Token tokens = 2; +} + +message SubscribeTokensResponse { + uint64 subscription_id = 1; + types.Token token = 2; +} + +message UpdateTokenSubscriptionRequest { + uint64 subscription_id = 1; + repeated bytes contract_addresses = 2; + repeated bytes token_ids = 3; +} + +message RetrieveTokenBalancesRequest { + types.TokenBalanceQuery query = 1; +} + +message SubscribeTokenBalancesRequest { + repeated bytes account_addresses = 1; + repeated bytes contract_addresses = 2; + repeated bytes token_ids = 3; +} + +message RetrieveTokenBalancesResponse { + string next_cursor = 1; + repeated types.TokenBalance balances = 2; +} + +message RetrieveTransactionsRequest { + types.TransactionQuery query = 1; +} + +message RetrieveTransactionsResponse { + string next_cursor = 1; + repeated types.Transaction transactions = 2; +} + +message RetrieveTokenContractsRequest { + types.TokenContractQuery query = 1; +} + +message RetrieveTokenContractsResponse { + string next_cursor = 1; + repeated types.TokenContract token_contracts = 2; } message SubscribeContractsRequest { @@ -74,3 +174,30 @@ message SubscribeEventsRequest { message SubscribeEventsResponse { types.Event event = 1; } + +message SubscribeTokenTransfersRequest { + repeated bytes contract_addresses = 1; + repeated bytes account_addresses = 2; + repeated bytes token_ids = 3; +} + +message SubscribeTokenTransfersResponse { + uint64 subscription_id = 1; + types.TokenTransfer transfer = 2; +} + +message UpdateTokenTransfersSubscriptionRequest { + uint64 subscription_id = 1; + repeated bytes contract_addresses = 2; + repeated bytes account_addresses = 3; + repeated bytes token_ids = 4; +} + +message RetrieveTokenTransfersRequest { + types.TokenTransferQuery query = 1; +} + +message RetrieveTokenTransfersResponse { + string next_cursor = 1; + repeated types.TokenTransfer transfers = 2; +} diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index 59014e16..c9e446aa 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -11,16 +11,18 @@ use introspect_types::{ Attributes, CairoDeserializer, ColumnDef, ColumnInfo, PrimaryTypeDef, ResultDef, TupleDef, TypeDef, }; +use num_bigint::{BigInt, BigUint, Sign}; use serde::ser::SerializeMap; use serde::Serializer; use serde_json::{Map, Serializer as JsonSerializer, Value}; use sqlx::{ any::AnyPoolOptions, postgres::PgPoolOptions, sqlite::SqliteConnectOptions, - sqlite::SqlitePoolOptions, Any, ConnectOptions, Pool, QueryBuilder, Row, + sqlite::SqlitePoolOptions, Any, Column, ConnectOptions, Pool, QueryBuilder, Row, }; use starknet::core::types::Felt; use tokio::sync::mpsc::error::TrySendError; use tokio::sync::{mpsc, Mutex}; +use tokio::time::{sleep, Duration}; use tokio_stream::wrappers::ReceiverStream; use tonic::{Request, Response, Status}; use torii_dojo::store::postgres::PgStore; @@ -35,10 +37,19 @@ use crate::proto::types::{ LogicalOperator, PaginationDirection, PatternMatching, }; use crate::proto::world::{ - world_server::World, RetrieveEntitiesRequest, RetrieveEntitiesResponse, RetrieveEventsRequest, - RetrieveEventsResponse, SubscribeContractsRequest, SubscribeContractsResponse, - SubscribeEntitiesRequest, SubscribeEntityResponse, SubscribeEventsRequest, - SubscribeEventsResponse, UpdateEntitiesSubscriptionRequest, WorldsRequest, WorldsResponse, + world_server::World, RetrieveContractsRequest, RetrieveContractsResponse, + RetrieveEntitiesRequest, RetrieveEntitiesResponse, RetrieveEventsRequest, + RetrieveEventsResponse, RetrieveTokenBalancesRequest, RetrieveTokenBalancesResponse, + RetrieveTokenContractsRequest, RetrieveTokenContractsResponse, RetrieveTokenTransfersRequest, + RetrieveTokenTransfersResponse, RetrieveTokensRequest, RetrieveTokensResponse, + RetrieveTransactionsRequest, RetrieveTransactionsResponse, SubscribeContractsRequest, + SubscribeContractsResponse, SubscribeEntitiesRequest, SubscribeEntityResponse, + SubscribeEventsRequest, SubscribeEventsResponse, SubscribeTokenBalancesRequest, + SubscribeTokenBalancesResponse, SubscribeTokenTransfersRequest, + SubscribeTokenTransfersResponse, SubscribeTokensRequest, SubscribeTokensResponse, + SubscribeTransactionsRequest, SubscribeTransactionsResponse, UpdateEntitiesSubscriptionRequest, + UpdateTokenBalancesSubscriptionRequest, UpdateTokenSubscriptionRequest, + UpdateTokenTransfersSubscriptionRequest, WorldsRequest, WorldsResponse, }; #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -94,6 +105,10 @@ struct EcsState { event_message_subscriptions: Mutex>, event_subscriptions: Mutex>, contract_subscriptions: Mutex>, + token_subscriptions: Mutex>, + token_balance_subscriptions: Mutex>, + token_transfer_subscriptions: Mutex>, + transaction_subscriptions: Mutex>, } struct EntitySubscription { @@ -112,6 +127,35 @@ struct ContractSubscription { sender: mpsc::Sender>, } +struct TokenSubscription { + contract_addresses: Vec>, + token_ids: Vec>, + seen: HashSet, + sender: mpsc::Sender>, +} + +struct TokenBalanceSubscription { + contract_addresses: Vec>, + account_addresses: Vec>, + token_ids: Vec>, + seen: HashSet, + sender: mpsc::Sender>, +} + +struct TokenTransferSubscription { + contract_addresses: Vec>, + account_addresses: Vec>, + token_ids: Vec>, + seen: HashSet, + sender: mpsc::Sender>, +} + +struct TransactionSubscription { + filter: types::TransactionFilter, + seen: HashSet, + sender: mpsc::Sender>, +} + #[derive(Clone)] struct ManagedTable { world_address: Felt, @@ -171,6 +215,10 @@ impl EcsService { event_message_subscriptions: Mutex::new(HashMap::new()), event_subscriptions: Mutex::new(HashMap::new()), contract_subscriptions: Mutex::new(HashMap::new()), + token_subscriptions: Mutex::new(HashMap::new()), + token_balance_subscriptions: Mutex::new(HashMap::new()), + token_transfer_subscriptions: Mutex::new(HashMap::new()), + transaction_subscriptions: Mutex::new(HashMap::new()), }), }; service.initialize().await?; @@ -867,6 +915,1090 @@ impl EcsService { Ok(contracts) } + fn scoped_table(&self, schema: &str, table: &str) -> String { + match self.state.backend { + DbBackend::Postgres => format!("{schema}.{table}"), + DbBackend::Sqlite => table.to_string(), + } + } + + fn pagination_limit(pagination: Option<&types::Pagination>, default: usize) -> usize { + pagination + .map(|pagination| pagination.limit) + .filter(|limit| *limit > 0) + .map(|limit| limit.min(1000) as usize) + .unwrap_or(default) + } + + async fn load_token_contracts( + &self, + query: &types::TokenContractQuery, + ) -> Result<(Vec, String)> { + let limit = Self::pagination_limit(query.pagination.as_ref(), 100); + let mut items = Vec::new(); + let include_erc20 = query.contract_types.is_empty() + || query + .contract_types + .iter() + .any(|kind| *kind == ContractType::Erc20 as i32); + let include_erc721 = query.contract_types.is_empty() + || query + .contract_types + .iter() + .any(|kind| *kind == ContractType::Erc721 as i32); + let include_erc1155 = query.contract_types.is_empty() + || query + .contract_types + .iter() + .any(|kind| *kind == ContractType::Erc1155 as i32); + + if include_erc20 { + let table = self.scoped_table("erc20", "token_metadata"); + let mut builder = QueryBuilder::::new(format!( + "SELECT token, name, symbol, decimals FROM {table}" + )); + push_blob_in_filter(&mut builder, "token", &query.contract_addresses); + for row in builder.build().fetch_all(&self.state.pool).await? { + items.push(types::TokenContract { + contract_address: row.try_get("token")?, + contract_type: ContractType::Erc20 as i32, + name: row + .try_get::, _>("name")? + .unwrap_or_default(), + symbol: row + .try_get::, _>("symbol")? + .unwrap_or_default(), + decimals: row + .try_get::, _>("decimals")? + .unwrap_or_default() as u32, + metadata: Vec::new(), + total_supply: None, + traits: String::new(), + token_metadata: Vec::new(), + }); + } + } + + if include_erc721 { + let table = self.scoped_table("erc721", "token_metadata"); + let uris = self.scoped_table("erc721", "token_uris"); + let mut builder = QueryBuilder::::new(format!( + "SELECT tm.token, tm.name, tm.symbol, tm.total_supply, \ + COALESCE((SELECT metadata_json FROM {uris} tu WHERE tu.token = tm.token ORDER BY tu.token_id LIMIT 1), '') AS token_metadata \ + FROM {table} tm" + )); + push_blob_in_filter(&mut builder, "tm.token", &query.contract_addresses); + for row in builder.build().fetch_all(&self.state.pool).await? { + items.push(types::TokenContract { + contract_address: row.try_get("token")?, + contract_type: ContractType::Erc721 as i32, + name: row + .try_get::, _>("name")? + .unwrap_or_default(), + symbol: row + .try_get::, _>("symbol")? + .unwrap_or_default(), + decimals: 0, + metadata: Vec::new(), + total_supply: row.try_get::>, _>("total_supply")?, + traits: String::new(), + token_metadata: row + .try_get::, _>("token_metadata")? + .unwrap_or_default() + .into_bytes(), + }); + } + } + + if include_erc1155 { + let table = self.scoped_table("erc1155", "token_metadata"); + let uris = self.scoped_table("erc1155", "token_uris"); + let mut builder = QueryBuilder::::new(format!( + "SELECT tm.token, tm.name, tm.symbol, tm.total_supply, \ + COALESCE((SELECT metadata_json FROM {uris} tu WHERE tu.token = tm.token ORDER BY tu.token_id LIMIT 1), '') AS token_metadata \ + FROM {table} tm" + )); + push_blob_in_filter(&mut builder, "tm.token", &query.contract_addresses); + for row in builder.build().fetch_all(&self.state.pool).await? { + items.push(types::TokenContract { + contract_address: row.try_get("token")?, + contract_type: ContractType::Erc1155 as i32, + name: row + .try_get::, _>("name")? + .unwrap_or_default(), + symbol: row + .try_get::, _>("symbol")? + .unwrap_or_default(), + decimals: 0, + metadata: Vec::new(), + total_supply: row.try_get::>, _>("total_supply")?, + traits: String::new(), + token_metadata: row + .try_get::, _>("token_metadata")? + .unwrap_or_default() + .into_bytes(), + }); + } + } + + items.sort_by(|a, b| a.contract_address.cmp(&b.contract_address)); + items.truncate(limit); + Ok((items, String::new())) + } + + async fn load_tokens(&self, query: &types::TokenQuery) -> Result<(Vec, String)> { + let limit = Self::pagination_limit(query.pagination.as_ref(), 100); + let mut items = Vec::new(); + + if query.token_ids.is_empty() { + let table = self.scoped_table("erc20", "token_metadata"); + let mut builder = QueryBuilder::::new(format!( + "SELECT token, name, symbol, decimals FROM {table}" + )); + push_blob_in_filter(&mut builder, "token", &query.contract_addresses); + for row in builder.build().fetch_all(&self.state.pool).await? { + items.push(types::Token { + token_id: None, + contract_address: row.try_get("token")?, + name: row + .try_get::, _>("name")? + .unwrap_or_default(), + symbol: row + .try_get::, _>("symbol")? + .unwrap_or_default(), + decimals: row + .try_get::, _>("decimals")? + .unwrap_or_default() as u32, + metadata: Vec::new(), + total_supply: None, + }); + } + } + + items.extend( + self.load_nft_tokens("erc721", query, ContractType::Erc721) + .await?, + ); + items.extend( + self.load_nft_tokens("erc1155", query, ContractType::Erc1155) + .await?, + ); + items.sort_by(|a, b| { + a.contract_address + .cmp(&b.contract_address) + .then_with(|| a.token_id.cmp(&b.token_id)) + }); + items.truncate(limit); + Ok((items, String::new())) + } + + async fn load_nft_tokens( + &self, + schema: &str, + query: &types::TokenQuery, + _kind: ContractType, + ) -> Result> { + let token_metadata = self.scoped_table(schema, "token_metadata"); + let token_uris = self.scoped_table(schema, "token_uris"); + let token_attributes = self.scoped_table(schema, "token_attributes"); + let mut builder = QueryBuilder::::new(format!( + "SELECT tu.token, tu.token_id, tu.metadata_json, tm.name, tm.symbol, tm.total_supply \ + FROM {token_uris} tu \ + LEFT JOIN {token_metadata} tm ON tm.token = tu.token" + )); + let mut has_where = false; + has_where |= push_blob_in_filter(&mut builder, "tu.token", &query.contract_addresses); + if !query.token_ids.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + has_where = true; + } + builder.push("tu.token_id IN ("); + { + let mut separated = builder.separated(", "); + for token_id in &query.token_ids { + separated.push_bind(token_id.clone()); + } + } + builder.push(")"); + } + for (index, filter) in query.attribute_filters.iter().enumerate() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + has_where = true; + } + builder.push(format!( + "EXISTS (SELECT 1 FROM {token_attributes} ta{index} WHERE ta{index}.token = tu.token AND ta{index}.token_id = tu.token_id AND ta{index}.key = " + )); + builder.push_bind(filter.trait_name.clone()); + builder.push(" AND ta"); + builder.push(index.to_string()); + builder.push(".value = "); + builder.push_bind(filter.trait_value.clone()); + builder.push(")"); + } + + let rows = builder.build().fetch_all(&self.state.pool).await?; + rows.into_iter() + .map(|row| { + Ok(types::Token { + token_id: Some(row.try_get("token_id")?), + contract_address: row.try_get("token")?, + name: row + .try_get::, _>("name")? + .unwrap_or_default(), + symbol: row + .try_get::, _>("symbol")? + .unwrap_or_default(), + decimals: 0, + metadata: row + .try_get::, _>("metadata_json")? + .unwrap_or_default() + .into_bytes(), + total_supply: row.try_get::>, _>("total_supply")?, + }) + }) + .collect() + } + + async fn load_token_balances( + &self, + query: &types::TokenBalanceQuery, + ) -> Result<(Vec, String)> { + let limit = Self::pagination_limit(query.pagination.as_ref(), 100); + let mut items = Vec::new(); + + { + let table = self.scoped_table("erc20", "balances"); + let mut builder = + QueryBuilder::::new(format!("SELECT wallet, token, balance FROM {table}")); + let mut has_where = false; + has_where |= push_blob_in_filter(&mut builder, "wallet", &query.account_addresses); + if !query.contract_addresses.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + } + builder.push("token IN ("); + { + let mut separated = builder.separated(", "); + for contract in &query.contract_addresses { + separated.push_bind(contract.clone()); + } + } + builder.push(")"); + } + for row in builder.build().fetch_all(&self.state.pool).await? { + items.push(types::TokenBalance { + balance: row.try_get("balance")?, + account_address: row.try_get("wallet")?, + contract_address: row.try_get("token")?, + token_id: None, + }); + } + } + + { + let table = self.scoped_table("erc721", "nft_ownership"); + let mut builder = + QueryBuilder::::new(format!("SELECT owner, token, token_id FROM {table}")); + let mut has_where = false; + has_where |= push_blob_in_filter(&mut builder, "owner", &query.account_addresses); + if !query.contract_addresses.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + has_where = true; + } + builder.push("token IN ("); + { + let mut separated = builder.separated(", "); + for contract in &query.contract_addresses { + separated.push_bind(contract.clone()); + } + } + builder.push(")"); + } + if !query.token_ids.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + } + builder.push("token_id IN ("); + { + let mut separated = builder.separated(", "); + for token_id in &query.token_ids { + separated.push_bind(token_id.clone()); + } + } + builder.push(")"); + } + for row in builder.build().fetch_all(&self.state.pool).await? { + items.push(types::TokenBalance { + balance: u256_bytes_from_u64(1), + account_address: row.try_get("owner")?, + contract_address: row.try_get("token")?, + token_id: Some(row.try_get("token_id")?), + }); + } + } + + { + let table = self.scoped_table("erc1155", "erc1155_balances"); + let mut builder = QueryBuilder::::new(format!( + "SELECT wallet, contract, token_id, balance FROM {table}" + )); + let mut has_where = false; + has_where |= push_blob_in_filter(&mut builder, "wallet", &query.account_addresses); + if !query.contract_addresses.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + has_where = true; + } + builder.push("contract IN ("); + { + let mut separated = builder.separated(", "); + for contract in &query.contract_addresses { + separated.push_bind(contract.clone()); + } + } + builder.push(")"); + } + if !query.token_ids.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + } + builder.push("token_id IN ("); + { + let mut separated = builder.separated(", "); + for token_id in &query.token_ids { + separated.push_bind(token_id.clone()); + } + } + builder.push(")"); + } + for row in builder.build().fetch_all(&self.state.pool).await? { + items.push(types::TokenBalance { + balance: row.try_get("balance")?, + account_address: row.try_get("wallet")?, + contract_address: row.try_get("contract")?, + token_id: Some(row.try_get("token_id")?), + }); + } + } + + items.sort_by(|a, b| { + a.contract_address + .cmp(&b.contract_address) + .then_with(|| a.account_address.cmp(&b.account_address)) + .then_with(|| a.token_id.cmp(&b.token_id)) + }); + items.truncate(limit); + Ok((items, String::new())) + } + + async fn load_token_transfers( + &self, + query: &types::TokenTransferQuery, + ) -> Result<(Vec, String)> { + let limit = Self::pagination_limit(query.pagination.as_ref(), 100); + let mut items = Vec::new(); + + items.extend(self.load_erc20_transfers(query).await?); + items.extend(self.load_erc721_transfers(query).await?); + items.extend(self.load_erc1155_transfers(query).await?); + + items.sort_by(|a, b| { + b.executed_at + .cmp(&a.executed_at) + .then_with(|| a.id.cmp(&b.id)) + }); + items.truncate(limit); + Ok((items, String::new())) + } + + async fn load_transactions( + &self, + query: &types::TransactionQuery, + ) -> Result<(Vec, String)> { + let limit = Self::pagination_limit(query.pagination.as_ref(), 100); + let filter = query.filter.as_ref().cloned().unwrap_or_default(); + if !filter.caller_addresses.is_empty() + || !filter.entrypoints.is_empty() + || !filter.model_selectors.is_empty() + { + return Ok((Vec::new(), String::new())); + } + + let mut by_hash: HashMap, (u64, u64)> = HashMap::new(); + for (hash, block_number, block_timestamp) in + self.load_transaction_rows_from_events(&filter).await? + { + let entry = by_hash + .entry(hash) + .or_insert((block_number, block_timestamp)); + if (block_number, block_timestamp) > *entry { + *entry = (block_number, block_timestamp); + } + } + for (hash, block_number, block_timestamp) in self + .load_transaction_rows_from_token_tables(&filter) + .await? + { + let entry = by_hash + .entry(hash) + .or_insert((block_number, block_timestamp)); + if (block_number, block_timestamp) > *entry { + *entry = (block_number, block_timestamp); + } + } + + let mut transactions = by_hash + .into_iter() + .map( + |(transaction_hash, (block_number, block_timestamp))| types::Transaction { + transaction_hash, + sender_address: Vec::new(), + calldata: Vec::new(), + max_fee: Vec::new(), + signature: Vec::new(), + nonce: Vec::new(), + block_number, + transaction_type: String::new(), + block_timestamp, + calls: Vec::new(), + unique_models: Vec::new(), + }, + ) + .collect::>(); + transactions.sort_by(|a, b| { + b.block_number + .cmp(&a.block_number) + .then_with(|| b.block_timestamp.cmp(&a.block_timestamp)) + .then_with(|| a.transaction_hash.cmp(&b.transaction_hash)) + }); + if !filter.transaction_hashes.is_empty() { + let wanted = filter + .transaction_hashes + .iter() + .cloned() + .collect::>(); + transactions.retain(|tx| wanted.contains(&tx.transaction_hash)); + } + transactions.truncate(limit); + Ok((transactions, String::new())) + } + + async fn load_transaction_rows_from_events( + &self, + filter: &types::TransactionFilter, + ) -> Result, u64, u64)>> { + let mut builder = QueryBuilder::::new( + "SELECT transaction_hash, block_number, executed_at, world_address FROM torii_ecs_events", + ); + let mut has_where = false; + if let Some(from_block) = filter.from_block { + builder.push(" WHERE block_number >= "); + builder.push_bind(from_block as i64); + has_where = true; + } + if let Some(to_block) = filter.to_block { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + has_where = true; + } + builder.push("block_number <= "); + builder.push_bind(to_block as i64); + } + if !filter.contract_addresses.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + } + builder.push("world_address IN ("); + { + let mut separated = builder.separated(", "); + for contract in &filter.contract_addresses { + separated.push_bind(felt_hex(felt_from_bytes(contract)?)); + } + } + builder.push(")"); + } + let rows = builder.build().fetch_all(&self.state.pool).await?; + rows.into_iter() + .map(|row| { + Ok(( + felt_from_hex(&row.try_get::("transaction_hash")?)? + .to_bytes_be() + .to_vec(), + row.try_get::("block_number")? as u64, + row.try_get::("executed_at")? as u64, + )) + }) + .collect() + } + + async fn load_transaction_rows_from_token_tables( + &self, + filter: &types::TransactionFilter, + ) -> Result, u64, u64)>> { + let mut rows = Vec::new(); + rows.extend( + self.load_token_tx_rows("erc20", "transfers", "token", filter) + .await?, + ); + rows.extend( + self.load_token_tx_rows("erc721", "nft_transfers", "token", filter) + .await?, + ); + rows.extend( + self.load_token_tx_rows("erc1155", "token_transfers", "token", filter) + .await?, + ); + Ok(rows) + } + + async fn load_token_tx_rows( + &self, + schema: &str, + table_name: &str, + contract_column: &str, + filter: &types::TransactionFilter, + ) -> Result, u64, u64)>> { + let table = self.scoped_table(schema, table_name); + let mut builder = QueryBuilder::::new(format!( + "SELECT tx_hash, block_number, COALESCE(timestamp, 0) AS timestamp, {contract_column} FROM {table}" + )); + let mut has_where = false; + if let Some(from_block) = filter.from_block { + builder.push(" WHERE block_number >= "); + builder.push_bind(from_block as i64); + has_where = true; + } + if let Some(to_block) = filter.to_block { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + has_where = true; + } + builder.push("block_number <= "); + builder.push_bind(to_block as i64); + } + if !filter.contract_addresses.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + } + builder.push(format!("{contract_column} IN (")); + { + let mut separated = builder.separated(", "); + for contract in &filter.contract_addresses { + separated.push_bind(contract.clone()); + } + } + builder.push(")"); + } + let rows = builder.build().fetch_all(&self.state.pool).await?; + rows.into_iter() + .map(|row| { + Ok(( + row.try_get("tx_hash")?, + row.try_get::("block_number")? as u64, + row.try_get::("timestamp")? as u64, + )) + }) + .collect() + } + + async fn load_erc20_transfers( + &self, + query: &types::TokenTransferQuery, + ) -> Result> { + let table = self.scoped_table("erc20", "transfers"); + let mut builder = QueryBuilder::::new(format!( + "SELECT id, token, from_addr, to_addr, amount, COALESCE(timestamp, 0) AS timestamp FROM {table}" + )); + push_transfer_filters(&mut builder, query, "token", "from_addr", "to_addr", None); + let rows = builder.build().fetch_all(&self.state.pool).await?; + rows.into_iter() + .map(|row| { + Ok(types::TokenTransfer { + id: format!("erc20:{}", row.try_get::("id")?), + contract_address: row.try_get("token")?, + from_address: row.try_get("from_addr")?, + to_address: row.try_get("to_addr")?, + amount: row.try_get("amount")?, + token_id: None, + executed_at: row.try_get::("timestamp")? as u64, + event_id: None, + }) + }) + .collect() + } + + async fn load_erc721_transfers( + &self, + query: &types::TokenTransferQuery, + ) -> Result> { + let table = self.scoped_table("erc721", "nft_transfers"); + let mut builder = QueryBuilder::::new(format!( + "SELECT id, token, from_addr, to_addr, token_id, COALESCE(timestamp, 0) AS timestamp FROM {table}" + )); + push_transfer_filters( + &mut builder, + query, + "token", + "from_addr", + "to_addr", + Some("token_id"), + ); + let rows = builder.build().fetch_all(&self.state.pool).await?; + rows.into_iter() + .map(|row| { + Ok(types::TokenTransfer { + id: format!("erc721:{}", row.try_get::("id")?), + contract_address: row.try_get("token")?, + from_address: row.try_get("from_addr")?, + to_address: row.try_get("to_addr")?, + amount: u256_bytes_from_u64(1), + token_id: Some(row.try_get("token_id")?), + executed_at: row.try_get::("timestamp")? as u64, + event_id: None, + }) + }) + .collect() + } + + async fn load_erc1155_transfers( + &self, + query: &types::TokenTransferQuery, + ) -> Result> { + let table = self.scoped_table("erc1155", "token_transfers"); + let mut builder = QueryBuilder::::new(format!( + "SELECT id, token, from_addr, to_addr, token_id, amount, COALESCE(timestamp, 0) AS timestamp FROM {table}" + )); + push_transfer_filters( + &mut builder, + query, + "token", + "from_addr", + "to_addr", + Some("token_id"), + ); + let rows = builder.build().fetch_all(&self.state.pool).await?; + rows.into_iter() + .map(|row| { + Ok(types::TokenTransfer { + id: format!("erc1155:{}", row.try_get::("id")?), + contract_address: row.try_get("token")?, + from_address: row.try_get("from_addr")?, + to_address: row.try_get("to_addr")?, + amount: row.try_get("amount")?, + token_id: Some(row.try_get("token_id")?), + executed_at: row.try_get::("timestamp")? as u64, + event_id: None, + }) + }) + .collect() + } + + async fn snapshot_token_seen( + &self, + contract_addresses: &[Vec], + token_ids: &[Vec], + ) -> Result> { + let (tokens, _) = self + .load_tokens(&types::TokenQuery { + contract_addresses: contract_addresses.to_vec(), + token_ids: token_ids.to_vec(), + attribute_filters: Vec::new(), + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 1000, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }) + .await?; + Ok(tokens + .into_iter() + .map(|token| token_subscription_key(&token)) + .collect()) + } + + async fn snapshot_token_balance_seen( + &self, + account_addresses: &[Vec], + contract_addresses: &[Vec], + token_ids: &[Vec], + ) -> Result> { + let (balances, _) = self + .load_token_balances(&types::TokenBalanceQuery { + account_addresses: account_addresses.to_vec(), + contract_addresses: contract_addresses.to_vec(), + token_ids: token_ids.to_vec(), + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 1000, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }) + .await?; + Ok(balances + .into_iter() + .map(|balance| token_balance_subscription_key(&balance)) + .collect()) + } + + async fn snapshot_token_transfer_seen( + &self, + account_addresses: &[Vec], + contract_addresses: &[Vec], + token_ids: &[Vec], + ) -> Result> { + let (transfers, _) = self + .load_token_transfers(&types::TokenTransferQuery { + account_addresses: account_addresses.to_vec(), + contract_addresses: contract_addresses.to_vec(), + token_ids: token_ids.to_vec(), + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 1000, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }) + .await?; + Ok(transfers.into_iter().map(|transfer| transfer.id).collect()) + } + + async fn snapshot_transaction_seen( + &self, + filter: &types::TransactionFilter, + ) -> Result> { + let (transactions, _) = self + .load_transactions(&types::TransactionQuery { + filter: Some(filter.clone()), + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 1000, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }) + .await?; + Ok(transactions + .into_iter() + .map(|transaction| hex::encode(transaction.transaction_hash)) + .collect()) + } + + fn spawn_token_poll(&self, subscription_id: u64) { + let service = self.clone(); + tokio::spawn(async move { + loop { + sleep(Duration::from_secs(1)).await; + let (contract_addresses, token_ids, seen, sender) = { + let subscriptions = service.state.token_subscriptions.lock().await; + let Some(subscription) = subscriptions.get(&subscription_id) else { + break; + }; + ( + subscription.contract_addresses.clone(), + subscription.token_ids.clone(), + subscription.seen.clone(), + subscription.sender.clone(), + ) + }; + let tokens = match service + .load_tokens(&types::TokenQuery { + contract_addresses, + token_ids, + attribute_filters: Vec::new(), + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 1000, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }) + .await + { + Ok((tokens, _)) => tokens, + Err(_) => continue, + }; + let mut sent = Vec::new(); + for token in tokens { + let key = token_subscription_key(&token); + if seen.contains(&key) { + continue; + } + if sender + .send(Ok(SubscribeTokensResponse { + subscription_id, + token: Some(token), + })) + .await + .is_err() + { + service + .state + .token_subscriptions + .lock() + .await + .remove(&subscription_id); + return; + } + sent.push(key); + } + if !sent.is_empty() { + if let Some(subscription) = service + .state + .token_subscriptions + .lock() + .await + .get_mut(&subscription_id) + { + subscription.seen.extend(sent); + } + } + } + }); + } + + fn spawn_token_balance_poll(&self, subscription_id: u64) { + let service = self.clone(); + tokio::spawn(async move { + loop { + sleep(Duration::from_secs(1)).await; + let (account_addresses, contract_addresses, token_ids, seen, sender) = { + let subscriptions = service.state.token_balance_subscriptions.lock().await; + let Some(subscription) = subscriptions.get(&subscription_id) else { + break; + }; + ( + subscription.account_addresses.clone(), + subscription.contract_addresses.clone(), + subscription.token_ids.clone(), + subscription.seen.clone(), + subscription.sender.clone(), + ) + }; + let balances = match service + .load_token_balances(&types::TokenBalanceQuery { + account_addresses, + contract_addresses, + token_ids, + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 1000, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }) + .await + { + Ok((balances, _)) => balances, + Err(_) => continue, + }; + let mut sent = Vec::new(); + for balance in balances { + let key = token_balance_subscription_key(&balance); + if seen.contains(&key) { + continue; + } + if sender + .send(Ok(SubscribeTokenBalancesResponse { + subscription_id, + balance: Some(balance), + })) + .await + .is_err() + { + service + .state + .token_balance_subscriptions + .lock() + .await + .remove(&subscription_id); + return; + } + sent.push(key); + } + if !sent.is_empty() { + if let Some(subscription) = service + .state + .token_balance_subscriptions + .lock() + .await + .get_mut(&subscription_id) + { + subscription.seen.extend(sent); + } + } + } + }); + } + + fn spawn_token_transfer_poll(&self, subscription_id: u64) { + let service = self.clone(); + tokio::spawn(async move { + loop { + sleep(Duration::from_secs(1)).await; + let (account_addresses, contract_addresses, token_ids, seen, sender) = { + let subscriptions = service.state.token_transfer_subscriptions.lock().await; + let Some(subscription) = subscriptions.get(&subscription_id) else { + break; + }; + ( + subscription.account_addresses.clone(), + subscription.contract_addresses.clone(), + subscription.token_ids.clone(), + subscription.seen.clone(), + subscription.sender.clone(), + ) + }; + let transfers = match service + .load_token_transfers(&types::TokenTransferQuery { + account_addresses, + contract_addresses, + token_ids, + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 1000, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }) + .await + { + Ok((transfers, _)) => transfers, + Err(_) => continue, + }; + let mut sent = Vec::new(); + for transfer in transfers { + if seen.contains(&transfer.id) { + continue; + } + if sender + .send(Ok(SubscribeTokenTransfersResponse { + subscription_id, + transfer: Some(transfer.clone()), + })) + .await + .is_err() + { + service + .state + .token_transfer_subscriptions + .lock() + .await + .remove(&subscription_id); + return; + } + sent.push(transfer.id); + } + if !sent.is_empty() { + if let Some(subscription) = service + .state + .token_transfer_subscriptions + .lock() + .await + .get_mut(&subscription_id) + { + subscription.seen.extend(sent); + } + } + } + }); + } + + fn spawn_transaction_poll(&self, subscription_id: u64) { + let service = self.clone(); + tokio::spawn(async move { + loop { + sleep(Duration::from_secs(1)).await; + let (filter, seen, sender) = { + let subscriptions = service.state.transaction_subscriptions.lock().await; + let Some(subscription) = subscriptions.get(&subscription_id) else { + break; + }; + ( + subscription.filter.clone(), + subscription.seen.clone(), + subscription.sender.clone(), + ) + }; + let transactions = match service + .load_transactions(&types::TransactionQuery { + filter: Some(filter), + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 1000, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }) + .await + { + Ok((transactions, _)) => transactions, + Err(_) => continue, + }; + let mut sent = Vec::new(); + for transaction in transactions { + let key = hex::encode(&transaction.transaction_hash); + if seen.contains(&key) { + continue; + } + if sender + .send(Ok(SubscribeTransactionsResponse { + transaction: Some(transaction), + })) + .await + .is_err() + { + service + .state + .transaction_subscriptions + .lock() + .await + .remove(&subscription_id); + return; + } + sent.push(key); + } + if !sent.is_empty() { + if let Some(subscription) = service + .state + .transaction_subscriptions + .lock() + .await + .get_mut(&subscription_id) + { + subscription.seen.extend(sent); + } + } + } + }); + } + async fn load_worlds(&self, requested: &[Felt]) -> Result> { let requested = requested.iter().copied().collect::>(); let mut by_world: HashMap, Vec> = HashMap::new(); @@ -1878,7 +3010,14 @@ impl World for EcsService { type SubscribeContractsStream = ReceiverStream>; type SubscribeEntitiesStream = ReceiverStream>; type SubscribeEventMessagesStream = ReceiverStream>; + type SubscribeTokenBalancesStream = + ReceiverStream>; + type SubscribeTokensStream = ReceiverStream>; + type SubscribeTokenTransfersStream = + ReceiverStream>; type SubscribeEventsStream = ReceiverStream>; + type SubscribeTransactionsStream = + ReceiverStream>; async fn subscribe_contracts( &self, @@ -2013,43 +3152,225 @@ impl World for EcsService { async fn update_event_messages_subscription( &self, - request: Request, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + if let Some(subscription) = self + .state + .event_message_subscriptions + .lock() + .await + .get_mut(&request.subscription_id) + { + subscription.clause = request.clause; + subscription.world_addresses = request.world_addresses.into_iter().collect(); + } + Ok(Response::new(())) + } + + async fn retrieve_event_messages( + &self, + request: Request, + ) -> Result, Status> { + let start = Instant::now(); + let query = request + .into_inner() + .query + .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; + let result = self.load_entity_page(TableKind::EventMessage, &query).await; + ::metrics::histogram!("torii_ecs_retrieve_event_messages_latency_seconds") + .record(start.elapsed().as_secs_f64()); + let (entities, next_cursor) = result.map_err(internal_status)?; + ::metrics::counter!("torii_ecs_retrieve_event_messages_returned_total") + .increment(entities.len() as u64); + Ok(Response::new(RetrieveEntitiesResponse { + next_cursor, + entities, + })) + } + + async fn subscribe_token_balances( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + let subscription_id = Self::next_subscription_id().await; + let (sender, receiver) = mpsc::channel(256); + sender + .send(Ok(SubscribeTokenBalancesResponse { + subscription_id, + balance: None, + })) + .await + .map_err(|_| Status::internal("subscription setup failed"))?; + let seen = self + .snapshot_token_balance_seen( + &request.account_addresses, + &request.contract_addresses, + &request.token_ids, + ) + .await + .map_err(internal_status)?; + self.state.token_balance_subscriptions.lock().await.insert( + subscription_id, + TokenBalanceSubscription { + contract_addresses: request.contract_addresses, + account_addresses: request.account_addresses, + token_ids: request.token_ids, + seen, + sender, + }, + ); + self.spawn_token_balance_poll(subscription_id); + Ok(Response::new(ReceiverStream::new(receiver))) + } + + async fn update_token_balances_subscription( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + let seen = self + .snapshot_token_balance_seen( + &request.account_addresses, + &request.contract_addresses, + &request.token_ids, + ) + .await + .map_err(internal_status)?; + if let Some(subscription) = self + .state + .token_balance_subscriptions + .lock() + .await + .get_mut(&request.subscription_id) + { + subscription.contract_addresses = request.contract_addresses; + subscription.account_addresses = request.account_addresses; + subscription.token_ids = request.token_ids; + subscription.seen = seen; + } + Ok(Response::new(())) + } + + async fn subscribe_tokens( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + let subscription_id = Self::next_subscription_id().await; + let (sender, receiver) = mpsc::channel(256); + sender + .send(Ok(SubscribeTokensResponse { + subscription_id, + token: None, + })) + .await + .map_err(|_| Status::internal("subscription setup failed"))?; + let seen = self + .snapshot_token_seen(&request.contract_addresses, &request.token_ids) + .await + .map_err(internal_status)?; + self.state.token_subscriptions.lock().await.insert( + subscription_id, + TokenSubscription { + contract_addresses: request.contract_addresses, + token_ids: request.token_ids, + seen, + sender, + }, + ); + self.spawn_token_poll(subscription_id); + Ok(Response::new(ReceiverStream::new(receiver))) + } + + async fn update_tokens_subscription( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + let seen = self + .snapshot_token_seen(&request.contract_addresses, &request.token_ids) + .await + .map_err(internal_status)?; + if let Some(subscription) = self + .state + .token_subscriptions + .lock() + .await + .get_mut(&request.subscription_id) + { + subscription.contract_addresses = request.contract_addresses; + subscription.token_ids = request.token_ids; + subscription.seen = seen; + } + Ok(Response::new(())) + } + + async fn subscribe_token_transfers( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + let subscription_id = Self::next_subscription_id().await; + let (sender, receiver) = mpsc::channel(256); + sender + .send(Ok(SubscribeTokenTransfersResponse { + subscription_id, + transfer: None, + })) + .await + .map_err(|_| Status::internal("subscription setup failed"))?; + let seen = self + .snapshot_token_transfer_seen( + &request.account_addresses, + &request.contract_addresses, + &request.token_ids, + ) + .await + .map_err(internal_status)?; + self.state.token_transfer_subscriptions.lock().await.insert( + subscription_id, + TokenTransferSubscription { + contract_addresses: request.contract_addresses, + account_addresses: request.account_addresses, + token_ids: request.token_ids, + seen, + sender, + }, + ); + self.spawn_token_transfer_poll(subscription_id); + Ok(Response::new(ReceiverStream::new(receiver))) + } + + async fn update_token_transfers_subscription( + &self, + request: Request, ) -> Result, Status> { let request = request.into_inner(); + let seen = self + .snapshot_token_transfer_seen( + &request.account_addresses, + &request.contract_addresses, + &request.token_ids, + ) + .await + .map_err(internal_status)?; if let Some(subscription) = self .state - .event_message_subscriptions + .token_transfer_subscriptions .lock() .await .get_mut(&request.subscription_id) { - subscription.clause = request.clause; - subscription.world_addresses = request.world_addresses.into_iter().collect(); + subscription.contract_addresses = request.contract_addresses; + subscription.account_addresses = request.account_addresses; + subscription.token_ids = request.token_ids; + subscription.seen = seen; } Ok(Response::new(())) } - async fn retrieve_event_messages( - &self, - request: Request, - ) -> Result, Status> { - let start = Instant::now(); - let query = request - .into_inner() - .query - .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; - let result = self.load_entity_page(TableKind::EventMessage, &query).await; - ::metrics::histogram!("torii_ecs_retrieve_event_messages_latency_seconds") - .record(start.elapsed().as_secs_f64()); - let (entities, next_cursor) = result.map_err(internal_status)?; - ::metrics::counter!("torii_ecs_retrieve_event_messages_returned_total") - .increment(entities.len() as u64); - Ok(Response::new(RetrieveEntitiesResponse { - next_cursor, - entities, - })) - } - async fn retrieve_events( &self, request: Request, @@ -2090,6 +3411,147 @@ impl World for EcsService { ); Ok(Response::new(ReceiverStream::new(receiver))) } + + async fn retrieve_tokens( + &self, + request: Request, + ) -> Result, Status> { + let query = request + .into_inner() + .query + .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; + let (tokens, next_cursor) = self.load_tokens(&query).await.map_err(internal_status)?; + Ok(Response::new(RetrieveTokensResponse { + next_cursor, + tokens, + })) + } + + async fn retrieve_token_transfers( + &self, + request: Request, + ) -> Result, Status> { + let query = request + .into_inner() + .query + .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; + let (transfers, next_cursor) = self + .load_token_transfers(&query) + .await + .map_err(internal_status)?; + Ok(Response::new(RetrieveTokenTransfersResponse { + next_cursor, + transfers, + })) + } + + async fn retrieve_token_balances( + &self, + request: Request, + ) -> Result, Status> { + let query = request + .into_inner() + .query + .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; + let (balances, next_cursor) = self + .load_token_balances(&query) + .await + .map_err(internal_status)?; + Ok(Response::new(RetrieveTokenBalancesResponse { + next_cursor, + balances, + })) + } + + async fn retrieve_transactions( + &self, + request: Request, + ) -> Result, Status> { + let query = request + .into_inner() + .query + .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; + let (transactions, next_cursor) = self + .load_transactions(&query) + .await + .map_err(internal_status)?; + Ok(Response::new(RetrieveTransactionsResponse { + next_cursor, + transactions, + })) + } + + async fn subscribe_transactions( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + let subscription_id = Self::next_subscription_id().await; + let (sender, receiver) = mpsc::channel(256); + sender + .send(Ok(SubscribeTransactionsResponse { transaction: None })) + .await + .map_err(|_| Status::internal("subscription setup failed"))?; + let filter = request.filter.unwrap_or_default(); + let seen = self + .snapshot_transaction_seen(&filter) + .await + .map_err(internal_status)?; + self.state.transaction_subscriptions.lock().await.insert( + subscription_id, + TransactionSubscription { + filter, + seen, + sender, + }, + ); + self.spawn_transaction_poll(subscription_id); + Ok(Response::new(ReceiverStream::new(receiver))) + } + + async fn retrieve_contracts( + &self, + request: Request, + ) -> Result, Status> { + let query = request + .into_inner() + .query + .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; + let contracts = self.load_contracts(&query).await.map_err(internal_status)?; + Ok(Response::new(RetrieveContractsResponse { contracts })) + } + + async fn retrieve_token_contracts( + &self, + request: Request, + ) -> Result, Status> { + let query = request + .into_inner() + .query + .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; + let (token_contracts, next_cursor) = self + .load_token_contracts(&query) + .await + .map_err(internal_status)?; + Ok(Response::new(RetrieveTokenContractsResponse { + next_cursor, + token_contracts, + })) + } + + async fn execute_sql( + &self, + request: Request, + ) -> Result, Status> { + let query = request.into_inner().query; + let rows = sqlx::query(&query) + .fetch_all(&self.state.pool) + .await + .map_err(|error| Status::invalid_argument(format!("Query error: {error}")))?; + Ok(Response::new(types::SqlQueryResponse { + rows: rows.iter().map(row_to_sql_row).collect(), + })) + } } #[derive(Clone, Copy)] @@ -2450,8 +3912,7 @@ fn type_to_proto_value(type_def: &TypeDef, value: Value) -> Result { | TypeDef::ClassHash | TypeDef::ContractAddress | TypeDef::StorageAddress - | TypeDef::StorageBaseAddress - | TypeDef::EthAddress => { + | TypeDef::StorageBaseAddress => { let bytes = value_as_felt_bytes(&value)?; let primitive = match type_def { TypeDef::ClassHash => types::primitive::PrimitiveType::ClassHash(bytes), @@ -2460,20 +3921,37 @@ fn type_to_proto_value(type_def: &TypeDef, value: Value) -> Result { | TypeDef::StorageBaseAddress => { types::primitive::PrimitiveType::ContractAddress(bytes) } - TypeDef::EthAddress => types::primitive::PrimitiveType::EthAddress(bytes), _ => types::primitive::PrimitiveType::Felt252(bytes), }; TyType::Primitive(types::Primitive { primitive_type: Some(primitive), }) } - TypeDef::U128 | TypeDef::I128 | TypeDef::U256 | TypeDef::U512 => { - TyType::Primitive(types::Primitive { - primitive_type: Some(types::primitive::PrimitiveType::U256(value_as_bytes( - &value, - ))), - }) - } + TypeDef::EthAddress => TyType::Primitive(types::Primitive { + primitive_type: Some(types::primitive::PrimitiveType::EthAddress( + value_as_fixed_unsigned_bytes(&value, 20)?, + )), + }), + TypeDef::U128 => TyType::Primitive(types::Primitive { + primitive_type: Some(types::primitive::PrimitiveType::U128( + value_as_fixed_unsigned_bytes(&value, 16)?, + )), + }), + TypeDef::I128 => TyType::Primitive(types::Primitive { + primitive_type: Some(types::primitive::PrimitiveType::I128( + value_as_fixed_signed_bytes(&value, 16)?, + )), + }), + TypeDef::U256 => TyType::Primitive(types::Primitive { + primitive_type: Some(types::primitive::PrimitiveType::U256( + value_as_fixed_unsigned_bytes(&value, 32)?, + )), + }), + TypeDef::U512 => TyType::Primitive(types::Primitive { + primitive_type: Some(types::primitive::PrimitiveType::U256( + value_as_fixed_unsigned_bytes(&value, 64)?, + )), + }), TypeDef::Utf8String | TypeDef::ShortUtf8 | TypeDef::ByteArray @@ -2628,13 +4106,6 @@ fn value_as_string(value: &Value) -> String { } } -fn value_as_bytes(value: &Value) -> Vec { - value.as_str().map_or_else( - || value_as_string(value).into_bytes(), - |value| value.as_bytes().to_vec(), - ) -} - fn value_as_felt_bytes(value: &Value) -> Result> { if value.is_null() { return Ok(Felt::ZERO.to_bytes_be().to_vec()); @@ -2649,6 +4120,277 @@ fn value_as_felt_bytes(value: &Value) -> Result> { Ok(felt_from_hex(trimmed)?.to_bytes_be().to_vec()) } +fn value_as_fixed_unsigned_bytes(value: &Value, width: usize) -> Result> { + let unsigned = value_as_big_uint(value)?; + let bytes = unsigned.to_bytes_be(); + if bytes.len() > width { + anyhow::bail!("value does not fit in {width} bytes"); + } + + let mut out = vec![0_u8; width]; + out[width - bytes.len()..].copy_from_slice(&bytes); + Ok(out) +} + +fn value_as_fixed_signed_bytes(value: &Value, width: usize) -> Result> { + let signed = value_as_big_int(value)?; + let bytes = signed.to_signed_bytes_be(); + if bytes.len() > width { + anyhow::bail!("value does not fit in {width} bytes"); + } + + let pad = if signed.sign() == Sign::Minus { + 0xff + } else { + 0x00 + }; + let mut out = vec![pad; width]; + out[width - bytes.len()..].copy_from_slice(&bytes); + Ok(out) +} + +fn value_as_big_uint(value: &Value) -> Result { + let parsed = value_as_big_int(value)?; + parsed + .to_biguint() + .ok_or_else(|| anyhow!("expected unsigned value, got negative integer")) +} + +fn value_as_big_int(value: &Value) -> Result { + if value.is_null() { + return Ok(BigInt::from(0_u8)); + } + + if let Some(value) = value.as_i64() { + return Ok(BigInt::from(value)); + } + + if let Some(value) = value.as_u64() { + return Ok(BigInt::from(value)); + } + + parse_big_int(value_as_string(value).trim()) +} + +fn parse_big_int(raw: &str) -> Result { + if raw.is_empty() { + return Ok(BigInt::from(0_u8)); + } + + if let Some(hex) = raw.strip_prefix("-0x") { + let magnitude = parse_big_uint_with_radix(hex, 16)?; + return Ok(-BigInt::from(magnitude)); + } + + if let Some(hex) = raw.strip_prefix("0x") { + let magnitude = parse_big_uint_with_radix(hex, 16)?; + return Ok(BigInt::from(magnitude)); + } + + if raw.contains(['e', 'E']) { + return parse_scientific_big_int(raw); + } + + BigInt::parse_bytes(raw.as_bytes(), 10) + .ok_or_else(|| anyhow!("failed to parse integer value: {raw}")) +} + +fn parse_scientific_big_int(raw: &str) -> Result { + let (mantissa, exponent) = raw + .split_once(['e', 'E']) + .ok_or_else(|| anyhow!("failed to parse integer value: {raw}"))?; + let exponent: i64 = exponent + .parse() + .map_err(|_| anyhow!("failed to parse integer value: {raw}"))?; + + let (negative, mantissa) = if let Some(rest) = mantissa.strip_prefix('-') { + (true, rest) + } else if let Some(rest) = mantissa.strip_prefix('+') { + (false, rest) + } else { + (false, mantissa) + }; + + let (whole, fractional) = mantissa.split_once('.').unwrap_or((mantissa, "")); + let digits = format!("{whole}{fractional}"); + let digits = digits.trim_start_matches('0'); + if digits.is_empty() { + return Ok(BigInt::from(0_u8)); + } + + let scale = exponent - fractional.len() as i64; + let magnitude = if scale >= 0 { + let zeros = "0".repeat(scale as usize); + BigInt::parse_bytes(format!("{digits}{zeros}").as_bytes(), 10) + } else { + let split_at = digits + .len() + .checked_sub((-scale) as usize) + .ok_or_else(|| anyhow!("failed to parse integer value: {raw}"))?; + let (integer, remainder) = digits.split_at(split_at); + if remainder.bytes().any(|byte| byte != b'0') { + return Err(anyhow!("failed to parse integer value: {raw}")); + } + let integer = if integer.is_empty() { "0" } else { integer }; + BigInt::parse_bytes(integer.as_bytes(), 10) + } + .ok_or_else(|| anyhow!("failed to parse integer value: {raw}"))?; + + Ok(if negative { -magnitude } else { magnitude }) +} + +fn parse_big_uint_with_radix(raw: &str, radix: u32) -> Result { + if raw.is_empty() { + return Ok(BigUint::default()); + } + + BigUint::parse_bytes(raw.as_bytes(), radix) + .ok_or_else(|| anyhow!("failed to parse integer value: {raw}")) +} + +fn push_blob_in_filter( + builder: &mut QueryBuilder<'_, Any>, + column: &str, + values: &[Vec], +) -> bool { + if values.is_empty() { + return false; + } + builder.push(" WHERE "); + builder.push(column); + builder.push(" IN ("); + { + let mut separated = builder.separated(", "); + for value in values { + separated.push_bind(value.clone()); + } + } + builder.push(")"); + true +} + +fn push_transfer_filters( + builder: &mut QueryBuilder<'_, Any>, + query: &types::TokenTransferQuery, + contract_column: &str, + from_column: &str, + to_column: &str, + token_id_column: Option<&str>, +) { + let mut has_where = false; + if !query.contract_addresses.is_empty() { + builder.push(" WHERE "); + builder.push(contract_column); + builder.push(" IN ("); + { + let mut separated = builder.separated(", "); + for contract in &query.contract_addresses { + separated.push_bind(contract.clone()); + } + } + builder.push(")"); + has_where = true; + } + if !query.account_addresses.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + has_where = true; + } + builder.push("("); + builder.push(from_column); + builder.push(" IN ("); + { + let mut separated = builder.separated(", "); + for account in &query.account_addresses { + separated.push_bind(account.clone()); + } + } + builder.push(") OR "); + builder.push(to_column); + builder.push(" IN ("); + { + let mut separated = builder.separated(", "); + for account in &query.account_addresses { + separated.push_bind(account.clone()); + } + } + builder.push("))"); + } + if let Some(token_id_column) = token_id_column { + if !query.token_ids.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + } + builder.push(token_id_column); + builder.push(" IN ("); + { + let mut separated = builder.separated(", "); + for token_id in &query.token_ids { + separated.push_bind(token_id.clone()); + } + } + builder.push(")"); + } + } +} + +fn token_subscription_key(token: &types::Token) -> String { + format!( + "{}:{}", + hex::encode(&token.contract_address), + token.token_id.as_ref().map(hex::encode).unwrap_or_default() + ) +} + +fn token_balance_subscription_key(balance: &types::TokenBalance) -> String { + format!( + "{}:{}:{}", + hex::encode(&balance.contract_address), + hex::encode(&balance.account_address), + balance + .token_id + .as_ref() + .map(hex::encode) + .unwrap_or_default() + ) +} + +fn u256_bytes_from_u64(value: u64) -> Vec { + let mut out = vec![0_u8; 32]; + out[24..].copy_from_slice(&value.to_be_bytes()); + out +} + +fn row_to_sql_row(row: &sqlx::any::AnyRow) -> types::SqlRow { + let mut fields = HashMap::new(); + for (index, column) in row.columns().iter().enumerate() { + let value_type = if let Ok(value) = row.try_get::, _>(index) { + value.map(types::sql_value::ValueType::Text) + } else if let Ok(value) = row.try_get::, _>(index) { + value.map(types::sql_value::ValueType::Integer) + } else if let Ok(value) = row.try_get::, _>(index) { + value.map(types::sql_value::ValueType::Real) + } else if let Ok(value) = row.try_get::>, _>(index) { + value.map(types::sql_value::ValueType::Blob) + } else if let Ok(value) = row.try_get::, _>(index) { + value.map(|value| types::sql_value::ValueType::Text(value.to_string())) + } else { + None + }; + fields.insert( + column.name().to_string(), + types::SqlValue { + value_type: Some(value_type.unwrap_or(types::sql_value::ValueType::Null(true))), + }, + ); + } + types::SqlRow { fields } +} + #[allow(dead_code)] fn value_to_primary_felt(value: &Value, type_def: &PrimaryTypeDef) -> Result { match type_def { @@ -3083,6 +4825,70 @@ mod tests { } } + #[test] + fn serializes_u128_as_fixed_width_u128() { + let ty = type_to_proto_value(&TypeDef::U128, serde_json::json!(10000_u64)).expect("u128"); + + let types::ty::TyType::Primitive(primitive) = ty.ty_type.expect("primitive") else { + panic!("expected primitive"); + }; + let Some(types::primitive::PrimitiveType::U128(bytes)) = primitive.primitive_type else { + panic!("expected u128 primitive"); + }; + + assert_eq!(bytes.len(), 16); + assert_eq!( + u128::from_be_bytes(bytes.try_into().expect("16 bytes")), + 10_000 + ); + } + + #[test] + fn serializes_eth_address_as_20_bytes() { + let ty = type_to_proto_value( + &TypeDef::EthAddress, + serde_json::json!("0x11223344556677889900aabbccddeeff00112233"), + ) + .expect("eth address"); + + let types::ty::TyType::Primitive(primitive) = ty.ty_type.expect("primitive") else { + panic!("expected primitive"); + }; + let Some(types::primitive::PrimitiveType::EthAddress(bytes)) = primitive.primitive_type + else { + panic!("expected eth_address primitive"); + }; + + assert_eq!(bytes.len(), 20); + assert_eq!( + hex::encode(bytes), + "11223344556677889900aabbccddeeff00112233" + ); + } + + #[test] + fn serializes_u256_as_fixed_width_u256() { + let ty = type_to_proto_value(&TypeDef::U256, serde_json::json!("0x1234")).expect("u256"); + + let types::ty::TyType::Primitive(primitive) = ty.ty_type.expect("primitive") else { + panic!("expected primitive"); + }; + let Some(types::primitive::PrimitiveType::U256(bytes)) = primitive.primitive_type else { + panic!("expected u256 primitive"); + }; + + assert_eq!(bytes.len(), 32); + assert_eq!(&bytes[30..], &[0x12, 0x34]); + assert!(bytes[..30].iter().all(|byte| *byte == 0)); + } + + #[test] + fn parses_scientific_notation_integer_strings() { + let value = parse_big_int("1.5495265022047578e+21").expect("scientific integer"); + + assert_eq!(value.to_string(), "1549526502204757800000"); + } + async fn seed_entity( service: &EcsService, kind: TableKind, diff --git a/examples/multi_sink_example/main.rs b/examples/multi_sink_example/main.rs index 7b632f03..382df69a 100644 --- a/examples/multi_sink_example/main.rs +++ b/examples/multi_sink_example/main.rs @@ -12,6 +12,7 @@ //! or also spin up the client and test in the browser (inside `client` directory). use std::sync::Arc; +use tonic::codec::CompressionEncoding; use tonic::transport::Server; use torii::{run, ToriiConfig}; use torii_log_sink::{LogDecoder, LogSink}; @@ -57,25 +58,28 @@ async fn main() -> Result<(), Box> { .register_encoded_file_descriptor_set(torii_sql_sink::FILE_DESCRIPTOR_SET) // SQL Sink .register_encoded_file_descriptor_set(torii_log_sink::FILE_DESCRIPTOR_SET) // Log Sink .build_v1() - .expect("Failed to build reflection v1"); + .expect("Failed to build reflection v1") + .accept_compressed(CompressionEncoding::Gzip); let reflection_v1alpha = tonic_reflection::server::Builder::configure() .register_encoded_file_descriptor_set(torii::TORII_DESCRIPTOR_SET) // Core Torii .register_encoded_file_descriptor_set(torii_sql_sink::FILE_DESCRIPTOR_SET) // SQL Sink .register_encoded_file_descriptor_set(torii_log_sink::FILE_DESCRIPTOR_SET) // Log Sink .build_v1alpha() - .expect("Failed to build reflection v1alpha"); + .expect("Failed to build reflection v1alpha") + .accept_compressed(CompressionEncoding::Gzip); + + let sql_service = SqlSinkServer::new((*sql_grpc_service).clone()) + .accept_compressed(CompressionEncoding::Gzip); + let log_service = LogSinkServer::new((*log_grpc_service).clone()) + .accept_compressed(CompressionEncoding::Gzip); Server::builder() // Accept HTTP/1.1 requests required for gRPC-Web to work. .accept_http1(true) // Add sink services. - .add_service(tonic_web::enable(SqlSinkServer::new( - (*sql_grpc_service).clone(), - ))) - .add_service(tonic_web::enable(LogSinkServer::new( - (*log_grpc_service).clone(), - ))) + .add_service(tonic_web::enable(sql_service)) + .add_service(tonic_web::enable(log_service)) // Add reflection services with ALL descriptors. .add_service(tonic_web::enable(reflection_v1)) .add_service(tonic_web::enable(reflection_v1alpha)) diff --git a/examples/simple_sql_sink/main.rs b/examples/simple_sql_sink/main.rs index 47040efc..b20a30c2 100644 --- a/examples/simple_sql_sink/main.rs +++ b/examples/simple_sql_sink/main.rs @@ -9,6 +9,7 @@ // Then: Open http://localhost:5173 in browser (after starting client) use std::sync::Arc; +use tonic::codec::CompressionEncoding; use tonic::transport::Server; use torii::{run, ToriiConfig}; use torii_sql_sink::{SqlDecoder, SqlSink}; @@ -30,11 +31,12 @@ async fn main() -> Result<(), Box> { let grpc_router = { use torii_sql_sink::proto::sql_sink_server::SqlSinkServer; + let sql_service = SqlSinkServer::new((*sql_grpc_service).clone()) + .accept_compressed(CompressionEncoding::Gzip); + Server::builder() .accept_http1(true) - .add_service(tonic_web::enable(SqlSinkServer::new( - (*sql_grpc_service).clone(), - ))) + .add_service(tonic_web::enable(sql_service)) // Torii will add the core service to this router }; diff --git a/src/grpc.rs b/src/grpc.rs index 6e4b0624..429cb139 100644 --- a/src/grpc.rs +++ b/src/grpc.rs @@ -10,6 +10,7 @@ use std::sync::{Arc, RwLock}; use tokio::sync::mpsc; use tokio_stream::wrappers::ReceiverStream; use tokio_stream::Stream; +use tonic::codec::CompressionEncoding; use tonic::{Request, Response, Status, Streaming}; pub mod proto { @@ -308,5 +309,5 @@ impl Torii for ToriiService { } pub fn create_grpc_service(state: GrpcState) -> ToriiServer { - ToriiServer::new(ToriiService::new(state)) + ToriiServer::new(ToriiService::new(state)).accept_compressed(CompressionEncoding::Gzip) } diff --git a/src/lib.rs b/src/lib.rs index 7cb6ba9b..f75e62f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use std::time::Duration; use tokio_util::sync::CancellationToken; +use tonic::codec::CompressionEncoding; use tonic::transport::Server; use tower_http::cors::{Any as CorsAny, CorsLayer}; @@ -701,11 +702,13 @@ pub async fn run(config: ToriiConfig) -> Result<(), Box> } else { let reflection_v1 = tonic_reflection::server::Builder::configure() .register_encoded_file_descriptor_set(FILE_DESCRIPTOR_SET) - .build_v1()?; + .build_v1()? + .accept_compressed(CompressionEncoding::Gzip); let reflection_v1alpha = tonic_reflection::server::Builder::configure() .register_encoded_file_descriptor_set(FILE_DESCRIPTOR_SET) - .build_v1alpha()?; + .build_v1alpha()? + .accept_compressed(CompressionEncoding::Gzip); grpc_router = grpc_router .add_service(tonic_web::enable(reflection_v1)) From 92929c646c5d00ebb9392ba3f74944612d5a464a Mon Sep 17 00:00:00 2001 From: Bengineer Date: Tue, 24 Mar 2026 13:48:58 +0000 Subject: [PATCH 02/21] Refactor Postgres Sink: Enhance schema handling and table management - Updated schema handling to use `Rc` instead of `Rc` for better memory efficiency. - Introduced `MultiContractEventIterator` to handle multiple event sources concurrently. - Modified table queries to include an owner field and adjusted related queries accordingly. - Improved error handling and logging during table initialization and event processing. - Cleaned up unused code and optimized imports across various modules. - Enhanced the `PgTable` struct to support new table creation and upgrades more effectively. - Updated tests and examples to reflect changes in event handling and schema management. --- Cargo.lock | 1 + Cargo.toml | 1 + bins/torii-introspect-bin/src/main.rs | 3 +- crates/introspect-postgres-sink/Cargo.toml | 1 + .../migrations/003_store.sql | 2 + crates/introspect-postgres-sink/src/create.rs | 59 ++- crates/introspect-postgres-sink/src/error.rs | 36 +- crates/introspect-postgres-sink/src/insert.rs | 89 ++++ crates/introspect-postgres-sink/src/lib.rs | 6 +- .../introspect-postgres-sink/src/processor.rs | 408 +++++++----------- crates/introspect-postgres-sink/src/query.rs | 129 +++--- crates/introspect-postgres-sink/src/table.rs | 79 +++- crates/introspect-postgres-sink/src/tables.rs | 229 ++++++++++ crates/introspect-postgres-sink/src/types.rs | 21 +- .../introspect-postgres-sink/src/upgrade.rs | 35 +- crates/introspect-postgres-sink/src/utils.rs | 4 + crates/introspect/src/tables.rs | 22 - crates/testing/src/event_reader.rs | 29 ++ crates/testing/src/lib.rs | 2 +- examples/introspect/restart.rs | 43 +- 20 files changed, 781 insertions(+), 418 deletions(-) create mode 100644 crates/introspect-postgres-sink/src/insert.rs create mode 100644 crates/introspect-postgres-sink/src/tables.rs diff --git a/Cargo.lock b/Cargo.lock index 903c8688..acea9fdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4939,6 +4939,7 @@ name = "torii-introspect-postgres-sink" version = "0.1.0" dependencies = [ "anyhow", + "arrayvec", "async-trait", "hex", "introspect-types", diff --git a/Cargo.toml b/Cargo.toml index b8596143..01448162 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -120,6 +120,7 @@ dojo-introspect = { git = "https://github.com/dojoengine/dojo-introspect", rev = # Utils resolve-path = "0.1.0" itertools = "0.14.0" +arrayvec = "0.7.6" # Torii core torii.path = "." diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index 4e16a1d7..a862a8ba 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -39,6 +39,7 @@ use torii_erc721::{ FILE_DESCRIPTOR_SET as ERC721_DESCRIPTOR_SET, }; use torii_introspect_postgres_sink::processor::IntrospectPgDb; +use torii_introspect_postgres_sink::SchemaMode; use torii_introspect_sqlite_sink::processor::IntrospectSqliteDb; use torii_runtime_common::database::{resolve_token_db_setup, TokenDbSetup}; use torii_sqlite::{is_sqlite_memory_path, sqlite_connect_options}; @@ -473,7 +474,7 @@ async fn run_with_postgres( ); let decoder = DojoDecoder::, _>::new(pool.clone(), provider); - let sink = IntrospectPgDb::new(pool.clone(), ()); + let sink = IntrospectPgDb::new(pool.clone(), SchemaMode::Address); decoder.store.initialize().await?; sink.initialize_introspect_pg_sink().await?; decoder.load_tables(&[]).await?; diff --git a/crates/introspect-postgres-sink/Cargo.toml b/crates/introspect-postgres-sink/Cargo.toml index 816f88dd..ca265369 100644 --- a/crates/introspect-postgres-sink/Cargo.toml +++ b/crates/introspect-postgres-sink/Cargo.toml @@ -29,6 +29,7 @@ starknet-types-core.workspace = true thiserror.workspace = true introspect-types.workspace = true itertools.workspace = true +arrayvec.workspace = true # Local crates torii-introspect.workspace = true diff --git a/crates/introspect-postgres-sink/migrations/003_store.sql b/crates/introspect-postgres-sink/migrations/003_store.sql index d58e2145..f5a83a78 100644 --- a/crates/introspect-postgres-sink/migrations/003_store.sql +++ b/crates/introspect-postgres-sink/migrations/003_store.sql @@ -22,7 +22,9 @@ CREATE TABLE IF NOT EXISTS introspect.db_tables ( "schema" TEXT NOT NULL, id felt252 NOT NULL, name TEXT NOT NULL, + "owner" felt252 NOT NULL, primary_def introspect.primary_def NOT NULL, + alive BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), created_block uint64 NOT NULL, diff --git a/crates/introspect-postgres-sink/src/create.rs b/crates/introspect-postgres-sink/src/create.rs index 41bf4d85..08d2e2df 100644 --- a/crates/introspect-postgres-sink/src/create.rs +++ b/crates/introspect-postgres-sink/src/create.rs @@ -1,24 +1,22 @@ use crate::{ - query::{CreatePgTable, CreatesType}, + query::{make_schema_query, CreatePgTable, CreatesType}, utils::{AsBytes, HasherExt}, - PgSchema, PgTypeError, PgTypeResult, PostgresField, PostgresScalar, PostgresType, PrimaryKey, - SchemaName, + PgTypeError, PgTypeResult, PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, }; use introspect_types::{ - ArrayDef, ColumnDef, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, PrimaryTypeDef, - StructDef, TupleDef, TypeDef, VariantDef, + ArrayDef, ColumnDef, ColumnInfo, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, + PrimaryTypeDef, StructDef, TupleDef, TypeDef, VariantDef, }; use itertools::Itertools; use starknet_types_core::felt::Felt; use std::rc::Rc; use torii_common::sql::{PgQuery, Queries}; -use torii_introspect::schema::TableInfo; use xxhash_rust::xxh3::Xxh3; pub trait PostgresTypeExtractor { fn extract_type( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult; @@ -34,7 +32,7 @@ pub trait PostgresFieldExtractor { } fn extract_field( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult { @@ -54,7 +52,7 @@ impl PostgresField { } } - pub fn new_composite(name: S, schema: &Rc, type_name: T) -> Self + pub fn new_composite(name: S, schema: &Rc, type_name: T) -> Self where S: Into, T: Into, @@ -80,6 +78,20 @@ impl PostgresFieldExtractor for ColumnDef { } } +impl PostgresFieldExtractor for (&Felt, &ColumnInfo) { + type Id = Felt; + fn name(&self) -> &str { + &self.1.name + } + + fn type_def(&self) -> &TypeDef { + &self.1.type_def + } + fn id(&self) -> &Self::Id { + &self.0 + } +} + impl PostgresFieldExtractor for MemberDef { type Id = String; fn name(&self) -> &str { @@ -111,7 +123,7 @@ impl PostgresFieldExtractor for (&Felt, &VariantDef) { impl PostgresTypeExtractor for TypeDef { fn extract_type( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult { @@ -187,7 +199,7 @@ impl From<&PrimaryDef> for PrimaryKey { impl PostgresTypeExtractor for ArrayDef { fn extract_type( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult { @@ -200,7 +212,7 @@ impl PostgresTypeExtractor for ArrayDef { impl PostgresTypeExtractor for FixedArrayDef { fn extract_type( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult { @@ -213,7 +225,7 @@ impl PostgresTypeExtractor for FixedArrayDef { impl PostgresTypeExtractor for StructDef { fn extract_type( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult { @@ -231,7 +243,7 @@ impl PostgresTypeExtractor for StructDef { impl PostgresTypeExtractor for EnumDef { fn extract_type( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult { @@ -259,7 +271,7 @@ impl PostgresTypeExtractor for EnumDef { impl PostgresTypeExtractor for TupleDef { fn extract_type( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult { @@ -280,7 +292,7 @@ impl PostgresTypeExtractor for TupleDef { impl PostgresTypeExtractor for OptionDef { fn extract_type( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, creates: &mut Vec>, ) -> PgTypeResult { @@ -289,13 +301,13 @@ impl PostgresTypeExtractor for OptionDef { } impl CreatePgTable { - pub fn new(schema: &Rc, id: &Felt, table: &TableInfo) -> PgTypeResult { - let TableInfo { - name, - attributes: _, - primary, - columns, - } = table; + pub fn new( + schema: &Rc, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: Vec<(&Felt, &ColumnInfo)>, + ) -> PgTypeResult { let mut creates = Vec::new(); let branch = Xxh3::new_based(id); let primary = primary.into(); @@ -311,6 +323,7 @@ impl CreatePgTable { }) } pub fn make_queries(&self, queries: &mut Vec) { + queries.add(make_schema_query(&self.name.0)); for pg_type in &self.pg_types { queries.add(pg_type.to_string()); } diff --git a/crates/introspect-postgres-sink/src/error.rs b/crates/introspect-postgres-sink/src/error.rs index 0dda8017..c5d11d1a 100644 --- a/crates/introspect-postgres-sink/src/error.rs +++ b/crates/introspect-postgres-sink/src/error.rs @@ -1,8 +1,8 @@ -use std::sync::PoisonError; - +use crate::tables::TableKey; use introspect_types::{PrimaryTypeDef, TypeDef}; use sqlx::Error as SqlxError; -use starknet_types_core::felt::Felt; +use starknet_types_core::felt::{Felt, FromStrError}; +use std::sync::PoisonError; use thiserror::Error; #[derive(Debug, Error)] @@ -114,15 +114,17 @@ pub enum PgDbError { #[error(transparent)] TypeError(#[from] PgTypeError), #[error("Table with id: {0} already exists, incoming name: {1}, existing name: {2}")] - TableAlreadyExists(Felt, String, String), + TableAlreadyExists(TableKey, String, String), #[error("Table not found with id: {0}")] - TableNotFound(Felt), + TableNotFound(TableKey), #[error("Table not alive - id: {0}, name: {1}")] TableNotAlive(Felt, String), #[error("Manager does not support updating")] UpdateNotSupported, #[error("Table poison error: {0}")] PoisonError(String), + #[error("Schema not found for address: {0:#063x}")] + SchemaNotFound(Felt), } pub type PgDbResult = std::result::Result; @@ -132,3 +134,27 @@ impl From> for PgDbError { Self::PoisonError(err.to_string()) } } + +#[derive(Debug, thiserror::Error)] +pub enum SchemaError { + #[error("Invalid address length for schema: {0} should be 63 characters long")] + InvalidAddressLength(String), + #[error(transparent)] + AddressFromStrError(#[from] FromStrError), + #[error("Schema {0} does not match expected schema {1}")] + SchemaMismatch(String, String), + #[error("Schema {1} not found for address: {0:#063x}")] + AddressNotFound(Felt, String), +} + +pub type SchemaResult = std::result::Result; + +#[derive(Debug, thiserror::Error)] +pub enum TableLoadError { + #[error(transparent)] + SchemaError(#[from] SchemaError), + #[error("Table {0} {1:#063x} not found for column {2} with id: {3:#063x}")] + ColumnTableNotFound(String, Felt, String, Felt), + #[error("Table {0} {1:#063x} not found for dead field {2} with id: {3}")] + TableDeadNotFound(String, Felt, String, u128), +} diff --git a/crates/introspect-postgres-sink/src/insert.rs b/crates/introspect-postgres-sink/src/insert.rs new file mode 100644 index 00000000..28c16f6a --- /dev/null +++ b/crates/introspect-postgres-sink/src/insert.rs @@ -0,0 +1,89 @@ +use crate::{json::PostgresJsonSerializer, table::PgTable, PgDbResult}; +use introspect_types::ColumnInfo; +use serde::ser::SerializeMap; +use serde_json::Serializer as JsonSerializer; +use starknet_types_core::felt::Felt; +use std::io::Write; +use torii_common::sql::{PgQuery, Queries}; +use torii_introspect::{tables::SerializeEntries, InsertsFields}; + +pub const METADATA_CONFLICTS: &str = "__updated_at = NOW(), __updated_block = EXCLUDED.__updated_block, __updated_tx = EXCLUDED.__updated_tx"; + +pub struct MetaData<'a> { + pub block_number: u64, + pub transaction_hash: &'a Felt, +} + +impl<'a> MetaData<'a> { + pub fn new(block_number: u64, transaction_hash: &'a Felt) -> Self { + Self { + block_number, + transaction_hash, + } + } +} + +pub fn pg_json_felt252(value: &Felt) -> String { + format!("\\x{}", hex::encode(value.to_bytes_be())) +} + +impl SerializeEntries for MetaData<'_> { + fn entry_count(&self) -> usize { + 4 + } + fn serialize_entries( + &self, + map: &mut ::SerializeMap, + ) -> Result<(), S::Error> { + let tx_hash = pg_json_felt252(&self.transaction_hash); + map.serialize_entry("__created_block", &self.block_number)?; + map.serialize_entry("__updated_block", &self.block_number)?; + map.serialize_entry("__created_tx", &tx_hash)?; + map.serialize_entry("__updated_tx", &tx_hash) + } +} + +impl PgTable { + pub fn insert_fields( + &self, + event: &InsertsFields, + block_number: u64, + transaction_hash: &Felt, + _from_address: &Felt, + queries: &mut Vec, + ) -> PgDbResult<()> { + let record = self.get_record_schema(&event.columns)?; + let table_name = &self.name; + let mut writer = Vec::new(); + let schema = &self.schema; + let metadata = MetaData::new(block_number, transaction_hash); + write!( + writer, + r#"INSERT INTO "{schema}"."{table_name}" SELECT * FROM jsonb_populate_recordset(NULL::"{schema}"."{table_name}", $$"# + ) + .unwrap(); + record.parse_records_with_metadata( + &event.records, + &metadata, + &mut JsonSerializer::new(&mut writer), + &PostgresJsonSerializer, + )?; + write!( + writer, + r#"$$) ON CONFLICT ("{}") DO UPDATE SET {METADATA_CONFLICTS}"#, + record.primary().name + ) + .unwrap(); + for ColumnInfo { name, .. } in record.columns() { + write!( + writer, + r#", "{name}" = COALESCE(EXCLUDED."{name}", "{table_name}"."{name}")"#, + name = name + ) + .unwrap(); + } + let string = unsafe { String::from_utf8_unchecked(writer) }; + queries.add(string); + Ok(()) + } +} diff --git a/crates/introspect-postgres-sink/src/lib.rs b/crates/introspect-postgres-sink/src/lib.rs index 83d42122..6dc4effd 100644 --- a/crates/introspect-postgres-sink/src/lib.rs +++ b/crates/introspect-postgres-sink/src/lib.rs @@ -1,10 +1,12 @@ pub mod create; pub mod error; +pub mod insert; pub mod json; pub mod processor; pub mod query; pub mod sink; pub mod table; +pub mod tables; pub mod types; pub mod upgrade; pub mod utils; @@ -13,9 +15,9 @@ pub use error::{ PgDbError, PgDbResult, PgTableError, PgTypeError, PgTypeResult, TableResult, UpgradeError, UpgradeResult, UpgradeResultExt, }; -pub use processor::IntrospectPgDb; +pub use processor::{IntrospectPgDb, SchemaMode}; pub use types::{ - PgSchema, PostgresArray, PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, + PostgresArray, PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, }; pub use utils::{truncate, HasherExt}; diff --git a/crates/introspect-postgres-sink/src/processor.rs b/crates/introspect-postgres-sink/src/processor.rs index 196a7ef1..b3761a2d 100644 --- a/crates/introspect-postgres-sink/src/processor.rs +++ b/crates/introspect-postgres-sink/src/processor.rs @@ -1,318 +1,237 @@ -use crate::json::PostgresJsonSerializer; -use crate::query::{fetch_columns, fetch_dead_fields, fetch_tables, CreatePgTable}; -use crate::table::{DeadField, PgTable}; -use crate::{PgDbError, PgDbResult, PgSchema, INTROSPECT_PG_SINK_MIGRATIONS}; -use introspect_types::ColumnInfo; -use serde_json::Serializer as JsonSerializer; +use crate::error::{SchemaError, SchemaResult, TableLoadError}; +use crate::query::{fetch_columns, fetch_dead_fields, fetch_tables, COMMIT_CMD}; +use crate::tables::{PgSchema, PostgresTables, TableKey}; +use crate::utils::felt_to_schema; +use crate::{PgDbError, PgDbResult, INTROSPECT_PG_SINK_MIGRATIONS}; +use introspect_types::ResultInto; +use itertools::Itertools; use sqlx::PgPool; use starknet_types_core::felt::Felt; -use std::collections::HashMap; -use std::io::Write; -use std::ops::Deref; -use std::rc::Rc; -use std::sync::RwLock; -use torii::etl::envelope::MetaData; -use torii_common::sql::{PgQuery, Queries}; -use torii_introspect::events::{IntrospectBody, IntrospectMsg}; -use torii_introspect::schema::TableSchema; -use torii_introspect::InsertsFields; +use std::collections::{HashMap, HashSet}; +use std::sync::Arc; +use torii_common::sql::PgQuery; +use torii_introspect::events::IntrospectBody; use torii_postgres::PostgresConnection; -pub const COMMIT_CMD: &str = "--COMMIT"; -pub const DEAD_MEMBERS_TABLE: &str = "__introspect_dead_fields"; -pub const TABLES_TABLE: &str = "__introspect_tables"; -pub const COLUMNS_TABLE: &str = "__introspect_columns"; -pub const METADATA_CONFLICTS: &str = "__updated_at = NOW(), __updated_block = EXCLUDED.__updated_block, __updated_tx = EXCLUDED.__updated_tx"; - -#[derive(Debug, Default)] -pub struct PostgresTables(pub RwLock>); - -#[derive(Debug, Default)] -pub struct DeadFields(pub RwLock>>); - -impl Deref for PostgresTables { - type Target = RwLock>; - - fn deref(&self) -> &Self::Target { - &self.0 - } +pub struct IntrospectPgDb { + tables: PostgresTables, + schemas: SchemaMode, + pool: T, } -impl Deref for DeadFields { - type Target = RwLock>>; +pub enum SchemaMode { + Single(Arc), + Address, + Named(HashMap>), + Addresses(HashSet), +} - fn deref(&self) -> &Self::Target { - &self.0 +impl From for SchemaMode { + fn from(value: String) -> Self { + SchemaMode::Single(value.into()) } } -impl From> for PgSchema { - fn from(value: Option) -> Self { - match value { - Some(s) => Self::Custom(s), - None => PgSchema::Public, - } +impl From<&str> for SchemaMode { + fn from(value: &str) -> Self { + SchemaMode::Single(value.into()) } } -impl From<()> for PgSchema { - fn from(_: ()) -> Self { - PgSchema::Public +impl From> for SchemaMode { + fn from(value: HashMap) -> Self { + SchemaMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) } } -impl From for PgSchema { - fn from(value: String) -> Self { - Self::Custom(value) +impl From<[(Felt, &str); N]> for SchemaMode { + fn from(value: [(Felt, &str); N]) -> Self { + SchemaMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) } } -impl From<&str> for PgSchema { - fn from(value: &str) -> Self { - Self::Custom(value.to_string()) +impl From<[(Felt, String); N]> for SchemaMode { + fn from(value: [(Felt, String); N]) -> Self { + SchemaMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) } } -impl From> for PgSchema { - fn from(value: Option<&str>) -> Self { - match value { - Some(s) => Self::Custom(s.to_string()), - None => PgSchema::Public, - } +impl From<[Felt; N]> for SchemaMode { + fn from(value: [Felt; N]) -> Self { + SchemaMode::Addresses(value.into_iter().collect()) } } -impl PostgresTables { - pub fn create_table( - &self, - schema: &Rc, - to_table: impl Into, - metadata: &MetaData, - queries: &mut Vec, - ) -> PgDbResult<()> { - let (id, table) = Into::::into(to_table).into(); - self.assert_table_not_exists(&id, &table.name)?; - CreatePgTable::new(schema, &id, &table)?.make_queries(queries); - let table = PgTable::new(schema, table, None); - table.insert_queries( - &id, - None, - metadata.block_number.unwrap_or_default(), - metadata.transaction_hash, - queries, - )?; - let mut tables: std::sync::RwLockWriteGuard<'_, HashMap> = self.write()?; - tables.insert(id, table); - Ok(()) +impl From> for SchemaMode { + fn from(value: Vec) -> Self { + SchemaMode::Addresses(value.into_iter().collect()) } +} - pub fn update_table( - &self, - to_table: impl Into, - metadata: &MetaData, - queries: &mut Vec, - ) -> PgDbResult<()> { - let tx_hash = &metadata.transaction_hash; - let block_number = metadata.block_number.unwrap_or_default(); - let (id, table) = Into::::into(to_table).into(); - let mut tables = self.write()?; - let existing = tables - .get_mut(&id) - .ok_or_else(|| PgDbError::TableNotFound(id))?; - let upgrades = existing.update_from_info(&id, &table)?; - upgrades.to_queries(&id, block_number, tx_hash, queries)?; - existing.insert_queries( - &id, - Some(&upgrades.columns_upgraded), - block_number, - metadata.transaction_hash, - queries, - ) +fn felt_try_from_schema(schema: &str) -> SchemaResult { + match schema.len() == 63 { + true => Felt::from_hex(schema).err_into(), + false => Err(SchemaError::InvalidAddressLength(schema.to_string())), } +} - pub fn assert_table_not_exists(&self, id: &Felt, name: &str) -> PgDbResult<()> { - match self.read()?.get(id) { - Some(existing) => Err(PgDbError::TableAlreadyExists( - *id, - name.to_string(), - existing.name.to_string(), - )), - None => Ok(()), +impl SchemaMode { + pub fn schemas(&self) -> Option>> { + match self { + SchemaMode::Single(name) => Some(vec![name.clone()]), + SchemaMode::Address => None, + SchemaMode::Named(map) => Some(map.values().cloned().collect()), + SchemaMode::Addresses(set) => Some(set.iter().map(felt_to_schema).map_into().collect()), } } - pub fn set_table_dead(&self, id: &Felt) -> PgDbResult<()> { - let mut tables = self.write()?; - match tables.get_mut(id) { - Some(table) => { - table.alive = false; - Ok(()) + pub fn get_schema_key(&self, schema: String, owner: &Felt) -> SchemaResult { + match self { + SchemaMode::Single(s) => match **s == *schema { + true => Ok(PgSchema::Single(s.clone())), + false => Err(SchemaError::SchemaMismatch(schema, s.to_string())), + }, + SchemaMode::Address => felt_try_from_schema(&schema).map(PgSchema::Address), + SchemaMode::Named(map) => match map.get(owner) { + Some(s) if **s == *schema => Ok(PgSchema::Named(s.clone())), + Some(s) => Err(SchemaError::SchemaMismatch(schema, s.to_string())), + None => Err(SchemaError::AddressNotFound(*owner, schema)), + }, + SchemaMode::Addresses(set) => { + let address = felt_try_from_schema(&schema)?; + match set.contains(&address) { + true => Ok(PgSchema::Address(address)), + false => Err(SchemaError::AddressNotFound(address, schema)), + } } - None => Err(PgDbError::TableNotFound(*id)), } } - pub fn insert_fields( - &self, - event: &InsertsFields, - context: &MetaData, - queries: &mut Vec, - ) -> PgDbResult<()> { - let tables = self.read().unwrap(); - let table = match tables.get(&event.table) { - Some(table) => Ok(table), - None => Err(PgDbError::TableNotFound(event.table)), - }?; - if !table.alive { - return Ok(()); - } - let record = table.get_record_schema(&event.columns)?; - let table_name = &table.name; - let mut writer = Vec::new(); - let schema = &table.schema; - write!( - writer, - r#"INSERT INTO "{schema}"."{table_name}" SELECT * FROM jsonb_populate_recordset(NULL::"{schema}"."{table_name}", $$"# - ) - .unwrap(); - record.parse_records_with_metadata( - &event.records, - context, - &mut JsonSerializer::new(&mut writer), - &PostgresJsonSerializer, - )?; - write!( - writer, - r#"$$) ON CONFLICT ("{}") DO UPDATE SET {METADATA_CONFLICTS}"#, - record.primary().name - ) - .unwrap(); - for ColumnInfo { name, .. } in record.columns() { - write!( - writer, - r#", "{name}" = COALESCE(EXCLUDED."{name}", "{table_name}"."{name}")"#, - name = name - ) - .unwrap(); - } - let string = unsafe { String::from_utf8_unchecked(writer) }; - queries.add(string); - Ok(()) + pub fn get_key(&self, schema: String, id: Felt, owner: &Felt) -> SchemaResult { + self.get_schema_key(schema, owner) + .map(|k| TableKey::new(k, id)) } - pub fn handle_message( - &self, - schema: &Rc, - msg: &IntrospectMsg, - metadata: &MetaData, - queries: &mut Vec, - ) -> PgDbResult<()> { - match msg { - IntrospectMsg::CreateTable(event) => { - self.create_table(schema, event.clone(), metadata, queries) - } - IntrospectMsg::UpdateTable(event) => { - self.update_table(event.clone(), metadata, queries) - } - IntrospectMsg::AddColumns(event) => self.set_table_dead(&event.table), - IntrospectMsg::DropColumns(event) => self.set_table_dead(&event.table), - IntrospectMsg::RetypeColumns(event) => self.set_table_dead(&event.table), - IntrospectMsg::RetypePrimary(event) => self.set_table_dead(&event.table), - IntrospectMsg::RenameTable(_) - | IntrospectMsg::DropTable(_) - | IntrospectMsg::RenameColumns(_) - | IntrospectMsg::RenamePrimary(_) => Ok(()), - IntrospectMsg::InsertsFields(event) => self.insert_fields(event, metadata, queries), - IntrospectMsg::DeleteRecords(_) | IntrospectMsg::DeletesFields(_) => Ok(()), + pub fn to_schema(&self, from_address: &Felt) -> PgDbResult { + match self { + SchemaMode::Single(name) => Ok(PgSchema::Single(name.clone())), + SchemaMode::Address => Ok(PgSchema::Address(*from_address)), + SchemaMode::Named(map) => match map.get(from_address) { + Some(schema) => Ok(PgSchema::Named(schema.clone())), + None => Err(PgDbError::SchemaNotFound(*from_address)), + }, + SchemaMode::Addresses(set) => match set.contains(from_address) { + true => Ok(PgSchema::Address(*from_address)), + false => Err(PgDbError::SchemaNotFound(*from_address)), + }, } } } -fn make_schema_query(schema: &PgSchema) -> String { - format!(r#"CREATE SCHEMA IF NOT EXISTS "{schema}""#) -} - -pub struct IntrospectPgDb { - tables: PostgresTables, - schema: PgSchema, - pool: T, -} - impl PostgresConnection for IntrospectPgDb { fn pool(&self) -> &PgPool { self.pool.pool() } } +// TODO: Add errors for unknown schema impl IntrospectPgDb { - pub fn new(pool: T, schema: impl Into) -> Self { + pub fn new>(pool: T, schemas: S) -> Self { Self { tables: PostgresTables::default(), - schema: schema.into(), + schemas: schemas.into(), pool, } } - - pub async fn load_store_data(&self) -> PgDbResult<()> { - let mut tables = fetch_tables(self.pool(), &self.schema) - .await? - .into_iter() - .map(|t| t.to_table(&self.schema)) - .collect::>(); - for (table_id, id, column_info) in fetch_columns(self.pool(), &self.schema).await? { - if let Some(table) = tables.get_mut(&table_id) { + pub async fn load_store_data(&self) -> PgDbResult> { + let mut errors = Vec::new(); + let schemas = self.schemas.schemas(); + let schemas = schemas + .as_ref() + .map(|s| s.iter().map(AsRef::as_ref).collect()); + let table_rows = fetch_tables(self.pool(), &schemas).await?; + let mut tables = HashMap::with_capacity(table_rows.len()); + for table in table_rows { + let (id, table) = table.into(); + tables.insert((table.schema.clone(), id), table); + } + for (schema, table_id, id, column_info) in fetch_columns(self.pool(), &schemas).await? { + if let Some(table) = tables.get_mut(&(schema.clone(), table_id)) { table.columns.insert(id, column_info); + } else { + errors.push(TableLoadError::ColumnTableNotFound( + schema, + table_id, + column_info.name, + id, + )); } } - for (table_id, id, field) in fetch_dead_fields(self.pool(), &self.schema).await? { - if let Some(table) = tables.get_mut(&table_id) { + for (schema, table_id, id, field) in fetch_dead_fields(self.pool(), &schemas).await? { + if let Some(table) = tables.get_mut(&(schema.clone(), table_id)) { table.dead.insert(id, field); + } else { + errors.push(TableLoadError::TableDeadNotFound( + schema, table_id, field.name, id, + )); } } - let mut tables_map = self.tables.write()?; - tables_map.extend(tables); - Ok(()) + let mut map = self.tables.write()?; + for ((schema, id), table) in tables { + match self.schemas.get_key(schema, id, &table.owner) { + Ok(key) => { + map.insert(key, table); + } + Err(err) => errors.push(TableLoadError::SchemaError(err)), + } + } + Ok(errors) } - pub async fn initialize_introspect_pg_sink(&self) -> PgDbResult<()> { + pub async fn initialize_introspect_pg_sink(&self) -> PgDbResult> { self.migrate(Some("introspect"), INTROSPECT_PG_SINK_MIGRATIONS) .await?; - self.execute_queries(make_schema_query(&self.schema)) - .await?; self.load_store_data().await } - pub async fn process_message( - &self, - msg: &IntrospectMsg, - metadata: &MetaData, - ) -> PgDbResult<()> { - let mut queries = Vec::new(); - { - let schema = Rc::new(self.schema.clone()); - self.tables - .handle_message(&schema, msg, metadata, &mut queries)?; - } - self.execute_queries(queries).await?; - Ok(()) - } - pub async fn process_messages( &self, msgs: Vec<&IntrospectBody>, ) -> PgDbResult>> { let mut queries = Vec::new(); let mut results = Vec::with_capacity(msgs.len()); - { - let schema = Rc::new(self.schema.clone()); - for body in msgs { - let (msg, metadata) = body.into(); - results.push( - self.tables - .handle_message(&schema, msg, metadata, &mut queries), - ); - } + + for body in msgs { + let (msg, metadata) = body.into(); + results.push(self.tables.handle_message( + self.schemas.to_schema(&metadata.from_address)?, + msg, + &metadata.from_address, + metadata.block_number.unwrap_or(u64::MAX), + &metadata.transaction_hash, + &mut queries, + )); } + self.process_queries(queries).await?; + Ok(results) + } + + pub async fn process_queries(&self, queries: Vec) -> PgDbResult<()> { let mut batch = Vec::new(); for query in queries { if query == *COMMIT_CMD { @@ -324,11 +243,6 @@ impl IntrospectPgDb { if !batch.is_empty() { self.execute_queries(batch).await?; } - Ok(results) + Ok(()) } } - -pub struct MessageWithContext<'a, M> { - pub msg: &'a M, - pub context: &'a MetaData, -} diff --git a/crates/introspect-postgres-sink/src/query.rs b/crates/introspect-postgres-sink/src/query.rs index 63b96983..2f14e62c 100644 --- a/crates/introspect-postgres-sink/src/query.rs +++ b/crates/introspect-postgres-sink/src/query.rs @@ -1,25 +1,25 @@ +use crate::table::PgTable; +use crate::{table::DeadField, PostgresField, PostgresType, PrimaryKey, SchemaName}; use introspect_types::{ColumnDef, ColumnInfo, MemberDef, PrimaryDef, TypeDef}; use itertools::Itertools; use sqlx::error::BoxDynError; +use sqlx::postgres::PgRow; use sqlx::prelude::FromRow; +use sqlx::query::QueryAs; use sqlx::Error::Encode as EncodeError; use sqlx::{postgres::PgArguments, types::Json}; use sqlx::{Arguments, Executor, Postgres}; use starknet_types_core::felt::Felt; -use torii_common::sql::{PgQuery, Queries, SqlxResult}; -use torii_introspect::postgres::types::{PgPrimary, Uint128}; -use torii_introspect::postgres::PgFelt; - -use crate::table::PgTable; -use crate::{ - processor::COMMIT_CMD, table::DeadField, PgSchema, PostgresField, PostgresType, PrimaryKey, - SchemaName, -}; use std::collections::HashMap; use std::{ fmt::{Display, Formatter, Result as FmtResult, Write}, rc::Rc, }; +use torii_common::sql::{PgQuery, Queries, SqlxResult}; +use torii_introspect::postgres::types::{PgPrimary, Uint128}; +use torii_introspect::postgres::PgFelt; + +pub const COMMIT_CMD: &str = "--COMMIT"; const CREATE_METADATA_COLUMNS: &str = "__created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __created_block public.uint64 NOT NULL, __updated_block public.uint64 NOT NULL, __created_tx public.felt252 NOT NULL, __updated_tx public.felt252 NOT NULL);"; const INSERT_DEAD_MEMBER_QUERY: &str = r#"INSERT INTO introspect.db_dead_fields @@ -28,8 +28,8 @@ const INSERT_DEAD_MEMBER_QUERY: &str = r#"INSERT INTO introspect.db_dead_fields ON CONFLICT ("schema", "table", id) DO UPDATE SET name = EXCLUDED.name, type_def = EXCLUDED.type_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; const INSERT_TABLE_QUERY: &str = r#"INSERT INTO introspect.db_tables - ("schema", id, name, primary_def, updated_at, created_block, updated_block, created_tx, updated_tx) - VALUES ($1, $2, $3, $4, NOW(), $5::uint64, $5::uint64, $6, $6) + ("schema", id, owner, name, primary_def, updated_at, created_block, updated_block, created_tx, updated_tx) + VALUES ($1, $2, $3, $4, $5, NOW(), $6::uint64, $6::uint64, $7, $7) ON CONFLICT ("schema", id) DO UPDATE SET name = EXCLUDED.name, primary_def = EXCLUDED.primary_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; const INSERT_COLUMN_QUERY: &str = r#"INSERT INTO introspect.db_columns @@ -38,22 +38,22 @@ const INSERT_COLUMN_QUERY: &str = r#"INSERT INTO introspect.db_columns ON CONFLICT ("schema", "table", id) DO UPDATE SET name = EXCLUDED.name, type_def = EXCLUDED.type_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; -const FETCH_TABLES_QUERY: &str = - r#"SELECT id, name, primary_def FROM introspect.db_tables WHERE "schema" = $1"#; -const FETCH_COLUMNS_QUERY: &str = - r#"SELECT "table", id, name, type_def FROM introspect.db_columns WHERE "schema" = $1"#; -const FETCH_DEAD_FIELDS_QUERY: &str = - r#"SELECT "table", id, name, type_def FROM introspect.db_dead_fields WHERE "schema" = $1"#; +const FETCH_TABLES_QUERY: &str = r#"SELECT "schema", id, name, primary_def, owner FROM introspect.db_tables WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; +const FETCH_COLUMNS_QUERY: &str = r#"SELECT "schema", "table", id, name, type_def FROM introspect.db_columns WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; +const FETCH_DEAD_FIELDS_QUERY: &str = r#"SELECT "schema", "table", id, name, type_def FROM introspect.db_dead_fields WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; #[derive(FromRow)] pub struct TableRow { + pub schema: String, pub id: PgFelt, pub name: String, pub primary_def: PgPrimary, + pub owner: PgFelt, } #[derive(FromRow)] pub struct ColumnRow { + pub schema: String, pub table: PgFelt, pub id: PgFelt, pub name: String, @@ -62,6 +62,7 @@ pub struct ColumnRow { #[derive(FromRow)] pub struct DeadFieldRow { + pub schema: String, pub table: PgFelt, pub id: Uint128, pub name: String, @@ -69,9 +70,11 @@ pub struct DeadFieldRow { } pub struct PgTableHead { + schema: String, id: Felt, name: String, primary: PrimaryDef, + owner: Felt, } #[derive(Debug)] @@ -84,7 +87,7 @@ pub struct CreatePgTable { #[derive(Debug)] pub struct TableUpgrade { - pub schema: Rc, + pub schema: Rc, pub name: String, pub old_name: Option, pub atomic: Vec, @@ -242,7 +245,7 @@ impl Display for CreatesType { impl CreatesType { pub fn new_struct>( - schema: &Rc, + schema: &Rc, name: S, fields: Vec, ) -> Self { @@ -252,11 +255,7 @@ impl CreatesType { }) } - pub fn new_enum>( - schema: &Rc, - name: S, - variants: Vec, - ) -> Self { + pub fn new_enum>(schema: &Rc, name: S, variants: Vec) -> Self { Self::Enum(CreateEnum { name: SchemaName::new(schema, name), variants, @@ -265,7 +264,7 @@ impl CreatesType { } impl TableUpgrade { - pub fn new>(schema: &Rc, name: S) -> Self { + pub fn new>(schema: &Rc, name: S) -> Self { Self { schema: schema.clone(), name: name.into(), @@ -496,7 +495,7 @@ impl TypeMods for Vec { impl ColumnUpgrade { pub fn maybe_alter( &mut self, - schema: &Rc, + schema: &Rc, name: &str, field: &str, pg_type: Option, @@ -513,7 +512,7 @@ impl ColumnUpgrade { pub fn add_struct_mod>( &mut self, - schema: &Rc, + schema: &Rc, name: S, mods: Vec, ) { @@ -527,7 +526,7 @@ impl ColumnUpgrade { } pub fn add_enum_mod>( &mut self, - schema: &Rc, + schema: &Rc, name: S, rename: Vec<(String, String)>, add: Vec, @@ -577,9 +576,10 @@ impl From for TypeMod { } } -impl From for (Felt, Felt, ColumnInfo) { +impl From for (String, Felt, Felt, ColumnInfo) { fn from(value: ColumnRow) -> Self { ( + value.schema, value.table.into(), value.id.into(), ColumnInfo { @@ -591,9 +591,10 @@ impl From for (Felt, Felt, ColumnInfo) { } } -impl From for (Felt, u128, DeadField) { +impl From for (String, Felt, u128, DeadField) { fn from(value: DeadFieldRow) -> Self { ( + value.schema, value.table.into(), value.id.into(), DeadField { @@ -606,23 +607,24 @@ impl From for (Felt, u128, DeadField) { impl From for PgTableHead { fn from(value: TableRow) -> Self { - let row = value; PgTableHead { - id: row.id.into(), - name: row.name, - primary: row.primary_def.into(), + schema: value.schema, + id: value.id.into(), + name: value.name, + primary: value.primary_def.into(), + owner: value.owner.into(), } } } - -impl PgTableHead { - pub fn to_table(self, schema: &PgSchema) -> (Felt, PgTable) { +impl From for (Felt, PgTable) { + fn from(value: PgTableHead) -> Self { ( - self.id, + value.id, PgTable { - schema: schema.clone(), - name: self.name, - primary: self.primary, + schema: value.schema, + owner: value.owner, + name: value.name, + primary: value.primary, columns: HashMap::new(), alive: true, dead: HashMap::new(), @@ -632,7 +634,7 @@ impl PgTableHead { } fn insert_dead_member_query( - schema: &PgSchema, + schema: &str, table: &Felt, fields: &[DeadFieldWithId], block_number: u64, @@ -651,7 +653,7 @@ fn insert_dead_member_query( } pub fn insert_columns_query( - schema: &PgSchema, + schema: &str, table: &Felt, columns: Vec<(&Felt, &ColumnInfo)>, block_number: u64, @@ -675,16 +677,18 @@ pub fn insert_columns_query( } pub fn insert_table_query( - schema: &PgSchema, + schema: &str, id: &Felt, name: &str, primary_def: &PrimaryDef, + from_address: &Felt, block_number: u64, transaction_hash: &Felt, ) -> Result { let mut args = PgArguments::default(); args.add(schema.to_string())?; args.add(PgFelt::from(*id))?; + args.add(PgFelt::from(*from_address))?; args.add(name.to_owned())?; args.add(PgPrimary::from(primary_def))?; args.add(block_number.to_string())?; @@ -693,12 +697,25 @@ pub fn insert_table_query( Ok(PgQuery::new(INSERT_TABLE_QUERY, args)) } +pub fn schema_query<'a, R>( + query: &'a str, + schemas: &'a Option>, +) -> QueryAs<'a, Postgres, R, PgArguments> +where + R: for<'r> FromRow<'r, PgRow>, +{ + let query = sqlx::query_as::<_, R>(query); + match schemas { + Some(schemas) => query.bind(schemas), + None => query.bind("{}".to_string()), + } +} + pub async fn fetch_tables<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( conn: E, - schema: &PgSchema, + schemas: &Option>, ) -> SqlxResult> { - sqlx::query_as::<_, TableRow>(FETCH_TABLES_QUERY) - .bind(schema.to_string()) + schema_query::(FETCH_TABLES_QUERY, schemas) .fetch_all(conn) .await .map(|rows| rows.into_iter().map_into().collect()) @@ -706,10 +723,9 @@ pub async fn fetch_tables<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( pub async fn fetch_columns<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( conn: E, - schema: &PgSchema, -) -> SqlxResult> { - sqlx::query_as::<_, ColumnRow>(FETCH_COLUMNS_QUERY) - .bind(schema.to_string()) + schemas: &Option>, +) -> SqlxResult> { + schema_query::(FETCH_COLUMNS_QUERY, schemas) .fetch_all(conn) .await .map(|rows| rows.into_iter().map_into().collect()) @@ -717,11 +733,14 @@ pub async fn fetch_columns<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( pub async fn fetch_dead_fields<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( conn: E, - schema: &PgSchema, -) -> SqlxResult> { - sqlx::query_as::<_, DeadFieldRow>(FETCH_DEAD_FIELDS_QUERY) - .bind(schema.to_string()) + schemas: &Option>, +) -> SqlxResult> { + schema_query::(FETCH_DEAD_FIELDS_QUERY, schemas) .fetch_all(conn) .await .map(|rows| rows.into_iter().map_into().collect()) } + +pub fn make_schema_query(schema: &str) -> String { + format!(r#"CREATE SCHEMA IF NOT EXISTS "{schema}""#) +} diff --git a/crates/introspect-postgres-sink/src/table.rs b/crates/introspect-postgres-sink/src/table.rs index eeef1a9c..956dbd93 100644 --- a/crates/introspect-postgres-sink/src/table.rs +++ b/crates/introspect-postgres-sink/src/table.rs @@ -1,20 +1,20 @@ -use introspect_types::{ColumnInfo, MemberDef, PrimaryDef, TypeDef}; +use crate::{ + query::{insert_columns_query, insert_table_query, CreatePgTable}, + PgDbResult, PgTableError, TableResult, +}; +use introspect_types::{ColumnInfo, MemberDef, PrimaryDef, ResultInto, TypeDef}; use itertools::Itertools; use sqlx::Error::Encode as EncodeError; use starknet_types_core::felt::Felt; -use std::collections::HashMap; +use std::{collections::HashMap, rc::Rc}; use torii_common::sql::PgQuery; use torii_introspect::{schema::TableInfo, tables::RecordSchema}; -use crate::{ - query::{insert_columns_query, insert_table_query}, - PgDbResult, PgSchema, PgTableError, TableResult, -}; - #[derive(Debug)] pub struct PgTable { - pub schema: PgSchema, + pub schema: String, pub name: String, + pub owner: Felt, pub primary: PrimaryDef, pub columns: HashMap, pub alive: bool, @@ -53,15 +53,34 @@ impl PgTable { .ok_or_else(|| PgTableError::ColumnNotFound(*id, self.name.clone())) } + pub fn schema(&self) -> Rc { + self.schema.as_str().into() + } + pub fn columns(&self, ids: &[Felt]) -> TableResult> { ids.iter() .map(|id| self.column(id)) .collect::>>() } - pub fn new(schema: &PgSchema, info: TableInfo, dead: Option>) -> Self { + pub fn columns_with_ids<'a>( + &'a self, + ids: &'a [Felt], + ) -> TableResult> { + ids.iter() + .map(|id| self.column(id).map(|col| (id, col))) + .collect::>>() + } + + pub fn new( + schema: String, + owner: Felt, + info: TableInfo, + dead: Option>, + ) -> Self { PgTable { - schema: schema.clone(), + schema, + owner, name: info.name, primary: info.primary, columns: info.columns.into_iter().map_into().collect(), @@ -69,6 +88,38 @@ impl PgTable { dead: dead.unwrap_or_default().into_iter().collect(), } } + + pub fn create_table(&self, id: &Felt, order: &[Felt]) -> TableResult { + CreatePgTable::new( + &self.schema(), + id, + &self.name, + &self.primary, + self.columns_with_ids(order)?, + ) + .err_into() + } + + pub fn create_table_queries( + &self, + id: &Felt, + order: &[Felt], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> PgDbResult<()> { + self.create_table(id, order)?.make_queries(queries); + self.insert_queries( + id, + None, + from_address, + block_number, + transaction_hash, + queries, + ) + } + pub fn get_record_schema(&self, columns: &[Felt]) -> TableResult> { Ok(RecordSchema::new(&self.primary, self.columns(columns)?)) } @@ -76,8 +127,9 @@ impl PgTable { &self, id: &Felt, column_ids: Option<&[Felt]>, + from_address: &Felt, block_number: u64, - transaction_hash: Felt, + transaction_hash: &Felt, queries: &mut Vec, ) -> PgDbResult<()> { queries.push( @@ -86,8 +138,9 @@ impl PgTable { id, &self.name, &self.primary, + from_address, block_number, - &transaction_hash, + transaction_hash, ) .map_err(EncodeError)?, ); @@ -96,7 +149,7 @@ impl PgTable { None => self.columns.iter().collect_vec(), }; queries.push( - insert_columns_query(&self.schema, id, columns, block_number, &transaction_hash) + insert_columns_query(&self.schema, id, columns, block_number, transaction_hash) .map_err(EncodeError)?, ); Ok(()) diff --git a/crates/introspect-postgres-sink/src/tables.rs b/crates/introspect-postgres-sink/src/tables.rs new file mode 100644 index 00000000..7691d44d --- /dev/null +++ b/crates/introspect-postgres-sink/src/tables.rs @@ -0,0 +1,229 @@ +use crate::table::PgTable; +use crate::{PgDbError, PgDbResult}; +use introspect_types::FeltIds; +use starknet_types_core::felt::Felt; +use std::collections::HashMap; +use std::fmt::Display; +use std::hash::{Hash, Hasher}; +use std::ops::Deref; +use std::sync::{Arc, RwLock}; +use torii_common::sql::PgQuery; +use torii_introspect::events::IntrospectMsg; +use torii_introspect::schema::TableSchema; +use torii_introspect::InsertsFields; + +pub const DEAD_MEMBERS_TABLE: &str = "__introspect_dead_fields"; +pub const TABLES_TABLE: &str = "__introspect_tables"; +pub const COLUMNS_TABLE: &str = "__introspect_columns"; + +#[derive(Debug, Default)] +pub struct PostgresTables(pub RwLock>); + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TableKey { + schema: PgSchema, + id: Felt, +} + +impl TableKey { + pub fn new(schema: PgSchema, id: Felt) -> Self { + Self { schema, id } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum PgSchema { + Single(Arc), + Address(Felt), + Named(Arc), +} + +impl Display for TableKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if !matches!(self.schema, PgSchema::Single(_)) { + write!(f, "{} ", self.schema)?; + } + write!(f, "{:#063x}", self.id) + } +} + +impl Display for PgSchema { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PgSchema::Address(addr) => write!(f, "{addr:063x}"), + PgSchema::Named(name) | PgSchema::Single(name) => name.fmt(f), + } + } +} + +impl Hash for TableKey { + fn hash(&self, state: &mut H) { + self.schema.hash(state); + self.id.hash(state); + } +} + +impl Hash for PgSchema { + fn hash(&self, state: &mut H) { + match self { + PgSchema::Address(addr) => addr.hash(state), + PgSchema::Named(name) => name.hash(state), + PgSchema::Single(_) => {} + } + } +} + +impl Deref for PostgresTables { + type Target = RwLock>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl PostgresTables { + pub fn create_table( + &self, + schema_key: PgSchema, + to_table: impl Into, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> PgDbResult<()> { + let (id, info) = Into::::into(to_table).into(); + let schema = schema_key.to_string(); + let key = TableKey::new(schema_key, id); + self.assert_table_not_exists(&key, &info.name)?; + let order = info.columns.ids(); + let table = PgTable::new(schema, *from_address, info, None); + table.create_table_queries( + &id, + &order, + from_address, + block_number, + transaction_hash, + queries, + )?; + let mut tables = self.write()?; + tables.insert(key, table); + Ok(()) + } + + pub fn update_table( + &self, + schema_key: PgSchema, + to_table: impl Into, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> PgDbResult<()> { + let (id, table) = Into::::into(to_table).into(); + let mut tables = self.write()?; + let key = TableKey::new(schema_key, id); + let existing = tables + .get_mut(&key) + .ok_or_else(|| PgDbError::TableNotFound(key.clone()))?; + let upgrades = existing.update_from_info(&id, &table)?; + upgrades.to_queries(&id, block_number, transaction_hash, queries)?; + existing.insert_queries( + &id, + Some(&upgrades.columns_upgraded), + from_address, + block_number, + transaction_hash, + queries, + ) + } + + pub fn assert_table_not_exists(&self, id: &TableKey, name: &str) -> PgDbResult<()> { + match self.read()?.get(id) { + Some(existing) => Err(PgDbError::TableAlreadyExists( + id.clone(), + name.to_string(), + existing.name.to_string(), + )), + None => Ok(()), + } + } + + pub fn set_table_dead(&self, schema: PgSchema, id: Felt) -> PgDbResult<()> { + let mut tables = self.write()?; + let key = TableKey::new(schema, id); + match tables.get_mut(&key) { + Some(table) => { + table.alive = false; + Ok(()) + } + None => Err(PgDbError::TableNotFound(key)), + } + } + + pub fn insert_fields( + &self, + schema: PgSchema, + event: &InsertsFields, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> PgDbResult<()> { + let tables = self.read().unwrap(); + let key = TableKey::new(schema, event.table); + let table = match tables.get(&key) { + Some(table) => Ok(table), + None => Err(PgDbError::TableNotFound(key)), + }?; + if !table.alive { + return Ok(()); + } + table.insert_fields(event, block_number, transaction_hash, from_address, queries) + } + + pub fn handle_message( + &self, + schema: PgSchema, + msg: &IntrospectMsg, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> PgDbResult<()> { + match msg { + IntrospectMsg::CreateTable(event) => self.create_table( + schema, + event.clone(), + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::UpdateTable(event) => self.update_table( + schema, + event.clone(), + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::AddColumns(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::DropColumns(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::RetypeColumns(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::RetypePrimary(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::RenameTable(_) + | IntrospectMsg::DropTable(_) + | IntrospectMsg::RenameColumns(_) + | IntrospectMsg::RenamePrimary(_) => Ok(()), + IntrospectMsg::InsertsFields(event) => self.insert_fields( + schema, + event, + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::DeleteRecords(_) | IntrospectMsg::DeletesFields(_) => Ok(()), + } + } +} diff --git a/crates/introspect-postgres-sink/src/types.rs b/crates/introspect-postgres-sink/src/types.rs index 7354b8b4..0e0eecc9 100644 --- a/crates/introspect-postgres-sink/src/types.rs +++ b/crates/introspect-postgres-sink/src/types.rs @@ -7,14 +7,8 @@ use std::{ use crate::{PgTypeError, PgTypeResult}; -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] -pub enum PgSchema { - Public, - Custom(String), -} - #[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] -pub struct SchemaName(pub Rc, pub String); +pub struct SchemaName(pub Rc, pub String); #[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] pub enum PostgresScalar { @@ -75,15 +69,6 @@ impl From for PostgresType { } } -impl Display for PgSchema { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - PgSchema::Custom(namespace) => write!(f, "{namespace}",), - PgSchema::Public => write!(f, "public"), - } - } -} - impl Display for SchemaName { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, r#""{}"."{}""#, self.0, self.1) @@ -156,7 +141,7 @@ impl From for PostgresType { } impl SchemaName { - pub fn new>(schema: &Rc, name: T) -> Self { + pub fn new>(schema: &Rc, name: T) -> Self { Self(schema.clone(), name.into()) } pub fn replace>(&mut self, name: S) -> String { @@ -184,7 +169,7 @@ impl PostgresType { }) } - pub fn composite>(schema: &Rc, name: S) -> Self { + pub fn composite>(schema: &Rc, name: S) -> Self { Self { scalar: PostgresScalar::Composite(SchemaName::new(schema, name)), array: PostgresArray::None, diff --git a/crates/introspect-postgres-sink/src/upgrade.rs b/crates/introspect-postgres-sink/src/upgrade.rs index f565d01d..e59190b1 100644 --- a/crates/introspect-postgres-sink/src/upgrade.rs +++ b/crates/introspect-postgres-sink/src/upgrade.rs @@ -2,8 +2,8 @@ use crate::{ create::PostgresTypeExtractor, query::{ColumnUpgrade, StructMod, StructMods, TableUpgrade}, table::{DeadField, PgTable}, - HasherExt, PgSchema, PgTypeError, PgTypeResult, PostgresScalar, PostgresType, TableResult, - UpgradeError, UpgradeResult, UpgradeResultExt, + HasherExt, PgTypeError, PgTypeResult, PostgresScalar, PostgresType, TableResult, UpgradeError, + UpgradeResult, UpgradeResultExt, }; use introspect_types::{ ArrayDef, ColumnDef, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, PrimaryTypeDef, @@ -18,6 +18,7 @@ impl PgTable { pub fn update_from_info(&mut self, id: &Felt, info: &TableInfo) -> TableResult { self.update(id, &info.name, &info.primary, &info.columns) } + pub fn update( &mut self, id: &Felt, @@ -26,7 +27,7 @@ impl PgTable { columns: &[ColumnDef], ) -> TableResult { let branch = Xxh3::new_based(id); - let schema = Rc::new(self.schema.clone()); + let schema: Rc = self.schema(); let mut table_mod = TableUpgrade::new(&schema, self.name.clone()); table_mod.rename_table(name); table_mod.rename_column(&mut self.primary.name, &primary.name); @@ -129,7 +130,7 @@ pub trait ExtractItem { fn as_tuple(&mut self) -> UpgradeResult<&mut TupleDef>; fn update_as_array( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &ArrayDef, dead: &mut HashMap, @@ -137,13 +138,13 @@ pub trait ExtractItem { ) -> UpgradeResult>; fn update_as_option( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &TypeDef, dead: &mut HashMap, queries: &mut ColumnUpgrade, ) -> UpgradeResult>; - fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> PgTypeResult; + fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> PgTypeResult; } impl ExtractItem for TypeDef { @@ -181,7 +182,7 @@ impl ExtractItem for TypeDef { fn update_as_array( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &ArrayDef, dead: &mut HashMap, @@ -195,7 +196,7 @@ impl ExtractItem for TypeDef { } fn update_as_option( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &TypeDef, dead: &mut HashMap, @@ -210,7 +211,7 @@ impl ExtractItem for TypeDef { } } } - fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> PgTypeResult { + fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> PgTypeResult { match self { TypeDef::None => Ok(PostgresScalar::None.into()), TypeDef::Bool => Ok(PostgresScalar::Boolean.into()), @@ -257,7 +258,7 @@ impl ExtractItem for TypeDef { pub trait CompareType { fn compare_type( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &Self, dead: &mut HashMap, @@ -297,7 +298,7 @@ pub trait UpgradeField { fn name(&self) -> &str; fn upgrade_field( &mut self, - schema: &Rc, + schema: &Rc, name: &str, branch: &Xxh3, new: &Self, @@ -312,7 +313,7 @@ pub trait UpgradeField { } fn add_field( &self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, queries: &mut ColumnUpgrade, ) -> UpgradeResult { @@ -350,7 +351,7 @@ impl UpgradeField for VariantDef { impl CompareType for TypeDef { fn compare_type( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &TypeDef, dead: &mut HashMap, @@ -439,7 +440,7 @@ impl CompareType for TypeDef { impl CompareType for StructDef { fn compare_type( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &StructDef, dead: &mut HashMap, @@ -477,7 +478,7 @@ impl CompareType for StructDef { impl CompareType for EnumDef { fn compare_type( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &EnumDef, dead: &mut HashMap, @@ -517,7 +518,7 @@ impl CompareType for EnumDef { impl CompareType for FixedArrayDef { fn compare_type( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &Self, dead: &mut HashMap, @@ -540,7 +541,7 @@ impl CompareType for FixedArrayDef { impl CompareType for TupleDef { fn compare_type( &mut self, - schema: &Rc, + schema: &Rc, branch: &Xxh3, new: &Self, dead: &mut HashMap, diff --git a/crates/introspect-postgres-sink/src/utils.rs b/crates/introspect-postgres-sink/src/utils.rs index a006d44e..9a68c4c4 100644 --- a/crates/introspect-postgres-sink/src/utils.rs +++ b/crates/introspect-postgres-sink/src/utils.rs @@ -8,6 +8,10 @@ pub fn truncate(s: &str, max_chars: usize) -> &str { } } +pub fn felt_to_schema(address: &Felt) -> String { + format!("{address:063x}") +} + const ALLOWED_TYPE_NAME_CHARS: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; diff --git a/crates/introspect/src/tables.rs b/crates/introspect/src/tables.rs index 43775d93..a9d645e7 100644 --- a/crates/introspect/src/tables.rs +++ b/crates/introspect/src/tables.rs @@ -5,9 +5,7 @@ use introspect_types::serialize_def::CairoTypeSerialization; use introspect_types::{CairoDeserializer, ColumnInfo, PrimaryDef, PrimaryTypeDef, TypeDef}; use serde::ser::{SerializeMap, SerializeSeq}; use serde::{Serialize, Serializer}; -use starknet_types_core::felt::Felt; use std::ops::Deref; -use torii::etl::envelope::MetaData; pub struct RecordSchema<'a> { primary: &'a PrimaryDef, @@ -215,23 +213,3 @@ impl SerializeEntries for () { Ok(()) } } - -pub fn pg_json_felt252(value: &Felt) -> String { - format!("\\x{}", hex::encode(value.to_bytes_be())) -} - -impl SerializeEntries for MetaData { - fn entry_count(&self) -> usize { - 4 - } - fn serialize_entries( - &self, - map: &mut ::SerializeMap, - ) -> Result<(), S::Error> { - let tx_hash = pg_json_felt252(&self.transaction_hash); - map.serialize_entry("__created_block", &self.block_number)?; - map.serialize_entry("__updated_block", &self.block_number)?; - map.serialize_entry("__created_tx", &tx_hash)?; - map.serialize_entry("__updated_tx", &tx_hash) - } -} diff --git a/crates/testing/src/event_reader.rs b/crates/testing/src/event_reader.rs index 9b79a376..98ac85e2 100644 --- a/crates/testing/src/event_reader.rs +++ b/crates/testing/src/event_reader.rs @@ -45,6 +45,10 @@ pub struct EventIterator { pub event: usize, } +pub struct MultiContractEventIterator { + iterators: VecDeque, +} + impl EventIterator { pub fn new>(path: P) -> Self { let path = resolve_path_like(path); @@ -63,6 +67,16 @@ impl EventIterator { } } +impl MultiContractEventIterator { + pub fn new>(paths: Vec

) -> Self { + let iterators = paths + .into_iter() + .map(|p| EventIterator::new(p)) + .collect::>(); + Self { iterators } + } +} + impl Iterator for EventIterator { type Item = EmittedEvent; @@ -81,3 +95,18 @@ impl Iterator for EventIterator { } } } + +impl Iterator for MultiContractEventIterator { + type Item = EmittedEvent; + + fn next(&mut self) -> Option { + while let Some(iterator) = self.iterators.front_mut() { + if let Some(event) = iterator.next() { + self.iterators.rotate_left(1); + return Some(event); + } + self.iterators.pop_front(); + } + None + } +} diff --git a/crates/testing/src/lib.rs b/crates/testing/src/lib.rs index 1635a8e8..70afaa2d 100644 --- a/crates/testing/src/lib.rs +++ b/crates/testing/src/lib.rs @@ -2,5 +2,5 @@ mod dojo; mod event_reader; pub mod utils; pub use dojo::FakeProvider; -pub use event_reader::EventIterator; +pub use event_reader::{EventIterator, MultiContractEventIterator}; pub use utils::{read_json_file, resolve_path_like}; diff --git a/examples/introspect/restart.rs b/examples/introspect/restart.rs index 1221bd2d..cf254d65 100644 --- a/examples/introspect/restart.rs +++ b/examples/introspect/restart.rs @@ -1,32 +1,49 @@ use itertools::Itertools; use sqlx::{postgres::PgPoolOptions, PgPool}; +use starknet::core::types::Felt; use std::sync::Arc; use torii_dojo::decoder::DojoDecoder; use torii_dojo::store::postgres::PgStore; use torii_dojo::DojoToriiError; use torii_introspect_postgres_sink::IntrospectPgDb; -use torii_test_utils::{resolve_path_like, EventIterator, FakeProvider}; +use torii_test_utils::{resolve_path_like, FakeProvider, MultiContractEventIterator}; const DB_URL: &str = "postgres://torii:torii@localhost:5432/torii"; -// const CHAIN_DATA_PATH: &str = "~/tc-tests/pistols-2"; -// const SCHEMA_NAME: &str = "pistols"; -const CHAIN_DATA_PATH: &str = "~/tc-tests/blob-arena-2"; -const SCHEMA_NAME: &str = "blob_arena"; +const EVENT_PATHS: [&str; 2] = ["~/tc-tests/blob-arena/events", "~/tc-tests/pistols/events"]; +const MODEL_CONTRACTS_PATH: &str = "~/tc-tests/model-contracts"; const BATCH_SIZE: usize = 10000; +const PISTOLS_ADDRESS: Felt = + Felt::from_hex_unchecked("08b4838140a3cbd36ebe64d4b5aaf56a30cc3753c928a79338bf56c53f506c5"); +const BLOB_ARENA_ADDRESS: Felt = + Felt::from_hex_unchecked("2d26295d6c541d64740e1ae56abc079b82b22c35ab83985ef8bd15dc0f9edfb"); + +// const SCHEMA_MAP: [(Felt, &str); 2] = [ +// (PISTOLS_ADDRESS, "pistols"), +// (BLOB_ARENA_ADDRESS, "blob_arena"), +// ]; + +const ADDRESSES: [Felt; 2] = [PISTOLS_ADDRESS, BLOB_ARENA_ADDRESS]; async fn run_events( - events: &mut EventIterator, + events: &mut MultiContractEventIterator, provider: FakeProvider, pool: Arc, end: Option, event_n: &mut u32, success: &mut u32, ) -> bool { + println!("Starting event processing run"); let decoder = DojoDecoder::, _>::new(pool.clone(), provider); - let db = IntrospectPgDb::new(pool.clone(), SCHEMA_NAME); + let db = IntrospectPgDb::new(pool.clone(), ADDRESSES); decoder.store.initialize().await.unwrap(); decoder.load_tables(&[]).await.unwrap(); - db.initialize_introspect_pg_sink().await.unwrap(); + let results = db.initialize_introspect_pg_sink().await.unwrap(); + if results.len() > 0 { + for err in results { + println!("Error loading table: {err}"); + } + panic!(""); + } let mut running = true; let mut this_run = 0; while running { @@ -72,11 +89,9 @@ async fn run_events( #[tokio::main] async fn main() { - let chain_path = resolve_path_like(CHAIN_DATA_PATH); - let events_path = chain_path.join("events"); - let contracts_path = chain_path.join("model-contracts"); - let provider = FakeProvider::new(contracts_path); - let mut event_iterator = EventIterator::new(events_path); + let event_paths = EVENT_PATHS.map(resolve_path_like).to_vec(); + let provider = FakeProvider::new(resolve_path_like(MODEL_CONTRACTS_PATH)); + let mut event_iterator = MultiContractEventIterator::new(event_paths); let pool = Arc::new(PgPoolOptions::new().connect(DB_URL).await.unwrap()); let mut event_n = 0; let mut success = 0; @@ -84,7 +99,7 @@ async fn main() { &mut event_iterator, provider.clone(), pool.clone(), - Some(500000), + Some(20000), &mut event_n, &mut success, ) From 3d4c548a826ae9171a2dc86d639768b9493e6fa7 Mon Sep 17 00:00:00 2001 From: Bengineer Date: Tue, 24 Mar 2026 17:29:20 +0000 Subject: [PATCH 03/21] Refactor database interaction and migration handling - Moved SQL-related functionality from `torii-common` to a new crate `torii-sql`. - Updated imports in various modules to reflect the new crate structure. - Removed the `db.rs` file from the `postgres` crate and refactored migration logic into `torii-sql`. - Introduced a new `DbConnection` trait for common database operations. - Implemented migration handling in `torii-sql` for both PostgreSQL and SQLite. - Updated Cargo.toml files to reflect the new dependencies and workspace structure. - Cleaned up unused code and dependencies across the affected crates. --- Cargo.lock | 75 +++--- Cargo.toml | 17 +- bins/torii-arcade/Cargo.toml | 8 +- bins/torii-introspect-bin/Cargo.toml | 9 +- crates/dojo/Cargo.toml | 13 +- crates/dojo/src/store/postgres.rs | 9 +- crates/dojo/src/store/sqlite.rs | 9 +- crates/introspect-postgres-sink/Cargo.toml | 4 +- crates/introspect-postgres-sink/src/query.rs | 2 +- crates/introspect-sql-sink/Cargo.toml | 30 +++ crates/introspect-sql-sink/src/error.rs | 160 ++++++++++++ crates/introspect-sql-sink/src/lib.rs | 14 + crates/introspect-sql-sink/src/processor.rs | 122 +++++++++ crates/introspect-sql-sink/src/schema.rs | 188 ++++++++++++++ crates/introspect-sql-sink/src/sink.rs | 101 ++++++++ crates/introspect-sql-sink/src/table.rs | 123 +++++++++ crates/introspect-sql-sink/src/tables.rs | 186 ++++++++++++++ crates/introspect-sql-sink/src/utils.rs | 99 +++++++ crates/introspect-sqlite-sink/Cargo.toml | 2 +- .../migrations/002_schema_state.sql | 6 +- crates/introspect/Cargo.toml | 1 + crates/introspect/src/postgres/global.rs | 2 +- crates/introspect/src/postgres/owned.rs | 2 +- crates/postgres/Cargo.toml | 16 +- crates/postgres/src/db.rs | 35 --- crates/postgres/src/lib.rs | 2 - crates/postgres/src/migration.rs | 203 +-------------- crates/sql/Cargo.toml | 20 ++ crates/sql/src/connection.rs | 45 ++++ crates/sql/src/lib.rs | 19 ++ crates/sql/src/migrate.rs | 218 ++++++++++++++++ crates/sql/src/postgres.rs | 241 ++++++++++++++++++ .../src/sql.rs => sql/src/query.rs} | 49 ++-- crates/sql/src/sqlite.rs | 189 ++++++++++++++ crates/sqlite/Cargo.toml | 2 +- crates/sqlite/src/db.rs | 2 +- crates/torii-common/src/lib.rs | 1 - 37 files changed, 1869 insertions(+), 355 deletions(-) create mode 100644 crates/introspect-sql-sink/Cargo.toml create mode 100644 crates/introspect-sql-sink/src/error.rs create mode 100644 crates/introspect-sql-sink/src/lib.rs create mode 100644 crates/introspect-sql-sink/src/processor.rs create mode 100644 crates/introspect-sql-sink/src/schema.rs create mode 100644 crates/introspect-sql-sink/src/sink.rs create mode 100644 crates/introspect-sql-sink/src/table.rs create mode 100644 crates/introspect-sql-sink/src/tables.rs create mode 100644 crates/introspect-sql-sink/src/utils.rs delete mode 100644 crates/postgres/src/db.rs create mode 100644 crates/sql/Cargo.toml create mode 100644 crates/sql/src/connection.rs create mode 100644 crates/sql/src/lib.rs create mode 100644 crates/sql/src/migrate.rs create mode 100644 crates/sql/src/postgres.rs rename crates/{torii-common/src/sql.rs => sql/src/query.rs} (74%) create mode 100644 crates/sql/src/sqlite.rs diff --git a/Cargo.lock b/Cargo.lock index acea9fdc..7e7bd732 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4624,6 +4624,7 @@ dependencies = [ "torii-introspect", "torii-introspect-postgres-sink", "torii-log-sink", + "torii-sql", "torii-sql-sink", "torii-test-utils", "tower 0.5.3", @@ -4657,7 +4658,7 @@ dependencies = [ "torii-introspect-postgres-sink", "torii-introspect-sqlite-sink", "torii-runtime-common", - "torii-sqlite", + "torii-sql", "tracing", "tracing-subscriber", "url", @@ -4731,8 +4732,7 @@ dependencies = [ "torii", "torii-common", "torii-introspect", - "torii-postgres", - "torii-sqlite", + "torii-sql", "tracing", ] @@ -4903,6 +4903,7 @@ dependencies = [ "tonic-build", "torii", "torii-common", + "torii-sql", ] [[package]] @@ -4928,7 +4929,7 @@ dependencies = [ "torii-introspect-postgres-sink", "torii-introspect-sqlite-sink", "torii-runtime-common", - "torii-sqlite", + "torii-sql", "tracing", "tracing-subscriber", "url", @@ -4953,9 +4954,33 @@ dependencies = [ "thiserror 2.0.18", "tokio", "torii", - "torii-common", "torii-introspect", - "torii-postgres", + "torii-sql", + "tracing", + "xxhash-rust", +] + +[[package]] +name = "torii-introspect-sql-sink" +version = "0.1.0" +dependencies = [ + "anyhow", + "arrayvec", + "async-trait", + "hex", + "introspect-types", + "itertools 0.14.0", + "metrics", + "serde", + "serde_json", + "sqlx", + "starknet", + "starknet-types-core", + "thiserror 2.0.18", + "tokio", + "torii", + "torii-introspect", + "torii-sql", "tracing", "xxhash-rust", ] @@ -4979,7 +5004,7 @@ dependencies = [ "tokio", "torii", "torii-introspect", - "torii-sqlite", + "torii-sql", "tracing", ] @@ -5028,35 +5053,25 @@ dependencies = [ ] [[package]] -name = "torii-postgres" +name = "torii-runtime-common" version = "0.1.0" dependencies = [ "anyhow", - "async-trait", - "crc", - "futures", - "hex", - "serde", - "serde_json", - "sqlx", - "starknet-types-core", - "thiserror 2.0.18", "tokio", + "tokio-postgres", "torii", - "torii-common", "tracing", - "xxhash-rust", ] [[package]] -name = "torii-runtime-common" +name = "torii-sql" version = "0.1.0" dependencies = [ - "anyhow", - "tokio", - "tokio-postgres", - "torii", - "tracing", + "async-trait", + "crc", + "futures", + "itertools 0.14.0", + "sqlx", ] [[package]] @@ -5083,16 +5098,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "torii-sqlite" -version = "0.1.0" -dependencies = [ - "async-trait", - "futures", - "sqlx", - "torii-common", -] - [[package]] name = "torii-test-utils" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 01448162..1d9bad29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,13 +11,13 @@ members = [ "crates/torii-erc20", "crates/torii-erc721", "crates/torii-erc1155", + "crates/sql", "crates/introspect", "crates/dojo", + "crates/introspect-sql-sink", "crates/introspect-postgres-sink", "crates/introspect-sqlite-sink", "crates/testing", - "crates/postgres", - "crates/sqlite", "bins/torii-erc20", "bins/torii-erc20-synth", "bins/torii-introspect-bin", @@ -76,12 +76,7 @@ clap = { version = "4.5", features = ["derive"] } starknet = "0.17" # Database -sqlx = { version = "0.8.6", features = [ - "runtime-tokio", - "sqlite", - "postgres", - "any", -] } +sqlx = { version = "0.8.6", features = ["runtime-tokio"] } crc = "3.4.0" # Hashing @@ -129,6 +124,7 @@ torii-config-common = { path = "crates/torii-config-common" } torii-runtime-common = { path = "crates/torii-runtime-common" } # Internal crates +torii-sql = { path = "crates/sql" } torii-sql-sink.path = "crates/torii-sql-sink" torii-log-sink.path = "crates/torii-log-sink" torii-arcade-sink.path = "crates/arcade-sink" @@ -138,12 +134,10 @@ torii-erc721.path = "crates/torii-erc721" torii-erc1155.path = "crates/torii-erc1155" torii-dojo.path = "./crates/dojo" torii-introspect.path = "crates/introspect" +torii-introspect-sql-sink.path = "./crates/introspect-sql-sink" torii-introspect-postgres-sink.path = "./crates/introspect-postgres-sink" torii-introspect-sqlite-sink.path = "./crates/introspect-sqlite-sink" torii-test-utils.path = "crates/testing" -torii-postgres.path = "crates/postgres" -torii-sqlite.path = "crates/sqlite" - [lib] name = "torii" @@ -228,6 +222,7 @@ torii-introspect.workspace = true torii-common.workspace = true torii-introspect-postgres-sink.workspace = true torii-test-utils.workspace = true +torii-sql = { workspace = true, features = ["postgres", "sqlite"] } # Example dependencies diff --git a/bins/torii-arcade/Cargo.toml b/bins/torii-arcade/Cargo.toml index a3f47206..d9436245 100644 --- a/bins/torii-arcade/Cargo.toml +++ b/bins/torii-arcade/Cargo.toml @@ -21,7 +21,7 @@ torii-erc1155 = { path = "../../crates/torii-erc1155" } torii-introspect-postgres-sink = { path = "../../crates/introspect-postgres-sink" } torii-introspect-sqlite-sink = { path = "../../crates/introspect-sqlite-sink" } torii-runtime-common.workspace = true -torii-sqlite.workspace = true +torii-sql = { workspace = true, features = ["postgres", "sqlite"] } tokio = { version = "1", features = ["full"] } tracing = "0.1" @@ -30,7 +30,11 @@ starknet = "0.17" url = "2.5" clap = { version = "4.5", features = ["derive", "env"] } anyhow = "1.0" -sqlx = { version = "0.8", features = ["postgres", "sqlite", "runtime-tokio-rustls"] } +sqlx = { version = "0.8", features = [ + "postgres", + "sqlite", + "runtime-tokio-rustls", +] } tonic.workspace = true tonic-reflection.workspace = true tonic-web.workspace = true diff --git a/bins/torii-introspect-bin/Cargo.toml b/bins/torii-introspect-bin/Cargo.toml index 97bed8b2..c75d7dc7 100644 --- a/bins/torii-introspect-bin/Cargo.toml +++ b/bins/torii-introspect-bin/Cargo.toml @@ -20,7 +20,7 @@ torii-ecs-sink = { path = "../../crates/torii-ecs-sink" } torii-introspect-postgres-sink = { path = "../../crates/introspect-postgres-sink" } torii-introspect-sqlite-sink = { path = "../../crates/introspect-sqlite-sink" } torii-runtime-common.workspace = true -torii-sqlite = { path = "../../crates/sqlite" } +torii-sql = { path = "../../crates/sql" } tokio = { version = "1", features = ["full"] } tracing = "0.1" @@ -29,7 +29,12 @@ starknet = "0.17" url = "2.5" clap = { version = "4.5", features = ["derive", "env"] } anyhow = "1.0" -sqlx = { version = "0.8", features = ["postgres", "sqlite", "runtime-tokio-rustls", "any"] } +sqlx = { version = "0.8", features = [ + "postgres", + "sqlite", + "runtime-tokio-rustls", + "any", +] } tonic.workspace = true tonic-reflection.workspace = true tonic-web.workspace = true diff --git a/crates/dojo/Cargo.toml b/crates/dojo/Cargo.toml index 0e09b633..153ded69 100644 --- a/crates/dojo/Cargo.toml +++ b/crates/dojo/Cargo.toml @@ -18,12 +18,6 @@ tracing.workspace = true thiserror.workspace = true hex.workspace = true itertools.workspace = true - -dojo-introspect.workspace = true -introspect-types.workspace = true -torii-introspect.workspace = true -torii-postgres.workspace = true -torii-sqlite.workspace = true sqlx = { workspace = true, features = [ "postgres", "sqlite", @@ -32,6 +26,13 @@ sqlx = { workspace = true, features = [ "migrate", ] } +dojo-introspect.workspace = true +introspect-types.workspace = true + +torii-introspect.workspace = true +torii-sql = { workspace = true, features = ["postgres", "sqlite"] } + + [build-dependencies] tonic-build.workspace = true diff --git a/crates/dojo/src/store/postgres.rs b/crates/dojo/src/store/postgres.rs index 84229ec0..351a49bb 100644 --- a/crates/dojo/src/store/postgres.rs +++ b/crates/dojo/src/store/postgres.rs @@ -13,11 +13,10 @@ use sqlx::{FromRow, Postgres}; use starknet_types_core::felt::Felt; use std::collections::HashMap; use std::ops::Deref; -use torii_common::sql::SqlxResult; use torii_introspect::postgres::owned::PgTypeDef; use torii_introspect::postgres::PgFelt; use torii_introspect::schema::ColumnKeyTrait; -use torii_postgres::db::PostgresConnection; +use torii_sql::{DbConnection, SqlxResult}; pub const FETCH_TABLES_QUERY: &str = r#" SELECT DISTINCT ON (owner, id) @@ -320,20 +319,20 @@ impl Deref for PgStore { } } -impl PgStore { +impl + Send + Sync> PgStore { pub async fn initialize(&self) -> SqlxResult<()> { self.migrate(Some("dojo"), DOJO_STORE_MIGRATIONS).await } } -impl From for PgStore { +impl> From for PgStore { fn from(pool: T) -> Self { PgStore(pool) } } #[async_trait] -impl DojoStoreTrait for PgStore { +impl + Send + Sync + 'static> DojoStoreTrait for PgStore { type Error = DojoPgStoreError; async fn save_table( diff --git a/crates/dojo/src/store/sqlite.rs b/crates/dojo/src/store/sqlite.rs index fd348d5e..c0a15c74 100644 --- a/crates/dojo/src/store/sqlite.rs +++ b/crates/dojo/src/store/sqlite.rs @@ -12,10 +12,9 @@ use starknet_types_core::felt::Felt; use std::collections::HashMap; use std::io; use std::ops::Deref; -use torii_common::sql::SqlxResult; use torii_common::{blob_to_felt, felt_to_blob}; use torii_introspect::schema::ColumnKeyTrait; -use torii_sqlite::SqliteConnection; +use torii_sql::{DbConnection, SqlxResult}; pub const DOJO_SQLITE_STORE_MIGRATIONS: Migrator = sqlx::migrate!("./migrations/sqlite"); @@ -162,21 +161,21 @@ impl Deref for SqliteStore { } } -impl SqliteStore { +impl + Send + Sync> SqliteStore { pub async fn initialize(&self) -> SqlxResult<()> { self.migrate(Some("dojo"), DOJO_SQLITE_STORE_MIGRATIONS) .await } } -impl From for SqliteStore { +impl> From for SqliteStore { fn from(pool: T) -> Self { Self(pool) } } #[async_trait] -impl DojoStoreTrait for SqliteStore { +impl + Send + Sync + 'static> DojoStoreTrait for SqliteStore { type Error = DojoSqliteStoreError; async fn save_table( diff --git a/crates/introspect-postgres-sink/Cargo.toml b/crates/introspect-postgres-sink/Cargo.toml index ca265369..25123775 100644 --- a/crates/introspect-postgres-sink/Cargo.toml +++ b/crates/introspect-postgres-sink/Cargo.toml @@ -9,7 +9,6 @@ license = "Apache-2.0" [dependencies] sqlx = { workspace = true, features = [ "postgres", - "sqlite", "runtime-tokio-rustls", "macros", "migrate", @@ -33,5 +32,4 @@ arrayvec.workspace = true # Local crates torii-introspect.workspace = true -torii-postgres.workspace = true -torii-common.workspace = true +torii-sql = { workspace = true, features = ["postgres"] } diff --git a/crates/introspect-postgres-sink/src/query.rs b/crates/introspect-postgres-sink/src/query.rs index 2f14e62c..bde355ac 100644 --- a/crates/introspect-postgres-sink/src/query.rs +++ b/crates/introspect-postgres-sink/src/query.rs @@ -15,9 +15,9 @@ use std::{ fmt::{Display, Formatter, Result as FmtResult, Write}, rc::Rc, }; -use torii_common::sql::{PgQuery, Queries, SqlxResult}; use torii_introspect::postgres::types::{PgPrimary, Uint128}; use torii_introspect::postgres::PgFelt; +use torii_sql::{PgQuery, Queries, SqlxResult}; pub const COMMIT_CMD: &str = "--COMMIT"; diff --git a/crates/introspect-sql-sink/Cargo.toml b/crates/introspect-sql-sink/Cargo.toml new file mode 100644 index 00000000..86e24faf --- /dev/null +++ b/crates/introspect-sql-sink/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "torii-introspect-sql-sink" +version = "0.1.0" +edition = "2021" +description = "Database sink implementation for Torii runtime" +authors = ["Torii Runtime "] +license = "Apache-2.0" + +[dependencies] +sqlx = { workspace = true, features = ["runtime-tokio-rustls", "macros"] } +anyhow.workspace = true +async-trait.workspace = true +metrics.workspace = true +xxhash-rust.workspace = true +hex.workspace = true +serde.workspace = true +serde_json.workspace = true +starknet.workspace = true +tokio.workspace = true +torii.workspace = true +tracing.workspace = true +starknet-types-core.workspace = true +thiserror.workspace = true +introspect-types.workspace = true +itertools.workspace = true +arrayvec.workspace = true + +# Local crates +torii-introspect.workspace = true +torii-sql.workspace = true diff --git a/crates/introspect-sql-sink/src/error.rs b/crates/introspect-sql-sink/src/error.rs new file mode 100644 index 00000000..09de383a --- /dev/null +++ b/crates/introspect-sql-sink/src/error.rs @@ -0,0 +1,160 @@ +use crate::TableKey; +use introspect_types::{PrimaryTypeDef, TypeDef}; +use sqlx::Error as SqlxError; +use starknet_types_core::felt::{Felt, FromStrError}; +use std::sync::PoisonError; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum TypeError { + #[error("Unsupported type for {0}")] + UnsupportedType(String), + #[error("Nested arrays are not supported")] + NestedArrays, +} + +pub type TypeResult = std::result::Result; + +#[derive(Debug, Error)] +pub enum TableError { + #[error("Column with id: {0} not found in table {1}")] + ColumnNotFound(Felt, String), + #[error(transparent)] + TypeError(#[from] TypeError), + #[error("Current type mismatch error")] + TypeMismatch, + #[error("Unsupported upgrade for table {table} column {column}: {reason}")] + UnsupportedUpgrade { + table: String, + column: String, + reason: UpgradeError, + }, +} + +pub type TableResult = std::result::Result; + +#[derive(Debug, thiserror::Error)] +pub enum UpgradeError { + #[error("Failed to upgrade type from {old} to {new}")] + TypeUpgradeError { + old: &'static str, + new: &'static str, + }, + #[error("Failed to upgrade primary from {old} to {new}")] + PrimaryUpgradeError { + old: &'static str, + new: &'static str, + }, + #[error(transparent)] + TypeCreationError(#[from] TypeError), + #[error("Array length cannot be decreased from {old} to {new}")] + ArrayLengthDecreaseError { old: u32, new: u32 }, + #[error("Cannot reduce element in tuple")] + TupleReductionError, +} + +pub type UpgradeResult = Result; + +impl UpgradeError { + pub fn type_upgrade_err(old: &TypeDef, new: &TypeDef) -> UpgradeResult { + Err(Self::TypeUpgradeError { + old: old.item_name(), + new: new.item_name(), + }) + } + pub fn type_upgrade_to_err(old: &TypeDef, new: &'static str) -> UpgradeResult { + Err(Self::TypeUpgradeError { + old: old.item_name(), + new, + }) + } + pub fn type_cast_err(old: &TypeDef, new: &'static str) -> UpgradeResult { + Err(Self::TypeUpgradeError { + old: old.item_name(), + new, + }) + } + pub fn array_shorten_err(old: u32, new: u32) -> UpgradeResult { + Err(Self::ArrayLengthDecreaseError { old, new }) + } + pub fn primary_upgrade_err(old: &PrimaryTypeDef, new: &PrimaryTypeDef) -> UpgradeResult { + Err(Self::PrimaryUpgradeError { + old: old.item_name(), + new: new.item_name(), + }) + } +} + +pub trait UpgradeResultExt { + fn to_table_result(self, table: &str, column: &str) -> TableResult; +} + +impl UpgradeResultExt for UpgradeResult { + fn to_table_result(self, table: &str, column: &str) -> TableResult { + self.map_err(|err| TableError::UnsupportedUpgrade { + table: table.to_string(), + column: column.to_string(), + reason: err, + }) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum DbError { + #[error(transparent)] + DatabaseError(#[from] SqlxError), + #[error("Invalid event format: {0}")] + InvalidEventFormat(String), + #[error(transparent)] + JsonError(#[from] serde_json::Error), + #[error(transparent)] + IoError(#[from] std::io::Error), + #[error(transparent)] + TableError(#[from] TableError), + #[error(transparent)] + TypeError(#[from] TypeError), + #[error("Table with id: {0} already exists, incoming name: {1}, existing name: {2}")] + TableAlreadyExists(TableKey, String, String), + #[error("Table not found with id: {0}")] + TableNotFound(TableKey), + #[error("Table not alive - id: {0}, name: {1}")] + TableNotAlive(Felt, String), + #[error("Manager does not support updating")] + UpdateNotSupported, + #[error("Table poison error: {0}")] + PoisonError(String), + #[error("Schema not found for address: {0:#063x}")] + SchemaNotFound(Felt), +} + +pub type DbResult = std::result::Result; + +impl From> for DbError { + fn from(err: PoisonError) -> Self { + Self::PoisonError(err.to_string()) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum SchemaError { + #[error("Invalid address length for schema: {0} should be 63 characters long")] + InvalidAddressLength(String), + #[error(transparent)] + AddressFromStrError(#[from] FromStrError), + #[error("Schema {0} does not match expected schema {1}")] + SchemaMismatch(String, String), + #[error("Schema {1} not found for address: {0:#063x}")] + AddressNotFound(Felt, String), +} + +pub type SchemaResult = std::result::Result; + +#[derive(Debug, thiserror::Error)] +pub enum TableLoadError { + #[error(transparent)] + SchemaError(#[from] SchemaError), + #[error("Table {0} {1:#063x} not found for column {2} with id: {3:#063x}")] + ColumnTableNotFound(String, Felt, String, Felt), + #[error("Table {0} {1:#063x} not found for dead field {2} with id: {3}")] + TableDeadNotFound(String, Felt, String, u128), +} diff --git a/crates/introspect-sql-sink/src/lib.rs b/crates/introspect-sql-sink/src/lib.rs new file mode 100644 index 00000000..d27f014b --- /dev/null +++ b/crates/introspect-sql-sink/src/lib.rs @@ -0,0 +1,14 @@ +pub mod error; +pub mod processor; +pub mod schema; +pub mod sink; +pub mod table; +pub mod tables; +pub mod utils; + +pub use error::{ + DbError, DbResult, TableError, TableResult, TypeError, TypeResult, UpgradeError, UpgradeResult, + UpgradeResultExt, +}; +pub use schema::{SchemaKey, SchemaMode, TableKey}; +pub use utils::{truncate, HasherExt}; diff --git a/crates/introspect-sql-sink/src/processor.rs b/crates/introspect-sql-sink/src/processor.rs new file mode 100644 index 00000000..e92cddea --- /dev/null +++ b/crates/introspect-sql-sink/src/processor.rs @@ -0,0 +1,122 @@ +use crate::error::{SchemaError, SchemaResult, TableLoadError}; +use crate::tables::DbTables; +use crate::utils::felt_to_schema; +use introspect_types::ResultInto; +use itertools::Itertools; +use sqlx::{Database, PgPool}; +use starknet_types_core::felt::Felt; +use std::collections::{HashMap, HashSet}; +use std::sync::Arc; +use torii_common::sql::PgQuery; +use torii_introspect::events::IntrospectBody; +use torii_postgres::PostgresConnection; + +pub struct IntrospectDb { + tables: DbTables, + schemas: SchemaMode, + pool: T, +} + +impl PostgresConnection for IntrospectDb { + fn pool(&self) -> &PgPool { + self.pool.pool() + } +} + +// TODO: Add errors for unknown schema +impl IntrospectDb { + pub fn new>(pool: T, schemas: S) -> Self { + Self { + tables: PostgresTables::default(), + schemas: schemas.into(), + pool, + } + } + pub async fn load_store_data(&self) -> PgDbResult> { + let mut errors = Vec::new(); + let schemas = self.schemas.schemas(); + let schemas = schemas + .as_ref() + .map(|s| s.iter().map(AsRef::as_ref).collect()); + let table_rows = fetch_tables(self.pool(), &schemas).await?; + let mut tables = HashMap::with_capacity(table_rows.len()); + for table in table_rows { + let (id, table) = table.into(); + tables.insert((table.schema.clone(), id), table); + } + for (schema, table_id, id, column_info) in fetch_columns(self.pool(), &schemas).await? { + if let Some(table) = tables.get_mut(&(schema.clone(), table_id)) { + table.columns.insert(id, column_info); + } else { + errors.push(TableLoadError::ColumnTableNotFound( + schema, + table_id, + column_info.name, + id, + )); + } + } + for (schema, table_id, id, field) in fetch_dead_fields(self.pool(), &schemas).await? { + if let Some(table) = tables.get_mut(&(schema.clone(), table_id)) { + table.dead.insert(id, field); + } else { + errors.push(TableLoadError::TableDeadNotFound( + schema, table_id, field.name, id, + )); + } + } + let mut map = self.tables.write()?; + for ((schema, id), table) in tables { + match self.schemas.get_key(schema, id, &table.owner) { + Ok(key) => { + map.insert(key, table); + } + Err(err) => errors.push(TableLoadError::SchemaError(err)), + } + } + Ok(errors) + } + + pub async fn initialize_introspect_pg_sink(&self) -> PgDbResult> { + self.migrate(Some("introspect"), INTROSPECT_PG_SINK_MIGRATIONS) + .await?; + self.load_store_data().await + } + + pub async fn process_messages( + &self, + msgs: Vec<&IntrospectBody>, + ) -> PgDbResult>> { + let mut queries = Vec::new(); + let mut results = Vec::with_capacity(msgs.len()); + + for body in msgs { + let (msg, metadata) = body.into(); + results.push(self.tables.handle_message( + self.schemas.to_schema(&metadata.from_address)?, + msg, + &metadata.from_address, + metadata.block_number.unwrap_or(u64::MAX), + &metadata.transaction_hash, + &mut queries, + )); + } + self.process_queries(queries).await?; + Ok(results) + } + + pub async fn process_queries(&self, queries: Vec) -> PgDbResult<()> { + let mut batch = Vec::new(); + for query in queries { + if query == *COMMIT_CMD { + self.execute_queries(std::mem::take(&mut batch)).await?; + } else { + batch.push(query); + } + } + if !batch.is_empty() { + self.execute_queries(batch).await?; + } + Ok(()) + } +} diff --git a/crates/introspect-sql-sink/src/schema.rs b/crates/introspect-sql-sink/src/schema.rs new file mode 100644 index 00000000..ce96b696 --- /dev/null +++ b/crates/introspect-sql-sink/src/schema.rs @@ -0,0 +1,188 @@ +use crate::error::{SchemaError, SchemaResult}; +use crate::utils::felt_to_schema; +use crate::{DbError, DbResult}; +use introspect_types::ResultInto; +use itertools::Itertools; +use starknet_types_core::felt::Felt; +use std::collections::{HashMap, HashSet}; +use std::fmt::Display; +use std::hash::{Hash, Hasher}; +use std::sync::Arc; + +pub enum SchemaMode { + Single(Arc), + Address, + Named(HashMap>), + Addresses(HashSet), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TableKey { + schema: SchemaKey, + id: Felt, +} + +impl TableKey { + pub fn new(schema: SchemaKey, id: Felt) -> Self { + Self { schema, id } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum SchemaKey { + Single(Arc), + Address(Felt), + Named(Arc), +} + +impl Hash for TableKey { + fn hash(&self, state: &mut H) { + self.schema.hash(state); + self.id.hash(state); + } +} + +impl Hash for SchemaKey { + fn hash(&self, state: &mut H) { + match self { + SchemaKey::Address(addr) => addr.hash(state), + SchemaKey::Named(name) => name.hash(state), + SchemaKey::Single(_) => {} + } + } +} + +impl Display for SchemaKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SchemaKey::Address(addr) => write!(f, "{addr:063x}"), + SchemaKey::Named(name) | SchemaKey::Single(name) => name.fmt(f), + } + } +} + +impl Display for TableKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if !matches!(self.schema, SchemaKey::Single(_)) { + write!(f, "{} ", self.schema)?; + } + write!(f, "{:#063x}", self.id) + } +} + +impl From for SchemaMode { + fn from(value: String) -> Self { + SchemaMode::Single(value.into()) + } +} + +impl From<&str> for SchemaMode { + fn from(value: &str) -> Self { + SchemaMode::Single(value.into()) + } +} + +impl From> for SchemaMode { + fn from(value: HashMap) -> Self { + SchemaMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + } +} + +impl From<[(Felt, &str); N]> for SchemaMode { + fn from(value: [(Felt, &str); N]) -> Self { + SchemaMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + } +} + +impl From<[(Felt, String); N]> for SchemaMode { + fn from(value: [(Felt, String); N]) -> Self { + SchemaMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + } +} + +impl From<[Felt; N]> for SchemaMode { + fn from(value: [Felt; N]) -> Self { + SchemaMode::Addresses(value.into_iter().collect()) + } +} + +impl From> for SchemaMode { + fn from(value: Vec) -> Self { + SchemaMode::Addresses(value.into_iter().collect()) + } +} + +fn felt_try_from_schema(schema: &str) -> SchemaResult { + match schema.len() == 63 { + true => Felt::from_hex(schema).err_into(), + false => Err(SchemaError::InvalidAddressLength(schema.to_string())), + } +} + +impl SchemaMode { + pub fn schemas(&self) -> Option>> { + match self { + SchemaMode::Single(name) => Some(vec![name.clone()]), + SchemaMode::Address => None, + SchemaMode::Named(map) => Some(map.values().cloned().collect()), + SchemaMode::Addresses(set) => Some(set.iter().map(felt_to_schema).map_into().collect()), + } + } + + pub fn get_schema_key(&self, schema: String, owner: &Felt) -> SchemaResult { + match self { + SchemaMode::Single(s) => match **s == *schema { + true => Ok(SchemaKey::Single(s.clone())), + false => Err(SchemaError::SchemaMismatch(schema, s.to_string())), + }, + SchemaMode::Address => felt_try_from_schema(&schema).map(SchemaKey::Address), + SchemaMode::Named(map) => match map.get(owner) { + Some(s) if **s == *schema => Ok(SchemaKey::Named(s.clone())), + Some(s) => Err(SchemaError::SchemaMismatch(schema, s.to_string())), + None => Err(SchemaError::AddressNotFound(*owner, schema)), + }, + SchemaMode::Addresses(set) => { + let address = felt_try_from_schema(&schema)?; + match set.contains(&address) { + true => Ok(SchemaKey::Address(address)), + false => Err(SchemaError::AddressNotFound(address, schema)), + } + } + } + } + + pub fn get_key(&self, schema: String, id: Felt, owner: &Felt) -> SchemaResult { + self.get_schema_key(schema, owner) + .map(|k| TableKey::new(k, id)) + } + + pub fn to_schema(&self, from_address: &Felt) -> DbResult { + match self { + SchemaMode::Single(name) => Ok(SchemaKey::Single(name.clone())), + SchemaMode::Address => Ok(SchemaKey::Address(*from_address)), + SchemaMode::Named(map) => match map.get(from_address) { + Some(schema) => Ok(SchemaKey::Named(schema.clone())), + None => Err(DbError::SchemaNotFound(*from_address)), + }, + SchemaMode::Addresses(set) => match set.contains(from_address) { + true => Ok(SchemaKey::Address(*from_address)), + false => Err(DbError::SchemaNotFound(*from_address)), + }, + } + } +} diff --git a/crates/introspect-sql-sink/src/sink.rs b/crates/introspect-sql-sink/src/sink.rs new file mode 100644 index 00000000..8fd0afa8 --- /dev/null +++ b/crates/introspect-sql-sink/src/sink.rs @@ -0,0 +1,101 @@ +use anyhow::Result; +use async_trait::async_trait; +use std::sync::Arc; +use torii::axum::Router; +use torii::etl::{ + envelope::{Envelope, TypeId}, + extractor::ExtractionBatch, + sink::{EventBus, Sink, SinkContext, TopicInfo}, +}; +use torii_introspect::events::{IntrospectBody, IntrospectMsg}; +use torii_postgres::PostgresConnection; + +pub const LOGGING_TARGET: &str = "torii::sinks::introspect::postgres"; +const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); + +#[async_trait] +impl Sink for IntrospectPgDb { + fn name(&self) -> &'static str { + "introspect-postgres" + } + + fn interested_types(&self) -> Vec { + vec![INTROSPECT_TYPE] + } + + async fn process(&self, envelopes: &[Envelope], _batch: &ExtractionBatch) -> Result<()> { + let mut processed = 0usize; + let mut create_tables: usize = 0usize; + let mut update_tables = 0usize; + let mut inserts_fields = 0usize; + let mut inserted_records = 0usize; + let mut delete_records = 0usize; + let mut msgs = Vec::with_capacity(envelopes.len()); + for envelope in envelopes { + if envelope.type_id == INTROSPECT_TYPE { + if let Some(body) = envelope.downcast_ref::() { + match &body.msg { + IntrospectMsg::CreateTable(_) => create_tables += 1, + IntrospectMsg::UpdateTable(_) => update_tables += 1, + IntrospectMsg::InsertsFields(event) => { + inserts_fields += 1; + inserted_records += event.records.len(); + } + IntrospectMsg::DeleteRecords(event) => { + delete_records += event.rows.len(); + } + _ => {} + } + processed += 1; + msgs.push(body); + } + } + } + self.process_messages(msgs).await?; + if processed > 0 { + tracing::info!( + target: LOGGING_TARGET, + processed, + create_tables, + update_tables, + inserts_fields, + inserted_records, + delete_records, + "Processed introspect envelopes" + ); + ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "create_table") + .increment(create_tables as u64); + ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "update_table") + .increment(update_tables as u64); + ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "inserts_fields") + .increment(inserts_fields as u64); + ::metrics::counter!("torii_introspect_sink_records_total", "message" => "inserts_fields") + .increment(inserted_records as u64); + ::metrics::counter!("torii_introspect_sink_records_total", "message" => "delete_records") + .increment(delete_records as u64); + } + + Ok(()) + } + + fn topics(&self) -> Vec { + Vec::new() + } + + fn build_routes(&self) -> Router { + Router::new() + } + + async fn initialize( + &mut self, + _event_bus: Arc, + _context: &SinkContext, + ) -> Result<()> { + self.initialize_introspect_pg_sink().await?; + tracing::info!( + target: LOGGING_TARGET, + "Initialized introspect Postgres sink" + ); + Ok(()) + } +} diff --git a/crates/introspect-sql-sink/src/table.rs b/crates/introspect-sql-sink/src/table.rs new file mode 100644 index 00000000..49903c30 --- /dev/null +++ b/crates/introspect-sql-sink/src/table.rs @@ -0,0 +1,123 @@ +use crate::{DbResult, TableError, TableResult}; +use introspect_types::{ColumnDef, ColumnInfo, MemberDef, PrimaryDef, TypeDef}; +use itertools::Itertools; +use sqlx::Database; +use starknet_types_core::felt::Felt; +use std::{collections::HashMap, rc::Rc}; +use torii_common::sql::FlexQuery; +use torii_introspect::{schema::TableInfo, tables::RecordSchema, Record}; + +#[derive(Debug)] +pub struct DbTable { + pub schema: String, + pub name: String, + pub owner: Felt, + pub primary: PrimaryDef, + pub columns: HashMap, + pub alive: bool, + pub dead: HashMap, +} + +#[derive(Debug)] +pub struct DeadField { + pub name: String, + pub type_def: TypeDef, +} + +impl From for DeadField { + fn from(value: MemberDef) -> Self { + DeadField { + name: value.name, + type_def: value.type_def, + } + } +} + +impl From for MemberDef { + fn from(value: DeadField) -> Self { + MemberDef { + name: value.name, + attributes: Vec::new(), + type_def: value.type_def, + } + } +} + +pub trait DbTableTrait { + fn create_table_queries( + &self, + id: &Felt, + order: &[Felt], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> DbResult<()>; + fn update_table_queries( + &mut self, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> DbResult<()>; + fn insert_fields_queries( + &self, + columns: &[Felt], + records: &[Record], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> DbResult<()>; +} + +impl DbTable { + pub fn column(&self, id: &Felt) -> TableResult<&ColumnInfo> { + self.columns + .get(id) + .ok_or_else(|| TableError::ColumnNotFound(*id, self.name.clone())) + } + + pub fn schema(&self) -> Rc { + self.schema.as_str().into() + } + + pub fn columns(&self, ids: &[Felt]) -> TableResult> { + ids.iter() + .map(|id| self.column(id)) + .collect::>>() + } + + pub fn columns_with_ids<'a>( + &'a self, + ids: &'a [Felt], + ) -> TableResult> { + ids.iter() + .map(|id| self.column(id).map(|col| (id, col))) + .collect::>>() + } + + pub fn new( + schema: String, + owner: Felt, + info: TableInfo, + dead: Option>, + ) -> Self { + DbTable { + schema, + owner, + name: info.name, + primary: info.primary, + columns: info.columns.into_iter().map_into().collect(), + alive: true, + dead: dead.unwrap_or_default().into_iter().collect(), + } + } + + pub fn get_record_schema(&self, columns: &[Felt]) -> TableResult> { + Ok(RecordSchema::new(&self.primary, self.columns(columns)?)) + } +} diff --git a/crates/introspect-sql-sink/src/tables.rs b/crates/introspect-sql-sink/src/tables.rs new file mode 100644 index 00000000..e60b342c --- /dev/null +++ b/crates/introspect-sql-sink/src/tables.rs @@ -0,0 +1,186 @@ +use crate::schema::{SchemaKey, TableKey}; +use crate::table::{DbTable, DbTableTrait}; +use crate::{DbError, DbResult}; +use introspect_types::FeltIds; +use sqlx::Database; +use starknet_types_core::felt::Felt; +use std::collections::HashMap; +use std::marker::PhantomData; +use std::ops::Deref; +use std::sync::RwLock; +use torii_common::sql::FlexQuery; +use torii_introspect::events::IntrospectMsg; +use torii_introspect::schema::TableSchema; +use torii_introspect::InsertsFields; + +pub const DEAD_MEMBERS_TABLE: &str = "__introspect_dead_fields"; +pub const TABLES_TABLE: &str = "__introspect_tables"; +pub const COLUMNS_TABLE: &str = "__introspect_columns"; + +#[derive(Debug, Default)] +pub struct DbTables(pub RwLock>, PhantomData); + +impl Deref for DbTables { + type Target = RwLock>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DbTables +where + DB: Database, + DbTable: DbTableTrait, +{ + pub fn create_table( + &self, + schema_key: SchemaKey, + to_table: impl Into, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> DbResult<()> { + let (id, info) = Into::::into(to_table).into(); + let schema = schema_key.to_string(); + let key = TableKey::new(schema_key, id); + self.assert_table_not_exists(&key, &info.name)?; + let order = info.columns.ids(); + let table = DbTable::new(schema, *from_address, info, None); + table.create_table_queries( + &id, + &order, + from_address, + block_number, + transaction_hash, + queries, + )?; + let mut tables = self.write()?; + tables.insert(key, table); + Ok(()) + } + + pub fn update_table( + &self, + schema_key: SchemaKey, + to_table: impl Into, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> DbResult<()> { + let (id, table) = Into::::into(to_table).into(); + let mut tables = self.write()?; + let key = TableKey::new(schema_key, id); + let existing = tables + .get_mut(&key) + .ok_or_else(|| DbError::TableNotFound(key.clone()))?; + existing.update_table_queries( + &table.name, + &table.primary, + &table.columns, + from_address, + block_number, + transaction_hash, + queries, + ) + } + + pub fn assert_table_not_exists(&self, id: &TableKey, name: &str) -> DbResult<()> { + match self.read()?.get(id) { + Some(existing) => Err(DbError::TableAlreadyExists( + id.clone(), + name.to_string(), + existing.name.to_string(), + )), + None => Ok(()), + } + } + + pub fn set_table_dead(&self, schema: SchemaKey, id: Felt) -> DbResult<()> { + let mut tables = self.write()?; + let key = TableKey::new(schema, id); + match tables.get_mut(&key) { + Some(table) => { + table.alive = false; + Ok(()) + } + None => Err(DbError::TableNotFound(key)), + } + } + + pub fn insert_fields( + &self, + schema: SchemaKey, + event: &InsertsFields, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> DbResult<()> { + let tables = self.read().unwrap(); + let key = TableKey::new(schema, event.table); + let table = match tables.get(&key) { + Some(table) => Ok(table), + None => Err(DbError::TableNotFound(key)), + }?; + if !table.alive { + return Ok(()); + } + table.insert_fields_queries( + &event.columns, + &event.records, + from_address, + block_number, + transaction_hash, + queries, + ) + } + + pub fn handle_message( + &self, + schema: SchemaKey, + msg: &IntrospectMsg, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> DbResult<()> { + match msg { + IntrospectMsg::CreateTable(event) => self.create_table( + schema, + event.clone(), + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::UpdateTable(event) => self.update_table( + schema, + event.clone(), + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::AddColumns(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::DropColumns(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::RetypeColumns(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::RetypePrimary(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::RenameTable(_) + | IntrospectMsg::DropTable(_) + | IntrospectMsg::RenameColumns(_) + | IntrospectMsg::RenamePrimary(_) => Ok(()), + IntrospectMsg::InsertsFields(event) => self.insert_fields( + schema, + event, + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::DeleteRecords(_) | IntrospectMsg::DeletesFields(_) => Ok(()), + } + } +} diff --git a/crates/introspect-sql-sink/src/utils.rs b/crates/introspect-sql-sink/src/utils.rs new file mode 100644 index 00000000..9a68c4c4 --- /dev/null +++ b/crates/introspect-sql-sink/src/utils.rs @@ -0,0 +1,99 @@ +use starknet_types_core::felt::Felt; +use xxhash_rust::xxh3::Xxh3; + +pub fn truncate(s: &str, max_chars: usize) -> &str { + match s.char_indices().nth(max_chars) { + None => s, + Some((idx, _)) => &s[..idx], + } +} + +pub fn felt_to_schema(address: &Felt) -> String { + format!("{address:063x}") +} + +const ALLOWED_TYPE_NAME_CHARS: &str = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; + +fn parse_type_name(type_name: &str) -> String { + fn parse_char(c: char) -> char { + if ALLOWED_TYPE_NAME_CHARS.contains(c) { + c + } else { + '_' + } + } + type_name + .chars() + .take(31) + .map(parse_char) + .collect::() + .to_lowercase() +} + +pub trait HasherExt { + fn new_based(base: &T) -> Self; + fn type_name(&self, name: &str) -> String; + fn tuple_name(&self) -> String; + fn branch(&self, name: &T) -> Self; + fn branch_to_type_name(&self, leaf: &T, name: &str) -> String; +} + +impl HasherExt for Xxh3 { + fn new_based(base: &T) -> Self { + let mut hash = Xxh3::new(); + let bytes = base.as_bytes(); + hash.update(&(bytes.len() as u32).to_le_bytes()); + hash.update(&bytes); + hash + } + + fn type_name(&self, name: &str) -> String { + let hash = &format!("{:032x}", self.digest128())[..31]; + format!("{}_{}", parse_type_name(name), hash) + } + + fn tuple_name(&self) -> String { + self.type_name("tuple") + } + + fn branch(&self, name: &T) -> Xxh3 { + let mut hasher = self.clone(); + let bytes = name.as_bytes(); + hasher.update(&(bytes.len() as u32).to_le_bytes()); + hasher.update(&bytes); + hasher + } + + fn branch_to_type_name(&self, leaf: &T, name: &str) -> String { + self.branch(leaf).type_name(name) + } +} + +pub trait AsBytes { + fn as_bytes(&self) -> Vec; +} + +impl AsBytes for Felt { + fn as_bytes(&self) -> Vec { + self.to_bytes_be().to_vec() + } +} + +impl AsBytes for str { + fn as_bytes(&self) -> Vec { + str::as_bytes(self).to_vec() + } +} + +impl AsBytes for String { + fn as_bytes(&self) -> Vec { + self.as_bytes().to_vec() + } +} + +impl AsBytes for u32 { + fn as_bytes(&self) -> Vec { + self.to_le_bytes().to_vec() + } +} diff --git a/crates/introspect-sqlite-sink/Cargo.toml b/crates/introspect-sqlite-sink/Cargo.toml index 49bb9f3e..f0ad8059 100644 --- a/crates/introspect-sqlite-sink/Cargo.toml +++ b/crates/introspect-sqlite-sink/Cargo.toml @@ -29,7 +29,7 @@ introspect-types.workspace = true itertools.workspace = true torii-introspect.workspace = true -torii-sqlite.workspace = true +torii-sql = { workspace = true, features = ["sqlite"] } [lints] workspace = true diff --git a/crates/introspect-sqlite-sink/migrations/002_schema_state.sql b/crates/introspect-sqlite-sink/migrations/002_schema_state.sql index caa564d4..83df4af8 100644 --- a/crates/introspect-sqlite-sink/migrations/002_schema_state.sql +++ b/crates/introspect-sqlite-sink/migrations/002_schema_state.sql @@ -1,6 +1,8 @@ CREATE TABLE IF NOT EXISTS introspect_sink_schema_state ( - table_id TEXT PRIMARY KEY, + "schema" TEXT NOT NULL, + table_id TEXT NOT NULL, table_schema_json TEXT NOT NULL, alive INTEGER NOT NULL DEFAULT 1, - updated_at INTEGER NOT NULL DEFAULT (unixepoch()) + updated_at INTEGER NOT NULL DEFAULT (unixepoch()), + PRIMARY KEY ("schema", table_id) ); diff --git a/crates/introspect/Cargo.toml b/crates/introspect/Cargo.toml index 4e00c48e..729e4483 100644 --- a/crates/introspect/Cargo.toml +++ b/crates/introspect/Cargo.toml @@ -28,6 +28,7 @@ async-trait.workspace = true bigdecimal.workspace = true torii-common.workspace = true +torii-sql = { workspace = true, features = ["postgres", "sqlite"] } [build-dependencies] tonic-build = "0.12" diff --git a/crates/introspect/src/postgres/global.rs b/crates/introspect/src/postgres/global.rs index 41f23449..d651ce22 100644 --- a/crates/introspect/src/postgres/global.rs +++ b/crates/introspect/src/postgres/global.rs @@ -6,7 +6,7 @@ use itertools::Itertools; use sqlx::types::Json; use sqlx::{FromRow, PgPool}; use starknet_types_core::felt::Felt; -use torii_common::sql::SqlxResult; +use torii_sql::SqlxResult; use crate::postgres::{attribute_type, felt252_type, string_type, PgAttribute, PgFelt}; diff --git a/crates/introspect/src/postgres/owned.rs b/crates/introspect/src/postgres/owned.rs index c781c520..bc0c2521 100644 --- a/crates/introspect/src/postgres/owned.rs +++ b/crates/introspect/src/postgres/owned.rs @@ -10,7 +10,7 @@ use sqlx::types::Json; use sqlx::{FromRow, PgPool, Postgres}; use starknet_types_core::felt::Felt; use std::collections::HashMap; -use torii_common::sql::SqlxResult; +use torii_sql::SqlxResult; pub const TABLE_INSERT_QUERY: &str = " INSERT INTO introspect.tables (owner, id, name, attributes, primary_def, column_ids, updated_at, created_block, updated_block, created_tx, updated_tx) diff --git a/crates/postgres/Cargo.toml b/crates/postgres/Cargo.toml index 9624b2f6..c2ae223c 100644 --- a/crates/postgres/Cargo.toml +++ b/crates/postgres/Cargo.toml @@ -13,19 +13,5 @@ sqlx = { workspace = true, features = [ "macros", "migrate", ] } -anyhow.workspace = true -async-trait.workspace = true -xxhash-rust.workspace = true -hex.workspace = true -serde.workspace = true -serde_json.workspace = true -tokio.workspace = true -torii.workspace = true -tracing.workspace = true -starknet-types-core.workspace = true -thiserror.workspace = true futures.workspace = true -crc.workspace = true - - -torii-common.workspace = true +torii-sql.workspace = true diff --git a/crates/postgres/src/db.rs b/crates/postgres/src/db.rs deleted file mode 100644 index ef5d608d..00000000 --- a/crates/postgres/src/db.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::migration::SchemaMigrator; -use async_trait::async_trait; -use sqlx::{migrate::Migrator, Postgres}; -pub use sqlx::{PgPool, Transaction}; -use std::ops::Deref; -use torii_common::sql::{Executable, SqlxResult}; - -#[async_trait] -pub trait PostgresConnection { - fn pool(&self) -> &PgPool; - - async fn begin(&self) -> SqlxResult> { - Ok(self.pool().begin().await?) - } - async fn migrate(&self, schema: Option<&'static str>, migrator: Migrator) -> SqlxResult<()> { - let result = match schema { - Some(schema) => SchemaMigrator::new(schema, migrator).run(self.pool()).await, - None => migrator.run(self.pool()).await, - }; - Ok(result?) - } - async fn execute_queries(&self, queries: impl Executable + Send) -> SqlxResult<()> { - let mut transaction = self.begin().await?; - queries.execute(&mut transaction).await?; - transaction.commit().await - } -} - -#[allow(clippy::explicit_auto_deref)] -#[async_trait] -impl + Send + Sync + 'static> PostgresConnection for T { - fn pool(&self) -> &PgPool { - &**self - } -} diff --git a/crates/postgres/src/lib.rs b/crates/postgres/src/lib.rs index a2da4928..5ff2b5ce 100644 --- a/crates/postgres/src/lib.rs +++ b/crates/postgres/src/lib.rs @@ -1,4 +1,2 @@ -pub mod db; -pub mod metadata; pub mod migration; pub use db::PostgresConnection; diff --git a/crates/postgres/src/migration.rs b/crates/postgres/src/migration.rs index 9be9fce7..3c430c91 100644 --- a/crates/postgres/src/migration.rs +++ b/crates/postgres/src/migration.rs @@ -1,7 +1,7 @@ use futures::future::BoxFuture; use sqlx::{ migrate::{AppliedMigration, Migrate, MigrateError, Migration, MigrationSource, Migrator}, - query, query_scalar, Acquire, PgConnection, Postgres, + query, query_scalar, Acquire, Connection, Database, PgConnection, Postgres, }; use sqlx::{query_as, Executor}; use std::{ @@ -10,43 +10,12 @@ use std::{ slice, time::{Duration, Instant}, }; +use torii_sql::AcquiredSchema; -pub struct SchemaMigrator { - pub migrator: Migrator, - pub schema: &'static str, -} - -pub struct PgAcquiredSchema<'a, A> -where - A: Acquire<'a>, -{ - pub connection: >::Connection, - pub schema: &'static str, -} - -impl<'a, A> Deref for PgAcquiredSchema<'a, A> -where - A: Acquire<'a, Database = Postgres>, -{ - type Target = PgConnection; - fn deref(&self) -> &Self::Target { - &self.connection - } -} - -impl<'a, A> DerefMut for PgAcquiredSchema<'a, A> -where - A: Acquire<'a, Database = Postgres>, -{ - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.connection - } -} - -impl<'a, A> Migrate for PgAcquiredSchema<'a, A> +impl Migrate for AcquiredSchema where - A: Acquire<'a, Database = Postgres>, - A: Executor<'a, Database = Postgres>, + DB: Database, + C: Connection, { fn ensure_migrations_table(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { Box::pin(async move { @@ -279,165 +248,3 @@ async fn revert_migration( Ok(()) } - -impl SchemaMigrator { - pub const fn new(schema: &'static str, migrator: Migrator) -> Self { - Self { migrator, schema } - } - pub async fn new_from_source<'s, S>( - schema: &'static str, - source: S, - ) -> Result - where - S: MigrationSource<'s>, - { - Migrator::new(source) - .await - .map(|migrator| Self { migrator, schema }) - } - - /// Specify whether applied migrations that are missing from the resolved migrations should be ignored. - pub fn set_ignore_missing(&mut self, ignore_missing: bool) -> &Self { - self.migrator.ignore_missing = ignore_missing; - self - } - - /// Specify whether or not to lock the database during migration. Defaults to `true`. - /// - /// ### Warning - /// Disabling locking can lead to errors or data loss if multiple clients attempt to apply migrations simultaneously - /// without some sort of mutual exclusion. - /// - /// This should only be used if the database does not support locking, e.g. CockroachDB which talks the Postgres - /// protocol but does not support advisory locks used by SQLx's migrations support for Postgres. - pub fn set_locking(&mut self, locking: bool) -> &Self { - self.migrator.locking = locking; - self - } - - /// Get an iterator over all known migrations. - pub fn iter(&self) -> slice::Iter<'_, Migration> { - self.migrator.migrations.iter() - } - - /// Check if a migration version exists. - pub fn version_exists(&self, version: i64) -> bool { - self.iter().any(|m| m.version == version) - } - - /// Run any pending migrations against the database; and, validate previously applied migrations - /// against the current migration source to detect accidental changes in previously-applied migrations. - /// - /// # Examples - /// - /// ```rust,no_run - /// # use sqlx::migrate::MigrateError; - /// # fn main() -> Result<(), MigrateError> { - /// # sqlx::__rt::test_block_on(async move { - /// use sqlx::migrate::Migrator; - /// use sqlx::sqlite::SqlitePoolOptions; - /// - /// let m = Migrator::new(std::path::Path::new("./migrations")).await?; - /// let pool = SqlitePoolOptions::new().connect("sqlite::memory:").await?; - /// m.run(&pool).await - /// # }) - /// # } - /// ``` - pub async fn run<'a, A>(&self, migrator: A) -> Result<(), MigrateError> - where - A: Acquire<'a, Database = Postgres>, - PgAcquiredSchema<'a, A>: Migrate, - { - let mut conn = PgAcquiredSchema { - connection: migrator.acquire().await?, - schema: self.schema, - }; - self.migrator.run_direct(&mut conn).await - } - - /// Run down migrations against the database until a specific version. - /// - /// # Examples - /// - /// ```rust,no_run - /// # use sqlx::migrate::MigrateError; - /// # fn main() -> Result<(), MigrateError> { - /// # sqlx::__rt::test_block_on(async move { - /// use sqlx::migrate::Migrator; - /// use sqlx::sqlite::SqlitePoolOptions; - /// - /// let m = Migrator::new(std::path::Path::new("./migrations")).await?; - /// let pool = SqlitePoolOptions::new().connect("sqlite::memory:").await?; - /// m.undo(&pool, 4).await - /// # }) - /// # } - /// ``` - pub async fn undo<'a, A>(&self, migrator: A, target: i64) -> Result<(), MigrateError> - where - A: Acquire<'a, Database = Postgres>, - PgAcquiredSchema<'a, A>: Migrate, - { - let mut conn = PgAcquiredSchema { - connection: migrator.acquire().await?, - schema: self.schema, - }; - // lock the database for exclusive access by the migrator - if self.migrator.locking { - conn.lock().await?; - } - - // creates [_migrations] table only if needed - // eventually this will likely migrate previous versions of the table - conn.ensure_migrations_table().await?; - - let version = conn.dirty_version().await?; - if let Some(version) = version { - return Err(MigrateError::Dirty(version)); - } - - let applied_migrations = conn.list_applied_migrations().await?; - validate_applied_migrations(&applied_migrations, &self.migrator)?; - - let applied_migrations: HashMap<_, _> = applied_migrations - .into_iter() - .map(|m| (m.version, m)) - .collect(); - - for migration in self - .iter() - .rev() - .filter(|m| m.migration_type.is_down_migration()) - .filter(|m| applied_migrations.contains_key(&m.version)) - .filter(|m| m.version > target) - { - conn.revert(migration).await?; - } - - // unlock the migrator to allow other migrators to run - // but do nothing as we already migrated - if self.migrator.locking { - conn.unlock().await?; - } - - Ok(()) - } -} - -fn validate_applied_migrations( - applied_migrations: &[AppliedMigration], - migrator: &Migrator, -) -> Result<(), MigrateError> { - if migrator.ignore_missing { - return Ok(()); - } - - let migrations: HashSet<_> = migrator.iter().map(|m| m.version).collect(); - - for applied_migration in applied_migrations { - if !migrations.contains(&applied_migration.version) { - return Err(MigrateError::VersionMissing(applied_migration.version)); - } - } - - Ok(()) -} diff --git a/crates/sql/Cargo.toml b/crates/sql/Cargo.toml new file mode 100644 index 00000000..8d43fa41 --- /dev/null +++ b/crates/sql/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "torii-sql" +version = "0.1.0" +edition = "2021" +description = "Common utilities for Torii token indexers" + +[dependencies] +async-trait = "0.1" +sqlx = { workspace = true, features = ["runtime-tokio-rustls"] } +itertools.workspace = true +futures.workspace = true +crc.workspace = true + +[features] +postgres = ["sqlx/postgres"] +sqlite = ["sqlx/sqlite"] +mysql = ["sqlx/mysql"] + +[lints] +workspace = true diff --git a/crates/sql/src/connection.rs b/crates/sql/src/connection.rs new file mode 100644 index 00000000..db0628d9 --- /dev/null +++ b/crates/sql/src/connection.rs @@ -0,0 +1,45 @@ +use crate::{query::Executable, AcquiredSchema, SqlxResult}; +use async_trait::async_trait; +use sqlx::{ + migrate::{Migrate, Migrator}, + Database, Pool, Transaction, +}; +use std::ops::Deref; + +#[async_trait] +pub trait DbConnection { + fn pool(&self) -> &Pool; + async fn begin(&self) -> SqlxResult> { + Ok(self.pool().begin().await?) + } + async fn migrate(&self, schema: Option<&'static str>, migrator: Migrator) -> SqlxResult<()> + where + ::Connection: Migrate, + AcquiredSchema::Connection>: Migrate, + { + let result = match schema { + Some(schema) => { + let mut conn = AcquiredSchema { + connection: self.pool().acquire().await?.detach(), + schema: schema, + }; + migrator.run_direct(&mut conn).await + } + None => migrator.run(self.pool()).await, + }; + Ok(result?) + } + async fn execute_queries(&self, queries: impl Executable + Send) -> SqlxResult<()> { + let mut transaction: Transaction<'_, DB> = self.begin().await?; + queries.execute(&mut transaction).await?; + transaction.commit().await + } +} + +#[allow(clippy::explicit_auto_deref)] +#[async_trait] +impl> + Send + Sync + 'static> DbConnection for T { + fn pool(&self) -> &Pool { + &**self + } +} diff --git a/crates/sql/src/lib.rs b/crates/sql/src/lib.rs new file mode 100644 index 00000000..2553d821 --- /dev/null +++ b/crates/sql/src/lib.rs @@ -0,0 +1,19 @@ +pub mod connection; +pub mod migrate; +pub mod query; + +pub use connection::DbConnection; +pub use migrate::{AcquiredSchema, SchemaMigrator}; +pub use query::{Executable, FlexQuery, Queries}; + +pub use sqlx::Error as SqlxError; +pub type SqlxResult = std::result::Result; + +#[cfg(feature = "postgres")] +pub mod postgres; + +#[cfg(feature = "sqlite")] +pub mod sqlite; + +// #[cfg(feature = "mysql")] +// pub mod mysql; diff --git a/crates/sql/src/migrate.rs b/crates/sql/src/migrate.rs new file mode 100644 index 00000000..42093cdc --- /dev/null +++ b/crates/sql/src/migrate.rs @@ -0,0 +1,218 @@ +use sqlx::{ + migrate::{AppliedMigration, Migrate, MigrateError, Migration, MigrationSource, Migrator}, + Acquire, Connection, Database, +}; +use std::{ + collections::HashMap, + ops::{Deref, DerefMut}, +}; +use std::{collections::HashSet, slice}; + +pub struct SchemaMigrator { + pub migrator: Migrator, + pub schema: &'static str, +} + +pub struct AcquiredSchema +where + DB: Database, + C: Connection, +{ + pub connection: C, + pub schema: &'static str, +} + +impl Deref for AcquiredSchema +where + DB: Database, + C: Connection, +{ + type Target = C; + fn deref(&self) -> &Self::Target { + &self.connection + } +} + +impl DerefMut for AcquiredSchema +where + DB: Database, + C: Connection, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.connection + } +} + +impl AcquiredSchema +where + DB: Database, + C: Connection, +{ + pub fn new(connection: C, schema: &'static str) -> Self { + Self { connection, schema } + } +} + +impl SchemaMigrator { + pub const fn new(schema: &'static str, migrator: Migrator) -> Self { + Self { migrator, schema } + } + pub async fn new_from_source<'s, S>( + schema: &'static str, + source: S, + ) -> Result + where + S: MigrationSource<'s>, + { + Migrator::new(source) + .await + .map(|migrator| Self { migrator, schema }) + } + + /// Specify whether applied migrations that are missing from the resolved migrations should be ignored. + pub fn set_ignore_missing(&mut self, ignore_missing: bool) -> &Self { + self.migrator.ignore_missing = ignore_missing; + self + } + + /// Specify whether or not to lock the database during migration. Defaults to `true`. + /// + /// ### Warning + /// Disabling locking can lead to errors or data loss if multiple clients attempt to apply migrations simultaneously + /// without some sort of mutual exclusion. + /// + /// This should only be used if the database does not support locking, e.g. CockroachDB which talks the Postgres + /// protocol but does not support advisory locks used by SQLx's migrations support for Postgres. + pub fn set_locking(&mut self, locking: bool) -> &Self { + self.migrator.locking = locking; + self + } + + /// Get an iterator over all known migrations. + pub fn iter(&self) -> slice::Iter<'_, Migration> { + self.migrator.migrations.iter() + } + + /// Check if a migration version exists. + pub fn version_exists(&self, version: i64) -> bool { + self.iter().any(|m| m.version == version) + } + + /// Run any pending migrations against the database; and, validate previously applied migrations + /// against the current migration source to detect accidental changes in previously-applied migrations. + /// + /// # Examples + /// + /// ```rust,no_run + /// # use sqlx::migrate::MigrateError; + /// # fn main() -> Result<(), MigrateError> { + /// # sqlx::__rt::test_block_on(async move { + /// use sqlx::migrate::Migrator; + /// use sqlx::sqlite::SqlitePoolOptions; + /// + /// let m = Migrator::new(std::path::Path::new("./migrations")).await?; + /// let pool = SqlitePoolOptions::new().connect("sqlite::memory:").await?; + /// m.run(&pool).await + /// # }) + /// # } + /// ``` + pub async fn run<'a, A>(&self, migrator: A) -> Result<(), MigrateError> + where + A: Acquire<'a>, + >::Connection: Connection, + AcquiredSchema: Migrate, + { + let mut conn = AcquiredSchema { + connection: migrator.acquire().await?, + schema: self.schema, + }; + self.migrator.run_direct(&mut conn).await + } + + /// Run down migrations against the database until a specific version. + /// + /// # Examples + /// + /// ```rust,no_run + /// # use sqlx::migrate::MigrateError; + /// # fn main() -> Result<(), MigrateError> { + /// # sqlx::__rt::test_block_on(async move { + /// use sqlx::migrate::Migrator; + /// use sqlx::sqlite::SqlitePoolOptions; + /// + /// let m = Migrator::new(std::path::Path::new("./migrations")).await?; + /// let pool = SqlitePoolOptions::new().connect("sqlite::memory:").await?; + /// m.undo(&pool, 4).await + /// # }) + /// # } + /// ``` + pub async fn undo<'a, A>(&self, migrator: A, target: i64) -> Result<(), MigrateError> + where + A: Acquire<'a>, + >::Connection: Connection, + AcquiredSchema: Migrate, + { + let mut conn = AcquiredSchema:: { + connection: migrator.acquire().await?, + schema: self.schema, + }; + // lock the database for exclusive access by the migrator + if self.migrator.locking { + conn.lock().await?; + } + + // creates [_migrations] table only if needed + // eventually this will likely migrate previous versions of the table + conn.ensure_migrations_table().await?; + + let version = conn.dirty_version().await?; + if let Some(version) = version { + return Err(MigrateError::Dirty(version)); + } + + let applied_migrations = conn.list_applied_migrations().await?; + validate_applied_migrations(&applied_migrations, &self.migrator)?; + + let applied_migrations: HashMap<_, _> = applied_migrations + .into_iter() + .map(|m| (m.version, m)) + .collect(); + + for migration in self + .iter() + .rev() + .filter(|m| m.migration_type.is_down_migration()) + .filter(|m| applied_migrations.contains_key(&m.version)) + .filter(|m| m.version > target) + { + conn.revert(migration).await?; + } + + // unlock the migrator to allow other migrators to run + // but do nothing as we already migrated + if self.migrator.locking { + conn.unlock().await?; + } + + Ok(()) + } +} + +fn validate_applied_migrations( + applied_migrations: &[AppliedMigration], + migrator: &Migrator, +) -> Result<(), MigrateError> { + if migrator.ignore_missing { + return Ok(()); + } + + let migrations: HashSet<_> = migrator.iter().map(|m| m.version).collect(); + + for applied_migration in applied_migrations { + if !migrations.contains(&applied_migration.version) { + return Err(MigrateError::VersionMissing(applied_migration.version)); + } + } + + Ok(()) +} diff --git a/crates/sql/src/postgres.rs b/crates/sql/src/postgres.rs new file mode 100644 index 00000000..a38ae923 --- /dev/null +++ b/crates/sql/src/postgres.rs @@ -0,0 +1,241 @@ +use crate::{AcquiredSchema, FlexQuery}; +use futures::future::BoxFuture; +use sqlx::migrate::{AppliedMigration, Migrate, MigrateError, Migration}; +use sqlx::{query, query_scalar, Connection, PgConnection, Postgres}; +use sqlx::{query_as, Executor}; +use std::time::{Duration, Instant}; + +pub type PgQuery = FlexQuery; + +impl Migrate for AcquiredSchema { + fn ensure_migrations_table(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { + Box::pin(async move { + // language=SQL + self.connection + .execute( + format!( + r#" +CREATE SCHEMA IF NOT EXISTS {schema}; +CREATE TABLE IF NOT EXISTS {schema}._sqlx_migrations ( + version BIGINT PRIMARY KEY, + description TEXT NOT NULL, + installed_on TIMESTAMPTZ NOT NULL DEFAULT now(), + success BOOLEAN NOT NULL, + checksum BYTEA NOT NULL, + execution_time BIGINT NOT NULL +); + "#, + schema = self.schema + ) + .as_str(), + ) + .await?; + + Ok(()) + }) + } + + fn dirty_version(&mut self) -> BoxFuture<'_, Result, MigrateError>> { + Box::pin(async move { + // language=SQL + + let row: Option<(i64,)> = query_as( + format!("SELECT version FROM {schema}._sqlx_migrations WHERE success = false ORDER BY version LIMIT 1", schema = self.schema).as_str() + ) + .fetch_optional(&mut self.connection) + .await?; + + Ok(row.map(|r: (i64,)| r.0)) + }) + } + + fn list_applied_migrations( + &mut self, + ) -> BoxFuture<'_, Result, MigrateError>> { + Box::pin(async move { + // language=SQL + let rows: Vec<(i64, Vec)> = query_as( + format!( + "SELECT version, checksum FROM {schema}._sqlx_migrations ORDER BY version", + schema = self.schema + ) + .as_str(), + ) + .fetch_all(&mut self.connection) + .await?; + + let migrations = rows + .into_iter() + .map(|(version, checksum)| AppliedMigration { + version, + checksum: checksum.into(), + }) + .collect(); + + Ok(migrations) + }) + } + + fn lock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { + Box::pin(async move { + let database_name = current_database(&mut self.connection).await?; + let lock_id = generate_lock_id(&database_name); + + // create an application lock over the database + // this function will not return until the lock is acquired + + // https://www.postgresql.org/docs/current/explicit-locking.html#ADVISORY-LOCKS + // https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS-TABLE + + // language=SQL + let _ = query("SELECT pg_advisory_lock($1)") + .bind(lock_id) + .execute(&mut self.connection) + .await?; + + Ok(()) + }) + } + + fn unlock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { + Box::pin(async move { + let database_name = current_database(self).await?; + let lock_id = generate_lock_id(&database_name); + + // language=SQL + let _ = query("SELECT pg_advisory_unlock($1)") + .bind(lock_id) + .execute(&mut self.connection) + .await?; + + Ok(()) + }) + } + + fn apply<'e: 'm, 'm>( + &'e mut self, + migration: &'m Migration, + ) -> BoxFuture<'m, Result> { + Box::pin(async move { + let start = Instant::now(); + let schema = self.schema; + // execute migration queries + if migration.no_tx { + execute_migration(self, schema, migration).await?; + } else { + // Use a single transaction for the actual migration script and the essential bookeeping so we never + // execute migrations twice. See https://github.com/launchbadge/sqlx/issues/1966. + // The `execution_time` however can only be measured for the whole transaction. This value _only_ exists for + // data lineage and debugging reasons, so it is not super important if it is lost. So we initialize it to -1 + // and update it once the actual transaction completed. + let mut tx = Connection::begin(&mut self.connection).await?; + execute_migration(&mut tx, schema, migration).await?; + tx.commit().await?; + } + + // Update `elapsed_time`. + // NOTE: The process may disconnect/die at this point, so the elapsed time value might be lost. We accept + // this small risk since this value is not super important. + let elapsed = start.elapsed(); + + // language=SQL + #[allow(clippy::cast_possible_truncation)] + let _ = query(&format!( + r#" + UPDATE {schema}._sqlx_migrations + SET execution_time = $1 + WHERE version = $2 + "#, + schema = self.schema + )) + .bind(elapsed.as_nanos() as i64) + .bind(migration.version) + .execute(&mut self.connection) + .await?; + + Ok(elapsed) + }) + } + + fn revert<'e: 'm, 'm>( + &'e mut self, + migration: &'m Migration, + ) -> BoxFuture<'m, Result> { + Box::pin(async move { + let start = Instant::now(); + let schema = self.schema; + // execute migration queries + if migration.no_tx { + revert_migration(&mut self.connection, schema, migration).await?; + } else { + // Use a single transaction for the actual migration script and the essential bookeeping so we never + // execute migrations twice. See https://github.com/launchbadge/sqlx/issues/1966. + let mut tx = Connection::begin(&mut self.connection).await?; + revert_migration(&mut tx, schema, migration).await?; + tx.commit().await?; + } + + let elapsed = start.elapsed(); + + Ok(elapsed) + }) + } +} + +async fn current_database(conn: &mut PgConnection) -> Result { + // language=SQL + Ok(query_scalar("SELECT current_database()") + .fetch_one(conn) + .await?) +} + +fn generate_lock_id(database_name: &str) -> i64 { + const CRC_IEEE: crc::Crc = crc::Crc::::new(&crc::CRC_32_ISO_HDLC); + // 0x3d32ad9e chosen by fair dice roll + 0x3d32ad9e * (CRC_IEEE.checksum(database_name.as_bytes()) as i64) +} + +async fn execute_migration( + conn: &mut PgConnection, + schema: &'static str, + migration: &Migration, +) -> Result<(), MigrateError> { + let _ = conn + .execute(&*migration.sql) + .await + .map_err(|e| MigrateError::ExecuteMigration(e, migration.version))?; + + // language=SQL + let _ = query( + format!(r#" + INSERT INTO {schema}._sqlx_migrations ( version, description, success, checksum, execution_time ) + VALUES ( $1, $2, TRUE, $3, -1 ) + "#).as_str() + ) + .bind(migration.version) + .bind(&*migration.description) + .bind(&*migration.checksum) + .execute(conn) + .await?; + + Ok(()) +} + +async fn revert_migration( + conn: &mut PgConnection, + schema: &'static str, + migration: &Migration, +) -> Result<(), MigrateError> { + let _ = conn + .execute(&*migration.sql) + .await + .map_err(|e| MigrateError::ExecuteMigration(e, migration.version))?; + + // language=SQL + let _ = query(format!(r#"DELETE FROM {schema}._sqlx_migrations WHERE version = $1"#).as_str()) + .bind(migration.version) + .execute(conn) + .await?; + + Ok(()) +} diff --git a/crates/torii-common/src/sql.rs b/crates/sql/src/query.rs similarity index 74% rename from crates/torii-common/src/sql.rs rename to crates/sql/src/query.rs index 531adaf0..6571095a 100644 --- a/crates/torii-common/src/sql.rs +++ b/crates/sql/src/query.rs @@ -1,23 +1,20 @@ use async_trait::async_trait; use itertools::Itertools; -use sqlx::{Database, Executor, Postgres}; -pub use sqlx::{PgPool, Transaction}; +use sqlx::{Database, Executor, Transaction}; use std::borrow::Cow; use std::sync::Arc; -pub use sqlx::Error as SqlxError; - -pub type SqlxResult = std::result::Result; +use crate::SqlxResult; #[async_trait] -pub trait Executable { +pub trait Executable { async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()>; } #[async_trait] -impl Executable for &str +impl Executable for &str where - for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, + for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { transaction.execute(self).await?; @@ -26,9 +23,9 @@ where } #[async_trait] -impl Executable for &String +impl Executable for &String where - for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, + for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { transaction.execute(self.as_str()).await?; @@ -37,9 +34,9 @@ where } #[async_trait] -impl Executable for String +impl Executable for String where - for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, + for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { transaction.execute(self.as_str()).await?; @@ -48,9 +45,9 @@ where } #[async_trait] -impl Executable for Cow<'_, str> +impl Executable for Cow<'_, str> where - for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, + for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { transaction.execute(self.as_ref()).await?; @@ -77,9 +74,9 @@ impl, DB: Database> QueryLike { } #[async_trait] -impl Executable for FlexStr +impl Executable for FlexStr where - for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, + for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { transaction.execute(self.as_ref()).await?; @@ -172,9 +169,9 @@ impl Queries for Vec> { } #[async_trait] -impl Executable for &[String; N] +impl Executable for &[String; N] where - for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, + for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { for query in self { @@ -185,7 +182,7 @@ where } #[async_trait] -impl + Send> Executable for Vec { +impl + Send> Executable for Vec { async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { for item in self { item.execute(transaction).await?; @@ -195,7 +192,7 @@ impl + Send> Executable for Vec { } #[async_trait] -impl<'a, DB: sqlx::Database, T> Executable for &'a Vec +impl<'a, DB: Database, T> Executable for &'a Vec where &'a T: Executable + Send, T: Send + Sync, @@ -209,7 +206,7 @@ where } #[async_trait] -impl<'a, DB: sqlx::Database, T> Executable for &'a [T] +impl<'a, DB: Database, T> Executable for &'a [T] where &'a T: Executable + Send, T: Send + Sync, @@ -223,10 +220,10 @@ where } #[async_trait] -impl + Send, DB: sqlx::Database> Executable for QueryLike +impl + Send, DB: Database> Executable for QueryLike where - for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, - for<'q> ::Arguments<'static>: sqlx::IntoArguments<'q, DB>, + for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, + for<'q> ::Arguments<'static>: sqlx::IntoArguments<'q, DB>, { async fn execute(mut self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { let sql = self.sql.as_ref(); @@ -236,6 +233,4 @@ where } } -pub type PgQuery = QueryLike; -pub type MySqlQuery = QueryLike; -pub type SqliteQuery = QueryLike; +pub type FlexQuery = QueryLike; diff --git a/crates/sql/src/sqlite.rs b/crates/sql/src/sqlite.rs new file mode 100644 index 00000000..70fca0bd --- /dev/null +++ b/crates/sql/src/sqlite.rs @@ -0,0 +1,189 @@ +use crate::{AcquiredSchema, FlexQuery}; +use futures::future::BoxFuture; +use sqlx::migrate::{AppliedMigration, Migrate, MigrateError, Migration}; +use sqlx::sqlite::SqliteConnectOptions; +use sqlx::{query, query_as, Acquire, Executor, Sqlite, SqliteConnection}; +use std::borrow::Cow; +use std::str::FromStr; +use std::time::{Duration, Instant}; + +pub type SqliteQuery = FlexQuery; + +impl AcquiredSchema { + fn table_name(&self) -> Cow<'static, str> { + Cow::Owned(format!("_sqlx_migrations_{}", self.schema)) + } +} + +impl Migrate for AcquiredSchema { + fn ensure_migrations_table(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { + Box::pin(async move { + let table_name = self.table_name(); + self.connection + .execute( + format!( + r#" +CREATE TABLE IF NOT EXISTS "{table_name}" ( + version BIGINT PRIMARY KEY, + description TEXT NOT NULL, + installed_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + success BOOLEAN NOT NULL, + checksum BLOB NOT NULL, + execution_time BIGINT NOT NULL +); + "# + ) + .as_str(), + ) + .await?; + + Ok(()) + }) + } + + fn dirty_version(&mut self) -> BoxFuture<'_, Result, MigrateError>> { + Box::pin(async move { + let table_name = self.table_name(); + let row: Option<(i64,)> = query_as( + format!( + r#"SELECT version FROM "{table_name}" WHERE success = false ORDER BY version LIMIT 1"# + ) + .as_str(), + ) + .fetch_optional(&mut self.connection) + .await?; + + Ok(row.map(|row| row.0)) + }) + } + + fn list_applied_migrations( + &mut self, + ) -> BoxFuture<'_, Result, MigrateError>> { + Box::pin(async move { + let table_name = self.table_name(); + let rows: Vec<(i64, Vec)> = query_as( + format!(r#"SELECT version, checksum FROM "{table_name}" ORDER BY version"#) + .as_str(), + ) + .fetch_all(&mut self.connection) + .await?; + + Ok(rows + .into_iter() + .map(|(version, checksum)| AppliedMigration { + version, + checksum: checksum.into(), + }) + .collect()) + }) + } + + fn lock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { + Box::pin(async move { Ok(()) }) + } + + fn unlock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { + Box::pin(async move { Ok(()) }) + } + + fn apply<'e: 'm, 'm>( + &'e mut self, + migration: &'m Migration, + ) -> BoxFuture<'m, Result> { + Box::pin(async move { + let table_name = self.table_name(); + let mut tx = self.begin().await?; + let start = Instant::now(); + + let _ = tx + .execute(&*migration.sql) + .await + .map_err(|e| MigrateError::ExecuteMigration(e, migration.version))?; + + let _ = query( + format!( + r#" +INSERT INTO "{table_name}" (version, description, success, checksum, execution_time) +VALUES (?1, ?2, TRUE, ?3, -1) + "# + ) + .as_str(), + ) + .bind(migration.version) + .bind(&*migration.description) + .bind(&*migration.checksum) + .execute(&mut *tx) + .await?; + + tx.commit().await?; + + let elapsed = start.elapsed(); + + #[allow(clippy::cast_possible_truncation)] + let _ = query( + format!( + r#" +UPDATE "{table_name}" +SET execution_time = ?1 +WHERE version = ?2 + "# + ) + .as_str(), + ) + .bind(elapsed.as_nanos() as i64) + .bind(migration.version) + .execute(&mut self.connection) + .await?; + + Ok(elapsed) + }) + } + + fn revert<'e: 'm, 'm>( + &'e mut self, + migration: &'m Migration, + ) -> BoxFuture<'m, Result> { + Box::pin(async move { + let table_name = self.table_name(); + let mut tx = self.begin().await?; + let start = Instant::now(); + + let _ = tx.execute(&*migration.sql).await?; + + let _ = query(format!(r#"DELETE FROM "{table_name}" WHERE version = ?1"#).as_str()) + .bind(migration.version) + .execute(&mut *tx) + .await?; + + tx.commit().await?; + + Ok(start.elapsed()) + }) + } +} + +pub fn is_sqlite_memory_path(path: &str) -> bool { + path == ":memory:" + || path == "sqlite::memory:" + || path == "sqlite://:memory:" + || path.contains("mode=memory") +} + +pub fn sqlite_connect_options(path: &str) -> Result { + if path == ":memory:" || path == "sqlite::memory:" { + return SqliteConnectOptions::from_str("sqlite::memory:"); + } + + let options = if path.starts_with("sqlite:") { + SqliteConnectOptions::from_str(path)? + } else { + SqliteConnectOptions::new().filename(path) + }; + + if path.starts_with("sqlite:") && path.contains("mode=") { + Ok(options) + } else { + Ok(options.create_if_missing(true)) + } +} diff --git a/crates/sqlite/Cargo.toml b/crates/sqlite/Cargo.toml index 08f62825..576e3b6a 100644 --- a/crates/sqlite/Cargo.toml +++ b/crates/sqlite/Cargo.toml @@ -13,7 +13,7 @@ sqlx = { workspace = true, features = [ "migrate", ] } -torii-common.workspace = true +torii-sql.workspace = true [lints] workspace = true diff --git a/crates/sqlite/src/db.rs b/crates/sqlite/src/db.rs index c9f4a200..e1c5989c 100644 --- a/crates/sqlite/src/db.rs +++ b/crates/sqlite/src/db.rs @@ -6,7 +6,7 @@ use sqlx::migrate::Migrator; use sqlx::sqlite::SqliteConnectOptions; use sqlx::Sqlite; pub use sqlx::{SqlitePool, Transaction}; -use torii_common::sql::SqlxResult; +use torii_sql::SqlxResult; use crate::migration::NamespaceMigrator; diff --git a/crates/torii-common/src/lib.rs b/crates/torii-common/src/lib.rs index 5a96b8dc..497cbb9a 100644 --- a/crates/torii-common/src/lib.rs +++ b/crates/torii-common/src/lib.rs @@ -5,7 +5,6 @@ pub mod json; pub mod metadata; -pub mod sql; pub mod token_uri; pub mod utils; From 1645a56f538097b6b1d3f255a6bbf1c1f6df5aee Mon Sep 17 00:00:00 2001 From: MartianGreed Date: Mon, 23 Mar 2026 16:07:44 +0100 Subject: [PATCH 04/21] fix(introspect-sqlite): improve type mapping --- Cargo.lock | 2 + bins/torii-arcade/src/main.rs | 9 +- bins/torii-erc20-synth/src/main.rs | 2 +- bins/torii-introspect-bin/src/main.rs | 24 +- bins/torii-tokens-synth/src/main.rs | 2 +- crates/introspect-sqlite-sink/Cargo.toml | 1 + crates/introspect-sqlite-sink/src/json.rs | 23 + .../introspect-sqlite-sink/src/processor.rs | 399 +++- crates/introspect-sqlite-sink/src/sink.rs | 11 +- crates/torii-common/src/metadata.rs | 3 +- crates/torii-ecs-sink/Cargo.toml | 1 + crates/torii-ecs-sink/src/grpc_service.rs | 1659 +++++++++++++++-- crates/torii-ecs-sink/src/sink.rs | 20 +- crates/torii-erc1155/src/storage.rs | 206 +- crates/torii-erc20/proto/erc20.proto | 2 + .../src/generated/erc20_descriptor.bin | Bin 14985 -> 15174 bytes .../src/generated/torii.sinks.erc20.rs | 3 + crates/torii-erc20/src/grpc_service.rs | 6 +- crates/torii-erc20/src/handlers.rs | 4 +- crates/torii-erc20/src/storage.rs | 285 +-- crates/torii-erc721/src/handlers.rs | 1 - crates/torii-erc721/src/storage.rs | 171 +- 22 files changed, 2274 insertions(+), 560 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61873410..3165c394 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4751,6 +4751,7 @@ dependencies = [ "introspect-types", "metrics", "num-bigint", + "primitive-types 0.14.0", "prost 0.13.5", "prost-types 0.13.5", "serde", @@ -4971,6 +4972,7 @@ dependencies = [ "introspect-types", "itertools 0.14.0", "metrics", + "primitive-types 0.14.0", "serde", "serde_json", "sqlx", diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index f1ace2e0..acc3ba05 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -321,7 +321,14 @@ async fn run_indexer(config: Config) -> Result<()> { } }; - let ecs_sink = EcsSink::new(&storage_database_url, config.max_db_connections).await?; + let ecs_sink = EcsSink::new( + &storage_database_url, + config.max_db_connections, + Some(erc20_db_url.as_str()), + Some(erc721_db_url.as_str()), + Some(erc1155_db_url.as_str()), + ) + .await?; let ecs_grpc_service = ecs_sink.get_grpc_service_impl(); let arcade_sink = ArcadeSink::new( &storage_database_url, diff --git a/bins/torii-erc20-synth/src/main.rs b/bins/torii-erc20-synth/src/main.rs index 401d0eda..fbd4eb2c 100644 --- a/bins/torii-erc20-synth/src/main.rs +++ b/bins/torii-erc20-synth/src/main.rs @@ -55,7 +55,7 @@ impl CommandHandler for SyntheticErc20MetadataCommandHandler { let symbol = format!("S{suffix}"); self.storage - .upsert_token_metadata(command.token, Some(&name), Some(&symbol), Some(18)) + .upsert_token_metadata(command.token, Some(&name), Some(&symbol), Some(18), None) .await } } diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index c7143f58..8e15f918 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -481,7 +481,17 @@ async fn run_with_postgres( let decoder: Arc = Arc::new(decoder); - let ecs_sink = EcsSink::new(storage_database_url, config.max_db_connections).await?; + let erc20_url = token_db_setup.as_ref().filter(|_| !token_targets.erc20.is_empty()).map(|s| s.erc20_url.as_str()); + let erc721_url = token_db_setup.as_ref().filter(|_| !token_targets.erc721.is_empty()).map(|s| s.erc721_url.as_str()); + let erc1155_url = token_db_setup.as_ref().filter(|_| !token_targets.erc1155.is_empty()).map(|s| s.erc1155_url.as_str()); + let ecs_sink = EcsSink::new( + storage_database_url, + config.max_db_connections, + erc20_url, + erc721_url, + erc1155_url, + ) + .await?; let ecs_grpc_service = ecs_sink.get_grpc_service_impl(); let reflection_builder = ReflectionBuilder::configure() @@ -627,7 +637,17 @@ async fn run_with_sqlite( let decoder: Arc = Arc::new(decoder); - let ecs_sink = EcsSink::new(storage_database_url, config.max_db_connections).await?; + let erc20_url = token_db_setup.as_ref().filter(|_| !token_targets.erc20.is_empty()).map(|s| s.erc20_url.as_str()); + let erc721_url = token_db_setup.as_ref().filter(|_| !token_targets.erc721.is_empty()).map(|s| s.erc721_url.as_str()); + let erc1155_url = token_db_setup.as_ref().filter(|_| !token_targets.erc1155.is_empty()).map(|s| s.erc1155_url.as_str()); + let ecs_sink = EcsSink::new( + storage_database_url, + config.max_db_connections, + erc20_url, + erc721_url, + erc1155_url, + ) + .await?; let ecs_grpc_service = ecs_sink.get_grpc_service_impl(); let reflection_builder = ReflectionBuilder::configure() diff --git a/bins/torii-tokens-synth/src/main.rs b/bins/torii-tokens-synth/src/main.rs index 94c79e67..792c4a14 100644 --- a/bins/torii-tokens-synth/src/main.rs +++ b/bins/torii-tokens-synth/src/main.rs @@ -114,7 +114,7 @@ impl CommandHandler for SyntheticErc20MetadataCommandHandler { let name = format!("Synthetic ERC20 {suffix}"); let symbol = format!("S{suffix}"); self.storage - .upsert_token_metadata(command.token, Some(&name), Some(&symbol), Some(18)) + .upsert_token_metadata(command.token, Some(&name), Some(&symbol), Some(18), None) .await } } diff --git a/crates/introspect-sqlite-sink/Cargo.toml b/crates/introspect-sqlite-sink/Cargo.toml index 49bb9f3e..6113d553 100644 --- a/crates/introspect-sqlite-sink/Cargo.toml +++ b/crates/introspect-sqlite-sink/Cargo.toml @@ -27,6 +27,7 @@ starknet-types-core.workspace = true thiserror.workspace = true introspect-types.workspace = true itertools.workspace = true +primitive-types.workspace = true torii-introspect.workspace = true torii-sqlite.workspace = true diff --git a/crates/introspect-sqlite-sink/src/json.rs b/crates/introspect-sqlite-sink/src/json.rs index 64c4668e..a4ca3c65 100644 --- a/crates/introspect-sqlite-sink/src/json.rs +++ b/crates/introspect-sqlite-sink/src/json.rs @@ -1,6 +1,7 @@ use introspect_types::serialize::ToCairoDeSeFrom; use introspect_types::serialize_def::CairoTypeSerialization; use introspect_types::{CairoDeserializer, ResultDef, TupleDef, TypeDef}; +use primitive_types::{U256, U512}; use serde::ser::SerializeMap; use serde::Serializer; @@ -31,6 +32,28 @@ impl CairoTypeSerialization for SqliteJsonSerializer { self.serialize_byte_array(serializer, value) } + fn serialize_u256( + &self, + serializer: S, + value: U256, + ) -> Result { + let U256([a, b, c, d]) = value; + let corrected = U256([d, c, b, a]); + let bytes = corrected.to_big_endian(); + self.serialize_byte_array(serializer, &bytes) + } + + fn serialize_u512( + &self, + serializer: S, + value: U512, + ) -> Result { + let U512([a, b, c, d, e, f, g, h]) = value; + let corrected = U512([h, g, f, e, d, c, b, a]); + let bytes = corrected.to_big_endian(); + self.serialize_byte_array(serializer, &bytes) + } + fn serialize_tuple<'a, S: Serializer>( &'a self, data: &mut impl CairoDeserializer, diff --git a/crates/introspect-sqlite-sink/src/processor.rs b/crates/introspect-sqlite-sink/src/processor.rs index 4eaaf92a..6297dfd9 100644 --- a/crates/introspect-sqlite-sink/src/processor.rs +++ b/crates/introspect-sqlite-sink/src/processor.rs @@ -1,6 +1,7 @@ use crate::json::SqliteJsonSerializer; use crate::table::{SqliteTable, SqliteTableError}; use crate::INTROSPECT_SQLITE_SINK_MIGRATIONS; +use introspect_types::{PrimaryTypeDef, TypeDef}; use serde_json::{Serializer as JsonSerializer, Value}; use sqlx::Error as SqlxError; use sqlx::Row; @@ -11,6 +12,7 @@ use std::ops::Deref; use std::sync::{PoisonError, RwLock}; use torii::etl::envelope::MetaData; use torii_introspect::events::{IntrospectBody, IntrospectMsg}; +use torii::etl::EventMsg; use torii_introspect::schema::TableSchema; use torii_introspect::InsertsFields; use torii_sqlite::SqliteConnection; @@ -137,12 +139,89 @@ impl SqliteTables { } } +fn sqlite_column_type(type_def: &TypeDef) -> &'static str { + match type_def { + TypeDef::Bool + | TypeDef::I8 + | TypeDef::I16 + | TypeDef::I32 + | TypeDef::U8 + | TypeDef::U16 + | TypeDef::U32 => "INTEGER", + + TypeDef::I64 + | TypeDef::U64 + | TypeDef::U128 + | TypeDef::I128 + | TypeDef::U256 + | TypeDef::U512 + | TypeDef::Felt252 + | TypeDef::ClassHash + | TypeDef::ContractAddress + | TypeDef::StorageAddress + | TypeDef::StorageBaseAddress + | TypeDef::EthAddress => "TEXT", + + TypeDef::Struct(_) + | TypeDef::Enum(_) + | TypeDef::Tuple(_) + | TypeDef::Array(_) + | TypeDef::FixedArray(_) + | TypeDef::Option(_) + | TypeDef::Nullable(_) + | TypeDef::Result(_) => "JSONB", + + _ => "TEXT", + } +} + +fn sqlite_primary_type(type_def: &PrimaryTypeDef) -> &'static str { + match type_def { + PrimaryTypeDef::Bool + | PrimaryTypeDef::I8 + | PrimaryTypeDef::I16 + | PrimaryTypeDef::I32 + | PrimaryTypeDef::U8 + | PrimaryTypeDef::U16 + | PrimaryTypeDef::U32 => "INTEGER", + + PrimaryTypeDef::I64 + | PrimaryTypeDef::U64 + | PrimaryTypeDef::U128 + | PrimaryTypeDef::I128 + | PrimaryTypeDef::Felt252 + | PrimaryTypeDef::ClassHash + | PrimaryTypeDef::ContractAddress + | PrimaryTypeDef::StorageAddress + | PrimaryTypeDef::StorageBaseAddress + | PrimaryTypeDef::EthAddress => "TEXT", + + _ => "TEXT", + } +} + +fn is_json_type(type_def: &TypeDef) -> bool { + matches!( + type_def, + TypeDef::Struct(_) + | TypeDef::Enum(_) + | TypeDef::Tuple(_) + | TypeDef::Array(_) + | TypeDef::FixedArray(_) + | TypeDef::Option(_) + | TypeDef::Nullable(_) + | TypeDef::Result(_) + ) +} + fn create_table_query(table: &SqliteTable) -> String { + let primary_type = sqlite_primary_type(&table.primary.type_def); let mut columns = Vec::with_capacity(table.columns.len() + 1); - columns.push(format!(r#""{}" TEXT PRIMARY KEY"#, table.primary.name)); + columns.push(format!(r#""{}" {primary_type} PRIMARY KEY"#, table.primary.name)); for column_id in &table.order { let column = &table.columns[column_id]; - columns.push(format!(r#""{}" TEXT"#, column.name)); + let col_type = sqlite_column_type(&column.type_def); + columns.push(format!(r#""{}" {col_type}"#, column.name)); } format!( r#"CREATE TABLE IF NOT EXISTS "{}" ({});"#, @@ -151,11 +230,153 @@ fn create_table_query(table: &SqliteTable) -> String { ) } -fn serialize_sqlite_value(value: &Value) -> Option { - match value { - Value::Null => None, - Value::String(value) => Some(value.clone()), - _ => Some(value.to_string()), +enum SqliteBindValue { + Null, + Integer(i64), + Text(String), +} + +fn to_bind_value(value: &Value, type_def: &TypeDef) -> SqliteBindValue { + if value.is_null() { + return SqliteBindValue::Null; + } + + match type_def { + TypeDef::Bool => match value.as_bool() { + Some(b) => SqliteBindValue::Integer(i64::from(b)), + None => SqliteBindValue::Null, + }, + TypeDef::I8 | TypeDef::I16 | TypeDef::I32 | TypeDef::U8 | TypeDef::U16 + | TypeDef::U32 => match value.as_i64() { + Some(n) => SqliteBindValue::Integer(n), + None => SqliteBindValue::Null, + }, + TypeDef::U64 => match value.as_u64() { + Some(n) => SqliteBindValue::Text(format!("0x{:x}", n)), + None => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + }, + TypeDef::I64 => match value.as_i64() { + Some(n) => SqliteBindValue::Text(format!("0x{:x}", n)), + None => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + }, + + TypeDef::Felt252 + | TypeDef::ClassHash + | TypeDef::ContractAddress + | TypeDef::StorageAddress + | TypeDef::StorageBaseAddress + | TypeDef::EthAddress => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + + TypeDef::U256 | TypeDef::U512 => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + + TypeDef::U128 => match value.as_u64() { + Some(n) => SqliteBindValue::Text(format!("0x{:032x}", n as u128)), + None => match value.as_str() { + Some(s) => match s.parse::() { + Ok(n) => SqliteBindValue::Text(format!("0x{:032x}", n)), + Err(_) => SqliteBindValue::Text(s.to_string()), + }, + None => SqliteBindValue::Null, + }, + }, + TypeDef::I128 => match value.as_i64() { + Some(n) => SqliteBindValue::Text(format!("{}", n as i128)), + None => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + }, + + TypeDef::Struct(_) + | TypeDef::Enum(_) + | TypeDef::Tuple(_) + | TypeDef::Array(_) + | TypeDef::FixedArray(_) + | TypeDef::Option(_) + | TypeDef::Nullable(_) + | TypeDef::Result(_) => SqliteBindValue::Text(value.to_string()), + + _ => match value { + Value::String(s) => SqliteBindValue::Text(s.clone()), + _ => SqliteBindValue::Text(value.to_string()), + }, + } +} + +fn primary_to_bind_value(value: &Value, type_def: &PrimaryTypeDef) -> SqliteBindValue { + if value.is_null() { + return SqliteBindValue::Null; + } + + match type_def { + PrimaryTypeDef::Bool => match value.as_bool() { + Some(b) => SqliteBindValue::Integer(i64::from(b)), + None => SqliteBindValue::Null, + }, + PrimaryTypeDef::I8 | PrimaryTypeDef::I16 | PrimaryTypeDef::I32 | PrimaryTypeDef::U8 + | PrimaryTypeDef::U16 | PrimaryTypeDef::U32 => match value.as_i64() { + Some(n) => SqliteBindValue::Integer(n), + None => SqliteBindValue::Null, + }, + PrimaryTypeDef::U64 => match value.as_u64() { + Some(n) => SqliteBindValue::Text(format!("0x{:x}", n)), + None => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + }, + PrimaryTypeDef::I64 => match value.as_i64() { + Some(n) => SqliteBindValue::Text(format!("0x{:x}", n)), + None => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + }, + + PrimaryTypeDef::Felt252 + | PrimaryTypeDef::ClassHash + | PrimaryTypeDef::ContractAddress + | PrimaryTypeDef::StorageAddress + | PrimaryTypeDef::StorageBaseAddress + | PrimaryTypeDef::EthAddress => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + + PrimaryTypeDef::U128 => match value.as_u64() { + Some(n) => SqliteBindValue::Text(format!("0x{:032x}", n as u128)), + None => match value.as_str() { + Some(s) => match s.parse::() { + Ok(n) => SqliteBindValue::Text(format!("0x{:032x}", n)), + Err(_) => SqliteBindValue::Text(s.to_string()), + }, + None => SqliteBindValue::Null, + }, + }, + PrimaryTypeDef::I128 => match value.as_i64() { + Some(n) => SqliteBindValue::Text(format!("{}", n as i128)), + None => match value.as_str() { + Some(s) => SqliteBindValue::Text(s.to_string()), + None => SqliteBindValue::Null, + }, + }, + + _ => match value { + Value::String(s) => SqliteBindValue::Text(s.clone()), + _ => SqliteBindValue::Text(value.to_string()), + }, } } @@ -250,6 +471,50 @@ impl IntrospectSqliteDb { Ok(()) } + async fn update_table( + &self, + event: impl Into, + ) -> SqliteDbResult<()> { + let table_schema: TableSchema = event.into(); + let id = table_schema.id; + let exists_in_memory = self.tables.read()?.contains_key(&id); + + if !exists_in_memory { + let (_, query) = self.tables.create_table(&self.namespace, table_schema.clone())?; + self.execute_queries(&[query]).await?; + self.persist_table_state(&table_schema, true).await?; + return Ok(()); + } + + let (old_columns, storage_name) = { + let tables = self.tables.read()?; + let old = tables.get(&id).unwrap(); + (old.columns.clone(), old.storage_name.clone()) + }; + + let (_, new_table) = + SqliteTable::new_from_table(self.namespace.prefix(), table_schema.clone()); + + let mut alter_queries = Vec::new(); + for (col_id, col_info) in &new_table.columns { + if !old_columns.contains_key(col_id) { + let col_type = sqlite_column_type(&col_info.type_def); + alter_queries.push(format!( + r#"ALTER TABLE "{storage_name}" ADD COLUMN "{}" {col_type}"#, + col_info.name + )); + } + } + + if !alter_queries.is_empty() { + self.execute_queries(&alter_queries).await?; + } + + self.tables.write()?.insert(id, new_table); + self.persist_table_state(&table_schema, true).await?; + Ok(()) + } + pub fn load_tables_no_commit(&self, table_schemas: Vec) -> SqliteDbResult<()> { let mut tables = self.tables.write()?; for table in table_schemas { @@ -273,24 +538,39 @@ impl IntrospectSqliteDb { Ok(()) } IntrospectMsg::UpdateTable(event) => { - self.tables.set_table_dead(&event.id)?; - self.persist_alive_state(event.id, false).await + self.update_table(event.clone()).await } IntrospectMsg::AddColumns(event) => { - self.tables.set_table_dead(&event.table)?; - self.persist_alive_state(event.table, false).await + tracing::warn!( + target: "torii::introspect_sqlite_sink", + table = %event.table, + "AddColumns received — table kept alive, new columns ignored until next UpdateTable" + ); + Ok(()) } IntrospectMsg::DropColumns(event) => { - self.tables.set_table_dead(&event.table)?; - self.persist_alive_state(event.table, false).await + tracing::warn!( + target: "torii::introspect_sqlite_sink", + table = %event.table, + "DropColumns received — table kept alive, columns left in place" + ); + Ok(()) } IntrospectMsg::RetypeColumns(event) => { - self.tables.set_table_dead(&event.table)?; - self.persist_alive_state(event.table, false).await + tracing::warn!( + target: "torii::introspect_sqlite_sink", + table = %event.table, + "RetypeColumns received — table kept alive, types unchanged" + ); + Ok(()) } IntrospectMsg::RetypePrimary(event) => { - self.tables.set_table_dead(&event.table)?; - self.persist_alive_state(event.table, false).await + tracing::warn!( + target: "torii::introspect_sqlite_sink", + table = %event.table, + "RetypePrimary received — table kept alive, primary type unchanged" + ); + Ok(()) } IntrospectMsg::RenameTable(_) | IntrospectMsg::DropTable(_) @@ -309,7 +589,16 @@ impl IntrospectSqliteDb { let mut results = Vec::with_capacity(msgs.len()); for body in msgs { let (msg, metadata) = body.into(); - results.push(self.process_message(msg, metadata).await); + let result = self.process_message(msg, metadata).await; + if let Err(ref err) = result { + tracing::warn!( + target: "torii::introspect_sqlite_sink", + event_id = msg.event_id(), + error = %err, + "Failed to process introspect message" + ); + } + results.push(result); } Ok(results) } @@ -339,14 +628,39 @@ impl IntrospectSqliteDb { ) .collect::>(); + let column_type_defs: Vec<&TypeDef> = event + .columns + .iter() + .map(|id| &table.columns[id].type_def) + .collect(); + + let placeholders = std::iter::once("?".to_string()) + .chain(column_type_defs.iter().map(|td| { + if is_json_type(td) { + "jsonb(?)".to_string() + } else { + "?".to_string() + } + })) + .collect::>() + .join(", "); + let update_columns = column_names .iter() .skip(1) - .map(|name| { - format!( - r#""{name}" = COALESCE(excluded."{name}", "{table_name}"."{name}")"#, - table_name = table.storage_name - ) + .zip(column_type_defs.iter()) + .map(|(name, td)| { + if is_json_type(td) { + format!( + r#""{name}" = COALESCE(jsonb(excluded."{name}"), "{table_name}"."{name}")"#, + table_name = table.storage_name + ) + } else { + format!( + r#""{name}" = COALESCE(excluded."{name}", "{table_name}"."{name}")"#, + table_name = table.storage_name + ) + } }) .collect::>() .join(", "); @@ -359,7 +673,7 @@ impl IntrospectSqliteDb { .map(|name| format!(r#""{name}""#)) .collect::>() .join(", "), - vec!["?"; column_names.len()].join(", "), + placeholders, table.primary.name, update_columns ); @@ -379,9 +693,40 @@ impl IntrospectSqliteDb { let object = value.as_object().ok_or(SqliteDbError::InvalidRecordFrame)?; let mut query = sqlx::query(&sql); - for column_name in &column_names { - let value = object.get(*column_name).and_then(serialize_sqlite_value); - query = query.bind(value); + + let primary_value = object + .get(table.primary.name.as_str()) + .cloned() + .unwrap_or(Value::Null); + match primary_to_bind_value(&primary_value, &table.primary.type_def) { + SqliteBindValue::Null => { + query = query.bind(None::>); + } + SqliteBindValue::Integer(n) => { + query = query.bind(n); + } + SqliteBindValue::Text(s) => { + query = query.bind(s); + } + } + + for (column_name, type_def) in column_names.iter().skip(1).zip(column_type_defs.iter()) + { + let val = object + .get(*column_name) + .cloned() + .unwrap_or(Value::Null); + match to_bind_value(&val, type_def) { + SqliteBindValue::Null => { + query = query.bind(None::); + } + SqliteBindValue::Integer(n) => { + query = query.bind(n); + } + SqliteBindValue::Text(s) => { + query = query.bind(s); + } + } } query.execute(&mut *tx).await?; } diff --git a/crates/introspect-sqlite-sink/src/sink.rs b/crates/introspect-sqlite-sink/src/sink.rs index 53de7d7c..86706aed 100644 --- a/crates/introspect-sqlite-sink/src/sink.rs +++ b/crates/introspect-sqlite-sink/src/sink.rs @@ -52,7 +52,16 @@ impl Sink for IntrospectSqliteDb { } } } - self.process_messages(msgs).await?; + let results = self.process_messages(msgs).await?; + let failed = results.iter().filter(|r| r.is_err()).count(); + if failed > 0 { + tracing::error!( + target: LOGGING_TARGET, + failed, + total = results.len(), + "Introspect messages failed — data may be missing from SQL tables" + ); + } if processed > 0 { tracing::info!( diff --git a/crates/torii-common/src/metadata.rs b/crates/torii-common/src/metadata.rs index 0fe1de28..8c8bd24c 100644 --- a/crates/torii-common/src/metadata.rs +++ b/crates/torii-common/src/metadata.rs @@ -42,12 +42,13 @@ impl MetadataFetcher { let name = self.fetch_string(contract, "name").await; let symbol = self.fetch_string(contract, "symbol").await; let decimals = self.fetch_decimals(contract).await; + let total_supply = self.fetch_total_supply(contract).await; TokenMetadata { name, symbol, decimals, - total_supply: None, + total_supply, } } diff --git a/crates/torii-ecs-sink/Cargo.toml b/crates/torii-ecs-sink/Cargo.toml index ae866f38..3d1458a1 100644 --- a/crates/torii-ecs-sink/Cargo.toml +++ b/crates/torii-ecs-sink/Cargo.toml @@ -28,6 +28,7 @@ tracing.workspace = true metrics.workspace = true hex.workspace = true num-bigint = "0.4" +primitive-types.workspace = true [build-dependencies] tonic-build.workspace = true diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index c9e446aa..af077167 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -12,12 +12,14 @@ use introspect_types::{ TypeDef, }; use num_bigint::{BigInt, BigUint, Sign}; +use primitive_types::{U256, U512}; use serde::ser::SerializeMap; use serde::Serializer; use serde_json::{Map, Serializer as JsonSerializer, Value}; use sqlx::{ - any::AnyPoolOptions, postgres::PgPoolOptions, sqlite::SqliteConnectOptions, - sqlite::SqlitePoolOptions, Any, Column, ConnectOptions, Pool, QueryBuilder, Row, + any::AnyPoolOptions, pool::PoolConnection, postgres::PgPoolOptions, + sqlite::SqliteConnectOptions, sqlite::SqlitePoolOptions, Any, Column, ConnectOptions, Pool, + QueryBuilder, Row, }; use starknet::core::types::Felt; use tokio::sync::mpsc::error::TrySendError; @@ -100,6 +102,12 @@ struct EcsState { pool: Pool, backend: DbBackend, database_url: String, + has_erc20: bool, + has_erc721: bool, + has_erc1155: bool, + erc20_url: Option, + erc721_url: Option, + erc1155_url: Option, managed_tables: Mutex>>>, entity_subscriptions: Mutex>, event_message_subscriptions: Mutex>, @@ -187,7 +195,13 @@ impl EntityAggregate { } impl EcsService { - pub async fn new(database_url: &str, max_connections: Option) -> Result { + pub async fn new( + database_url: &str, + max_connections: Option, + erc20_url: Option<&str>, + erc721_url: Option<&str>, + erc1155_url: Option<&str>, + ) -> Result { sqlx::any::install_default_drivers(); let backend = DbBackend::detect(database_url); @@ -205,11 +219,21 @@ impl EcsService { .connect(&database_url) .await?; + let has_erc20 = erc20_url.is_some(); + let has_erc721 = erc721_url.is_some(); + let has_erc1155 = erc1155_url.is_some(); + let service = Self { state: Arc::new(EcsState { pool, backend, database_url, + has_erc20, + has_erc721, + has_erc1155, + erc20_url: erc20_url.map(|s| s.to_string()), + erc721_url: erc721_url.map(|s| s.to_string()), + erc1155_url: erc1155_url.map(|s| s.to_string()), managed_tables: Mutex::new(None), entity_subscriptions: Mutex::new(HashMap::new()), event_message_subscriptions: Mutex::new(HashMap::new()), @@ -371,6 +395,64 @@ impl EcsService { Ok(()) } + pub async fn attach_erc_databases(&self) -> Result<()> { + if self.state.backend != DbBackend::Sqlite { + return Ok(()); + } + let mut conn = self.acquire_initialized_connection().await?; + for (schema, url) in [ + ("erc20", &self.state.erc20_url), + ("erc721", &self.state.erc721_url), + ("erc1155", &self.state.erc1155_url), + ] { + if let Some(url) = url { + let path = sqlite_db_path(url); + let file_exists = std::path::Path::new(&path).exists(); + tracing::info!( + schema, + path = %path, + file_exists, + "Attaching ERC database" + ); + attach_sqlite_database(&mut conn, schema, url).await?; + match sqlx::query(&format!( + "SELECT name FROM {schema}.sqlite_master WHERE type='table' LIMIT 5" + )) + .fetch_all(&mut *conn) + .await + { + Ok(rows) => { + let tables: Vec = + rows.iter().filter_map(|r| r.try_get("name").ok()).collect(); + tracing::info!(schema, ?tables, "Attached ERC database — found tables"); + } + Err(e) => { + tracing::error!( + schema, + error = %e, + "Attached ERC database but failed to list tables" + ); + } + } + } + } + Ok(()) + } + + async fn acquire_initialized_connection(&self) -> Result> { + let mut conn = self.state.pool.acquire().await?; + if self.state.backend == DbBackend::Sqlite { + attach_sqlite_databases( + &mut conn, + self.state.erc20_url.as_deref(), + self.state.erc721_url.as_deref(), + self.state.erc1155_url.as_deref(), + ) + .await?; + } + Ok(conn) + } + pub async fn record_contract_progress( &self, contract_address: Felt, @@ -916,9 +998,256 @@ impl EcsService { } fn scoped_table(&self, schema: &str, table: &str) -> String { + format!("{schema}.{table}") + } + + async fn sql_object_exists_on_connection( + &self, + conn: &mut PoolConnection, + schema: Option<&str>, + name: &str, + ) -> Result { + match self.state.backend { + DbBackend::Sqlite => { + let query = match schema { + Some(schema) => format!( + "SELECT 1 FROM {schema}.sqlite_master \ + WHERE type IN ('table', 'view') AND name = ? LIMIT 1" + ), + None => "SELECT 1 FROM sqlite_master \ + WHERE type IN ('table', 'view') AND name = ? LIMIT 1" + .to_string(), + }; + + let exists = sqlx::query_scalar::(&query) + .bind(name) + .fetch_optional(&mut **conn) + .await; + match exists { + Ok(row) => Ok(row.is_some()), + Err(_) if schema.is_some() => Ok(false), + Err(error) => Err(error.into()), + } + } + DbBackend::Postgres => { + let schema = schema.unwrap_or("public"); + let exists = sqlx::query_scalar::( + "SELECT 1 + FROM ( + SELECT table_name AS object_name + FROM information_schema.tables + WHERE table_schema = $1 + UNION ALL + SELECT table_name AS object_name + FROM information_schema.views + WHERE table_schema = $1 + ) objects + WHERE object_name = $2 + LIMIT 1", + ) + .bind(schema) + .bind(name) + .fetch_optional(&mut **conn) + .await?; + Ok(exists.is_some()) + } + } + } + + async fn replace_sql_compat_view_on_connection( + &self, + conn: &mut PoolConnection, + view_name: &str, + select_sql: &str, + ) -> Result<()> { match self.state.backend { - DbBackend::Postgres => format!("{schema}.{table}"), - DbBackend::Sqlite => table.to_string(), + DbBackend::Sqlite => { + sqlx::query(&format!("DROP VIEW IF EXISTS {view_name}")) + .execute(&mut **conn) + .await?; + sqlx::query(&format!("CREATE TEMP VIEW {view_name} AS {select_sql}")) + .execute(&mut **conn) + .await?; + } + DbBackend::Postgres => { + sqlx::query(&format!( + "CREATE OR REPLACE VIEW {view_name} AS {select_sql}" + )) + .execute(&mut **conn) + .await?; + } + } + Ok(()) + } + + async fn ensure_sql_compat_views_on_connection( + &self, + conn: &mut PoolConnection, + ) -> Result<()> { + let controllers_sql = self.controllers_view_sql(conn).await?; + self.replace_sql_compat_view_on_connection(conn, "controllers", &controllers_sql) + .await?; + let event_messages_historical_sql = self.event_messages_historical_view_sql().await?; + self.replace_sql_compat_view_on_connection( + conn, + "event_messages_historical", + &event_messages_historical_sql, + ) + .await?; + let token_balances_sql = self.token_balances_view_sql(conn).await?; + self.replace_sql_compat_view_on_connection(conn, "token_balances", &token_balances_sql) + .await?; + Ok(()) + } + + async fn controllers_view_sql(&self, conn: &mut PoolConnection) -> Result { + let mut address_sources = Vec::new(); + for (table, column) in [ + ("NUMS-LeaderboardScore", "player"), + ("NUMS-Claimed", "player_id"), + ("NUMS-BundleIssuance", "recipient"), + ] { + if self + .sql_object_exists_on_connection(conn, None, table) + .await? + { + address_sources.push(format!( + "SELECT {column} AS address FROM \"{table}\" \ + WHERE {column} IS NOT NULL AND {column} != ''" + )); + } + } + + let source_sql = if address_sources.is_empty() { + "SELECT NULL AS address WHERE 1 = 0".to_string() + } else { + address_sources.join(" UNION ") + }; + + Ok(format!( + "SELECT address, address AS username, address AS id, NULL AS deployed_at \ + FROM ({source_sql}) controller_addresses" + )) + } + + async fn event_messages_historical_view_sql(&self) -> Result { + let executed_at = match self.state.backend { + DbBackend::Sqlite => "datetime(meta.executed_at, 'unixepoch')", + DbBackend::Postgres => "TO_TIMESTAMP(meta.executed_at)::TEXT", + }; + let created_at = match self.state.backend { + DbBackend::Sqlite => "datetime(meta.created_at, 'unixepoch')", + DbBackend::Postgres => "TO_TIMESTAMP(meta.created_at)::TEXT", + }; + let updated_at = match self.state.backend { + DbBackend::Sqlite => "datetime(meta.updated_at, 'unixepoch')", + DbBackend::Postgres => "TO_TIMESTAMP(meta.updated_at)::TEXT", + }; + let deleted_predicate = match self.state.backend { + DbBackend::Sqlite => "meta.deleted = 0", + DbBackend::Postgres => "meta.deleted = FALSE", + }; + let recipient = match self.state.backend { + DbBackend::Sqlite => "COALESCE(json_extract(models.row_json, '$.recipient'), '')", + DbBackend::Postgres => "COALESCE(models.row_json::jsonb ->> 'recipient', '')", + }; + + Ok(format!( + "SELECT \ + models.world_address || ':' || models.entity_id AS id, \ + models.world_address || ':' || models.entity_id AS event_id, \ + models.world_address || ':' || models.table_id AS model_id, \ + models.entity_id, \ + {recipient} || '/' AS keys, \ + models.row_json AS data, \ + models.world_address, \ + {created_at} AS created_at, \ + {updated_at} AS updated_at, \ + {executed_at} AS executed_at \ + FROM torii_ecs_entity_models models \ + JOIN torii_ecs_entity_meta meta + ON meta.kind = models.kind + AND meta.world_address = models.world_address + AND meta.table_id = models.table_id + AND meta.entity_id = models.entity_id + WHERE models.kind = 'event_message' + AND {deleted_predicate}" + )) + } + + async fn token_balances_view_sql(&self, conn: &mut PoolConnection) -> Result { + let mut parts = Vec::new(); + + if self + .sql_object_exists_on_connection(conn, Some("erc20"), "balances") + .await? + { + let token = sql_hex_blob_expr(self.state.backend, "token", 64); + let wallet = sql_hex_blob_expr(self.state.backend, "wallet", 64); + let balance = sql_hex_blob_expr(self.state.backend, "balance", 64); + parts.push(format!( + "SELECT \ + {wallet} || '/' || {token} AS id, \ + {wallet} AS account_address, \ + {token} AS contract_address, \ + {token} AS token_id, \ + {balance} AS balance \ + FROM {}", + self.scoped_table("erc20", "balances") + )); + } + + if self + .sql_object_exists_on_connection(conn, Some("erc721"), "nft_ownership") + .await? + { + let token = sql_hex_blob_expr(self.state.backend, "token", 64); + let owner = sql_hex_blob_expr(self.state.backend, "owner", 64); + let token_id = sql_hex_blob_expr(self.state.backend, "token_id", 64); + let one = sql_hex_literal_expr(self.state.backend, "1", 64); + parts.push(format!( + "SELECT \ + {owner} || '/' || {token} || ':' || {token_id} AS id, \ + {owner} AS account_address, \ + {token} AS contract_address, \ + {token_id} AS token_id, \ + {one} AS balance \ + FROM {}", + self.scoped_table("erc721", "nft_ownership") + )); + } + + if self + .sql_object_exists_on_connection(conn, Some("erc1155"), "erc1155_balances") + .await? + { + let contract = sql_hex_blob_expr(self.state.backend, "contract", 64); + let wallet = sql_hex_blob_expr(self.state.backend, "wallet", 64); + let token_id = sql_hex_blob_expr(self.state.backend, "token_id", 64); + let balance = sql_hex_blob_expr(self.state.backend, "balance", 64); + parts.push(format!( + "SELECT \ + {wallet} || '/' || {contract} || ':' || {token_id} AS id, \ + {wallet} AS account_address, \ + {contract} AS contract_address, \ + {token_id} AS token_id, \ + {balance} AS balance \ + FROM {}", + self.scoped_table("erc1155", "erc1155_balances") + )); + } + + if parts.is_empty() { + Ok("SELECT \ + CAST(NULL AS TEXT) AS id, \ + CAST(NULL AS TEXT) AS account_address, \ + CAST(NULL AS TEXT) AS contract_address, \ + CAST(NULL AS TEXT) AS token_id, \ + CAST(NULL AS TEXT) AS balance \ + WHERE 1 = 0" + .to_string()) + } else { + Ok(parts.join(" UNION ALL ")) } } @@ -936,61 +1265,93 @@ impl EcsService { ) -> Result<(Vec, String)> { let limit = Self::pagination_limit(query.pagination.as_ref(), 100); let mut items = Vec::new(); - let include_erc20 = query.contract_types.is_empty() - || query - .contract_types - .iter() - .any(|kind| *kind == ContractType::Erc20 as i32); - let include_erc721 = query.contract_types.is_empty() - || query - .contract_types - .iter() - .any(|kind| *kind == ContractType::Erc721 as i32); - let include_erc1155 = query.contract_types.is_empty() - || query - .contract_types - .iter() - .any(|kind| *kind == ContractType::Erc1155 as i32); + let mut conn = self.acquire_initialized_connection().await?; + let include_erc20 = self.state.has_erc20 + && (query.contract_types.is_empty() + || query + .contract_types + .iter() + .any(|kind| *kind == ContractType::Erc20 as i32)); + let include_erc721 = self.state.has_erc721 + && (query.contract_types.is_empty() + || query + .contract_types + .iter() + .any(|kind| *kind == ContractType::Erc721 as i32)); + let include_erc1155 = self.state.has_erc1155 + && (query.contract_types.is_empty() + || query + .contract_types + .iter() + .any(|kind| *kind == ContractType::Erc1155 as i32)); if include_erc20 { let table = self.scoped_table("erc20", "token_metadata"); let mut builder = QueryBuilder::::new(format!( - "SELECT token, name, symbol, decimals FROM {table}" + "SELECT token, name, symbol, decimals, total_supply FROM {table}" )); push_blob_in_filter(&mut builder, "token", &query.contract_addresses); - for row in builder.build().fetch_all(&self.state.pool).await? { - items.push(types::TokenContract { - contract_address: row.try_get("token")?, - contract_type: ContractType::Erc20 as i32, - name: row - .try_get::, _>("name")? - .unwrap_or_default(), - symbol: row - .try_get::, _>("symbol")? - .unwrap_or_default(), - decimals: row - .try_get::, _>("decimals")? - .unwrap_or_default() as u32, - metadata: Vec::new(), - total_supply: None, - traits: String::new(), - token_metadata: Vec::new(), - }); + match builder.build().fetch_all(&mut *conn).await { + Ok(rows) => { + for row in rows { + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; + items.push(types::TokenContract { + contract_address, + contract_type: ContractType::Erc20 as i32, + name: row + .try_get::, _>("name")? + .unwrap_or_default(), + symbol: row + .try_get::, _>("symbol")? + .unwrap_or_default(), + decimals: row + .try_get::, _>("decimals")? + .and_then(|s| s.parse::().ok()) + .unwrap_or_default(), + metadata: Vec::new(), + total_supply: canonical_optional_u256_bytes_from_db( + row.try_get::>, _>("total_supply")?, + )?, + traits: String::new(), + token_metadata: Vec::new(), + }); + } + } + Err(e) => { + tracing::warn!( + error = %e, + "Failed to query erc20.token_metadata — returning empty ERC20 contracts" + ); + } } } if include_erc721 { let table = self.scoped_table("erc721", "token_metadata"); let uris = self.scoped_table("erc721", "token_uris"); + let ownership = self.scoped_table("erc721", "nft_ownership"); let mut builder = QueryBuilder::::new(format!( "SELECT tm.token, tm.name, tm.symbol, tm.total_supply, \ + (SELECT COUNT(DISTINCT o.token_id) FROM {ownership} o WHERE o.token = tm.token) AS ownership_count, \ COALESCE((SELECT metadata_json FROM {uris} tu WHERE tu.token = tm.token ORDER BY tu.token_id LIMIT 1), '') AS token_metadata \ FROM {table} tm" )); push_blob_in_filter(&mut builder, "tm.token", &query.contract_addresses); - for row in builder.build().fetch_all(&self.state.pool).await? { + for row in builder.build().fetch_all(&mut *conn).await? { + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; + let total_supply = canonical_optional_u256_bytes_from_db( + row.try_get::>, _>("total_supply")?, + )? + .or_else(|| { + row.try_get::, _>("ownership_count") + .ok() + .flatten() + .map(|c| u256_bytes_from_u64(c as u64)) + }); items.push(types::TokenContract { - contract_address: row.try_get("token")?, + contract_address, contract_type: ContractType::Erc721 as i32, name: row .try_get::, _>("name")? @@ -1000,7 +1361,7 @@ impl EcsService { .unwrap_or_default(), decimals: 0, metadata: Vec::new(), - total_supply: row.try_get::>, _>("total_supply")?, + total_supply, traits: String::new(), token_metadata: row .try_get::, _>("token_metadata")? @@ -1019,9 +1380,11 @@ impl EcsService { FROM {table} tm" )); push_blob_in_filter(&mut builder, "tm.token", &query.contract_addresses); - for row in builder.build().fetch_all(&self.state.pool).await? { + for row in builder.build().fetch_all(&mut *conn).await? { + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; items.push(types::TokenContract { - contract_address: row.try_get("token")?, + contract_address, contract_type: ContractType::Erc1155 as i32, name: row .try_get::, _>("name")? @@ -1031,7 +1394,9 @@ impl EcsService { .unwrap_or_default(), decimals: 0, metadata: Vec::new(), - total_supply: row.try_get::>, _>("total_supply")?, + total_supply: canonical_optional_u256_bytes_from_db( + row.try_get::>, _>("total_supply")?, + )?, traits: String::new(), token_metadata: row .try_get::, _>("token_metadata")? @@ -1049,17 +1414,20 @@ impl EcsService { async fn load_tokens(&self, query: &types::TokenQuery) -> Result<(Vec, String)> { let limit = Self::pagination_limit(query.pagination.as_ref(), 100); let mut items = Vec::new(); + let mut conn = self.acquire_initialized_connection().await?; - if query.token_ids.is_empty() { + if self.state.has_erc20 && query.token_ids.is_empty() { let table = self.scoped_table("erc20", "token_metadata"); let mut builder = QueryBuilder::::new(format!( "SELECT token, name, symbol, decimals FROM {table}" )); push_blob_in_filter(&mut builder, "token", &query.contract_addresses); - for row in builder.build().fetch_all(&self.state.pool).await? { + for row in builder.build().fetch_all(&mut *conn).await? { + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; items.push(types::Token { token_id: None, - contract_address: row.try_get("token")?, + contract_address, name: row .try_get::, _>("name")? .unwrap_or_default(), @@ -1067,22 +1435,27 @@ impl EcsService { .try_get::, _>("symbol")? .unwrap_or_default(), decimals: row - .try_get::, _>("decimals")? - .unwrap_or_default() as u32, + .try_get::, _>("decimals")? + .and_then(|s| s.parse::().ok()) + .unwrap_or_default(), metadata: Vec::new(), total_supply: None, }); } } - items.extend( - self.load_nft_tokens("erc721", query, ContractType::Erc721) - .await?, - ); - items.extend( - self.load_nft_tokens("erc1155", query, ContractType::Erc1155) - .await?, - ); + if self.state.has_erc721 { + items.extend( + self.load_nft_tokens(&mut conn, "erc721", query, ContractType::Erc721) + .await?, + ); + } + if self.state.has_erc1155 { + items.extend( + self.load_nft_tokens(&mut conn, "erc1155", query, ContractType::Erc1155) + .await?, + ); + } items.sort_by(|a, b| { a.contract_address .cmp(&b.contract_address) @@ -1094,6 +1467,7 @@ impl EcsService { async fn load_nft_tokens( &self, + conn: &mut PoolConnection, schema: &str, query: &types::TokenQuery, _kind: ContractType, @@ -1115,11 +1489,11 @@ impl EcsService { builder.push(" WHERE "); has_where = true; } - builder.push("tu.token_id IN ("); + builder.push("hex(tu.token_id) IN ("); { let mut separated = builder.separated(", "); for token_id in &query.token_ids { - separated.push_bind(token_id.clone()); + separated.push_bind(hex::encode_upper(token_id)); } } builder.push(")"); @@ -1142,12 +1516,16 @@ impl EcsService { builder.push(")"); } - let rows = builder.build().fetch_all(&self.state.pool).await?; + let rows = builder.build().fetch_all(&mut **conn).await?; rows.into_iter() .map(|row| { + let token_id = + canonical_u256_bytes_from_db(&row.try_get::, _>("token_id")?)?; + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; Ok(types::Token { - token_id: Some(row.try_get("token_id")?), - contract_address: row.try_get("token")?, + token_id: Some(token_id), + contract_address, name: row .try_get::, _>("name")? .unwrap_or_default(), @@ -1159,7 +1537,9 @@ impl EcsService { .try_get::, _>("metadata_json")? .unwrap_or_default() .into_bytes(), - total_supply: row.try_get::>, _>("total_supply")?, + total_supply: canonical_optional_u256_bytes_from_db( + row.try_get::>, _>("total_supply")?, + )?, }) }) .collect() @@ -1171,8 +1551,9 @@ impl EcsService { ) -> Result<(Vec, String)> { let limit = Self::pagination_limit(query.pagination.as_ref(), 100); let mut items = Vec::new(); + let mut conn = self.acquire_initialized_connection().await?; - { + if self.state.has_erc20 { let table = self.scoped_table("erc20", "balances"); let mut builder = QueryBuilder::::new(format!("SELECT wallet, token, balance FROM {table}")); @@ -1184,26 +1565,42 @@ impl EcsService { } else { builder.push(" WHERE "); } - builder.push("token IN ("); + builder.push("hex(token) IN ("); { let mut separated = builder.separated(", "); for contract in &query.contract_addresses { - separated.push_bind(contract.clone()); + separated.push_bind(hex::encode_upper(contract)); } } builder.push(")"); } - for row in builder.build().fetch_all(&self.state.pool).await? { - items.push(types::TokenBalance { - balance: row.try_get("balance")?, - account_address: row.try_get("wallet")?, - contract_address: row.try_get("token")?, - token_id: None, - }); + match builder.build().fetch_all(&mut *conn).await { + Ok(rows) => { + for row in rows { + let balance = + canonical_u256_bytes_from_db(&row.try_get::, _>("balance")?)?; + let account_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("wallet")?)?; + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; + items.push(types::TokenBalance { + balance, + account_address, + contract_address, + token_id: None, + }); + } + } + Err(e) => { + tracing::warn!( + error = %e, + "Failed to query erc20.balances — returning empty ERC20 balances" + ); + } } } - { + if self.state.has_erc721 { let table = self.scoped_table("erc721", "nft_ownership"); let mut builder = QueryBuilder::::new(format!("SELECT owner, token, token_id FROM {table}")); @@ -1216,11 +1613,11 @@ impl EcsService { builder.push(" WHERE "); has_where = true; } - builder.push("token IN ("); + builder.push("hex(token) IN ("); { let mut separated = builder.separated(", "); for contract in &query.contract_addresses { - separated.push_bind(contract.clone()); + separated.push_bind(hex::encode_upper(contract)); } } builder.push(")"); @@ -1231,26 +1628,42 @@ impl EcsService { } else { builder.push(" WHERE "); } - builder.push("token_id IN ("); + builder.push("hex(token_id) IN ("); { let mut separated = builder.separated(", "); for token_id in &query.token_ids { - separated.push_bind(token_id.clone()); + separated.push_bind(hex::encode_upper(token_id)); } } builder.push(")"); } - for row in builder.build().fetch_all(&self.state.pool).await? { - items.push(types::TokenBalance { - balance: u256_bytes_from_u64(1), - account_address: row.try_get("owner")?, - contract_address: row.try_get("token")?, - token_id: Some(row.try_get("token_id")?), - }); + match builder.build().fetch_all(&mut *conn).await { + Ok(rows) => { + for row in rows { + let account_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("owner")?)?; + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; + let token_id = + canonical_u256_bytes_from_db(&row.try_get::, _>("token_id")?)?; + items.push(types::TokenBalance { + balance: u256_bytes_from_u64(1), + account_address, + contract_address, + token_id: Some(token_id), + }); + } + } + Err(e) => { + tracing::warn!( + error = %e, + "Failed to query erc721.nft_ownership — returning empty ERC721 balances" + ); + } } } - { + if self.state.has_erc1155 { let table = self.scoped_table("erc1155", "erc1155_balances"); let mut builder = QueryBuilder::::new(format!( "SELECT wallet, contract, token_id, balance FROM {table}" @@ -1264,11 +1677,11 @@ impl EcsService { builder.push(" WHERE "); has_where = true; } - builder.push("contract IN ("); + builder.push("hex(contract) IN ("); { let mut separated = builder.separated(", "); for contract in &query.contract_addresses { - separated.push_bind(contract.clone()); + separated.push_bind(hex::encode_upper(contract)); } } builder.push(")"); @@ -1279,22 +1692,40 @@ impl EcsService { } else { builder.push(" WHERE "); } - builder.push("token_id IN ("); + builder.push("hex(token_id) IN ("); { let mut separated = builder.separated(", "); for token_id in &query.token_ids { - separated.push_bind(token_id.clone()); + separated.push_bind(hex::encode_upper(token_id)); } } builder.push(")"); } - for row in builder.build().fetch_all(&self.state.pool).await? { - items.push(types::TokenBalance { - balance: row.try_get("balance")?, - account_address: row.try_get("wallet")?, - contract_address: row.try_get("contract")?, - token_id: Some(row.try_get("token_id")?), - }); + match builder.build().fetch_all(&mut *conn).await { + Ok(rows) => { + for row in rows { + let balance = + canonical_u256_bytes_from_db(&row.try_get::, _>("balance")?)?; + let account_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("wallet")?)?; + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("contract")?)?; + let token_id = + canonical_u256_bytes_from_db(&row.try_get::, _>("token_id")?)?; + items.push(types::TokenBalance { + balance, + account_address, + contract_address, + token_id: Some(token_id), + }); + } + } + Err(e) => { + tracing::warn!( + error = %e, + "Failed to query erc1155.erc1155_balances — returning empty ERC1155 balances" + ); + } } } @@ -1314,10 +1745,17 @@ impl EcsService { ) -> Result<(Vec, String)> { let limit = Self::pagination_limit(query.pagination.as_ref(), 100); let mut items = Vec::new(); + let mut conn = self.acquire_initialized_connection().await?; - items.extend(self.load_erc20_transfers(query).await?); - items.extend(self.load_erc721_transfers(query).await?); - items.extend(self.load_erc1155_transfers(query).await?); + if self.state.has_erc20 { + items.extend(self.load_erc20_transfers(&mut conn, query).await?); + } + if self.state.has_erc721 { + items.extend(self.load_erc721_transfers(&mut conn, query).await?); + } + if self.state.has_erc1155 { + items.extend(self.load_erc1155_transfers(&mut conn, query).await?); + } items.sort_by(|a, b| { b.executed_at @@ -1457,18 +1895,24 @@ impl EcsService { filter: &types::TransactionFilter, ) -> Result, u64, u64)>> { let mut rows = Vec::new(); - rows.extend( - self.load_token_tx_rows("erc20", "transfers", "token", filter) - .await?, - ); - rows.extend( - self.load_token_tx_rows("erc721", "nft_transfers", "token", filter) - .await?, - ); - rows.extend( - self.load_token_tx_rows("erc1155", "token_transfers", "token", filter) - .await?, - ); + if self.state.has_erc20 { + rows.extend( + self.load_token_tx_rows("erc20", "transfers", "token", filter) + .await?, + ); + } + if self.state.has_erc721 { + rows.extend( + self.load_token_tx_rows("erc721", "nft_transfers", "token", filter) + .await?, + ); + } + if self.state.has_erc1155 { + rows.extend( + self.load_token_tx_rows("erc1155", "token_transfers", "token", filter) + .await?, + ); + } Ok(rows) } @@ -1481,7 +1925,7 @@ impl EcsService { ) -> Result, u64, u64)>> { let table = self.scoped_table(schema, table_name); let mut builder = QueryBuilder::::new(format!( - "SELECT tx_hash, block_number, COALESCE(timestamp, 0) AS timestamp, {contract_column} FROM {table}" + "SELECT tx_hash, block_number, COALESCE(timestamp, '0') AS timestamp, {contract_column} FROM {table}" )); let mut has_where = false; if let Some(from_block) = filter.from_block { @@ -1505,11 +1949,11 @@ impl EcsService { } else { builder.push(" WHERE "); } - builder.push(format!("{contract_column} IN (")); + builder.push(format!("hex({contract_column}) IN (")); { let mut separated = builder.separated(", "); for contract in &filter.contract_addresses { - separated.push_bind(contract.clone()); + separated.push_bind(hex::encode_upper(contract)); } } builder.push(")"); @@ -1519,8 +1963,12 @@ impl EcsService { .map(|row| { Ok(( row.try_get("tx_hash")?, - row.try_get::("block_number")? as u64, - row.try_get::("timestamp")? as u64, + row.try_get::("block_number")? + .parse::() + .unwrap_or(0), + row.try_get::("timestamp")? + .parse::() + .unwrap_or(0), )) }) .collect() @@ -1528,24 +1976,35 @@ impl EcsService { async fn load_erc20_transfers( &self, + conn: &mut PoolConnection, query: &types::TokenTransferQuery, ) -> Result> { let table = self.scoped_table("erc20", "transfers"); let mut builder = QueryBuilder::::new(format!( - "SELECT id, token, from_addr, to_addr, amount, COALESCE(timestamp, 0) AS timestamp FROM {table}" + "SELECT id, token, from_addr, to_addr, amount, COALESCE(timestamp, '0') AS timestamp FROM {table}" )); push_transfer_filters(&mut builder, query, "token", "from_addr", "to_addr", None); - let rows = builder.build().fetch_all(&self.state.pool).await?; + let rows = builder.build().fetch_all(&mut **conn).await?; rows.into_iter() .map(|row| { + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; + let from_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("from_addr")?)?; + let to_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("to_addr")?)?; + let amount = canonical_u256_bytes_from_db(&row.try_get::, _>("amount")?)?; Ok(types::TokenTransfer { id: format!("erc20:{}", row.try_get::("id")?), - contract_address: row.try_get("token")?, - from_address: row.try_get("from_addr")?, - to_address: row.try_get("to_addr")?, - amount: row.try_get("amount")?, + contract_address, + from_address, + to_address, + amount, token_id: None, - executed_at: row.try_get::("timestamp")? as u64, + executed_at: row + .try_get::("timestamp")? + .parse::() + .unwrap_or(0), event_id: None, }) }) @@ -1554,11 +2013,12 @@ impl EcsService { async fn load_erc721_transfers( &self, + conn: &mut PoolConnection, query: &types::TokenTransferQuery, ) -> Result> { let table = self.scoped_table("erc721", "nft_transfers"); let mut builder = QueryBuilder::::new(format!( - "SELECT id, token, from_addr, to_addr, token_id, COALESCE(timestamp, 0) AS timestamp FROM {table}" + "SELECT id, token, from_addr, to_addr, token_id, COALESCE(timestamp, '0') AS timestamp FROM {table}" )); push_transfer_filters( &mut builder, @@ -1568,17 +2028,28 @@ impl EcsService { "to_addr", Some("token_id"), ); - let rows = builder.build().fetch_all(&self.state.pool).await?; + let rows = builder.build().fetch_all(&mut **conn).await?; rows.into_iter() .map(|row| { + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; + let from_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("from_addr")?)?; + let to_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("to_addr")?)?; + let token_id = + canonical_u256_bytes_from_db(&row.try_get::, _>("token_id")?)?; Ok(types::TokenTransfer { id: format!("erc721:{}", row.try_get::("id")?), - contract_address: row.try_get("token")?, - from_address: row.try_get("from_addr")?, - to_address: row.try_get("to_addr")?, + contract_address, + from_address, + to_address, amount: u256_bytes_from_u64(1), - token_id: Some(row.try_get("token_id")?), - executed_at: row.try_get::("timestamp")? as u64, + token_id: Some(token_id), + executed_at: row + .try_get::("timestamp")? + .parse::() + .unwrap_or(0), event_id: None, }) }) @@ -1587,11 +2058,12 @@ impl EcsService { async fn load_erc1155_transfers( &self, + conn: &mut PoolConnection, query: &types::TokenTransferQuery, ) -> Result> { let table = self.scoped_table("erc1155", "token_transfers"); let mut builder = QueryBuilder::::new(format!( - "SELECT id, token, from_addr, to_addr, token_id, amount, COALESCE(timestamp, 0) AS timestamp FROM {table}" + "SELECT id, token, from_addr, to_addr, token_id, amount, COALESCE(timestamp, '0') AS timestamp FROM {table}" )); push_transfer_filters( &mut builder, @@ -1601,17 +2073,29 @@ impl EcsService { "to_addr", Some("token_id"), ); - let rows = builder.build().fetch_all(&self.state.pool).await?; + let rows = builder.build().fetch_all(&mut **conn).await?; rows.into_iter() .map(|row| { + let contract_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("token")?)?; + let from_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("from_addr")?)?; + let to_address = + canonical_felt_bytes_from_db(&row.try_get::, _>("to_addr")?)?; + let token_id = + canonical_u256_bytes_from_db(&row.try_get::, _>("token_id")?)?; + let amount = canonical_u256_bytes_from_db(&row.try_get::, _>("amount")?)?; Ok(types::TokenTransfer { id: format!("erc1155:{}", row.try_get::("id")?), - contract_address: row.try_get("token")?, - from_address: row.try_get("from_addr")?, - to_address: row.try_get("to_addr")?, - amount: row.try_get("amount")?, - token_id: Some(row.try_get("token_id")?), - executed_at: row.try_get::("timestamp")? as u64, + contract_address, + from_address, + to_address, + amount, + token_id: Some(token_id), + executed_at: row + .try_get::("timestamp")? + .parse::() + .unwrap_or(0), event_id: None, }) }) @@ -2196,6 +2680,18 @@ impl EcsService { } else { Some(table_ids.as_slice()) }; + let all_model_map = if table_id_filter.is_some() { + self.load_managed_tables(Some(kind)) + .await? + .into_iter() + .filter(|t| { + world_filter_set.is_empty() || world_filter_set.contains(&t.world_address) + }) + .map(|t| (felt_hex(t.table.id), t)) + .collect::>() + } else { + model_map.clone() + }; let member_pushdown = member_pushdown_from_clause(query.clause.as_ref(), &model_map); let target_limit = query.pagination.as_ref().map_or(100, |pagination| { if pagination.limit == 0 { @@ -2238,7 +2734,7 @@ impl EcsService { let meta_start = Instant::now(); let candidate_meta = self - .load_entity_meta_for_keys(kind, table_id_filter, candidate_keys.as_slice()) + .load_entity_meta_for_keys(kind, None, candidate_keys.as_slice()) .await?; ::metrics::histogram!("torii_ecs_load_entity_page_meta_rows_seconds") .record(meta_start.elapsed().as_secs_f64()); @@ -2248,7 +2744,7 @@ impl EcsService { for chunk in candidate_keys.chunks(256) { let rows_start = Instant::now(); let rows = self - .load_entity_page_rows(kind, &world_filters, table_id_filter, chunk) + .load_entity_page_rows(kind, &world_filters, None, chunk) .await?; ::metrics::histogram!("torii_ecs_load_entity_page_rows_seconds") .record(rows_start.elapsed().as_secs_f64()); @@ -2269,7 +2765,7 @@ impl EcsService { continue; }; let Some(entity) = - build_entity_from_snapshot(key, meta, row_map.get(key), &model_map)? + build_entity_from_snapshot(key, meta, row_map.get(key), &all_model_map)? else { continue; }; @@ -3544,8 +4040,15 @@ impl World for EcsService { request: Request, ) -> Result, Status> { let query = request.into_inner().query; + let mut conn = self + .acquire_initialized_connection() + .await + .map_err(internal_status)?; + self.ensure_sql_compat_views_on_connection(&mut conn) + .await + .map_err(internal_status)?; let rows = sqlx::query(&query) - .fetch_all(&self.state.pool) + .fetch_all(&mut *conn) .await .map_err(|error| Status::invalid_argument(format!("Query error: {error}")))?; Ok(Response::new(types::SqlQueryResponse { @@ -3575,6 +4078,82 @@ fn internal_status(error: anyhow::Error) -> Status { Status::internal(error.to_string()) } +fn sql_hex_blob_expr(backend: DbBackend, column: &str, width: usize) -> String { + match backend { + DbBackend::Sqlite => { + let zeros = "0".repeat(width); + format!("'0x' || lower(substr('{zeros}' || hex({column}), -{width}, {width}))") + } + DbBackend::Postgres => { + format!("'0x' || lower(lpad(encode({column}, 'hex'), {width}, '0'))") + } + } +} + +fn sql_hex_literal_expr(backend: DbBackend, value: &str, width: usize) -> String { + match backend { + DbBackend::Sqlite => { + let zeros = "0".repeat(width); + format!("'0x' || substr('{zeros}' || '{value}', -{width}, {width})") + } + DbBackend::Postgres => format!("'0x' || lpad('{value}', {width}, '0')"), + } +} + +async fn attach_sqlite_databases( + conn: &mut PoolConnection, + erc20_url: Option<&str>, + erc721_url: Option<&str>, + erc1155_url: Option<&str>, +) -> Result<()> { + for (schema, url) in [ + ("erc20", erc20_url), + ("erc721", erc721_url), + ("erc1155", erc1155_url), + ] { + if let Some(url) = url { + attach_sqlite_database(conn, schema, url).await?; + } + } + Ok(()) +} + +async fn attach_sqlite_database( + conn: &mut PoolConnection, + schema: &str, + url: &str, +) -> Result<()> { + let attached = + sqlx::query_scalar::("SELECT 1 FROM pragma_database_list WHERE name = ? LIMIT 1") + .bind(schema) + .fetch_optional(&mut **conn) + .await? + .is_some(); + if attached { + return Ok(()); + } + + let path = sqlite_db_path(url).replace('\'', "''"); + sqlx::query(&format!("ATTACH DATABASE '{path}' AS {schema}")) + .execute(&mut **conn) + .await?; + Ok(()) +} + +fn sqlite_db_path(url: &str) -> String { + let path = url + .strip_prefix("sqlite://") + .or_else(|| url.strip_prefix("sqlite:")) + .unwrap_or(url); + let p = std::path::Path::new(path); + if let (Some(parent), Some(file_name)) = (p.parent(), p.file_name()) { + if let Ok(abs_parent) = parent.canonicalize() { + return abs_parent.join(file_name).to_string_lossy().into_owned(); + } + } + path.to_string() +} + fn sqlite_url(path: &str) -> Result { if path == ":memory:" || path == "sqlite::memory:" { return Ok("sqlite::memory:".to_string()); @@ -3619,6 +4198,20 @@ impl CairoTypeSerialization for SnapshotJsonSerializer { self.serialize_byte_array(serializer, value) } + fn serialize_u256(&self, serializer: S, value: U256) -> Result { + let U256([a, b, c, d]) = value; + let corrected = U256([d, c, b, a]); + let bytes = corrected.to_big_endian(); + self.serialize_byte_array(serializer, &bytes) + } + + fn serialize_u512(&self, serializer: S, value: U512) -> Result { + let U512([a, b, c, d, e, f, g, h]) = value; + let corrected = U512([h, g, f, e, d, c, b, a]); + let bytes = corrected.to_big_endian(); + self.serialize_byte_array(serializer, &bytes) + } + fn serialize_tuple<'a, S: Serializer>( &'a self, data: &mut impl CairoDeserializer, @@ -4256,13 +4849,11 @@ fn push_blob_in_filter( if values.is_empty() { return false; } - builder.push(" WHERE "); - builder.push(column); - builder.push(" IN ("); + builder.push(format!(" WHERE hex({column}) IN (")); { let mut separated = builder.separated(", "); for value in values { - separated.push_bind(value.clone()); + separated.push_bind(hex::encode_upper(value)); } } builder.push(")"); @@ -4279,13 +4870,11 @@ fn push_transfer_filters( ) { let mut has_where = false; if !query.contract_addresses.is_empty() { - builder.push(" WHERE "); - builder.push(contract_column); - builder.push(" IN ("); + builder.push(format!(" WHERE hex({contract_column}) IN (")); { let mut separated = builder.separated(", "); for contract in &query.contract_addresses { - separated.push_bind(contract.clone()); + separated.push_bind(hex::encode_upper(contract)); } } builder.push(")"); @@ -4298,22 +4887,18 @@ fn push_transfer_filters( builder.push(" WHERE "); has_where = true; } - builder.push("("); - builder.push(from_column); - builder.push(" IN ("); + builder.push(format!("(hex({from_column}) IN (")); { let mut separated = builder.separated(", "); for account in &query.account_addresses { - separated.push_bind(account.clone()); + separated.push_bind(hex::encode_upper(account)); } } - builder.push(") OR "); - builder.push(to_column); - builder.push(" IN ("); + builder.push(format!(") OR hex({to_column}) IN (")); { let mut separated = builder.separated(", "); for account in &query.account_addresses { - separated.push_bind(account.clone()); + separated.push_bind(hex::encode_upper(account)); } } builder.push("))"); @@ -4325,12 +4910,11 @@ fn push_transfer_filters( } else { builder.push(" WHERE "); } - builder.push(token_id_column); - builder.push(" IN ("); + builder.push(format!("hex({token_id_column}) IN (")); { let mut separated = builder.separated(", "); for token_id in &query.token_ids { - separated.push_bind(token_id.clone()); + separated.push_bind(hex::encode_upper(token_id)); } } builder.push(")"); @@ -4359,6 +4943,30 @@ fn token_balance_subscription_key(balance: &types::TokenBalance) -> String { ) } +fn canonical_felt_bytes_from_db(bytes: &[u8]) -> Result> { + Ok(felt_from_bytes(bytes)?.to_bytes_be().to_vec()) +} + +fn canonical_optional_u256_bytes_from_db(bytes: Option>) -> Result>> { + bytes + .as_deref() + .map(canonical_u256_bytes_from_db) + .transpose() +} + +fn canonical_u256_bytes_from_db(bytes: &[u8]) -> Result> { + if bytes.len() > 32 { + return Err(anyhow!("U256 payload exceeds 32 bytes")); + } + + let value = if bytes.is_empty() { + U256::zero() + } else { + U256::from_big_endian(bytes) + }; + Ok(value.to_big_endian().to_vec()) +} + fn u256_bytes_from_u64(value: u64) -> Vec { let mut out = vec![0_u8; 32]; out[24..].copy_from_slice(&value.to_be_bytes()); @@ -4797,6 +5405,8 @@ fn felt_from_bytes(value: &[u8]) -> Result { #[cfg(test)] mod tests { + use std::collections::BTreeMap; + use super::*; use introspect_types::{ColumnDef, PrimaryDef, PrimaryTypeDef, TypeDef}; use tokio::time::{timeout, Duration}; @@ -4810,6 +5420,37 @@ mod tests { format!("sqlite:file:torii-ecs-sink-{name}-{nonce}?mode=memory&cache=shared") } + fn temp_sqlite_url(name: &str) -> String { + let nonce = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .expect("clock before epoch") + .as_nanos(); + let path = std::env::temp_dir().join(format!("torii-ecs-sink-{name}-{nonce}.db")); + format!("sqlite://{}", path.display()) + } + + fn sql_rows_to_maps(rows: &[types::SqlRow]) -> Vec> { + rows.iter() + .map(|row| { + row.fields + .iter() + .map(|(name, value)| { + let value = match value.value_type.as_ref() { + Some(types::sql_value::ValueType::Text(value)) => value.clone(), + Some(types::sql_value::ValueType::Integer(value)) => value.to_string(), + Some(types::sql_value::ValueType::Real(value)) => value.to_string(), + Some(types::sql_value::ValueType::Blob(value)) => { + format!("0x{}", hex::encode(value)) + } + Some(types::sql_value::ValueType::Null(_)) | None => String::new(), + }; + (name.clone(), value) + }) + .collect::>() + }) + .collect() + } + fn member_bool_clause(model: &str, member: &str, value: bool) -> types::Clause { types::Clause { clause_type: Some(ClauseType::Member(types::MemberClause { @@ -4979,43 +5620,134 @@ mod tests { .expect("insert entity model"); } - #[tokio::test] - async fn subscribe_entities_update_flow() { - let db_path = test_db_path("entities-sub"); - let service = EcsService::new(&db_path, Some(1)) - .await - .expect("service init"); - let world = Felt::from(10_u64); - let table = Felt::from(20_u64); - let entity = Felt::from(30_u64); - seed_entity( - &service, - TableKind::Entity, - world, - table, - "test-Lobby", - entity, - true, - ) - .await; - - let response = service - .subscribe_entities(Request::new(SubscribeEntitiesRequest { - clause: Some(member_bool_clause("test-Lobby", "open", true)), - world_addresses: vec![world.to_bytes_be().to_vec()], - })) - .await - .expect("subscribe entities"); - let mut stream = response.into_inner(); - - let setup = timeout(Duration::from_secs(1), stream.next()) - .await - .expect("setup timeout") - .expect("setup frame") - .expect("setup ok"); - let subscription_id = setup.subscription_id; - assert!(setup.entity.is_none()); - + async fn seed_model_with_bool( + service: &EcsService, + kind: TableKind, + world_address: Felt, + table_id: Felt, + table_name: &str, + entity_id: Felt, + field_name: &str, + field_value: bool, + ) { + sqlx::query( + "CREATE TABLE IF NOT EXISTS dojo_tables ( + owner BLOB NOT NULL, + id BLOB NOT NULL, + name TEXT NOT NULL, + attributes TEXT NOT NULL, + keys_json TEXT NOT NULL, + values_json TEXT NOT NULL, + legacy INTEGER NOT NULL, + created_at INTEGER, + updated_at INTEGER, + created_block INTEGER, + updated_block INTEGER, + created_tx BLOB, + updated_tx BLOB, + PRIMARY KEY(owner, id) + )", + ) + .execute(&service.state.pool) + .await + .expect("create dojo_tables"); + sqlx::query( + "CREATE TABLE IF NOT EXISTS dojo_columns ( + owner BLOB NOT NULL, + table_id BLOB NOT NULL, + id BLOB NOT NULL, + payload TEXT NOT NULL, + PRIMARY KEY(owner, table_id, id) + )", + ) + .execute(&service.state.pool) + .await + .expect("create dojo_columns"); + + let table = CreateTable { + id: table_id, + name: table_name.to_string(), + attributes: vec![], + primary: PrimaryDef { + name: "entity_id".to_string(), + attributes: vec![], + type_def: PrimaryTypeDef::Felt252, + }, + columns: vec![ColumnDef { + id: Felt::from(1_u64), + name: field_name.to_string(), + attributes: vec![], + type_def: TypeDef::Bool, + }], + }; + + service.cache_created_table(world_address, &table).await; + service + .record_table_kind(world_address, table_id, kind) + .await + .expect("record table kind"); + service + .upsert_entity_meta(kind, world_address, table_id, entity_id, 1, false) + .await + .expect("upsert entity meta"); + + let row_json = serde_json::json!({ field_name: field_value }).to_string(); + sqlx::query( + "INSERT INTO torii_ecs_entity_models ( + kind, world_address, table_id, entity_id, row_json, updated_at + ) VALUES (?1, ?2, ?3, ?4, ?5, ?6) + ON CONFLICT(kind, world_address, table_id, entity_id) DO UPDATE SET + row_json = excluded.row_json, + updated_at = excluded.updated_at", + ) + .bind(kind.as_str()) + .bind(felt_hex(world_address)) + .bind(felt_hex(table_id)) + .bind(felt_hex(entity_id)) + .bind(row_json) + .bind(1_i64) + .execute(&service.state.pool) + .await + .expect("insert entity model"); + } + + #[tokio::test] + async fn subscribe_entities_update_flow() { + let db_path = test_db_path("entities-sub"); + let service = EcsService::new(&db_path, Some(1), None, None, None) + .await + .expect("service init"); + let world = Felt::from(10_u64); + let table = Felt::from(20_u64); + let entity = Felt::from(30_u64); + seed_entity( + &service, + TableKind::Entity, + world, + table, + "test-Lobby", + entity, + true, + ) + .await; + + let response = service + .subscribe_entities(Request::new(SubscribeEntitiesRequest { + clause: Some(member_bool_clause("test-Lobby", "open", true)), + world_addresses: vec![world.to_bytes_be().to_vec()], + })) + .await + .expect("subscribe entities"); + let mut stream = response.into_inner(); + + let setup = timeout(Duration::from_secs(1), stream.next()) + .await + .expect("setup timeout") + .expect("setup frame") + .expect("setup ok"); + let subscription_id = setup.subscription_id; + assert!(setup.entity.is_none()); + service .publish_entity_update(TableKind::Entity, world, entity) .await @@ -5049,7 +5781,7 @@ mod tests { #[tokio::test] async fn subscribe_event_messages_update_flow() { let db_path = test_db_path("event-messages-sub"); - let service = EcsService::new(&db_path, Some(1)) + let service = EcsService::new(&db_path, Some(1), None, None, None) .await .expect("service init"); let world = Felt::from(101_u64); @@ -5115,7 +5847,7 @@ mod tests { #[tokio::test] async fn subscribe_events_keys_filter() { let db_path = test_db_path("events-sub"); - let service = EcsService::new(&db_path, Some(1)) + let service = EcsService::new(&db_path, Some(1), None, None, None) .await .expect("service init"); let world = Felt::from(1_u64); @@ -5180,7 +5912,7 @@ mod tests { #[tokio::test] async fn subscribe_contracts_query_filter() { let db_path = test_db_path("contracts-sub"); - let service = EcsService::new(&db_path, Some(1)) + let service = EcsService::new(&db_path, Some(1), None, None, None) .await .expect("service init"); let world_contract = Felt::from(1111_u64); @@ -5227,7 +5959,7 @@ mod tests { #[tokio::test] async fn retrieve_entities_without_filters_uses_bounded_query() { let db_path = test_db_path("retrieve-entities"); - let service = EcsService::new(&db_path, Some(1)) + let service = EcsService::new(&db_path, Some(1), None, None, None) .await .expect("service init"); let world = Felt::from(900_u64); @@ -5276,4 +6008,523 @@ mod tests { assert_eq!(response.entities.len(), 1); assert!(!response.next_cursor.is_empty() || response.entities.len() < 10); } + + #[tokio::test] + async fn retrieve_entities_includes_co_located_models_for_matching_entity() { + let db_path = test_db_path("retrieve-entities-colocated"); + let service = EcsService::new(&db_path, Some(1), None, None, None) + .await + .expect("service init"); + let world = Felt::from(910_u64); + let entity = Felt::from(1010_u64); + + seed_model_with_bool( + &service, + TableKind::Entity, + world, + Felt::from(911_u64), + "NUMS-QuestDefinition", + entity, + "enabled", + true, + ) + .await; + seed_model_with_bool( + &service, + TableKind::Entity, + world, + Felt::from(912_u64), + "NUMS-QuestAssociation", + entity, + "linked", + true, + ) + .await; + + let response = service + .retrieve_entities(Request::new(RetrieveEntitiesRequest { + query: Some(types::Query { + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 10, + direction: PaginationDirection::Forward as i32, + order_by: vec![], + }), + world_addresses: vec![world.to_bytes_be().to_vec()], + models: vec![], + clause: Some(member_bool_clause("NUMS-QuestDefinition", "enabled", true)), + no_hashed_keys: false, + historical: false, + }), + })) + .await + .expect("retrieve entities") + .into_inner(); + + assert_eq!(response.entities.len(), 1); + let model_names = response.entities[0] + .models + .iter() + .map(|model| model.name.clone()) + .collect::>(); + assert_eq!(model_names.len(), 2); + assert!(model_names.contains("NUMS-QuestDefinition")); + assert!(model_names.contains("NUMS-QuestAssociation")); + } + + #[tokio::test] + async fn execute_sql_exposes_legacy_compat_views() { + let db_path = test_db_path("sql-compat"); + let erc20_url = temp_sqlite_url("erc20"); + let erc721_url = temp_sqlite_url("erc721"); + let service = EcsService::new(&db_path, Some(1), Some(&erc20_url), Some(&erc721_url), None) + .await + .expect("service init"); + service + .attach_erc_databases() + .await + .expect("attach erc dbs"); + + sqlx::query( + r#"CREATE TABLE "NUMS-LeaderboardScore" ( + entity_id TEXT PRIMARY KEY, + leaderboard_id TEXT, + game_id TEXT, + player TEXT, + score TEXT, + timestamp TEXT + )"#, + ) + .execute(&service.state.pool) + .await + .expect("create leaderboard table"); + sqlx::query( + r#"CREATE TABLE "NUMS-Claimed" ( + entity_id TEXT PRIMARY KEY, + player_id TEXT, + game_id TEXT, + reward TEXT, + time TEXT + )"#, + ) + .execute(&service.state.pool) + .await + .expect("create claimed table"); + sqlx::query( + r#"CREATE TABLE "NUMS-BundleIssuance" ( + entity_id TEXT PRIMARY KEY, + bundle_id INTEGER, + recipient TEXT, + issued_at TEXT + )"#, + ) + .execute(&service.state.pool) + .await + .expect("create bundle issuance table"); + + let player = "0x008b95a26e1392ed9e817607bfae2dd93efb9c66ee7db0b018091a11d9037006"; + sqlx::query(r#"INSERT INTO "NUMS-LeaderboardScore" (entity_id, leaderboard_id, game_id, player, score, timestamp) + VALUES (?1, ?2, ?3, ?4, ?5, ?6)"#) + .bind("score-1") + .bind("0x1") + .bind("0x2") + .bind(player) + .bind("0xb") + .bind("0x69c2703d") + .execute(&service.state.pool) + .await + .expect("insert leaderboard row"); + sqlx::query( + r#"INSERT INTO "NUMS-Claimed" (entity_id, player_id, game_id, reward, time) + VALUES (?1, ?2, ?3, ?4, ?5)"#, + ) + .bind("claim-1") + .bind(player) + .bind("0x2") + .bind("0x8c") + .bind("0x69c2703d") + .execute(&service.state.pool) + .await + .expect("insert claimed row"); + sqlx::query( + r#"INSERT INTO "NUMS-BundleIssuance" (entity_id, bundle_id, recipient, issued_at) + VALUES (?1, ?2, ?3, ?4)"#, + ) + .bind("issuance-1") + .bind(1_i64) + .bind(player) + .bind("0x69c2dbf7") + .execute(&service.state.pool) + .await + .expect("insert issuance row"); + + let world = + Felt::from_hex("0x048d9413e93af3644407a952ba99596310cb285575819aed9251fe9f45883be2") + .expect("world"); + let table = + Felt::from_hex("0x027fb20c50c1bc8220c8d7643d495f921c67c7c69ffe3cb6b5d5a81dd1564fd7") + .expect("table"); + let entity = Felt::from(12345_u64); + service + .record_table_kind(world, table, TableKind::EventMessage) + .await + .expect("record table kind"); + service + .upsert_entity_meta( + TableKind::EventMessage, + world, + table, + entity, + 1_774_351_127, + false, + ) + .await + .expect("upsert event meta"); + let row_json = serde_json::json!({ + "amount": "0x1e3660", + "bundle_id": 1, + "payment_token": "0x0037d4aef94ac5e9b2d49eb763bfa2db76f3f82e31506a78ef8458dc458e820b", + "recipient": player, + "referrer": { "Some": player } + }) + .to_string(); + sqlx::query( + "INSERT INTO torii_ecs_entity_models ( + kind, world_address, table_id, entity_id, row_json, updated_at + ) VALUES (?1, ?2, ?3, ?4, ?5, ?6)", + ) + .bind(TableKind::EventMessage.as_str()) + .bind(felt_hex(world)) + .bind(felt_hex(table)) + .bind(felt_hex(entity)) + .bind(row_json) + .bind(1_774_351_127_i64) + .execute(&service.state.pool) + .await + .expect("insert event model"); + + sqlx::query( + "CREATE TABLE erc20.balances ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + token BLOB NOT NULL, + wallet BLOB NOT NULL, + balance BLOB NOT NULL, + last_block TEXT NOT NULL, + last_tx_hash BLOB NOT NULL + )", + ) + .execute(&service.state.pool) + .await + .expect("create erc20 balances"); + sqlx::query( + "INSERT INTO erc20.balances (token, wallet, balance, last_block, last_tx_hash) + VALUES (?1, ?2, ?3, ?4, ?5)", + ) + .bind(Felt::from(0x99_u64).to_bytes_be().to_vec()) + .bind(Felt::from(0x55_u64).to_bytes_be().to_vec()) + .bind(vec![1_u8]) + .bind("1") + .bind(vec![0_u8; 32]) + .execute(&service.state.pool) + .await + .expect("insert erc20 balance"); + + sqlx::query( + "CREATE TABLE erc721.nft_ownership ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + token BLOB NOT NULL, + token_id BLOB NOT NULL, + owner BLOB NOT NULL, + block_number TEXT NOT NULL, + tx_hash BLOB NOT NULL, + timestamp TEXT NOT NULL + )", + ) + .execute(&service.state.pool) + .await + .expect("create erc721 ownership"); + sqlx::query( + "INSERT INTO erc721.nft_ownership (token, token_id, owner, block_number, tx_hash, timestamp) + VALUES (?1, ?2, ?3, ?4, ?5, ?6)", + ) + .bind(Felt::from(0x1137_u64).to_bytes_be().to_vec()) + .bind(vec![0x04_u8]) + .bind(Felt::from(0x25145_u64).to_bytes_be().to_vec()) + .bind("1") + .bind(vec![1_u8; 32]) + .bind("1774350232") + .execute(&service.state.pool) + .await + .expect("insert erc721 ownership"); + + let controllers = service + .execute_sql(Request::new(types::SqlQueryRequest { + query: "SELECT address, username FROM controllers LIMIT 5".to_string(), + })) + .await + .expect("controllers query") + .into_inner(); + let controller_rows = sql_rows_to_maps(&controllers.rows); + assert!(!controller_rows.is_empty()); + assert_eq!(controller_rows[0].get("address"), Some(&player.to_string())); + assert_eq!( + controller_rows[0].get("username"), + Some(&player.to_string()) + ); + + let historical = service + .execute_sql(Request::new(types::SqlQueryRequest { + query: "SELECT model_id, data FROM event_messages_historical LIMIT 5".to_string(), + })) + .await + .expect("historical query") + .into_inner(); + let historical_rows = sql_rows_to_maps(&historical.rows); + assert!(!historical_rows.is_empty()); + assert_eq!( + historical_rows[0].get("model_id"), + Some(&format!("{}:{}", felt_hex(world), felt_hex(table))) + ); + assert!(historical_rows[0] + .get("data") + .expect("data column") + .contains("\"recipient\"")); + + let token_balances = service + .execute_sql(Request::new(types::SqlQueryRequest { + query: "SELECT account_address, contract_address, token_id, balance FROM token_balances ORDER BY account_address, contract_address LIMIT 10".to_string(), + })) + .await + .expect("token balances query") + .into_inner(); + let token_rows = sql_rows_to_maps(&token_balances.rows); + assert!(token_rows.len() >= 2); + assert!(token_rows + .iter() + .any(|row| row.get("balance").is_some_and(|v| v.ends_with('1')))); + } + + #[tokio::test] + async fn retrieve_token_balances_uses_initialized_second_sqlite_connection() { + let db_path = test_db_path("token-balances-second-conn"); + let erc20_url = temp_sqlite_url("erc20-second-conn"); + let erc721_url = temp_sqlite_url("erc721-second-conn"); + let service = EcsService::new(&db_path, Some(2), Some(&erc20_url), Some(&erc721_url), None) + .await + .expect("service init"); + service + .attach_erc_databases() + .await + .expect("attach erc dbs"); + + let mut setup_conn = service + .acquire_initialized_connection() + .await + .expect("setup connection"); + sqlx::query( + "CREATE TABLE erc20.balances ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + token BLOB NOT NULL, + wallet BLOB NOT NULL, + balance BLOB NOT NULL, + last_block TEXT NOT NULL, + last_tx_hash BLOB NOT NULL + )", + ) + .execute(&mut *setup_conn) + .await + .expect("create erc20 balances"); + sqlx::query( + "INSERT INTO erc20.balances (token, wallet, balance, last_block, last_tx_hash) + VALUES (?1, ?2, ?3, ?4, ?5)", + ) + .bind(Felt::from(0x99_u64).to_bytes_be().to_vec()) + .bind(Felt::from(0x55_u64).to_bytes_be().to_vec()) + .bind(vec![1_u8]) + .bind("1") + .bind(vec![0_u8; 32]) + .execute(&mut *setup_conn) + .await + .expect("insert erc20 balance"); + drop(setup_conn); + + let _held_conn = service + .acquire_initialized_connection() + .await + .expect("held connection"); + + let response = service + .retrieve_token_balances(Request::new(RetrieveTokenBalancesRequest { + query: Some(types::TokenBalanceQuery { + account_addresses: vec![], + contract_addresses: vec![], + token_ids: vec![], + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 10, + direction: PaginationDirection::Forward as i32, + order_by: vec![], + }), + }), + })) + .await + .expect("retrieve token balances") + .into_inner(); + + assert_eq!(response.balances.len(), 1); + assert_eq!( + response.balances[0].contract_address, + Felt::from(0x99_u64).to_bytes_be().to_vec() + ); + assert_eq!( + response.balances[0].account_address, + Felt::from(0x55_u64).to_bytes_be().to_vec() + ); + assert_eq!(response.balances[0].balance, u256_bytes_from_u64(1)); + assert_eq!(response.balances[0].token_id, None); + } + + #[tokio::test] + async fn retrieve_token_contracts_normalizes_total_supply_to_u256_width() { + let db_path = test_db_path("token-contracts-encoding"); + let erc20_url = temp_sqlite_url("erc20-token-contracts-encoding"); + let service = EcsService::new(&db_path, Some(1), Some(&erc20_url), None, None) + .await + .expect("service init"); + service + .attach_erc_databases() + .await + .expect("attach erc dbs"); + + let mut conn = service + .acquire_initialized_connection() + .await + .expect("setup connection"); + sqlx::query( + "CREATE TABLE erc20.token_metadata ( + token BLOB PRIMARY KEY, + name TEXT, + symbol TEXT, + decimals TEXT, + total_supply BLOB + )", + ) + .execute(&mut *conn) + .await + .expect("create token metadata"); + sqlx::query( + "INSERT INTO erc20.token_metadata (token, name, symbol, decimals, total_supply) + VALUES (?1, ?2, ?3, ?4, ?5)", + ) + .bind(Felt::from(0x99_u64).to_bytes_be().to_vec()) + .bind("Nums") + .bind("NUMS") + .bind("18") + .bind(vec![0x12_u8, 0x34_u8, 0x56_u8]) + .execute(&mut *conn) + .await + .expect("insert token metadata"); + drop(conn); + + let response = service + .retrieve_token_contracts(Request::new(RetrieveTokenContractsRequest { + query: Some(types::TokenContractQuery { + contract_addresses: vec![], + contract_types: vec![ContractType::Erc20 as i32], + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 10, + direction: PaginationDirection::Forward as i32, + order_by: vec![], + }), + }), + })) + .await + .expect("retrieve token contracts") + .into_inner(); + + assert_eq!(response.token_contracts.len(), 1); + let contract = &response.token_contracts[0]; + let expected_total_supply = + canonical_u256_bytes_from_db(&[0x12, 0x34, 0x56]).expect("canonical"); + assert_eq!( + contract.contract_address, + Felt::from(0x99_u64).to_bytes_be().to_vec() + ); + assert_eq!(contract.total_supply.as_ref(), Some(&expected_total_supply)); + assert_eq!(contract.metadata, Vec::::new()); + assert_eq!(contract.token_metadata, Vec::::new()); + } + + #[tokio::test] + async fn retrieve_token_balances_normalizes_erc721_token_id_to_u256_width() { + let db_path = test_db_path("token-balances-encoding"); + let erc721_url = temp_sqlite_url("erc721-token-balances-encoding"); + let service = EcsService::new(&db_path, Some(1), None, Some(&erc721_url), None) + .await + .expect("service init"); + service + .attach_erc_databases() + .await + .expect("attach erc dbs"); + + let mut conn = service + .acquire_initialized_connection() + .await + .expect("setup connection"); + sqlx::query( + "CREATE TABLE erc721.nft_ownership ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + token BLOB NOT NULL, + token_id BLOB NOT NULL, + owner BLOB NOT NULL + )", + ) + .execute(&mut *conn) + .await + .expect("create ownership"); + sqlx::query( + "INSERT INTO erc721.nft_ownership (token, token_id, owner) + VALUES (?1, ?2, ?3)", + ) + .bind(Felt::from(0x1137_u64).to_bytes_be().to_vec()) + .bind(vec![0x04_u8]) + .bind(Felt::from(0x25145_u64).to_bytes_be().to_vec()) + .execute(&mut *conn) + .await + .expect("insert ownership"); + drop(conn); + + let response = service + .retrieve_token_balances(Request::new(RetrieveTokenBalancesRequest { + query: Some(types::TokenBalanceQuery { + account_addresses: vec![], + contract_addresses: vec![], + token_ids: vec![], + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 10, + direction: PaginationDirection::Forward as i32, + order_by: vec![], + }), + }), + })) + .await + .expect("retrieve token balances") + .into_inner(); + + assert_eq!(response.balances.len(), 1); + let balance = &response.balances[0]; + let expected_token_id = u256_bytes_from_u64(4); + assert_eq!( + balance.contract_address, + Felt::from(0x1137_u64).to_bytes_be().to_vec() + ); + assert_eq!( + balance.account_address, + Felt::from(0x25145_u64).to_bytes_be().to_vec() + ); + assert_eq!(balance.balance, u256_bytes_from_u64(1)); + assert_eq!(balance.token_id.as_ref(), Some(&expected_token_id)); + } } diff --git a/crates/torii-ecs-sink/src/sink.rs b/crates/torii-ecs-sink/src/sink.rs index 314a46af..8b48c473 100644 --- a/crates/torii-ecs-sink/src/sink.rs +++ b/crates/torii-ecs-sink/src/sink.rs @@ -22,9 +22,24 @@ pub struct EcsSink { } impl EcsSink { - pub async fn new(database_url: &str, max_connections: Option) -> Result { + pub async fn new( + database_url: &str, + max_connections: Option, + erc20_url: Option<&str>, + erc721_url: Option<&str>, + erc1155_url: Option<&str>, + ) -> Result { Ok(Self { - service: Arc::new(EcsService::new(database_url, max_connections).await?), + service: Arc::new( + EcsService::new( + database_url, + max_connections, + erc20_url, + erc721_url, + erc1155_url, + ) + .await?, + ), }) } @@ -222,6 +237,7 @@ impl Sink for EcsSink { _event_bus: Arc, _context: &SinkContext, ) -> Result<()> { + self.service.attach_erc_databases().await?; Ok(()) } } diff --git a/crates/torii-erc1155/src/storage.rs b/crates/torii-erc1155/src/storage.rs index e39345cd..f5c3f886 100644 --- a/crates/torii-erc1155/src/storage.rs +++ b/crates/torii-erc1155/src/storage.rs @@ -179,11 +179,11 @@ impl Erc1155Storage { to_addr BYTEA NOT NULL, token_id BYTEA NOT NULL, amount BYTEA NOT NULL, - is_batch BIGINT NOT NULL DEFAULT 0, - batch_index BIGINT NOT NULL DEFAULT 0, - block_number BIGINT NOT NULL, + is_batch TEXT NOT NULL DEFAULT '0', + batch_index TEXT NOT NULL DEFAULT '0', + block_number TEXT NOT NULL, tx_hash BYTEA NOT NULL, - timestamp BIGINT, + timestamp TEXT, UNIQUE(token, tx_hash, token_id, from_addr, to_addr, batch_index) ); CREATE INDEX IF NOT EXISTS idx_token_transfers_token ON erc1155.token_transfers(token); @@ -198,7 +198,7 @@ impl Erc1155Storage { token BYTEA NOT NULL, transfer_id BIGINT NOT NULL REFERENCES erc1155.token_transfers(id), direction TEXT NOT NULL CHECK(direction IN ('sent', 'received', 'both')), - block_number BIGINT NOT NULL + block_number TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_token_wallet_activity_wallet_block ON erc1155.token_wallet_activity(wallet_address, block_number DESC); CREATE INDEX IF NOT EXISTS idx_token_wallet_activity_wallet_token ON erc1155.token_wallet_activity(wallet_address, token, block_number DESC); @@ -208,10 +208,10 @@ impl Erc1155Storage { token BYTEA NOT NULL, owner BYTEA NOT NULL, operator BYTEA NOT NULL, - approved BIGINT NOT NULL, - block_number BIGINT NOT NULL, + approved TEXT NOT NULL, + block_number TEXT NOT NULL, tx_hash BYTEA NOT NULL, - timestamp BIGINT, + timestamp TEXT, UNIQUE(token, owner, operator) ); @@ -220,7 +220,7 @@ impl Erc1155Storage { token_id BYTEA NOT NULL, uri TEXT, metadata_json TEXT, - updated_at BIGINT NOT NULL DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT), + updated_at TEXT NOT NULL DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT::TEXT), PRIMARY KEY (token, token_id) ); @@ -252,7 +252,7 @@ impl Erc1155Storage { facet_key_id BIGINT NOT NULL REFERENCES erc1155.facet_keys(id) ON DELETE CASCADE, value_norm TEXT NOT NULL, value_display TEXT NOT NULL, - token_count BIGINT NOT NULL DEFAULT 0, + token_count TEXT NOT NULL DEFAULT '0', UNIQUE(token, facet_key_id, value_norm) ); CREATE INDEX IF NOT EXISTS idx_facet_values_token_key_value ON erc1155.facet_values(token, facet_key_id, value_norm); @@ -273,8 +273,8 @@ impl Erc1155Storage { wallet BYTEA NOT NULL, token_id BYTEA NOT NULL, balance BYTEA NOT NULL, - last_block BIGINT NOT NULL, - updated_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT), + last_block TEXT NOT NULL, + updated_at TEXT DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT::TEXT), UNIQUE(contract, wallet, token_id) ); CREATE INDEX IF NOT EXISTS idx_erc1155_balances_contract ON erc1155.erc1155_balances(contract); @@ -288,9 +288,9 @@ impl Erc1155Storage { token_id BYTEA NOT NULL, computed_balance BYTEA NOT NULL, actual_balance BYTEA NOT NULL, - adjusted_at_block BIGINT NOT NULL, + adjusted_at_block TEXT NOT NULL, tx_hash BYTEA NOT NULL, - created_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT) + created_at TEXT DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT::TEXT) ); CREATE INDEX IF NOT EXISTS idx_erc1155_adjustments_wallet ON erc1155.erc1155_balance_adjustments(wallet); @@ -338,11 +338,11 @@ impl Erc1155Storage { to_addr BLOB NOT NULL, token_id BLOB NOT NULL, amount BLOB NOT NULL, - is_batch INTEGER NOT NULL DEFAULT 0, - batch_index INTEGER NOT NULL DEFAULT 0, - block_number INTEGER NOT NULL, + is_batch TEXT NOT NULL DEFAULT '0', + batch_index TEXT NOT NULL DEFAULT '0', + block_number TEXT NOT NULL, tx_hash BLOB NOT NULL, - timestamp INTEGER, + timestamp TEXT, UNIQUE(token, tx_hash, token_id, from_addr, to_addr, batch_index) )", [], @@ -381,7 +381,7 @@ impl Erc1155Storage { token BLOB NOT NULL, transfer_id INTEGER NOT NULL, direction TEXT NOT NULL CHECK(direction IN ('sent', 'received', 'both')), - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, FOREIGN KEY (transfer_id) REFERENCES token_transfers(id) )", [], @@ -406,10 +406,10 @@ impl Erc1155Storage { token BLOB NOT NULL, owner BLOB NOT NULL, operator BLOB NOT NULL, - approved INTEGER NOT NULL, - block_number INTEGER NOT NULL, + approved TEXT NOT NULL, + block_number TEXT NOT NULL, tx_hash BLOB NOT NULL, - timestamp INTEGER, + timestamp TEXT, UNIQUE(token, owner, operator) )", [], @@ -422,7 +422,7 @@ impl Erc1155Storage { token_id BLOB NOT NULL, uri TEXT, metadata_json TEXT, - updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + updated_at TEXT NOT NULL DEFAULT (strftime('%s', 'now')), PRIMARY KEY (token, token_id) )", [], @@ -458,7 +458,7 @@ impl Erc1155Storage { facet_key_id INTEGER NOT NULL, value_norm TEXT NOT NULL, value_display TEXT NOT NULL, - token_count INTEGER NOT NULL DEFAULT 0, + token_count TEXT NOT NULL DEFAULT '0', UNIQUE(token, facet_key_id, value_norm), FOREIGN KEY (facet_key_id) REFERENCES facet_keys(id) ON DELETE CASCADE ); @@ -486,8 +486,8 @@ impl Erc1155Storage { wallet BLOB NOT NULL, token_id BLOB NOT NULL, balance BLOB NOT NULL, - last_block INTEGER NOT NULL, - updated_at INTEGER DEFAULT (strftime('%s', 'now')), + last_block TEXT NOT NULL, + updated_at TEXT DEFAULT (strftime('%s', 'now')), UNIQUE(contract, wallet, token_id) )", [], @@ -518,9 +518,9 @@ impl Erc1155Storage { token_id BLOB NOT NULL, computed_balance BLOB NOT NULL, actual_balance BLOB NOT NULL, - adjusted_at_block INTEGER NOT NULL, + adjusted_at_block TEXT NOT NULL, tx_hash BLOB NOT NULL, - created_at INTEGER DEFAULT (strftime('%s', 'now')) + created_at TEXT DEFAULT (strftime('%s', 'now')) )", [], )?; @@ -568,7 +568,7 @@ impl Erc1155Storage { { let mut stmt = tx.prepare_cached( "INSERT OR IGNORE INTO token_transfers (token, operator, from_addr, to_addr, token_id, amount, is_batch, batch_index, block_number, tx_hash, timestamp) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, COALESCE(?11, strftime('%s', 'now')))", + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, COALESCE(?11, CAST(strftime('%s', 'now') AS TEXT)))", )?; let mut wallet_both_stmt = tx.prepare_cached( "INSERT INTO token_wallet_activity (wallet_address, token, transfer_id, direction, block_number) @@ -592,6 +592,7 @@ impl Erc1155Storage { let amount_blob = u256_to_blob(transfer.amount); let tx_hash_blob = felt_to_blob(transfer.tx_hash); + let ts_str = transfer.timestamp.map(|t| t.to_string()); let rows = stmt.execute(params![ &token_blob, &operator_blob, @@ -599,11 +600,11 @@ impl Erc1155Storage { &to_blob, &token_id_blob, &amount_blob, - transfer.is_batch as i32, - transfer.batch_index, - transfer.block_number, + (transfer.is_batch as i32).to_string(), + transfer.batch_index.to_string(), + transfer.block_number.to_string(), &tx_hash_blob, - transfer.timestamp, + ts_str, ])?; if rows > 0 { @@ -611,6 +612,7 @@ impl Erc1155Storage { let transfer_id = tx.last_insert_rowid(); // Insert wallet activity records + let block_str = transfer.block_number.to_string(); if transfer.from != Felt::ZERO && transfer.to != Felt::ZERO && transfer.from == transfer.to @@ -619,7 +621,7 @@ impl Erc1155Storage { &from_blob, &token_blob, transfer_id, - transfer.block_number + &block_str ])?; } else { if transfer.from != Felt::ZERO { @@ -627,7 +629,7 @@ impl Erc1155Storage { &from_blob, &token_blob, transfer_id, - transfer.block_number + &block_str ])?; } if transfer.to != Felt::ZERO { @@ -635,7 +637,7 @@ impl Erc1155Storage { &to_blob, &token_blob, transfer_id, - transfer.block_number + &block_str ])?; } } @@ -667,7 +669,7 @@ impl Erc1155Storage { { let mut stmt = tx.prepare_cached( "INSERT OR REPLACE INTO token_operators (token, owner, operator, approved, block_number, tx_hash, timestamp) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, COALESCE(?7, strftime('%s', 'now')))", + VALUES (?1, ?2, ?3, ?4, ?5, ?6, COALESCE(?7, CAST(strftime('%s', 'now') AS TEXT)))", )?; for approval in approvals { @@ -676,14 +678,15 @@ impl Erc1155Storage { let operator_blob = felt_to_blob(approval.operator); let tx_hash_blob = felt_to_blob(approval.tx_hash); + let ts_str = approval.timestamp.map(|t| t.to_string()); stmt.execute(params![ &token_blob, &owner_blob, &operator_blob, - approval.approved as i32, - approval.block_number, + (approval.approved as i32).to_string(), + approval.block_number.to_string(), &tx_hash_blob, - approval.timestamp, + ts_str, ])?; inserted += 1; @@ -814,18 +817,18 @@ impl Erc1155Storage { if let Some(block_min) = block_from { query.push_str(" AND t.block_number >= ?"); - params_vec.push(Box::new(block_min as i64)); + params_vec.push(Box::new(block_min.to_string())); } if let Some(block_max) = block_to { query.push_str(" AND t.block_number <= ?"); - params_vec.push(Box::new(block_max as i64)); + params_vec.push(Box::new(block_max.to_string())); } if let Some(c) = cursor { query.push_str(" AND (t.block_number < ? OR (t.block_number = ? AND t.id < ?))"); - params_vec.push(Box::new(c.block_number as i64)); - params_vec.push(Box::new(c.block_number as i64)); + params_vec.push(Box::new(c.block_number.to_string())); + params_vec.push(Box::new(c.block_number.to_string())); params_vec.push(Box::new(c.id)); } @@ -844,11 +847,11 @@ impl Erc1155Storage { let to_bytes: Vec = row.get(4)?; let token_id_bytes: Vec = row.get(5)?; let amount_bytes: Vec = row.get(6)?; - let is_batch: i32 = row.get(7)?; - let batch_index: i32 = row.get(8)?; - let block_number: i64 = row.get(9)?; + let is_batch_str: String = row.get(7)?; + let batch_index_str: String = row.get(8)?; + let block_number_str: String = row.get(9)?; let tx_hash_bytes: Vec = row.get(10)?; - let timestamp: Option = row.get(11)?; + let timestamp_str: Option = row.get(11)?; Ok(TokenTransferData { id: Some(id), @@ -858,11 +861,11 @@ impl Erc1155Storage { to: blob_to_felt(&to_bytes), token_id: blob_to_u256(&token_id_bytes), amount: blob_to_u256(&amount_bytes), - is_batch: is_batch != 0, - batch_index: batch_index as u32, - block_number: block_number as u64, + is_batch: is_batch_str.parse::().unwrap_or(0) != 0, + batch_index: batch_index_str.parse::().unwrap_or(0), + block_number: block_number_str.parse::().unwrap_or(0), tx_hash: blob_to_felt(&tx_hash_bytes), - timestamp, + timestamp: timestamp_str.and_then(|s| s.parse::().ok()), }) })?; @@ -988,12 +991,13 @@ impl Erc1155Storage { return self.pg_get_latest_block().await; } let conn = self.conn.lock().unwrap(); - let block: Option = conn + let block: Option = conn .query_row("SELECT MAX(block_number) FROM token_transfers", [], |row| { row.get(0) }) - .ok(); - Ok(block.map(|b| b as u64)) + .ok() + .flatten(); + Ok(block.and_then(|b| b.parse::().ok())) } // ===== Balance Tracking Methods ===== @@ -1042,7 +1046,7 @@ impl Erc1155Storage { let wallet_blob = felt_to_blob(wallet); let token_id_blob = u256_to_blob(token_id); - let result: Option<(Vec, i64)> = conn + let result: Option<(Vec, String)> = conn .query_row( "SELECT balance, last_block FROM erc1155_balances WHERE contract = ? AND wallet = ? AND token_id = ?", @@ -1051,7 +1055,7 @@ impl Erc1155Storage { ) .ok(); - Ok(result.map(|(bytes, block)| (blob_to_u256(&bytes), block as u64))) + Ok(result.map(|(bytes, block_str)| (blob_to_u256(&bytes), block_str.parse::().unwrap_or(0)))) } /// Get balances for multiple (contract, wallet, token_id) tuples in a single query @@ -1342,7 +1346,7 @@ impl Erc1155Storage { &wallet_blob, &token_id_blob, &balance_blob, - last_block as i64, + last_block.to_string(), ])?; } } @@ -1369,7 +1373,7 @@ impl Erc1155Storage { &token_id_blob, &computed_blob, &actual_blob, - adj.adjusted_at_block as i64, + adj.adjusted_at_block.to_string(), &tx_hash_blob, ])?; } @@ -2054,11 +2058,11 @@ impl Erc1155Storage { let mut to_vec = Vec::with_capacity(transfers.len()); let mut token_id_vec = Vec::with_capacity(transfers.len()); let mut amount_vec = Vec::with_capacity(transfers.len()); - let mut is_batch_vec = Vec::with_capacity(transfers.len()); - let mut batch_index_vec = Vec::with_capacity(transfers.len()); - let mut block_vec = Vec::with_capacity(transfers.len()); + let mut is_batch_vec: Vec = Vec::with_capacity(transfers.len()); + let mut batch_index_vec: Vec = Vec::with_capacity(transfers.len()); + let mut block_vec: Vec = Vec::with_capacity(transfers.len()); let mut tx_hash_vec = Vec::with_capacity(transfers.len()); - let mut ts_vec = Vec::with_capacity(transfers.len()); + let mut ts_vec: Vec = Vec::with_capacity(transfers.len()); for transfer in transfers { token_vec.push(felt_to_blob(transfer.token)); @@ -2067,14 +2071,15 @@ impl Erc1155Storage { to_vec.push(felt_to_blob(transfer.to)); token_id_vec.push(u256_to_blob(transfer.token_id)); amount_vec.push(u256_to_blob(transfer.amount)); - is_batch_vec.push((transfer.is_batch as i32) as i64); - batch_index_vec.push(transfer.batch_index as i64); - block_vec.push(transfer.block_number as i64); + is_batch_vec.push((transfer.is_batch as i32).to_string()); + batch_index_vec.push(transfer.batch_index.to_string()); + block_vec.push(transfer.block_number.to_string()); tx_hash_vec.push(felt_to_blob(transfer.tx_hash)); ts_vec.push( transfer .timestamp - .unwrap_or_else(|| chrono::Utc::now().timestamp()), + .unwrap_or_else(|| chrono::Utc::now().timestamp()) + .to_string(), ); } @@ -2093,11 +2098,11 @@ impl Erc1155Storage { $4::bytea[], $5::bytea[], $6::bytea[], - $7::bigint[], - $8::bigint[], - $9::bigint[], + $7::text[], + $8::text[], + $9::text[], $10::bytea[], - $11::bigint[] + $11::text[] ) AS i(token, operator, from_addr, to_addr, token_id, amount, is_batch, batch_index, block_number, tx_hash, timestamp) ON CONFLICT (token, tx_hash, token_id, from_addr, to_addr, batch_index) DO NOTHING RETURNING id, token, from_addr, to_addr, block_number @@ -2147,22 +2152,23 @@ impl Erc1155Storage { let mut token_vec = Vec::with_capacity(approvals.len()); let mut owner_vec = Vec::with_capacity(approvals.len()); let mut operator_vec = Vec::with_capacity(approvals.len()); - let mut approved_vec = Vec::with_capacity(approvals.len()); - let mut block_vec = Vec::with_capacity(approvals.len()); + let mut approved_vec: Vec = Vec::with_capacity(approvals.len()); + let mut block_vec: Vec = Vec::with_capacity(approvals.len()); let mut tx_hash_vec = Vec::with_capacity(approvals.len()); - let mut ts_vec = Vec::with_capacity(approvals.len()); + let mut ts_vec: Vec = Vec::with_capacity(approvals.len()); for approval in approvals { token_vec.push(felt_to_blob(approval.token)); owner_vec.push(felt_to_blob(approval.owner)); operator_vec.push(felt_to_blob(approval.operator)); - approved_vec.push((approval.approved as i32) as i64); - block_vec.push(approval.block_number as i64); + approved_vec.push((approval.approved as i32).to_string()); + block_vec.push(approval.block_number.to_string()); tx_hash_vec.push(felt_to_blob(approval.tx_hash)); ts_vec.push( approval .timestamp - .unwrap_or_else(|| chrono::Utc::now().timestamp()), + .unwrap_or_else(|| chrono::Utc::now().timestamp()) + .to_string(), ); } @@ -2175,10 +2181,10 @@ impl Erc1155Storage { $1::bytea[], $2::bytea[], $3::bytea[], - $4::bigint[], - $5::bigint[], + $4::text[], + $5::text[], $6::bytea[], - $7::bigint[] + $7::text[] ) WITH ORDINALITY AS i(token, owner, operator, approved, block_number, tx_hash, timestamp, ord) ORDER BY token, owner, operator, ord DESC ON CONFLICT (token, owner, operator) DO UPDATE SET @@ -2219,7 +2225,7 @@ impl Erc1155Storage { let rows = client .execute( "INSERT INTO erc1155.token_uris (token, token_id, uri, updated_at) - SELECT DISTINCT ON (token, token_id) i.token, i.token_id, i.uri, EXTRACT(EPOCH FROM NOW())::BIGINT + SELECT DISTINCT ON (token, token_id) i.token, i.token_id, i.uri, EXTRACT(EPOCH FROM NOW())::BIGINT::TEXT FROM unnest( $1::bytea[], $2::bytea[], @@ -2307,15 +2313,15 @@ impl Erc1155Storage { } if let Some(block_min) = block_from { query.push_str(" AND t.block_number >= "); - query.push_str(&Self::pg_next_param(&mut params, block_min as i64)); + query.push_str(&Self::pg_next_param(&mut params, block_min.to_string())); } if let Some(block_max) = block_to { query.push_str(" AND t.block_number <= "); - query.push_str(&Self::pg_next_param(&mut params, block_max as i64)); + query.push_str(&Self::pg_next_param(&mut params, block_max.to_string())); } if let Some(c) = cursor { - let p1 = Self::pg_next_param(&mut params, c.block_number as i64); - let p2 = Self::pg_next_param(&mut params, c.block_number as i64); + let p1 = Self::pg_next_param(&mut params, c.block_number.to_string()); + let p2 = Self::pg_next_param(&mut params, c.block_number.to_string()); let p3 = Self::pg_next_param(&mut params, c.id); query.push_str(&format!( " AND (t.block_number < {p1} OR (t.block_number = {p2} AND t.id < {p3}))" @@ -2339,11 +2345,11 @@ impl Erc1155Storage { to: blob_to_felt(&row.get::>(4)), token_id: blob_to_u256(&row.get::>(5)), amount: blob_to_u256(&row.get::>(6)), - is_batch: row.get::(7) != 0, - batch_index: row.get::(8) as u32, - block_number: row.get::(9) as u64, + is_batch: row.get::(7).parse::().unwrap_or(0) != 0, + batch_index: row.get::(8).parse::().unwrap_or(0), + block_number: row.get::(9).parse::().unwrap_or(0), tx_hash: blob_to_felt(&row.get::>(10)), - timestamp: Some(row.get::(11)), + timestamp: row.get::(11).parse::().ok(), }) .collect(); @@ -2491,8 +2497,8 @@ impl Erc1155Storage { let row = client .query_one("SELECT MAX(block_number) FROM erc1155.token_transfers", &[]) .await?; - let v: Option = row.get(0); - Ok(v.map(|x| x as u64)) + let v: Option = row.get(0); + Ok(v.and_then(|x| x.parse::().ok())) } async fn pg_get_balance( @@ -2537,7 +2543,7 @@ impl Erc1155Storage { Ok(row.map(|r| { ( blob_to_u256(&r.get::>(0)), - r.get::(1) as u64, + r.get::(1).parse::().unwrap_or(0), ) })) } @@ -2696,13 +2702,13 @@ impl Erc1155Storage { ON CONFLICT(contract, wallet, token_id) DO UPDATE SET balance = EXCLUDED.balance, last_block = EXCLUDED.last_block, - updated_at = EXTRACT(EPOCH FROM NOW())::BIGINT", + updated_at = EXTRACT(EPOCH FROM NOW())::BIGINT::TEXT", &[ &felt_to_blob(*contract), &felt_to_blob(*wallet), &u256_to_blob(*token_id), &u256_to_blob(*balance), - &(last_block as i64), + &last_block.to_string(), ], ).await?; } @@ -2718,7 +2724,7 @@ impl Erc1155Storage { &u256_to_blob(adj.token_id), &u256_to_blob(adj.computed_balance), &u256_to_blob(adj.actual_balance), - &(adj.adjusted_at_block as i64), + &adj.adjusted_at_block.to_string(), &felt_to_blob(adj.tx_hash), ], ).await?; @@ -3040,7 +3046,7 @@ impl TokenUriStore for Erc1155Storage { tx.execute( "INSERT INTO erc1155.token_uris (token, token_id, uri, metadata_json, updated_at) - VALUES ($1, $2, $3, $4, EXTRACT(EPOCH FROM NOW())::BIGINT) + VALUES ($1, $2, $3, $4, EXTRACT(EPOCH FROM NOW())::BIGINT::TEXT) ON CONFLICT(token, token_id) DO UPDATE SET uri = EXCLUDED.uri, metadata_json = EXCLUDED.metadata_json, @@ -3195,7 +3201,7 @@ fn sqlite_sync_facets_for_token( for facet_value_id in existing_rows { tx.execute( "UPDATE facet_values - SET token_count = CASE WHEN token_count > 0 THEN token_count - 1 ELSE 0 END + SET token_count = CAST(CASE WHEN CAST(token_count AS INTEGER) > 0 THEN CAST(token_count AS INTEGER) - 1 ELSE 0 END AS TEXT) WHERE id = ?1", params![facet_value_id], )?; @@ -3236,7 +3242,7 @@ fn sqlite_sync_facets_for_token( params![&token_blob, &token_id_blob, facet_key_id, facet_value_id], )?; tx.execute( - "UPDATE facet_values SET token_count = token_count + 1 WHERE id = ?1", + "UPDATE facet_values SET token_count = CAST(CAST(token_count AS INTEGER) + 1 AS TEXT) WHERE id = ?1", params![facet_value_id], )?; } @@ -3263,7 +3269,7 @@ async fn pg_sync_facets_for_token( let facet_value_id: i64 = row.get(0); tx.execute( "UPDATE erc1155.facet_values - SET token_count = GREATEST(token_count - 1, 0) + SET token_count = CAST(GREATEST(CAST(token_count AS BIGINT) - 1, 0) AS TEXT) WHERE id = $1", &[&facet_value_id], ) @@ -3314,7 +3320,7 @@ async fn pg_sync_facets_for_token( ) .await?; tx.execute( - "UPDATE erc1155.facet_values SET token_count = token_count + 1 WHERE id = $1", + "UPDATE erc1155.facet_values SET token_count = CAST(CAST(token_count AS BIGINT) + 1 AS TEXT) WHERE id = $1", &[&facet_value_id], ) .await?; diff --git a/crates/torii-erc20/proto/erc20.proto b/crates/torii-erc20/proto/erc20.proto index 877cf943..1335d227 100644 --- a/crates/torii-erc20/proto/erc20.proto +++ b/crates/torii-erc20/proto/erc20.proto @@ -240,6 +240,8 @@ message TokenMetadataEntry { optional string symbol = 3; // Token decimals (e.g. 18) optional uint32 decimals = 4; + // Total supply as U256 (variable length, up to 32 bytes) + optional bytes total_supply = 5; } // Response for GetTokenMetadata RPC diff --git a/crates/torii-erc20/src/generated/erc20_descriptor.bin b/crates/torii-erc20/src/generated/erc20_descriptor.bin index 6c0fb0b334f10e8bdab61c259edfec7f5bcbad93..f7ab92a33e071ed9c86e2f3d1959cf0d140af500 100644 GIT binary patch delta 1056 zcmYk5&rcIU6vuboPM39-TG$qf<%b246mW&6g%(?45TS$^57K+ptC$ikBpxxOsZG5w zO`2euG^uG);>B?Fq=_Dtn~7Kd0iy|N>cKbD-K@v&oA>#=H`&=&`=1X~_UYigI%|+0 z+%jHXH)mLXAzyg3n|r>$x3~LZ#1kfw{w?)^A*(yG$ln>$gLiz)oBO}@?3?kCUiy_~ zeWpiIPS4&9=#%8n+1uy`GPcPm^#e8OZ$hU-$#7PT2=_+t^T3Uamw7}(ucM#Y(IWt_ z=|m!;|Ed#J5vQ)PC<7WWwF{#BBdr+G+99)ZY)uOAu*)yU*Hc|rKya3IC6iMug=-C&^bmL@ zo*p;^J;-LUG;C@|puFba;}PEx=p(p3rNd&=BKIxDtRhe*RairF5sZ)%(OiV_37f#f z63-)1atX0Z$tA=tB|$968DP>f|GE^l$}Ry&l))IWX8;mq7#(BtlE75q*0Oc8;u0zn z6)=J}p^6>|jk1RfG{w}8K{@56<(%&rbT8XtR8z#|s{Cmp$i0b}RRujDSW(A~sxTCB zBC4to%h(josUfv()m(xgQF94#!I~gaatjZT9YH$XKBKW868RCK`u&~Cq zC4s5V?^jDWiH)vB^pXv yu0#`ku0%sgOGxlnz=?e(ZS%yf$Xpxr0eem#3feFjb|MmOm`^>{_MYVn`Pe_6Q=xtU delta 912 zcmYL|&1(}u7>9S>oou$V4T+m=8xva-DJ37S?UIkSNs1JWt-)KpSNsR6Vm(U;Aw~}+ zLm&_ctOU}l;eiHPY9KdK_;@@(HT;c(7BmG0E$fq;Z?kwi>M z5V42E*ZhcrImz5$H9X&vNiPY%U#`b4iN3;exU_6)El^(bK{*?3fu3Lv7A=b-xB2IC z(QX4}o(k8{+y*1*M>Mx#bxjgD?C_hFqTLAyah6U%5F|Q+*z`KUq+R}|;@I7Q03^C# zBxDC5(S_7CR`3W+J^rI&-|7W~ibM~L6-lUK41HxNY4>%ifVyE}XK z5OnWpumi**#MfnqxZDsn_gT{;Fpape`@kN79+z8GBt~F)UjqunI`C6*`P1quH>&x%3%d7~C=MazLaHRG5Pp*`+-~?0 zB`(~1C?zPv>%a} PLZS9pd-Ck$`AP8~Bxizc diff --git a/crates/torii-erc20/src/generated/torii.sinks.erc20.rs b/crates/torii-erc20/src/generated/torii.sinks.erc20.rs index 53f9970d..e45d53d9 100644 --- a/crates/torii-erc20/src/generated/torii.sinks.erc20.rs +++ b/crates/torii-erc20/src/generated/torii.sinks.erc20.rs @@ -282,6 +282,9 @@ pub struct TokenMetadataEntry { /// Token decimals (e.g. 18) #[prost(uint32, optional, tag = "4")] pub decimals: ::core::option::Option, + /// Total supply as U256 (variable length, up to 32 bytes) + #[prost(bytes = "vec", optional, tag = "5")] + pub total_supply: ::core::option::Option<::prost::alloc::vec::Vec>, } /// Response for GetTokenMetadata RPC #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/crates/torii-erc20/src/grpc_service.rs b/crates/torii-erc20/src/grpc_service.rs index 2d983ec1..255964e0 100644 --- a/crates/torii-erc20/src/grpc_service.rs +++ b/crates/torii-erc20/src/grpc_service.rs @@ -458,11 +458,12 @@ impl Erc20Trait for Erc20Service { .ok_or_else(|| Status::invalid_argument("Invalid token address"))?; let entries = match self.storage.get_token_metadata(token).await { - Ok(Some((name, symbol, decimals))) => vec![TokenMetadataEntry { + Ok(Some((name, symbol, decimals, total_supply))) => vec![TokenMetadataEntry { token: token.to_bytes_be().to_vec(), name, symbol, decimals: decimals.map(|d| d as u32), + total_supply: total_supply.map(u256_to_bytes), }], Ok(None) => vec![], Err(e) => return Err(Status::internal(format!("Query failed: {e}"))), @@ -489,11 +490,12 @@ impl Erc20Trait for Erc20Service { let entries = all .into_iter() - .map(|(token, name, symbol, decimals)| TokenMetadataEntry { + .map(|(token, name, symbol, decimals, total_supply)| TokenMetadataEntry { token: token.to_bytes_be().to_vec(), name, symbol, decimals: decimals.map(|d| d as u32), + total_supply: total_supply.map(u256_to_bytes), }) .collect(); diff --git a/crates/torii-erc20/src/handlers.rs b/crates/torii-erc20/src/handlers.rs index da4bfb52..cc4b4f8a 100644 --- a/crates/torii-erc20/src/handlers.rs +++ b/crates/torii-erc20/src/handlers.rs @@ -9,7 +9,7 @@ use std::sync::{Arc, Mutex}; use torii::command::CommandHandler; use torii::etl::sink::EventBus; use torii::UpdateType; -use torii_common::MetadataFetcher; +use torii_common::{u256_to_bytes, MetadataFetcher}; use crate::proto; use crate::storage::Erc20Storage; @@ -105,6 +105,7 @@ impl CommandHandler for Erc20MetadataCommandHandler { meta.name.as_deref(), meta.symbol.as_deref(), meta.decimals, + meta.total_supply, ) .await?; @@ -115,6 +116,7 @@ impl CommandHandler for Erc20MetadataCommandHandler { name: meta.name, symbol: meta.symbol, decimals: meta.decimals.map(|d| d as u32), + total_supply: meta.total_supply.map(u256_to_bytes), }; let mut buf = Vec::new(); diff --git a/crates/torii-erc20/src/storage.rs b/crates/torii-erc20/src/storage.rs index f08b2599..58737a6a 100644 --- a/crates/torii-erc20/src/storage.rs +++ b/crates/torii-erc20/src/storage.rs @@ -113,14 +113,14 @@ struct ActivityInsertRow { token: Vec, ref_id: i64, role: &'static str, - block_number: i64, + block_number: String, } struct BalanceUpsertRow { token: Vec, wallet: Vec, balance: Vec, - last_block: i64, + last_block: String, last_tx_hash: Vec, } @@ -129,7 +129,7 @@ struct AdjustmentInsertRow { wallet: Vec, computed_balance: Vec, actual_balance: Vec, - adjusted_at_block: i64, + adjusted_at_block: String, tx_hash: Vec, } @@ -357,9 +357,9 @@ impl Erc20Storage { from_addr BYTEA NOT NULL, to_addr BYTEA NOT NULL, amount BYTEA NOT NULL, - block_number BIGINT NOT NULL, + block_number TEXT NOT NULL, tx_hash BYTEA NOT NULL, - timestamp BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT), + timestamp TEXT DEFAULT (EXTRACT(EPOCH FROM NOW())::TEXT), UNIQUE(token, tx_hash, from_addr, to_addr) ); CREATE INDEX IF NOT EXISTS idx_transfers_token ON erc20.transfers(token); @@ -376,9 +376,9 @@ impl Erc20Storage { owner BYTEA NOT NULL, spender BYTEA NOT NULL, amount BYTEA NOT NULL, - block_number BIGINT NOT NULL, + block_number TEXT NOT NULL, tx_hash BYTEA NOT NULL, - timestamp BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT), + timestamp TEXT DEFAULT (EXTRACT(EPOCH FROM NOW())::TEXT), UNIQUE(token, tx_hash, owner, spender) ); CREATE INDEX IF NOT EXISTS idx_approvals_owner ON erc20.approvals(owner, block_number DESC); @@ -391,7 +391,7 @@ impl Erc20Storage { token BYTEA NOT NULL, transfer_id BIGINT NOT NULL REFERENCES erc20.transfers(id), direction TEXT NOT NULL CHECK(direction IN ('sent', 'received', 'both')), - block_number BIGINT NOT NULL + block_number TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_wallet_activity_wallet_block ON erc20.wallet_activity(wallet_address, block_number DESC); CREATE INDEX IF NOT EXISTS idx_wallet_activity_wallet_token ON erc20.wallet_activity(wallet_address, token, block_number DESC); @@ -403,7 +403,7 @@ impl Erc20Storage { token BYTEA NOT NULL, approval_id BIGINT NOT NULL REFERENCES erc20.approvals(id), role TEXT NOT NULL CHECK(role IN ('owner', 'spender', 'both')), - block_number BIGINT NOT NULL + block_number TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_approval_activity_account_block ON erc20.approval_activity(account_address, block_number DESC); CREATE INDEX IF NOT EXISTS idx_approval_activity_account_token ON erc20.approval_activity(account_address, token, block_number DESC); @@ -414,9 +414,9 @@ impl Erc20Storage { token BYTEA NOT NULL, wallet BYTEA NOT NULL, balance BYTEA NOT NULL, - last_block BIGINT NOT NULL, + last_block TEXT NOT NULL, last_tx_hash BYTEA NOT NULL, - updated_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT), + updated_at TEXT DEFAULT (EXTRACT(EPOCH FROM NOW())::TEXT), UNIQUE(token, wallet) ); CREATE INDEX IF NOT EXISTS idx_balances_token ON erc20.balances(token); @@ -428,9 +428,9 @@ impl Erc20Storage { wallet BYTEA NOT NULL, computed_balance BYTEA NOT NULL, actual_balance BYTEA NOT NULL, - adjusted_at_block BIGINT NOT NULL, + adjusted_at_block TEXT NOT NULL, tx_hash BYTEA NOT NULL, - created_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT) + created_at TEXT DEFAULT (EXTRACT(EPOCH FROM NOW())::TEXT) ); CREATE INDEX IF NOT EXISTS idx_adjustments_wallet ON erc20.balance_adjustments(wallet); CREATE INDEX IF NOT EXISTS idx_adjustments_token ON erc20.balance_adjustments(token); @@ -439,7 +439,8 @@ impl Erc20Storage { token BYTEA PRIMARY KEY, name TEXT, symbol TEXT, - decimals BIGINT + decimals TEXT, + total_supply BYTEA ); ", ) @@ -515,9 +516,9 @@ impl Erc20Storage { from_addr BLOB NOT NULL, to_addr BLOB NOT NULL, amount BLOB NOT NULL, - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, tx_hash BLOB NOT NULL, - timestamp INTEGER DEFAULT (strftime('%s', 'now')), + timestamp TEXT DEFAULT (strftime('%s', 'now')), UNIQUE(token, tx_hash, from_addr, to_addr) )", [], @@ -567,9 +568,9 @@ impl Erc20Storage { owner BLOB NOT NULL, spender BLOB NOT NULL, amount BLOB NOT NULL, - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, tx_hash BLOB NOT NULL, - timestamp INTEGER DEFAULT (strftime('%s', 'now')), + timestamp TEXT DEFAULT (strftime('%s', 'now')), UNIQUE(token, tx_hash, owner, spender) )", [], @@ -610,7 +611,7 @@ impl Erc20Storage { token BLOB NOT NULL, transfer_id INTEGER NOT NULL, direction TEXT NOT NULL CHECK(direction IN ('sent', 'received', 'both')), - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, FOREIGN KEY (transfer_id) REFERENCES transfers(id) )", [], @@ -645,7 +646,7 @@ impl Erc20Storage { token BLOB NOT NULL, approval_id INTEGER NOT NULL, role TEXT NOT NULL CHECK(role IN ('owner', 'spender', 'both')), - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, FOREIGN KEY (approval_id) REFERENCES approvals(id) )", [], @@ -677,9 +678,9 @@ impl Erc20Storage { token BLOB NOT NULL, wallet BLOB NOT NULL, balance BLOB NOT NULL, - last_block INTEGER NOT NULL, + last_block TEXT NOT NULL, last_tx_hash BLOB NOT NULL, - updated_at INTEGER DEFAULT (strftime('%s', 'now')), + updated_at TEXT DEFAULT (strftime('%s', 'now')), UNIQUE(token, wallet) )", [], @@ -704,9 +705,9 @@ impl Erc20Storage { wallet BLOB NOT NULL, computed_balance BLOB NOT NULL, actual_balance BLOB NOT NULL, - adjusted_at_block INTEGER NOT NULL, + adjusted_at_block TEXT NOT NULL, tx_hash BLOB NOT NULL, - created_at INTEGER DEFAULT (strftime('%s', 'now')) + created_at TEXT DEFAULT (strftime('%s', 'now')) )", [], )?; @@ -727,7 +728,8 @@ impl Erc20Storage { token BLOB PRIMARY KEY, name TEXT, symbol TEXT, - decimals INTEGER + decimals TEXT, + total_supply BLOB )", [], )?; @@ -950,21 +952,20 @@ impl Erc20Storage { let amount_blob = u256_to_blob(transfer.amount); let tx_hash_blob = felt_to_blob(transfer.tx_hash); - // Insert transfer let rows = transfer_stmt.execute(params![ &token_blob, &from_blob, &to_blob, &amount_blob, - transfer.block_number, + transfer.block_number.to_string(), &tx_hash_blob, - transfer.timestamp, + transfer.timestamp.map(|t| t.to_string()), ])?; if rows > 0 { inserted += 1; let transfer_id = tx.last_insert_rowid(); - let block_number = transfer.block_number as i64; + let block_number = transfer.block_number.to_string(); // Insert wallet activity records // This enables O(log n) wallet queries instead of O(n) OR scans @@ -987,7 +988,7 @@ impl Erc20Storage { token: token_blob.clone(), ref_id: transfer_id, role: "sent", - block_number, + block_number: block_number.clone(), }); } // Receiver record @@ -1047,21 +1048,20 @@ impl Erc20Storage { let amount_blob = u256_to_blob(approval.amount); let tx_hash_blob = felt_to_blob(approval.tx_hash); - // Insert approval let rows = approval_stmt.execute(params![ &token_blob, &owner_blob, &spender_blob, &amount_blob, - approval.block_number, + approval.block_number.to_string(), &tx_hash_blob, - approval.timestamp, + approval.timestamp.map(|t| t.to_string()), ])?; if rows > 0 { inserted += 1; let approval_id = tx.last_insert_rowid(); - let block_number = approval.block_number as i64; + let block_number = approval.block_number.to_string(); // Insert approval activity records if approval.owner != Felt::ZERO @@ -1083,7 +1083,7 @@ impl Erc20Storage { token: token_blob.clone(), ref_id: approval_id, role: "owner", - block_number, + block_number: block_number.clone(), }); } // Spender record @@ -1210,19 +1210,19 @@ impl Erc20Storage { // Block range filters if let Some(block_min) = block_from { query.push_str(" AND t.block_number >= ?"); - params_vec.push(Box::new(block_min as i64)); + params_vec.push(Box::new(block_min.to_string())); } if let Some(block_max) = block_to { query.push_str(" AND t.block_number <= ?"); - params_vec.push(Box::new(block_max as i64)); + params_vec.push(Box::new(block_max.to_string())); } // Cursor-based pagination if let Some(c) = cursor { query.push_str(" AND (t.block_number < ? OR (t.block_number = ? AND t.id < ?))"); - params_vec.push(Box::new(c.block_number as i64)); - params_vec.push(Box::new(c.block_number as i64)); + params_vec.push(Box::new(c.block_number.to_string())); + params_vec.push(Box::new(c.block_number.to_string())); params_vec.push(Box::new(c.id)); } @@ -1239,9 +1239,9 @@ impl Erc20Storage { let from_bytes: Vec = row.get(2)?; let to_bytes: Vec = row.get(3)?; let amount_bytes: Vec = row.get(4)?; - let block_number: i64 = row.get(5)?; + let block_number_str: String = row.get(5)?; let tx_hash_bytes: Vec = row.get(6)?; - let timestamp: Option = row.get(7)?; + let timestamp_str: Option = row.get(7)?; Ok(TransferData { id: Some(id), @@ -1249,9 +1249,9 @@ impl Erc20Storage { from: blob_to_felt(&from_bytes), to: blob_to_felt(&to_bytes), amount: blob_to_u256(&amount_bytes), - block_number: block_number as u64, + block_number: block_number_str.parse::().unwrap_or(0), tx_hash: blob_to_felt(&tx_hash_bytes), - timestamp, + timestamp: timestamp_str.and_then(|s| s.parse::().ok()), }) })?; @@ -1352,19 +1352,19 @@ impl Erc20Storage { // Block range filters if let Some(block_min) = block_from { query.push_str(" AND a.block_number >= ?"); - params_vec.push(Box::new(block_min as i64)); + params_vec.push(Box::new(block_min.to_string())); } if let Some(block_max) = block_to { query.push_str(" AND a.block_number <= ?"); - params_vec.push(Box::new(block_max as i64)); + params_vec.push(Box::new(block_max.to_string())); } // Cursor-based pagination if let Some(c) = cursor { query.push_str(" AND (a.block_number < ? OR (a.block_number = ? AND a.id < ?))"); - params_vec.push(Box::new(c.block_number as i64)); - params_vec.push(Box::new(c.block_number as i64)); + params_vec.push(Box::new(c.block_number.to_string())); + params_vec.push(Box::new(c.block_number.to_string())); params_vec.push(Box::new(c.id)); } @@ -1381,9 +1381,9 @@ impl Erc20Storage { let owner_bytes: Vec = row.get(2)?; let spender_bytes: Vec = row.get(3)?; let amount_bytes: Vec = row.get(4)?; - let block_number: i64 = row.get(5)?; + let block_number_str: String = row.get(5)?; let tx_hash_bytes: Vec = row.get(6)?; - let timestamp: Option = row.get(7)?; + let timestamp_str: Option = row.get(7)?; Ok(ApprovalData { id: Some(id), @@ -1391,9 +1391,9 @@ impl Erc20Storage { owner: blob_to_felt(&owner_bytes), spender: blob_to_felt(&spender_bytes), amount: blob_to_u256(&amount_bytes), - block_number: block_number as u64, + block_number: block_number_str.parse::().unwrap_or(0), tx_hash: blob_to_felt(&tx_hash_bytes), - timestamp, + timestamp: timestamp_str.and_then(|s| s.parse::().ok()), }) })?; @@ -1451,12 +1451,13 @@ impl Erc20Storage { return self.pg_get_latest_block().await; } let conn = self.conn.lock().unwrap(); - let block: Option = conn + let block: Option = conn .query_row("SELECT MAX(block_number) FROM transfers", [], |row| { row.get(0) }) - .ok(); - Ok(block.map(|b| b as u64)) + .ok() + .flatten(); + Ok(block.and_then(|b| b.parse::().ok())) } // ===== Balance Tracking Methods ===== @@ -1494,7 +1495,7 @@ impl Erc20Storage { let token_blob = felt_to_blob(token); let wallet_blob = felt_to_blob(wallet); - let result: Option<(Vec, i64)> = conn + let result: Option<(Vec, String)> = conn .query_row( "SELECT balance, last_block FROM balances WHERE token = ? AND wallet = ?", params![&token_blob, &wallet_blob], @@ -1502,7 +1503,7 @@ impl Erc20Storage { ) .ok(); - Ok(result.map(|(bytes, block)| (blob_to_u256(&bytes), block as u64))) + Ok(result.map(|(bytes, block_str)| (blob_to_u256(&bytes), block_str.parse::().unwrap_or(0)))) } /// Get balances with optional token/wallet filters and cursor pagination. @@ -1557,7 +1558,7 @@ impl Erc20Storage { let token_bytes: Vec = row.get(1)?; let wallet_bytes: Vec = row.get(2)?; let balance_bytes: Vec = row.get(3)?; - let last_block: i64 = row.get(4)?; + let last_block_str: String = row.get(4)?; let last_tx_hash_bytes: Vec = row.get(5)?; Ok(( @@ -1566,7 +1567,7 @@ impl Erc20Storage { token: blob_to_felt(&token_bytes), wallet: blob_to_felt(&wallet_bytes), balance: blob_to_u256(&balance_bytes), - last_block: last_block as u64, + last_block: last_block_str.parse::().unwrap_or(0), last_tx_hash: blob_to_felt(&last_tx_hash_bytes), }, )) @@ -1882,7 +1883,7 @@ impl Erc20Storage { token: felt_to_blob(*token), wallet: felt_to_blob(*wallet), balance: u256_to_blob(balance), - last_block: *last_block as i64, + last_block: last_block.to_string(), last_tx_hash: felt_to_blob(*last_tx_hash), }); } @@ -1897,7 +1898,7 @@ impl Erc20Storage { wallet: felt_to_blob(adj.wallet), computed_balance: u256_to_blob(adj.computed_balance), actual_balance: u256_to_blob(adj.actual_balance), - adjusted_at_block: adj.adjusted_at_block as i64, + adjusted_at_block: adj.adjusted_at_block.to_string(), tx_hash: felt_to_blob(adj.tx_hash), }) .collect::>(); @@ -1992,9 +1993,8 @@ impl Erc20Storage { name: Option<&str>, symbol: Option<&str>, decimals: Option, + total_supply: Option, ) -> Result<()> { - // Some on-chain metadata payloads include embedded NUL bytes. - // PostgreSQL TEXT rejects '\0', so normalize before persistence. let clean_name = name.map(|s| s.replace('\0', "")); let clean_symbol = symbol.map(|s| s.replace('\0', "")); if self.backend == StorageBackend::Postgres { @@ -2004,23 +2004,27 @@ impl Erc20Storage { clean_name.as_deref(), clean_symbol.as_deref(), decimals, + total_supply, ) .await; } let conn = self.conn.lock().unwrap(); let token_blob = felt_to_blob(token); + let supply_blob = total_supply.map(u256_to_blob); conn.execute( - "INSERT INTO token_metadata (token, name, symbol, decimals) - VALUES (?1, ?2, ?3, ?4) + "INSERT INTO token_metadata (token, name, symbol, decimals, total_supply) + VALUES (?1, ?2, ?3, ?4, ?5) ON CONFLICT(token) DO UPDATE SET name = COALESCE(excluded.name, token_metadata.name), symbol = COALESCE(excluded.symbol, token_metadata.symbol), - decimals = COALESCE(excluded.decimals, token_metadata.decimals)", + decimals = COALESCE(excluded.decimals, token_metadata.decimals), + total_supply = COALESCE(excluded.total_supply, token_metadata.total_supply)", params![ &token_blob, clean_name.as_deref(), clean_symbol.as_deref(), - decimals.map(|d| d as i64) + decimals.map(|d| d.to_string()), + supply_blob.as_deref() ], )?; Ok(()) @@ -2030,7 +2034,7 @@ impl Erc20Storage { pub async fn get_token_metadata( &self, token: Felt, - ) -> Result, Option, Option)>> { + ) -> Result, Option, Option, Option)>> { if self.backend == StorageBackend::Postgres { return self.pg_get_token_metadata(token).await; } @@ -2038,13 +2042,14 @@ impl Erc20Storage { let token_blob = felt_to_blob(token); let result = conn .query_row( - "SELECT name, symbol, decimals FROM token_metadata WHERE token = ?", + "SELECT name, symbol, decimals, total_supply FROM token_metadata WHERE token = ?", params![&token_blob], |row| { let name: Option = row.get(0)?; let symbol: Option = row.get(1)?; - let decimals: Option = row.get(2)?; - Ok((name, symbol, decimals.map(|d| d as u8))) + let decimals: Option = row.get(2)?; + let total_supply: Option> = row.get(3)?; + Ok((name, symbol, decimals.and_then(|d| d.parse::().ok()), total_supply.map(|b| blob_to_u256(&b)))) }, ) .ok(); @@ -2054,19 +2059,21 @@ impl Erc20Storage { /// Get all token metadata pub async fn get_all_token_metadata( &self, - ) -> Result, Option, Option)>> { + ) -> Result, Option, Option, Option)>> { let conn = self.conn.lock().unwrap(); - let mut stmt = conn.prepare("SELECT token, name, symbol, decimals FROM token_metadata")?; + let mut stmt = conn.prepare("SELECT token, name, symbol, decimals, total_supply FROM token_metadata")?; let rows = stmt.query_map([], |row| { let token_bytes: Vec = row.get(0)?; let name: Option = row.get(1)?; let symbol: Option = row.get(2)?; - let decimals: Option = row.get(3)?; + let decimals: Option = row.get(3)?; + let total_supply: Option> = row.get(4)?; Ok(( blob_to_felt(&token_bytes), name, symbol, - decimals.map(|d| d as u8), + decimals.and_then(|d| d.parse::().ok()), + total_supply.map(|b| blob_to_u256(&b)), )) })?; rows.collect::, _>>().map_err(Into::into) @@ -2080,7 +2087,7 @@ impl Erc20Storage { cursor: Option, limit: u32, ) -> Result<( - Vec<(Felt, Option, Option, Option)>, + Vec<(Felt, Option, Option, Option, Option)>, Option, )> { if self.backend == StorageBackend::Postgres { @@ -2092,7 +2099,7 @@ impl Erc20Storage { let mut out = if let Some(cursor_token) = cursor { let cursor_blob = felt_to_blob(cursor_token); let mut stmt = conn.prepare( - "SELECT token, name, symbol, decimals + "SELECT token, name, symbol, decimals, total_supply FROM token_metadata WHERE token > ?1 ORDER BY token ASC @@ -2102,18 +2109,20 @@ impl Erc20Storage { let token_bytes: Vec = row.get(0)?; let name: Option = row.get(1)?; let symbol: Option = row.get(2)?; - let decimals: Option = row.get(3)?; + let decimals: Option = row.get(3)?; + let total_supply: Option> = row.get(4)?; Ok(( blob_to_felt(&token_bytes), name, symbol, - decimals.map(|d| d as u8), + decimals.and_then(|d| d.parse::().ok()), + total_supply.map(|b| blob_to_u256(&b)), )) })?; rows.collect::, _>>()? } else { let mut stmt = conn.prepare( - "SELECT token, name, symbol, decimals + "SELECT token, name, symbol, decimals, total_supply FROM token_metadata ORDER BY token ASC LIMIT ?1", @@ -2122,12 +2131,14 @@ impl Erc20Storage { let token_bytes: Vec = row.get(0)?; let name: Option = row.get(1)?; let symbol: Option = row.get(2)?; - let decimals: Option = row.get(3)?; + let decimals: Option = row.get(3)?; + let total_supply: Option> = row.get(4)?; Ok(( blob_to_felt(&token_bytes), name, symbol, - decimals.map(|d| d as u8), + decimals.and_then(|d| d.parse::().ok()), + total_supply.map(|b| blob_to_u256(&b)), )) })?; rows.collect::, _>>()? @@ -2172,21 +2183,22 @@ impl Erc20Storage { let mut from_vec = Vec::with_capacity(transfers.len()); let mut to_vec = Vec::with_capacity(transfers.len()); let mut amount_vec = Vec::with_capacity(transfers.len()); - let mut block_vec = Vec::with_capacity(transfers.len()); + let mut block_vec: Vec = Vec::with_capacity(transfers.len()); let mut tx_hash_vec = Vec::with_capacity(transfers.len()); - let mut ts_vec = Vec::with_capacity(transfers.len()); + let mut ts_vec: Vec = Vec::with_capacity(transfers.len()); for transfer in transfers { token_vec.push(felt_to_blob(transfer.token)); from_vec.push(felt_to_blob(transfer.from)); to_vec.push(felt_to_blob(transfer.to)); amount_vec.push(u256_to_blob(transfer.amount)); - block_vec.push(transfer.block_number as i64); + block_vec.push(transfer.block_number.to_string()); tx_hash_vec.push(felt_to_blob(transfer.tx_hash)); ts_vec.push( transfer .timestamp - .unwrap_or_else(|| chrono::Utc::now().timestamp()), + .unwrap_or_else(|| chrono::Utc::now().timestamp()) + .to_string(), ); } @@ -2201,9 +2213,9 @@ impl Erc20Storage { $2::bytea[], $3::bytea[], $4::bytea[], - $5::bigint[], + $5::text[], $6::bytea[], - $7::bigint[] + $7::text[] ) AS i(token, from_addr, to_addr, amount, block_number, tx_hash, timestamp) ON CONFLICT (token, tx_hash, from_addr, to_addr) DO NOTHING RETURNING id, token, from_addr, to_addr, block_number @@ -2248,21 +2260,22 @@ impl Erc20Storage { let mut owner_vec = Vec::with_capacity(approvals.len()); let mut spender_vec = Vec::with_capacity(approvals.len()); let mut amount_vec = Vec::with_capacity(approvals.len()); - let mut block_vec = Vec::with_capacity(approvals.len()); + let mut block_vec: Vec = Vec::with_capacity(approvals.len()); let mut tx_hash_vec = Vec::with_capacity(approvals.len()); - let mut ts_vec = Vec::with_capacity(approvals.len()); + let mut ts_vec: Vec = Vec::with_capacity(approvals.len()); for approval in approvals { token_vec.push(felt_to_blob(approval.token)); owner_vec.push(felt_to_blob(approval.owner)); spender_vec.push(felt_to_blob(approval.spender)); amount_vec.push(u256_to_blob(approval.amount)); - block_vec.push(approval.block_number as i64); + block_vec.push(approval.block_number.to_string()); tx_hash_vec.push(felt_to_blob(approval.tx_hash)); ts_vec.push( approval .timestamp - .unwrap_or_else(|| chrono::Utc::now().timestamp()), + .unwrap_or_else(|| chrono::Utc::now().timestamp()) + .to_string(), ); } @@ -2277,9 +2290,9 @@ impl Erc20Storage { $2::bytea[], $3::bytea[], $4::bytea[], - $5::bigint[], + $5::text[], $6::bytea[], - $7::bigint[] + $7::text[] ) AS i(token, owner, spender, amount, block_number, tx_hash, timestamp) ON CONFLICT (token, tx_hash, owner, spender) DO NOTHING RETURNING id, token, owner, spender, block_number @@ -2385,17 +2398,17 @@ impl Erc20Storage { if let Some(block_min) = block_from { query.push_str(" AND t.block_number >= "); - query.push_str(&Self::pg_next_param(&mut params, block_min as i64)); + query.push_str(&Self::pg_next_param(&mut params, block_min.to_string())); } if let Some(block_max) = block_to { query.push_str(" AND t.block_number <= "); - query.push_str(&Self::pg_next_param(&mut params, block_max as i64)); + query.push_str(&Self::pg_next_param(&mut params, block_max.to_string())); } if let Some(c) = cursor { - let p1 = Self::pg_next_param(&mut params, c.block_number as i64); - let p2 = Self::pg_next_param(&mut params, c.block_number as i64); + let p1 = Self::pg_next_param(&mut params, c.block_number.to_string()); + let p2 = Self::pg_next_param(&mut params, c.block_number.to_string()); let p3 = Self::pg_next_param(&mut params, c.id); query.push_str(&format!( " AND (t.block_number < {p1} OR (t.block_number = {p2} AND t.id < {p3}))" @@ -2420,9 +2433,9 @@ impl Erc20Storage { from: blob_to_felt(&row.get::>(2)), to: blob_to_felt(&row.get::>(3)), amount: blob_to_u256(&row.get::>(4)), - block_number: row.get::(5) as u64, + block_number: row.get::(5).parse::().unwrap_or(0), tx_hash: blob_to_felt(&row.get::>(6)), - timestamp: Some(row.get::(7)), + timestamp: row.get::>(7).and_then(|s| s.parse::().ok()), }) .collect(); @@ -2502,15 +2515,15 @@ impl Erc20Storage { if let Some(block_min) = block_from { query.push_str(" AND a.block_number >= "); - query.push_str(&Self::pg_next_param(&mut params, block_min as i64)); + query.push_str(&Self::pg_next_param(&mut params, block_min.to_string())); } if let Some(block_max) = block_to { query.push_str(" AND a.block_number <= "); - query.push_str(&Self::pg_next_param(&mut params, block_max as i64)); + query.push_str(&Self::pg_next_param(&mut params, block_max.to_string())); } if let Some(c) = cursor { - let p1 = Self::pg_next_param(&mut params, c.block_number as i64); - let p2 = Self::pg_next_param(&mut params, c.block_number as i64); + let p1 = Self::pg_next_param(&mut params, c.block_number.to_string()); + let p2 = Self::pg_next_param(&mut params, c.block_number.to_string()); let p3 = Self::pg_next_param(&mut params, c.id); query.push_str(&format!( " AND (a.block_number < {p1} OR (a.block_number = {p2} AND a.id < {p3}))" @@ -2534,9 +2547,9 @@ impl Erc20Storage { owner: blob_to_felt(&row.get::>(2)), spender: blob_to_felt(&row.get::>(3)), amount: blob_to_u256(&row.get::>(4)), - block_number: row.get::(5) as u64, + block_number: row.get::(5).parse::().unwrap_or(0), tx_hash: blob_to_felt(&row.get::>(6)), - timestamp: Some(row.get::(7)), + timestamp: row.get::>(7).and_then(|s| s.parse::().ok()), }) .collect(); @@ -2580,8 +2593,8 @@ impl Erc20Storage { let row = client .query_one("SELECT MAX(block_number) FROM erc20.transfers", &[]) .await?; - let v: Option = row.get(0); - Ok(v.map(|x| x as u64)) + let v: Option = row.get(0); + Ok(v.and_then(|x| x.parse::().ok())) } async fn pg_get_balance(&self, token: Felt, wallet: Felt) -> Result> { @@ -2610,7 +2623,7 @@ impl Erc20Storage { Ok(row.map(|r| { ( blob_to_u256(&r.get::>(0)), - r.get::(1) as u64, + r.get::(1).parse::().unwrap_or(0), ) })) } @@ -2656,7 +2669,7 @@ impl Erc20Storage { token: blob_to_felt(&row.get::>(1)), wallet: blob_to_felt(&row.get::>(2)), balance: blob_to_u256(&row.get::>(3)), - last_block: row.get::(4) as u64, + last_block: row.get::(4).parse::().unwrap_or(0), last_tx_hash: blob_to_felt(&row.get::>(5)), }); } @@ -2805,7 +2818,7 @@ impl Erc20Storage { felt_to_blob(*token), felt_to_blob(*wallet), u256_to_blob(balance), - *last_block as i64, + last_block.to_string(), felt_to_blob(*last_tx_hash), )); } @@ -2814,27 +2827,27 @@ impl Erc20Storage { let mut tokens = Vec::with_capacity(chunk.len()); let mut wallets = Vec::with_capacity(chunk.len()); let mut balances = Vec::with_capacity(chunk.len()); - let mut last_blocks = Vec::with_capacity(chunk.len()); + let mut last_blocks: Vec = Vec::with_capacity(chunk.len()); let mut tx_hashes = Vec::with_capacity(chunk.len()); for (token, wallet, balance, last_block, tx_hash) in chunk { tokens.push(token.clone()); wallets.push(wallet.clone()); balances.push(balance.clone()); - last_blocks.push(*last_block); + last_blocks.push(last_block.clone()); tx_hashes.push(tx_hash.clone()); } tx.execute( "INSERT INTO erc20.balances (token, wallet, balance, last_block, last_tx_hash, updated_at) - SELECT token, wallet, balance, last_block, last_tx_hash, EXTRACT(EPOCH FROM NOW())::BIGINT - FROM unnest($1::bytea[], $2::bytea[], $3::bytea[], $4::bigint[], $5::bytea[]) + SELECT token, wallet, balance, last_block, last_tx_hash, EXTRACT(EPOCH FROM NOW())::TEXT + FROM unnest($1::bytea[], $2::bytea[], $3::bytea[], $4::text[], $5::bytea[]) AS b(token, wallet, balance, last_block, last_tx_hash) ON CONFLICT (token, wallet) DO UPDATE SET balance = EXCLUDED.balance, last_block = EXCLUDED.last_block, last_tx_hash = EXCLUDED.last_tx_hash, - updated_at = EXTRACT(EPOCH FROM NOW())::BIGINT + updated_at = EXTRACT(EPOCH FROM NOW())::TEXT WHERE erc20.balances.balance IS DISTINCT FROM EXCLUDED.balance OR erc20.balances.last_block IS DISTINCT FROM EXCLUDED.last_block OR erc20.balances.last_tx_hash IS DISTINCT FROM EXCLUDED.last_tx_hash", @@ -2848,7 +2861,7 @@ impl Erc20Storage { let mut wallets = Vec::with_capacity(chunk.len()); let mut computed = Vec::with_capacity(chunk.len()); let mut actual = Vec::with_capacity(chunk.len()); - let mut blocks = Vec::with_capacity(chunk.len()); + let mut blocks: Vec = Vec::with_capacity(chunk.len()); let mut tx_hashes = Vec::with_capacity(chunk.len()); for adj in chunk { @@ -2856,7 +2869,7 @@ impl Erc20Storage { wallets.push(felt_to_blob(adj.wallet)); computed.push(u256_to_blob(adj.computed_balance)); actual.push(u256_to_blob(adj.actual_balance)); - blocks.push(adj.adjusted_at_block as i64); + blocks.push(adj.adjusted_at_block.to_string()); tx_hashes.push(felt_to_blob(adj.tx_hash)); } @@ -2864,7 +2877,7 @@ impl Erc20Storage { "INSERT INTO erc20.balance_adjustments (token, wallet, computed_balance, actual_balance, adjusted_at_block, tx_hash) SELECT token, wallet, computed_balance, actual_balance, adjusted_at_block, tx_hash - FROM unnest($1::bytea[], $2::bytea[], $3::bytea[], $4::bytea[], $5::bigint[], $6::bytea[]) + FROM unnest($1::bytea[], $2::bytea[], $3::bytea[], $4::bytea[], $5::text[], $6::bytea[]) AS a(token, wallet, computed_balance, actual_balance, adjusted_at_block, tx_hash)", &[&tokens, &wallets, &computed, &actual, &blocks, &tx_hashes], ) @@ -2932,23 +2945,28 @@ impl Erc20Storage { name: Option<&str>, symbol: Option<&str>, decimals: Option, + total_supply: Option, ) -> Result<()> { let clean_name = name.map(|s| s.replace('\0', "")); let clean_symbol = symbol.map(|s| s.replace('\0', "")); + let supply_blob: Option> = total_supply.map(u256_to_blob); + let decimals_str = decimals.map(|d| d.to_string()); let client = self.pg_client().await?; client .execute( - "INSERT INTO erc20.token_metadata (token, name, symbol, decimals) - VALUES ($1, $2, $3, $4) + "INSERT INTO erc20.token_metadata (token, name, symbol, decimals, total_supply) + VALUES ($1, $2, $3, $4, $5) ON CONFLICT (token) DO UPDATE SET name = COALESCE(EXCLUDED.name, erc20.token_metadata.name), symbol = COALESCE(EXCLUDED.symbol, erc20.token_metadata.symbol), - decimals = COALESCE(EXCLUDED.decimals, erc20.token_metadata.decimals)", + decimals = COALESCE(EXCLUDED.decimals, erc20.token_metadata.decimals), + total_supply = COALESCE(EXCLUDED.total_supply, erc20.token_metadata.total_supply)", &[ &felt_to_blob(token), &clean_name.as_deref(), &clean_symbol.as_deref(), - &decimals.map(|d| d as i64), + &decimals_str.as_deref(), + &supply_blob, ], ) .await?; @@ -2958,17 +2976,18 @@ impl Erc20Storage { async fn pg_get_token_metadata( &self, token: Felt, - ) -> Result, Option, Option)>> { + ) -> Result, Option, Option, Option)>> { let client = self.pg_client().await?; let row = client .query_opt( - "SELECT name, symbol, decimals FROM erc20.token_metadata WHERE token = $1", + "SELECT name, symbol, decimals, total_supply FROM erc20.token_metadata WHERE token = $1", &[&felt_to_blob(token)], ) .await?; Ok(row.map(|r| { - let decimals: Option = r.get(2); - (r.get(0), r.get(1), decimals.map(|d| d as u8)) + let decimals: Option = r.get(2); + let total_supply: Option> = r.get(3); + (r.get(0), r.get(1), decimals.and_then(|d| d.parse::().ok()), total_supply.map(|b| blob_to_u256(&b))) })) } @@ -2977,7 +2996,7 @@ impl Erc20Storage { cursor: Option, limit: u32, ) -> Result<( - Vec<(Felt, Option, Option, Option)>, + Vec<(Felt, Option, Option, Option, Option)>, Option, )> { let client = self.pg_client().await?; @@ -2985,7 +3004,7 @@ impl Erc20Storage { let rows = if let Some(cursor_token) = cursor { client .query( - "SELECT token, name, symbol, decimals + "SELECT token, name, symbol, decimals, total_supply FROM erc20.token_metadata WHERE token > $1 ORDER BY token ASC @@ -2996,7 +3015,7 @@ impl Erc20Storage { } else { client .query( - "SELECT token, name, symbol, decimals + "SELECT token, name, symbol, decimals, total_supply FROM erc20.token_metadata ORDER BY token ASC LIMIT $1", @@ -3005,15 +3024,17 @@ impl Erc20Storage { .await? }; - let mut out: Vec<(Felt, Option, Option, Option)> = rows + let mut out: Vec<(Felt, Option, Option, Option, Option)> = rows .into_iter() .map(|row| { - let decimals: Option = row.get(3); + let decimals: Option = row.get(3); + let total_supply: Option> = row.get(4); ( blob_to_felt(&row.get::>(0)), row.get(1), row.get(2), - decimals.map(|d| d as u8), + decimals.and_then(|d| d.parse::().ok()), + total_supply.map(|b| blob_to_u256(&b)), ) }) .collect(); diff --git a/crates/torii-erc721/src/handlers.rs b/crates/torii-erc721/src/handlers.rs index e121cb00..bfe65d47 100644 --- a/crates/torii-erc721/src/handlers.rs +++ b/crates/torii-erc721/src/handlers.rs @@ -75,7 +75,6 @@ impl Erc721MetadataCommandHandler { .symbol .as_deref() .is_some_and(|value| !value.trim().is_empty()) - && meta.total_supply.is_some() } fn metadata_retry_delay(attempt: u8) -> std::time::Duration { diff --git a/crates/torii-erc721/src/storage.rs b/crates/torii-erc721/src/storage.rs index 0bfd23f5..0c7bf958 100644 --- a/crates/torii-erc721/src/storage.rs +++ b/crates/torii-erc721/src/storage.rs @@ -129,9 +129,9 @@ impl Erc721Storage { token BYTEA NOT NULL, token_id BYTEA NOT NULL, owner BYTEA NOT NULL, - block_number BIGINT NOT NULL, + block_number TEXT NOT NULL, tx_hash BYTEA NOT NULL, - timestamp BIGINT, + timestamp TEXT, UNIQUE(token, token_id) ); CREATE INDEX IF NOT EXISTS idx_nft_ownership_owner ON erc721.nft_ownership(owner); @@ -143,9 +143,9 @@ impl Erc721Storage { token_id BYTEA NOT NULL, from_addr BYTEA NOT NULL, to_addr BYTEA NOT NULL, - block_number BIGINT NOT NULL, + block_number TEXT NOT NULL, tx_hash BYTEA NOT NULL, - timestamp BIGINT, + timestamp TEXT, UNIQUE(token, tx_hash, token_id, from_addr, to_addr) ); CREATE INDEX IF NOT EXISTS idx_nft_transfers_token ON erc721.nft_transfers(token); @@ -160,7 +160,7 @@ impl Erc721Storage { token BYTEA NOT NULL, transfer_id BIGINT NOT NULL REFERENCES erc721.nft_transfers(id), direction TEXT NOT NULL CHECK(direction IN ('sent', 'received', 'both')), - block_number BIGINT NOT NULL + block_number TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_nft_wallet_activity_wallet_block ON erc721.nft_wallet_activity(wallet_address, block_number DESC); CREATE INDEX IF NOT EXISTS idx_nft_wallet_activity_wallet_token ON erc721.nft_wallet_activity(wallet_address, token, block_number DESC); @@ -171,9 +171,9 @@ impl Erc721Storage { token_id BYTEA NOT NULL, owner BYTEA NOT NULL, approved BYTEA NOT NULL, - block_number BIGINT NOT NULL, + block_number TEXT NOT NULL, tx_hash BYTEA NOT NULL, - timestamp BIGINT + timestamp TEXT ); CREATE TABLE IF NOT EXISTS erc721.nft_operators ( @@ -181,10 +181,10 @@ impl Erc721Storage { token BYTEA NOT NULL, owner BYTEA NOT NULL, operator BYTEA NOT NULL, - approved BIGINT NOT NULL, - block_number BIGINT NOT NULL, + approved TEXT NOT NULL, + block_number TEXT NOT NULL, tx_hash BYTEA NOT NULL, - timestamp BIGINT, + timestamp TEXT, UNIQUE(token, owner, operator) ); @@ -200,7 +200,7 @@ impl Erc721Storage { token_id BYTEA NOT NULL, uri TEXT, metadata_json TEXT, - updated_at BIGINT NOT NULL DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT), + updated_at TEXT NOT NULL DEFAULT (EXTRACT(EPOCH FROM NOW())::BIGINT::TEXT), PRIMARY KEY (token, token_id) ); CREATE INDEX IF NOT EXISTS idx_token_uris_token ON erc721.token_uris(token); @@ -233,7 +233,7 @@ impl Erc721Storage { facet_key_id BIGINT NOT NULL REFERENCES erc721.facet_keys(id) ON DELETE CASCADE, value_norm TEXT NOT NULL, value_display TEXT NOT NULL, - token_count BIGINT NOT NULL DEFAULT 0, + token_count TEXT NOT NULL DEFAULT '0', UNIQUE(token, facet_key_id, value_norm) ); CREATE INDEX IF NOT EXISTS idx_facet_values_token_key_value ON erc721.facet_values(token, facet_key_id, value_norm); @@ -282,9 +282,9 @@ impl Erc721Storage { token BLOB NOT NULL, token_id BLOB NOT NULL, owner BLOB NOT NULL, - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, tx_hash BLOB NOT NULL, - timestamp INTEGER, + timestamp TEXT, UNIQUE(token, token_id) )", [], @@ -308,9 +308,9 @@ impl Erc721Storage { token_id BLOB NOT NULL, from_addr BLOB NOT NULL, to_addr BLOB NOT NULL, - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, tx_hash BLOB NOT NULL, - timestamp INTEGER, + timestamp TEXT, UNIQUE(token, tx_hash, token_id, from_addr, to_addr) )", [], @@ -349,7 +349,7 @@ impl Erc721Storage { token BLOB NOT NULL, transfer_id INTEGER NOT NULL, direction TEXT NOT NULL CHECK(direction IN ('sent', 'received', 'both')), - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, FOREIGN KEY (transfer_id) REFERENCES nft_transfers(id) )", [], @@ -375,9 +375,9 @@ impl Erc721Storage { token_id BLOB NOT NULL, owner BLOB NOT NULL, approved BLOB NOT NULL, - block_number INTEGER NOT NULL, + block_number TEXT NOT NULL, tx_hash BLOB NOT NULL, - timestamp INTEGER + timestamp TEXT )", [], )?; @@ -389,10 +389,10 @@ impl Erc721Storage { token BLOB NOT NULL, owner BLOB NOT NULL, operator BLOB NOT NULL, - approved INTEGER NOT NULL, - block_number INTEGER NOT NULL, + approved TEXT NOT NULL, + block_number TEXT NOT NULL, tx_hash BLOB NOT NULL, - timestamp INTEGER, + timestamp TEXT, UNIQUE(token, owner, operator) )", [], @@ -415,7 +415,7 @@ impl Erc721Storage { token_id BLOB NOT NULL, uri TEXT, metadata_json TEXT, - updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + updated_at TEXT NOT NULL DEFAULT (strftime('%s', 'now')), PRIMARY KEY (token, token_id) ); CREATE INDEX IF NOT EXISTS idx_token_uris_token ON token_uris(token); @@ -449,7 +449,7 @@ impl Erc721Storage { facet_key_id INTEGER NOT NULL, value_norm TEXT NOT NULL, value_display TEXT NOT NULL, - token_count INTEGER NOT NULL DEFAULT 0, + token_count TEXT NOT NULL DEFAULT '0', UNIQUE(token, facet_key_id, value_norm), FOREIGN KEY (facet_key_id) REFERENCES facet_keys(id) ON DELETE CASCADE ); @@ -527,9 +527,9 @@ impl Erc721Storage { &token_id_blob, &from_blob, &to_blob, - transfer.block_number, + transfer.block_number.to_string(), &tx_hash_blob, - transfer.timestamp, + transfer.timestamp.map(|t| t.to_string()), ])?; if rows > 0 { @@ -542,9 +542,9 @@ impl Erc721Storage { &token_blob, &token_id_blob, &to_blob, - transfer.block_number, + transfer.block_number.to_string(), &tx_hash_blob, - transfer.timestamp, + transfer.timestamp.map(|t| t.to_string()), ])?; } @@ -557,7 +557,7 @@ impl Erc721Storage { &from_blob, &token_blob, transfer_id, - transfer.block_number + transfer.block_number.to_string() ])?; } else { if transfer.from != Felt::ZERO { @@ -565,7 +565,7 @@ impl Erc721Storage { &from_blob, &token_blob, transfer_id, - transfer.block_number + transfer.block_number.to_string() ])?; } if transfer.to != Felt::ZERO { @@ -573,7 +573,7 @@ impl Erc721Storage { &to_blob, &token_blob, transfer_id, - transfer.block_number + transfer.block_number.to_string() ])?; } } @@ -618,10 +618,10 @@ impl Erc721Storage { &token_blob, &owner_blob, &operator_blob, - approval.approved as i32, - approval.block_number, + (approval.approved as u64).to_string(), + approval.block_number.to_string(), &tx_hash_blob, - approval.timestamp, + approval.timestamp.map(|t| t.to_string()), ])?; inserted += 1; @@ -709,18 +709,18 @@ impl Erc721Storage { if let Some(block_min) = block_from { query.push_str(" AND t.block_number >= ?"); - params_vec.push(Box::new(block_min as i64)); + params_vec.push(Box::new(block_min.to_string())); } if let Some(block_max) = block_to { query.push_str(" AND t.block_number <= ?"); - params_vec.push(Box::new(block_max as i64)); + params_vec.push(Box::new(block_max.to_string())); } if let Some(c) = cursor { query.push_str(" AND (t.block_number < ? OR (t.block_number = ? AND t.id < ?))"); - params_vec.push(Box::new(c.block_number as i64)); - params_vec.push(Box::new(c.block_number as i64)); + params_vec.push(Box::new(c.block_number.to_string())); + params_vec.push(Box::new(c.block_number.to_string())); params_vec.push(Box::new(c.id)); } @@ -737,9 +737,9 @@ impl Erc721Storage { let token_id_bytes: Vec = row.get(2)?; let from_bytes: Vec = row.get(3)?; let to_bytes: Vec = row.get(4)?; - let block_number: i64 = row.get(5)?; + let block_number_str: String = row.get(5)?; let tx_hash_bytes: Vec = row.get(6)?; - let timestamp: Option = row.get(7)?; + let timestamp_str: Option = row.get(7)?; Ok(NftTransferData { id: Some(id), @@ -747,9 +747,9 @@ impl Erc721Storage { token_id: blob_to_u256(&token_id_bytes), from: blob_to_felt(&from_bytes), to: blob_to_felt(&to_bytes), - block_number: block_number as u64, + block_number: block_number_str.parse::().unwrap_or(0), tx_hash: blob_to_felt(&tx_hash_bytes), - timestamp, + timestamp: timestamp_str.and_then(|s| s.parse::().ok()), }) })?; @@ -817,8 +817,8 @@ impl Erc721Storage { if let Some(c) = cursor { query.push_str(" AND (block_number < ? OR (block_number = ? AND id < ?))"); - params_vec.push(Box::new(c.block_number as i64)); - params_vec.push(Box::new(c.block_number as i64)); + params_vec.push(Box::new(c.block_number.to_string())); + params_vec.push(Box::new(c.block_number.to_string())); params_vec.push(Box::new(c.id)); } @@ -834,14 +834,14 @@ impl Erc721Storage { let token_bytes: Vec = row.get(1)?; let token_id_bytes: Vec = row.get(2)?; let owner_bytes: Vec = row.get(3)?; - let block_number: i64 = row.get(4)?; + let block_number_str: String = row.get(4)?; Ok(NftOwnershipData { id: Some(id), token: blob_to_felt(&token_bytes), token_id: blob_to_u256(&token_id_bytes), owner: blob_to_felt(&owner_bytes), - block_number: block_number as u64, + block_number: block_number_str.parse::().unwrap_or(0), }) })?; @@ -964,12 +964,13 @@ impl Erc721Storage { return self.pg_get_latest_block().await; } let conn = self.conn.lock().unwrap(); - let block: Option = conn + let block: Option = conn .query_row("SELECT MAX(block_number) FROM nft_transfers", [], |row| { row.get(0) }) - .ok(); - Ok(block.map(|b| b as u64)) + .ok() + .flatten(); + Ok(block.and_then(|b| b.parse::().ok())) } // ===== Token Metadata Methods ===== @@ -1623,21 +1624,22 @@ impl Erc721Storage { let mut token_id_vec = Vec::with_capacity(transfers.len()); let mut from_vec = Vec::with_capacity(transfers.len()); let mut to_vec = Vec::with_capacity(transfers.len()); - let mut block_vec = Vec::with_capacity(transfers.len()); + let mut block_vec: Vec = Vec::with_capacity(transfers.len()); let mut tx_hash_vec = Vec::with_capacity(transfers.len()); - let mut ts_vec = Vec::with_capacity(transfers.len()); + let mut ts_vec: Vec = Vec::with_capacity(transfers.len()); for transfer in transfers { token_vec.push(felt_to_blob(transfer.token)); token_id_vec.push(u256_to_blob(transfer.token_id)); from_vec.push(felt_to_blob(transfer.from)); to_vec.push(felt_to_blob(transfer.to)); - block_vec.push(transfer.block_number as i64); + block_vec.push(transfer.block_number.to_string()); tx_hash_vec.push(felt_to_blob(transfer.tx_hash)); ts_vec.push( transfer .timestamp - .unwrap_or_else(|| chrono::Utc::now().timestamp()), + .unwrap_or_else(|| chrono::Utc::now().timestamp()) + .to_string(), ); } @@ -1652,9 +1654,9 @@ impl Erc721Storage { $2::bytea[], $3::bytea[], $4::bytea[], - $5::bigint[], + $5::text[], $6::bytea[], - $7::bigint[] + $7::text[] ) AS i(token, token_id, from_addr, to_addr, block_number, tx_hash, timestamp) ON CONFLICT (token, tx_hash, token_id, from_addr, to_addr) DO NOTHING RETURNING id, token, token_id, from_addr, to_addr, block_number, tx_hash, timestamp @@ -1712,22 +1714,23 @@ impl Erc721Storage { let mut token_vec = Vec::with_capacity(approvals.len()); let mut owner_vec = Vec::with_capacity(approvals.len()); let mut operator_vec = Vec::with_capacity(approvals.len()); - let mut approved_vec = Vec::with_capacity(approvals.len()); - let mut block_vec = Vec::with_capacity(approvals.len()); + let mut approved_vec: Vec = Vec::with_capacity(approvals.len()); + let mut block_vec: Vec = Vec::with_capacity(approvals.len()); let mut tx_hash_vec = Vec::with_capacity(approvals.len()); - let mut ts_vec = Vec::with_capacity(approvals.len()); + let mut ts_vec: Vec = Vec::with_capacity(approvals.len()); for approval in approvals { token_vec.push(felt_to_blob(approval.token)); owner_vec.push(felt_to_blob(approval.owner)); operator_vec.push(felt_to_blob(approval.operator)); - approved_vec.push((approval.approved as i32) as i64); - block_vec.push(approval.block_number as i64); + approved_vec.push((approval.approved as u64).to_string()); + block_vec.push(approval.block_number.to_string()); tx_hash_vec.push(felt_to_blob(approval.tx_hash)); ts_vec.push( approval .timestamp - .unwrap_or_else(|| chrono::Utc::now().timestamp()), + .unwrap_or_else(|| chrono::Utc::now().timestamp()) + .to_string(), ); } @@ -1740,10 +1743,10 @@ impl Erc721Storage { $1::bytea[], $2::bytea[], $3::bytea[], - $4::bigint[], - $5::bigint[], + $4::text[], + $5::text[], $6::bytea[], - $7::bigint[] + $7::text[] ) WITH ORDINALITY AS i(token, owner, operator, approved, block_number, tx_hash, timestamp, ord) ORDER BY token, owner, operator, ord DESC ON CONFLICT (token, owner, operator) DO UPDATE SET @@ -1832,15 +1835,15 @@ impl Erc721Storage { } if let Some(block_min) = block_from { query.push_str(" AND t.block_number >= "); - query.push_str(&Self::pg_next_param(&mut params, block_min as i64)); + query.push_str(&Self::pg_next_param(&mut params, block_min.to_string())); } if let Some(block_max) = block_to { query.push_str(" AND t.block_number <= "); - query.push_str(&Self::pg_next_param(&mut params, block_max as i64)); + query.push_str(&Self::pg_next_param(&mut params, block_max.to_string())); } if let Some(c) = cursor { - let p1 = Self::pg_next_param(&mut params, c.block_number as i64); - let p2 = Self::pg_next_param(&mut params, c.block_number as i64); + let p1 = Self::pg_next_param(&mut params, c.block_number.to_string()); + let p2 = Self::pg_next_param(&mut params, c.block_number.to_string()); let p3 = Self::pg_next_param(&mut params, c.id); query.push_str(&format!( " AND (t.block_number < {p1} OR (t.block_number = {p2} AND t.id < {p3}))" @@ -1862,9 +1865,9 @@ impl Erc721Storage { token_id: blob_to_u256(&row.get::>(2)), from: blob_to_felt(&row.get::>(3)), to: blob_to_felt(&row.get::>(4)), - block_number: row.get::(5) as u64, + block_number: row.get::(5).parse::().unwrap_or(0), tx_hash: blob_to_felt(&row.get::>(6)), - timestamp: Some(row.get::(7)), + timestamp: row.get::(7).parse::().ok(), }) .collect(); let next_cursor = if transfers.len() == limit as usize { @@ -1911,8 +1914,8 @@ impl Erc721Storage { query.push_str(&format!(" AND token IN ({list})")); } if let Some(c) = cursor { - let p1 = Self::pg_next_param(&mut params, c.block_number as i64); - let p2 = Self::pg_next_param(&mut params, c.block_number as i64); + let p1 = Self::pg_next_param(&mut params, c.block_number.to_string()); + let p2 = Self::pg_next_param(&mut params, c.block_number.to_string()); let p3 = Self::pg_next_param(&mut params, c.id); query.push_str(&format!( " AND (block_number < {p1} OR (block_number = {p2} AND id < {p3}))" @@ -1932,7 +1935,7 @@ impl Erc721Storage { token: blob_to_felt(&row.get::>(1)), token_id: blob_to_u256(&row.get::>(2)), owner: blob_to_felt(&row.get::>(3)), - block_number: row.get::(4) as u64, + block_number: row.get::(4).parse::().unwrap_or(0), }) .collect(); let next_cursor = if ownership.len() == limit as usize { @@ -2077,8 +2080,8 @@ impl Erc721Storage { let row = client .query_one("SELECT MAX(block_number) FROM erc721.nft_transfers", &[]) .await?; - let v: Option = row.get(0); - Ok(v.map(|x| x as u64)) + let v: Option = row.get(0); + Ok(v.and_then(|x| x.parse::().ok())) } async fn pg_has_token_metadata(&self, token: Felt) -> Result { @@ -2369,7 +2372,7 @@ impl TokenUriStore for Erc721Storage { tx.execute( "INSERT INTO erc721.token_uris (token, token_id, uri, metadata_json, updated_at) - VALUES ($1, $2, $3, $4, EXTRACT(EPOCH FROM NOW())::BIGINT) + VALUES ($1, $2, $3, $4, EXTRACT(EPOCH FROM NOW())::BIGINT::TEXT) ON CONFLICT(token, token_id) DO UPDATE SET uri = EXCLUDED.uri, metadata_json = EXCLUDED.metadata_json, @@ -2734,7 +2737,7 @@ fn sqlite_apply_facet_sync_plan( )?; let mut update_count_stmt = tx.prepare_cached( "UPDATE facet_values - SET token_count = MAX(token_count + ?2, 0) + SET token_count = CAST(MAX(CAST(token_count AS INTEGER) + ?2, 0) AS TEXT) WHERE id = ?1", )?; @@ -2912,7 +2915,7 @@ async fn pg_apply_facet_sync_plan( for (facet_value_id, delta) in &plan.count_deltas { tx.execute( "UPDATE erc721.facet_values - SET token_count = GREATEST(token_count + $2, 0) + SET token_count = CAST(GREATEST(CAST(token_count AS BIGINT) + $2, 0) AS TEXT) WHERE id = $1", &[facet_value_id, delta], ) @@ -3082,7 +3085,7 @@ mod tests { { let conn = storage.conn.lock().unwrap(); conn.execute( - "UPDATE token_uris SET updated_at = 123 WHERE token = ?1 AND token_id = ?2", + "UPDATE token_uris SET updated_at = '123' WHERE token = ?1 AND token_id = ?2", params![felt_to_blob(result.contract), u256_to_blob(result.token_id)], ) .expect("set sentinel updated_at"); @@ -3093,9 +3096,9 @@ mod tests { .await .expect("store unchanged token uri"); - let (updated_at, attr_count): (i64, i64) = { + let (updated_at, attr_count): (String, i64) = { let conn = storage.conn.lock().unwrap(); - let updated_at: i64 = conn + let updated_at: String = conn .query_row( "SELECT updated_at FROM token_uris WHERE token = ?1 AND token_id = ?2", params![felt_to_blob(result.contract), u256_to_blob(result.token_id)], @@ -3112,7 +3115,7 @@ mod tests { (updated_at, attr_count) }; - assert_eq!(updated_at, 123); + assert_eq!(updated_at, "123"); assert_eq!(attr_count, 1); let _ = std::fs::remove_file(db_path); @@ -3192,7 +3195,7 @@ mod tests { { let conn = storage.conn.lock().unwrap(); conn.execute( - "UPDATE facet_values SET token_count = 0 WHERE id IN ( + "UPDATE facet_values SET token_count = '0' WHERE id IN ( SELECT facet_value_id FROM facet_token_map WHERE token = ?1 AND token_id = ?2 )", params![felt_to_blob(result.contract), u256_to_blob(result.token_id)], @@ -3221,7 +3224,7 @@ mod tests { .expect("count facet mappings"); let positive_counts: i64 = conn .query_row( - "SELECT COUNT(*) FROM facet_values WHERE token_count > 0", + "SELECT COUNT(*) FROM facet_values WHERE CAST(token_count AS INTEGER) > 0", [], |row| row.get(0), ) From 7f1e64ba421f31c0605dca8a790c868e9785e49f Mon Sep 17 00:00:00 2001 From: MartianGreed Date: Wed, 25 Mar 2026 12:54:27 +0100 Subject: [PATCH 05/21] feat(controller-sink): add a sink to sync controllers from api --- Cargo.lock | 19 + Cargo.toml | 2 + bins/torii-introspect-bin/Cargo.toml | 1 + bins/torii-introspect-bin/src/config.rs | 21 + bins/torii-introspect-bin/src/main.rs | 36 ++ crates/torii-controllers-sink/Cargo.toml | 22 + crates/torii-controllers-sink/src/lib.rs | 703 ++++++++++++++++++++++ crates/torii-ecs-sink/proto/types.proto | 12 + crates/torii-ecs-sink/proto/world.proto | 10 + crates/torii-ecs-sink/src/grpc_service.rs | 236 +++++++- 10 files changed, 1055 insertions(+), 7 deletions(-) create mode 100644 crates/torii-controllers-sink/Cargo.toml create mode 100644 crates/torii-controllers-sink/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3165c394..4b7a23f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4711,6 +4711,24 @@ dependencies = [ "anyhow", ] +[[package]] +name = "torii-controllers-sink" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "metrics", + "reqwest", + "serde", + "serde_json", + "sqlx", + "starknet", + "tokio", + "torii", + "tracing", +] + [[package]] name = "torii-dojo" version = "0.1.0" @@ -4923,6 +4941,7 @@ dependencies = [ "torii", "torii-common", "torii-config-common", + "torii-controllers-sink", "torii-dojo", "torii-ecs-sink", "torii-erc1155", diff --git a/Cargo.toml b/Cargo.toml index 954b4a71..3750ca3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "crates/torii-runtime-common", "crates/torii-sql-sink", "crates/torii-log-sink", + "crates/torii-controllers-sink", "crates/arcade-sink", "crates/torii-ecs-sink", "crates/torii-erc20", @@ -130,6 +131,7 @@ torii-runtime-common = { path = "crates/torii-runtime-common" } # Internal crates torii-sql-sink.path = "crates/torii-sql-sink" torii-log-sink.path = "crates/torii-log-sink" +torii-controllers-sink.path = "crates/torii-controllers-sink" torii-arcade-sink.path = "crates/arcade-sink" torii-ecs-sink.path = "crates/torii-ecs-sink" torii-erc20.path = "crates/torii-erc20" diff --git a/bins/torii-introspect-bin/Cargo.toml b/bins/torii-introspect-bin/Cargo.toml index 97bed8b2..bffe1bdb 100644 --- a/bins/torii-introspect-bin/Cargo.toml +++ b/bins/torii-introspect-bin/Cargo.toml @@ -12,6 +12,7 @@ path = "src/main.rs" torii = { path = "../../" } torii-common = { path = "../../crates/torii-common" } torii-config-common.workspace = true +torii-controllers-sink.workspace = true torii-dojo = { path = "../../crates/dojo" } torii-erc20 = { path = "../../crates/torii-erc20" } torii-erc721 = { path = "../../crates/torii-erc721" } diff --git a/bins/torii-introspect-bin/src/config.rs b/bins/torii-introspect-bin/src/config.rs index 7cf2091f..88d6ce0a 100644 --- a/bins/torii-introspect-bin/src/config.rs +++ b/bins/torii-introspect-bin/src/config.rs @@ -84,6 +84,14 @@ pub struct Config { #[arg(long, default_value = "3000")] pub port: u16, + /// Cartridge-compatible GraphQL API used to fetch controller usernames. + #[arg(long, default_value = "https://api.cartridge.gg/query")] + pub controllers_api_url: String, + + /// Enable controller synchronization into the introspect database. + #[arg(long)] + pub controllers: bool, + /// Enable Prometheus metrics collection. #[arg(long)] pub observability: bool, @@ -185,6 +193,19 @@ mod tests { assert!(cfg.observability); } + #[test] + fn controllers_sync_defaults_to_disabled() { + let cfg = Config::parse_from(["torii-server", "--contract", "0x1"]); + assert_eq!(cfg.controllers_api_url, "https://api.cartridge.gg/query"); + assert!(!cfg.controllers); + } + + #[test] + fn controllers_flag_enables_sync() { + let cfg = Config::parse_from(["torii-server", "--contract", "0x1", "--controllers"]); + assert!(cfg.controllers); + } + #[test] fn storage_database_url_accepts_sqlite() { let cfg = Config::parse_from([ diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index 8e15f918..25410e2d 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -39,6 +39,7 @@ use torii_erc721::{ Erc721Decoder, Erc721MetadataCommandHandler, Erc721Service, Erc721Sink, Erc721Storage, FILE_DESCRIPTOR_SET as ERC721_DESCRIPTOR_SET, }; +use torii_controllers_sink::ControllersSink; use torii_introspect_postgres_sink::processor::IntrospectPgDb; use torii_introspect_sqlite_sink::processor::IntrospectSqliteDb; use torii_runtime_common::database::{resolve_token_db_setup, TokenDbSetup}; @@ -339,6 +340,17 @@ async fn run_indexer(config: Config) -> Result<()> { tracing::info!("Storage backend: {:?}", backend); tracing::info!("Engine database URL: {}", engine_database_url); tracing::info!("Storage database URL: {}", storage_database_url); + tracing::info!( + "Controllers sync: {}", + if config.controllers { + "enabled" + } else { + "disabled" + } + ); + if config.controllers { + tracing::info!("Controllers API URL: {}", config.controllers_api_url); + } if let Some(db_setup) = &token_db_setup { tracing::info!("ERC20 storage database URL: {}", db_setup.erc20_url); tracing::info!("ERC721 storage database URL: {}", db_setup.erc721_url); @@ -510,6 +522,18 @@ async fn run_with_postgres( .add_decoder(decoder) .add_sink_boxed(Box::new(ecs_sink)) .add_sink_boxed(Box::new(sink)); + let torii_config = if config.controllers { + torii_config.add_sink_boxed(Box::new( + ControllersSink::new( + storage_database_url, + config.max_db_connections, + Some(config.controllers_api_url.clone()), + ) + .await?, + )) + } else { + torii_config + }; let (torii_config, reflection_builder, token_services, _token_uri_services) = configure_token_support( @@ -666,6 +690,18 @@ async fn run_with_sqlite( .add_decoder(decoder) .add_sink_boxed(Box::new(ecs_sink)) .add_sink_boxed(Box::new(IntrospectSqliteDb::new(pool.clone(), ()))); + let torii_config = if config.controllers { + torii_config.add_sink_boxed(Box::new( + ControllersSink::new( + storage_database_url, + config.max_db_connections, + Some(config.controllers_api_url.clone()), + ) + .await?, + )) + } else { + torii_config + }; let (torii_config, reflection_builder, token_services, _token_uri_services) = configure_token_support( diff --git a/crates/torii-controllers-sink/Cargo.toml b/crates/torii-controllers-sink/Cargo.toml new file mode 100644 index 00000000..0879849c --- /dev/null +++ b/crates/torii-controllers-sink/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "torii-controllers-sink" +version = "0.1.0" +edition = "2021" + +[dependencies] +torii = { path = "../.." } + +anyhow.workspace = true +async-trait.workspace = true +chrono.workspace = true +metrics.workspace = true +reqwest = { version = "0.12", features = ["json", "rustls-tls"] } +serde.workspace = true +serde_json.workspace = true +sqlx = { workspace = true, features = ["runtime-tokio", "sqlite", "postgres", "any"] } +starknet.workspace = true +tokio.workspace = true +tracing.workspace = true + +[lints] +workspace = true diff --git a/crates/torii-controllers-sink/src/lib.rs b/crates/torii-controllers-sink/src/lib.rs new file mode 100644 index 00000000..4b278325 --- /dev/null +++ b/crates/torii-controllers-sink/src/lib.rs @@ -0,0 +1,703 @@ +use std::str::FromStr; +use std::sync::Arc; +use std::time::Duration; + +use anyhow::{anyhow, Context, Result}; +use async_trait::async_trait; +use chrono::{DateTime, TimeZone, Utc}; +use reqwest::Client; +use serde::Deserialize; +use serde_json::json; +use sqlx::{any::AnyPoolOptions, sqlite::SqliteConnectOptions, Any, ConnectOptions, Pool, Row}; +use starknet::core::types::Felt; +use torii::axum::Router; +use torii::etl::extractor::ExtractionBatch; +use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; +use torii::etl::TypeId; + +pub const DEFAULT_API_QUERY_URL: &str = "https://api.cartridge.gg/query"; +pub const CONTROLLERS_TABLE: &str = "controllers"; +pub const CONTROLLERS_STATE_TABLE: &str = "torii_controller_sync_state"; + +const MAX_RETRIES: u32 = 3; +const INITIAL_BACKOFF: Duration = Duration::from_secs(2); +const CONTROLLERS_TYPE: TypeId = TypeId::new("controllers.sync"); + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum DbBackend { + Sqlite, + Postgres, +} + +impl DbBackend { + fn detect(database_url: &str) -> Self { + if database_url.starts_with("postgres://") || database_url.starts_with("postgresql://") { + Self::Postgres + } else { + Self::Sqlite + } + } +} + +#[derive(Debug, Clone, Deserialize)] +struct ControllerAccount { + username: String, +} + +#[derive(Debug, Clone, Deserialize)] +struct ControllerNode { + address: String, + #[serde(rename = "createdAt")] + created_at: String, + account: ControllerAccount, +} + +#[derive(Debug, Clone, Deserialize)] +struct ControllerEdge { + node: ControllerNode, +} + +#[derive(Debug, Clone, Deserialize, Default)] +struct ControllersConnection { + edges: Vec, +} + +#[derive(Debug, Clone, Deserialize)] +struct ControllersData { + controllers: ControllersConnection, +} + +#[derive(Debug, Clone, Deserialize)] +struct GraphQlError { + message: String, +} + +#[derive(Debug, Clone, Deserialize)] +struct ControllersResponse { + data: Option, + errors: Option>, +} + +#[derive(Debug, Clone)] +struct StoredController { + id: String, + address: String, + username: String, + deployed_at: String, + updated_at: i64, +} + +impl TryFrom for StoredController { + type Error = anyhow::Error; + + fn try_from(value: ControllerNode) -> Result { + let created_at = DateTime::parse_from_rfc3339(&value.created_at) + .with_context(|| format!("invalid controller createdAt returned by API: {}", value.created_at))? + .with_timezone(&Utc); + let felt_addr = Felt::from_str(&value.address) + .with_context(|| format!("invalid controller address returned by API: {}", value.address))?; + let normalized = format!("{:#066x}", felt_addr); + Ok(Self { + id: normalized.clone(), + address: normalized, + username: value.account.username, + deployed_at: created_at.to_rfc3339(), + updated_at: Utc::now().timestamp(), + }) + } +} + +struct ControllersStore { + pool: Pool, + backend: DbBackend, +} + +impl ControllersStore { + async fn new(database_url: &str, max_connections: Option) -> Result { + sqlx::any::install_default_drivers(); + + let backend = DbBackend::detect(database_url); + let database_url = match backend { + DbBackend::Postgres => database_url.to_string(), + DbBackend::Sqlite => sqlite_url(database_url)?, + }; + + let pool = AnyPoolOptions::new() + .max_connections(max_connections.unwrap_or(if backend == DbBackend::Sqlite { + 1 + } else { + 5 + })) + .connect(&database_url) + .await?; + + Ok(Self { pool, backend }) + } + + async fn initialize(&self) -> Result<()> { + if self.backend == DbBackend::Sqlite { + sqlx::query("PRAGMA journal_mode=WAL") + .execute(&self.pool) + .await + .ok(); + sqlx::query("PRAGMA synchronous=NORMAL") + .execute(&self.pool) + .await + .ok(); + sqlx::query("PRAGMA foreign_keys=ON") + .execute(&self.pool) + .await + .ok(); + } + + sqlx::query(&format!( + "CREATE TABLE IF NOT EXISTS {CONTROLLERS_TABLE} ( + id TEXT PRIMARY KEY, + address TEXT NOT NULL UNIQUE, + username TEXT NOT NULL, + deployed_at TEXT NOT NULL, + updated_at BIGINT NOT NULL + )" + )) + .execute(&self.pool) + .await?; + + sqlx::query(&format!( + "CREATE TABLE IF NOT EXISTS {CONTROLLERS_STATE_TABLE} ( + id INTEGER PRIMARY KEY CHECK (id = 1), + synced_until BIGINT + )" + )) + .execute(&self.pool) + .await?; + + Ok(()) + } + + async fn load_synced_until(&self) -> Result> { + let row = sqlx::query(&format!( + "SELECT synced_until FROM {CONTROLLERS_STATE_TABLE} WHERE id = 1" + )) + .fetch_optional(&self.pool) + .await?; + + Ok(row.and_then(|row| row.try_get::, _>(0).ok()).flatten()) + } + + async fn is_empty(&self) -> Result { + let row = sqlx::query_scalar::(&format!( + "SELECT COUNT(*) FROM {CONTROLLERS_TABLE}" + )) + .fetch_one(&self.pool) + .await?; + + Ok(row == 0) + } + + async fn store_synced_until(&self, synced_until: i64) -> Result<()> { + let sql = match self.backend { + DbBackend::Sqlite => format!( + "INSERT INTO {CONTROLLERS_STATE_TABLE} (id, synced_until) VALUES (?1, ?2) + ON CONFLICT(id) DO UPDATE SET synced_until = excluded.synced_until" + ), + DbBackend::Postgres => format!( + "INSERT INTO {CONTROLLERS_STATE_TABLE} (id, synced_until) VALUES ($1, $2) + ON CONFLICT(id) DO UPDATE SET synced_until = excluded.synced_until" + ), + }; + + sqlx::query(&sql) + .bind(1_i32) + .bind(synced_until) + .execute(&self.pool) + .await?; + + Ok(()) + } + + async fn upsert_controller(&self, controller: &StoredController) -> Result<()> { + let sql = match self.backend { + DbBackend::Sqlite => format!( + "INSERT INTO {CONTROLLERS_TABLE} (id, address, username, deployed_at, updated_at) + VALUES (?1, ?2, ?3, ?4, ?5) + ON CONFLICT(address) DO UPDATE SET + id = excluded.id, + username = excluded.username, + deployed_at = excluded.deployed_at, + updated_at = excluded.updated_at" + ), + DbBackend::Postgres => format!( + "INSERT INTO {CONTROLLERS_TABLE} (id, address, username, deployed_at, updated_at) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT(address) DO UPDATE SET + id = excluded.id, + username = excluded.username, + deployed_at = excluded.deployed_at, + updated_at = excluded.updated_at" + ), + }; + + sqlx::query(&sql) + .bind(&controller.id) + .bind(&controller.address) + .bind(&controller.username) + .bind(&controller.deployed_at) + .bind(controller.updated_at) + .execute(&self.pool) + .await?; + + Ok(()) + } +} + +pub struct ControllersSink { + store: Arc, + api_url: String, + client: Client, +} + +impl ControllersSink { + pub async fn new( + database_url: &str, + max_connections: Option, + api_url: Option, + ) -> Result { + Ok(Self { + store: Arc::new(ControllersStore::new(database_url, max_connections).await?), + api_url: api_url.unwrap_or_else(|| DEFAULT_API_QUERY_URL.to_string()), + client: Client::new(), + }) + } + + fn batch_time_window(batch: &ExtractionBatch) -> Option<(i64, i64)> { + let mut timestamps = batch.blocks.values().map(|block| block.timestamp as i64); + let first = timestamps.next()?; + let (min_ts, max_ts) = timestamps.fold((first, first), |(min_ts, max_ts), ts| { + (min_ts.min(ts), max_ts.max(ts)) + }); + Some((min_ts, max_ts)) + } + + fn build_query(lower_bound: DateTime, upper_bound: DateTime) -> String { + format!( + r#" +query {{ + controllers(where:{{ + createdAtGT:"{}", + createdAtLTE:"{}" + }}, orderBy:{{ + field:CREATED_AT, + direction:ASC + }}) {{ + edges {{ + node {{ + address + createdAt + account {{ + username + }} + }} + }} + }} +}}"#, + lower_bound.to_rfc3339(), + upper_bound.to_rfc3339(), + ) + } + + async fn fetch_controllers( + &self, + lower_bound: DateTime, + upper_bound: DateTime, + ) -> Result> { + let query = Self::build_query(lower_bound, upper_bound); + let mut attempts = 0; + + loop { + attempts += 1; + let result = self + .client + .post(&self.api_url) + .json(&json!({ "query": query })) + .send() + .await; + + match result { + Ok(response) if response.status().is_success() => { + let body: ControllersResponse = response.json().await?; + if let Some(errors) = body.errors { + let msg = errors + .into_iter() + .map(|error| error.message) + .collect::>() + .join("; "); + return Err(anyhow!("controller GraphQL query failed: {msg}")); + } + + return Ok(body + .data + .unwrap_or(ControllersData { + controllers: ControllersConnection::default(), + }) + .controllers + .edges + .into_iter() + .map(|edge| edge.node) + .collect()); + } + Ok(response) if attempts < MAX_RETRIES => { + let error_text = response.text().await.unwrap_or_default(); + tracing::warn!( + target: "torii::sinks::controllers", + attempt = attempts, + max_retries = MAX_RETRIES, + error_text, + "Controller fetch failed, retrying" + ); + } + Ok(response) => { + let error_text = response.text().await.unwrap_or_default(); + return Err(anyhow!("controller API returned error: {error_text}")); + } + Err(error) if attempts < MAX_RETRIES => { + tracing::warn!( + target: "torii::sinks::controllers", + attempt = attempts, + max_retries = MAX_RETRIES, + error = %error, + "Controller fetch transport error, retrying" + ); + } + Err(error) => return Err(error.into()), + } + + let backoff = INITIAL_BACKOFF * (1 << (attempts - 1)); + tokio::time::sleep(backoff).await; + } + } + + async fn sync_batch(&self, batch: &ExtractionBatch) -> Result<()> { + let Some((batch_from_ts, batch_to_ts)) = Self::batch_time_window(batch) else { + return Ok(()); + }; + + let synced_until = self.store.load_synced_until().await?; + if synced_until.is_some_and(|ts| ts >= batch_to_ts) { + return Ok(()); + } + + let effective_start = synced_until.unwrap_or_else(|| batch_from_ts.saturating_sub(1)); + let lower_bound = utc_timestamp(effective_start)?; + let upper_bound = utc_timestamp(batch_to_ts)?; + let controllers = self.fetch_controllers(lower_bound, upper_bound).await?; + + let mut stored = 0_u64; + for controller in controllers { + let controller = StoredController::try_from(controller)?; + self.store.upsert_controller(&controller).await?; + stored += 1; + } + + self.store.store_synced_until(batch_to_ts).await?; + + tracing::info!( + target: "torii::sinks::controllers", + stored, + batch_from_ts, + batch_to_ts, + synced_until, + "Synchronized controllers for batch window" + ); + ::metrics::counter!("torii_controller_sync_batches_total", "status" => "ok").increment(1); + ::metrics::counter!("torii_controller_synced_total").increment(stored); + + Ok(()) + } + + async fn full_sync_from_api(&self) -> Result<()> { + let lower_bound = utc_timestamp(0)?; + let upper_bound = Utc::now(); + let controllers = self.fetch_controllers(lower_bound, upper_bound).await?; + + let mut stored = 0_u64; + for controller in controllers { + let controller = StoredController::try_from(controller)?; + self.store.upsert_controller(&controller).await?; + stored += 1; + } + + self.store.store_synced_until(upper_bound.timestamp()).await?; + + tracing::info!( + target: "torii::sinks::controllers", + stored, + synced_until = upper_bound.timestamp(), + "Completed initial full controller sync" + ); + ::metrics::counter!("torii_controller_sync_batches_total", "status" => "ok").increment(1); + ::metrics::counter!("torii_controller_synced_total").increment(stored); + + Ok(()) + } +} + +#[async_trait] +impl Sink for ControllersSink { + fn name(&self) -> &str { + "controllers" + } + + fn interested_types(&self) -> Vec { + vec![CONTROLLERS_TYPE] + } + + async fn process(&self, _envelopes: &[torii::etl::Envelope], batch: &ExtractionBatch) -> Result<()> { + match self.sync_batch(batch).await { + Ok(()) => Ok(()), + Err(error) => { + ::metrics::counter!("torii_controller_sync_batches_total", "status" => "error") + .increment(1); + Err(error) + } + } + } + + fn topics(&self) -> Vec { + Vec::new() + } + + fn build_routes(&self) -> Router { + Router::new() + } + + async fn initialize( + &mut self, + _event_bus: Arc, + _context: &SinkContext, + ) -> Result<()> { + self.store.initialize().await?; + if self.store.is_empty().await? { + self.full_sync_from_api().await?; + } + Ok(()) + } +} + +fn utc_timestamp(timestamp: i64) -> Result> { + Utc.timestamp_opt(timestamp, 0) + .single() + .ok_or_else(|| anyhow!("invalid UTC timestamp: {timestamp}")) +} + +fn sqlite_url(path: &str) -> Result { + if path == ":memory:" || path == "sqlite::memory:" { + return Ok("sqlite::memory:".to_string()); + } + if path.starts_with("sqlite:") { + return Ok(path.to_string()); + } + let options = SqliteConnectOptions::from_str(&format!("sqlite://{path}")) + .or_else(|_| Ok::<_, sqlx::Error>(SqliteConnectOptions::new().filename(path)))?; + if let Some(parent) = options + .get_filename() + .parent() + .filter(|parent| !parent.as_os_str().is_empty()) + { + std::fs::create_dir_all(parent)?; + } + Ok(options.to_url_lossy().to_string()) +} + +#[cfg(test)] +mod tests { + use super::*; + use serde_json::Value; + use sqlx::query_scalar; + use tokio::net::TcpListener; + use torii::command::CommandBus; + use torii::axum::{extract::State, routing::post, Json, Router}; + use torii::grpc::SubscriptionManager; + + async fn initialize_sink(sink: &mut ControllersSink) { + let event_bus = Arc::new(EventBus::new(Arc::new(SubscriptionManager::new()))); + let command_bus = CommandBus::new(Vec::new(), 1).unwrap(); + let context = SinkContext { + database_root: ".".into(), + command_bus: command_bus.sender(), + }; + Sink::initialize(sink, event_bus, &context).await.unwrap(); + } + + #[derive(Clone)] + struct TestGraphQlState { + body: Value, + } + + async fn graphql_handler( + State(state): State, + Json(_payload): Json, + ) -> Json { + Json(state.body) + } + + async fn spawn_graphql_server(body: Value) -> Result { + let state = TestGraphQlState { body }; + let app = Router::new() + .route("/query", post(graphql_handler)) + .with_state(state); + let listener = TcpListener::bind("127.0.0.1:0").await?; + let addr = listener.local_addr()?; + tokio::spawn(async move { + torii::axum::serve(listener, app) + .await + .expect("test server should run"); + }); + Ok(format!("http://{addr}/query")) + } + + fn make_batch(from_ts: u64, to_ts: u64) -> ExtractionBatch { + let mut batch = ExtractionBatch::empty(); + batch.add_block_context(1, Felt::ONE, Felt::ZERO, from_ts); + batch.add_block_context(2, Felt::TWO, Felt::ONE, to_ts); + batch + } + + #[tokio::test] + async fn controllers_sink_persists_rows_and_progress() { + let api_url = spawn_graphql_server(json!({ + "data": { + "controllers": { + "edges": [ + { + "node": { + "address": "0x123", + "createdAt": "2024-03-20T12:00:00Z", + "account": { "username": "test_user" } + } + } + ] + } + } + })) + .await + .unwrap(); + + let sink = ControllersSink::new(":memory:", Some(1), Some(api_url)) + .await + .unwrap(); + sink.store.initialize().await.unwrap(); + + sink.process(&[], &make_batch(1_710_936_000, 1_710_936_100)) + .await + .unwrap(); + + let username: String = query_scalar(&format!( + "SELECT username FROM {CONTROLLERS_TABLE} WHERE address = ?1" + )) + .bind("0x0000000000000000000000000000000000000000000000000000000000000123") + .fetch_one(&sink.store.pool) + .await + .unwrap(); + assert_eq!(username, "test_user"); + + let synced_until: i64 = query_scalar(&format!( + "SELECT synced_until FROM {CONTROLLERS_STATE_TABLE} WHERE id = 1" + )) + .fetch_one(&sink.store.pool) + .await + .unwrap(); + assert_eq!(synced_until, 1_710_936_100); + } + + #[tokio::test] + async fn controllers_sink_upserts_existing_address() { + let api_url = spawn_graphql_server(json!({ + "data": { + "controllers": { + "edges": [ + { + "node": { + "address": "0x123", + "createdAt": "2024-03-20T12:00:00Z", + "account": { "username": "user_one" } + } + } + ] + } + } + })) + .await + .unwrap(); + + let sink = ControllersSink::new(":memory:", Some(1), Some(api_url)) + .await + .unwrap(); + sink.store.initialize().await.unwrap(); + + let controller = StoredController::try_from(ControllerNode { + address: "0x123".to_string(), + created_at: "2024-03-19T12:00:00Z".to_string(), + account: ControllerAccount { + username: "old_name".to_string(), + }, + }) + .unwrap(); + sink.store.upsert_controller(&controller).await.unwrap(); + + sink.process(&[], &make_batch(1_710_936_000, 1_710_936_100)) + .await + .unwrap(); + + let username: String = query_scalar(&format!( + "SELECT username FROM {CONTROLLERS_TABLE} WHERE id = ?1" + )) + .bind("0x0000000000000000000000000000000000000000000000000000000000000123") + .fetch_one(&sink.store.pool) + .await + .unwrap(); + assert_eq!(username, "user_one"); + } + + #[tokio::test] + async fn initialize_runs_full_sync_when_table_is_empty() { + let api_url = spawn_graphql_server(json!({ + "data": { + "controllers": { + "edges": [ + { + "node": { + "address": "0x456", + "createdAt": "2024-03-20T12:00:00Z", + "account": { "username": "boot_user" } + } + } + ] + } + } + })) + .await + .unwrap(); + + let mut sink = ControllersSink::new(":memory:", Some(1), Some(api_url)) + .await + .unwrap(); + initialize_sink(&mut sink).await; + + let username: String = query_scalar(&format!( + "SELECT username FROM {CONTROLLERS_TABLE} WHERE address = ?1" + )) + .bind("0x0000000000000000000000000000000000000000000000000000000000000456") + .fetch_one(&sink.store.pool) + .await + .unwrap(); + assert_eq!(username, "boot_user"); + + let synced_until: i64 = query_scalar(&format!( + "SELECT synced_until FROM {CONTROLLERS_STATE_TABLE} WHERE id = 1" + )) + .fetch_one(&sink.store.pool) + .await + .unwrap(); + assert!(synced_until > 0); + } +} diff --git a/crates/torii-ecs-sink/proto/types.proto b/crates/torii-ecs-sink/proto/types.proto index cabfae3e..97bd8454 100644 --- a/crates/torii-ecs-sink/proto/types.proto +++ b/crates/torii-ecs-sink/proto/types.proto @@ -148,6 +148,12 @@ enum OrderDirection { DESC = 1; } +message Controller { + bytes address = 1; + string username = 2; + uint64 deployed_at_timestamp = 3; +} + enum PaginationDirection { FORWARD = 0; BACKWARD = 1; @@ -160,6 +166,12 @@ message Pagination { repeated OrderBy order_by = 4; } +message ControllerQuery { + repeated bytes contract_addresses = 1; + repeated string usernames = 2; + Pagination pagination = 3; +} + message TokenAttributeFilter { string trait_name = 1; string trait_value = 2; diff --git a/crates/torii-ecs-sink/proto/world.proto b/crates/torii-ecs-sink/proto/world.proto index fc0c519f..aadcd8d3 100644 --- a/crates/torii-ecs-sink/proto/world.proto +++ b/crates/torii-ecs-sink/proto/world.proto @@ -26,6 +26,7 @@ service World { rpc RetrieveTokenBalances (RetrieveTokenBalancesRequest) returns (RetrieveTokenBalancesResponse); rpc RetrieveTransactions (RetrieveTransactionsRequest) returns (RetrieveTransactionsResponse); rpc SubscribeTransactions (SubscribeTransactionsRequest) returns (stream SubscribeTransactionsResponse); + rpc RetrieveControllers (RetrieveControllersRequest) returns (RetrieveControllersResponse); rpc RetrieveContracts (RetrieveContractsRequest) returns (RetrieveContractsResponse); rpc RetrieveTokenContracts (RetrieveTokenContractsRequest) returns (RetrieveTokenContractsResponse); rpc ExecuteSql (types.SqlQueryRequest) returns (types.SqlQueryResponse); @@ -39,6 +40,15 @@ message SubscribeTransactionsResponse { types.Transaction transaction = 1; } +message RetrieveControllersRequest { + types.ControllerQuery query = 1; +} + +message RetrieveControllersResponse { + string next_cursor = 1; + repeated types.Controller controllers = 2; +} + message RetrieveContractsRequest { types.ContractQuery query = 1; } diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index af077167..0ec1c36d 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -40,9 +40,10 @@ use crate::proto::types::{ }; use crate::proto::world::{ world_server::World, RetrieveContractsRequest, RetrieveContractsResponse, - RetrieveEntitiesRequest, RetrieveEntitiesResponse, RetrieveEventsRequest, - RetrieveEventsResponse, RetrieveTokenBalancesRequest, RetrieveTokenBalancesResponse, - RetrieveTokenContractsRequest, RetrieveTokenContractsResponse, RetrieveTokenTransfersRequest, + RetrieveControllersRequest, RetrieveControllersResponse, RetrieveEntitiesRequest, + RetrieveEntitiesResponse, RetrieveEventsRequest, RetrieveEventsResponse, + RetrieveTokenBalancesRequest, RetrieveTokenBalancesResponse, RetrieveTokenContractsRequest, + RetrieveTokenContractsResponse, RetrieveTokenTransfersRequest, RetrieveTokenTransfersResponse, RetrieveTokensRequest, RetrieveTokensResponse, RetrieveTransactionsRequest, RetrieveTransactionsResponse, SubscribeContractsRequest, SubscribeContractsResponse, SubscribeEntitiesRequest, SubscribeEntityResponse, @@ -997,6 +998,119 @@ impl EcsService { Ok(contracts) } + async fn load_controllers( + &self, + query: &types::ControllerQuery, + ) -> Result<(Vec, String)> { + let pagination = query.pagination.clone().unwrap_or(types::Pagination { + cursor: String::new(), + limit: 100, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }); + let limit = Self::pagination_limit(Some(&pagination), 100); + let target_limit = limit.saturating_add(1); + let direction_is_backward = pagination.direction == PaginationDirection::Backward as i32; + let order_sql = if direction_is_backward { "DESC" } else { "ASC" }; + + let mut conn = self.acquire_initialized_connection().await?; + self.ensure_sql_compat_views_on_connection(&mut conn).await?; + + let mut builder = + QueryBuilder::::new("SELECT address, username, deployed_at FROM controllers"); + let mut has_where = false; + + if !query.contract_addresses.is_empty() { + builder.push(" WHERE address IN ("); + { + let mut separated = builder.separated(", "); + for address in &query.contract_addresses { + separated.push_bind(format!("{:#066x}", felt_from_bytes(address)?)); + } + } + builder.push(")"); + has_where = true; + } + + if !query.usernames.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + has_where = true; + } + builder.push("username IN ("); + { + let mut separated = builder.separated(", "); + for username in &query.usernames { + separated.push_bind(username.clone()); + } + } + builder.push(")"); + } + + if !pagination.cursor.is_empty() { + if has_where { + builder.push(" AND "); + } else { + builder.push(" WHERE "); + } + builder.push("LOWER(SUBSTR(address, 3)) "); + builder.push(if direction_is_backward { "< " } else { "> " }); + builder.push_bind( + pagination + .cursor + .trim_start_matches("0x") + .trim_start_matches("0X") + .to_ascii_lowercase(), + ); + } + + builder.push(" ORDER BY address "); + builder.push(order_sql); + builder.push(" LIMIT "); + builder.push_bind(target_limit as i64); + + let rows = builder.build().fetch_all(&mut *conn).await?; + let mut controllers = rows + .into_iter() + .map(|row| { + let address = row.try_get::("address")?; + let deployed_at_timestamp = row + .try_get::, _>("deployed_at")? + .and_then(|value| chrono::DateTime::parse_from_rfc3339(&value).ok()) + .map(|value| value.timestamp() as u64) + .unwrap_or_default(); + Ok(types::Controller { + address: felt_from_hex(&address)?.to_bytes_be().to_vec(), + username: row + .try_get::, _>("username")? + .unwrap_or_default(), + deployed_at_timestamp, + }) + }) + .collect::>>()?; + + let has_more = controllers.len() > limit; + if has_more { + controllers.truncate(limit); + } + if direction_is_backward { + controllers.reverse(); + } + + let next_cursor = if has_more { + controllers + .last() + .map(|controller| hex::encode(&controller.address)) + .unwrap_or_default() + } else { + String::new() + }; + + Ok((controllers, next_cursor)) + } + fn scoped_table(&self, schema: &str, table: &str) -> String { format!("{schema}.{table}") } @@ -1084,9 +1198,14 @@ impl EcsService { &self, conn: &mut PoolConnection, ) -> Result<()> { - let controllers_sql = self.controllers_view_sql(conn).await?; - self.replace_sql_compat_view_on_connection(conn, "controllers", &controllers_sql) - .await?; + if !self + .sql_object_exists_on_connection(conn, None, "controllers") + .await? + { + let controllers_sql = self.controllers_view_sql(conn).await?; + self.replace_sql_compat_view_on_connection(conn, "controllers", &controllers_sql) + .await?; + } let event_messages_historical_sql = self.event_messages_historical_view_sql().await?; self.replace_sql_compat_view_on_connection( conn, @@ -4017,6 +4136,24 @@ impl World for EcsService { Ok(Response::new(RetrieveContractsResponse { contracts })) } + async fn retrieve_controllers( + &self, + request: Request, + ) -> Result, Status> { + let query = request + .into_inner() + .query + .ok_or_else(|| Status::invalid_argument("Missing query argument"))?; + let (controllers, next_cursor) = self + .load_controllers(&query) + .await + .map_err(internal_status)?; + Ok(Response::new(RetrieveControllersResponse { + next_cursor, + controllers, + })) + } + async fn retrieve_token_contracts( &self, request: Request, @@ -6257,6 +6394,31 @@ mod tests { .await .expect("insert erc721 ownership"); + sqlx::query( + "CREATE TABLE controllers ( + id TEXT PRIMARY KEY, + address TEXT NOT NULL UNIQUE, + username TEXT NOT NULL, + deployed_at TEXT NOT NULL, + updated_at BIGINT NOT NULL + )", + ) + .execute(&service.state.pool) + .await + .expect("create controllers backing table"); + sqlx::query( + "INSERT INTO controllers (id, address, username, deployed_at, updated_at) + VALUES (?1, ?2, ?3, ?4, ?5)", + ) + .bind(player) + .bind(player) + .bind("cartridge_user") + .bind("2024-03-20T12:00:00Z") + .bind(1_710_936_000_i64) + .execute(&service.state.pool) + .await + .expect("insert controller backing row"); + let controllers = service .execute_sql(Request::new(types::SqlQueryRequest { query: "SELECT address, username FROM controllers LIMIT 5".to_string(), @@ -6269,7 +6431,7 @@ mod tests { assert_eq!(controller_rows[0].get("address"), Some(&player.to_string())); assert_eq!( controller_rows[0].get("username"), - Some(&player.to_string()) + Some(&"cartridge_user".to_string()) ); let historical = service @@ -6527,4 +6689,64 @@ mod tests { assert_eq!(balance.balance, u256_bytes_from_u64(1)); assert_eq!(balance.token_id.as_ref(), Some(&expected_token_id)); } + + #[tokio::test] + async fn retrieve_controllers_reads_backing_table() { + let db_path = test_db_path("retrieve-controllers"); + let service = EcsService::new(&db_path, Some(1), None, None, None) + .await + .expect("service init"); + let controller = format!("{:#066x}", Felt::from(0x123_u64)); + + sqlx::query( + "CREATE TABLE controllers ( + id TEXT PRIMARY KEY, + address TEXT NOT NULL UNIQUE, + username TEXT NOT NULL, + deployed_at TEXT NOT NULL, + updated_at BIGINT NOT NULL + )", + ) + .execute(&service.state.pool) + .await + .expect("create controllers table"); + sqlx::query( + "INSERT INTO controllers (id, address, username, deployed_at, updated_at) + VALUES (?1, ?2, ?3, ?4, ?5)", + ) + .bind(&controller) + .bind(&controller) + .bind("alice") + .bind("2024-03-20T12:00:00Z") + .bind(1_710_936_000_i64) + .execute(&service.state.pool) + .await + .expect("insert controller"); + + let response = service + .retrieve_controllers(Request::new(RetrieveControllersRequest { + query: Some(types::ControllerQuery { + contract_addresses: vec![Felt::from(0x123_u64).to_bytes_be().to_vec()], + usernames: Vec::new(), + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 10, + direction: PaginationDirection::Forward as i32, + order_by: Vec::new(), + }), + }), + })) + .await + .expect("retrieve controllers") + .into_inner(); + + assert_eq!(response.controllers.len(), 1); + assert!(response.next_cursor.is_empty()); + assert_eq!( + response.controllers[0].address, + Felt::from(0x123_u64).to_bytes_be().to_vec() + ); + assert_eq!(response.controllers[0].username, "alice"); + assert_eq!(response.controllers[0].deployed_at_timestamp, 1_710_936_000); + } } From 1d46005e26930fe67c8a839fd98e6a3a5b429217 Mon Sep 17 00:00:00 2001 From: Valentin Dosimont Date: Wed, 25 Mar 2026 15:08:27 +0100 Subject: [PATCH 06/21] fix(ci): satisfy fmt and clippy on ecs harness --- bins/torii-introspect-bin/src/main.rs | 32 +++- crates/introspect-sqlite-sink/src/json.rs | 22 +-- .../introspect-sqlite-sink/src/processor.rs | 158 +++++++----------- crates/torii-controllers-sink/src/lib.rs | 44 +++-- crates/torii-ecs-sink/src/grpc_service.rs | 92 +++++----- crates/torii-erc1155/src/storage.rs | 4 +- crates/torii-erc20/src/grpc_service.rs | 16 +- crates/torii-erc20/src/storage.rs | 63 +++++-- 8 files changed, 232 insertions(+), 199 deletions(-) diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index 25410e2d..95595491 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -19,6 +19,7 @@ use torii::etl::extractor::{ use torii::{EtlConcurrencyConfig, ToriiConfigBuilder}; use torii_common::{MetadataFetcher, TokenUriService}; use torii_config_common::apply_observability_env; +use torii_controllers_sink::ControllersSink; use torii_dojo::decoder::DojoDecoder; use torii_dojo::store::postgres::PgStore; use torii_dojo::store::sqlite::SqliteStore; @@ -39,7 +40,6 @@ use torii_erc721::{ Erc721Decoder, Erc721MetadataCommandHandler, Erc721Service, Erc721Sink, Erc721Storage, FILE_DESCRIPTOR_SET as ERC721_DESCRIPTOR_SET, }; -use torii_controllers_sink::ControllersSink; use torii_introspect_postgres_sink::processor::IntrospectPgDb; use torii_introspect_sqlite_sink::processor::IntrospectSqliteDb; use torii_runtime_common::database::{resolve_token_db_setup, TokenDbSetup}; @@ -493,9 +493,18 @@ async fn run_with_postgres( let decoder: Arc = Arc::new(decoder); - let erc20_url = token_db_setup.as_ref().filter(|_| !token_targets.erc20.is_empty()).map(|s| s.erc20_url.as_str()); - let erc721_url = token_db_setup.as_ref().filter(|_| !token_targets.erc721.is_empty()).map(|s| s.erc721_url.as_str()); - let erc1155_url = token_db_setup.as_ref().filter(|_| !token_targets.erc1155.is_empty()).map(|s| s.erc1155_url.as_str()); + let erc20_url = token_db_setup + .as_ref() + .filter(|_| !token_targets.erc20.is_empty()) + .map(|s| s.erc20_url.as_str()); + let erc721_url = token_db_setup + .as_ref() + .filter(|_| !token_targets.erc721.is_empty()) + .map(|s| s.erc721_url.as_str()); + let erc1155_url = token_db_setup + .as_ref() + .filter(|_| !token_targets.erc1155.is_empty()) + .map(|s| s.erc1155_url.as_str()); let ecs_sink = EcsSink::new( storage_database_url, config.max_db_connections, @@ -661,9 +670,18 @@ async fn run_with_sqlite( let decoder: Arc = Arc::new(decoder); - let erc20_url = token_db_setup.as_ref().filter(|_| !token_targets.erc20.is_empty()).map(|s| s.erc20_url.as_str()); - let erc721_url = token_db_setup.as_ref().filter(|_| !token_targets.erc721.is_empty()).map(|s| s.erc721_url.as_str()); - let erc1155_url = token_db_setup.as_ref().filter(|_| !token_targets.erc1155.is_empty()).map(|s| s.erc1155_url.as_str()); + let erc20_url = token_db_setup + .as_ref() + .filter(|_| !token_targets.erc20.is_empty()) + .map(|s| s.erc20_url.as_str()); + let erc721_url = token_db_setup + .as_ref() + .filter(|_| !token_targets.erc721.is_empty()) + .map(|s| s.erc721_url.as_str()); + let erc1155_url = token_db_setup + .as_ref() + .filter(|_| !token_targets.erc1155.is_empty()) + .map(|s| s.erc1155_url.as_str()); let ecs_sink = EcsSink::new( storage_database_url, config.max_db_connections, diff --git a/crates/introspect-sqlite-sink/src/json.rs b/crates/introspect-sqlite-sink/src/json.rs index a4ca3c65..3b7c28d8 100644 --- a/crates/introspect-sqlite-sink/src/json.rs +++ b/crates/introspect-sqlite-sink/src/json.rs @@ -32,24 +32,18 @@ impl CairoTypeSerialization for SqliteJsonSerializer { self.serialize_byte_array(serializer, value) } - fn serialize_u256( - &self, - serializer: S, - value: U256, - ) -> Result { - let U256([a, b, c, d]) = value; - let corrected = U256([d, c, b, a]); + fn serialize_u256(&self, serializer: S, value: U256) -> Result { + let limbs = value.0; + let corrected = U256([limbs[3], limbs[2], limbs[1], limbs[0]]); let bytes = corrected.to_big_endian(); self.serialize_byte_array(serializer, &bytes) } - fn serialize_u512( - &self, - serializer: S, - value: U512, - ) -> Result { - let U512([a, b, c, d, e, f, g, h]) = value; - let corrected = U512([h, g, f, e, d, c, b, a]); + fn serialize_u512(&self, serializer: S, value: U512) -> Result { + let limbs = value.0; + let corrected = U512([ + limbs[7], limbs[6], limbs[5], limbs[4], limbs[3], limbs[2], limbs[1], limbs[0], + ]); let bytes = corrected.to_big_endian(); self.serialize_byte_array(serializer, &bytes) } diff --git a/crates/introspect-sqlite-sink/src/processor.rs b/crates/introspect-sqlite-sink/src/processor.rs index 6297dfd9..07e14456 100644 --- a/crates/introspect-sqlite-sink/src/processor.rs +++ b/crates/introspect-sqlite-sink/src/processor.rs @@ -11,8 +11,8 @@ use std::fmt::Display; use std::ops::Deref; use std::sync::{PoisonError, RwLock}; use torii::etl::envelope::MetaData; -use torii_introspect::events::{IntrospectBody, IntrospectMsg}; use torii::etl::EventMsg; +use torii_introspect::events::{IntrospectBody, IntrospectMsg}; use torii_introspect::schema::TableSchema; use torii_introspect::InsertsFields; use torii_sqlite::SqliteConnection; @@ -140,63 +140,38 @@ impl SqliteTables { } fn sqlite_column_type(type_def: &TypeDef) -> &'static str { - match type_def { + if is_json_type(type_def) { + "JSONB" + } else if matches!( + type_def, TypeDef::Bool - | TypeDef::I8 - | TypeDef::I16 - | TypeDef::I32 - | TypeDef::U8 - | TypeDef::U16 - | TypeDef::U32 => "INTEGER", - - TypeDef::I64 - | TypeDef::U64 - | TypeDef::U128 - | TypeDef::I128 - | TypeDef::U256 - | TypeDef::U512 - | TypeDef::Felt252 - | TypeDef::ClassHash - | TypeDef::ContractAddress - | TypeDef::StorageAddress - | TypeDef::StorageBaseAddress - | TypeDef::EthAddress => "TEXT", - - TypeDef::Struct(_) - | TypeDef::Enum(_) - | TypeDef::Tuple(_) - | TypeDef::Array(_) - | TypeDef::FixedArray(_) - | TypeDef::Option(_) - | TypeDef::Nullable(_) - | TypeDef::Result(_) => "JSONB", - - _ => "TEXT", + | TypeDef::I8 + | TypeDef::I16 + | TypeDef::I32 + | TypeDef::U8 + | TypeDef::U16 + | TypeDef::U32 + ) { + "INTEGER" + } else { + "TEXT" } } fn sqlite_primary_type(type_def: &PrimaryTypeDef) -> &'static str { - match type_def { + if matches!( + type_def, PrimaryTypeDef::Bool - | PrimaryTypeDef::I8 - | PrimaryTypeDef::I16 - | PrimaryTypeDef::I32 - | PrimaryTypeDef::U8 - | PrimaryTypeDef::U16 - | PrimaryTypeDef::U32 => "INTEGER", - - PrimaryTypeDef::I64 - | PrimaryTypeDef::U64 - | PrimaryTypeDef::U128 - | PrimaryTypeDef::I128 - | PrimaryTypeDef::Felt252 - | PrimaryTypeDef::ClassHash - | PrimaryTypeDef::ContractAddress - | PrimaryTypeDef::StorageAddress - | PrimaryTypeDef::StorageBaseAddress - | PrimaryTypeDef::EthAddress => "TEXT", - - _ => "TEXT", + | PrimaryTypeDef::I8 + | PrimaryTypeDef::I16 + | PrimaryTypeDef::I32 + | PrimaryTypeDef::U8 + | PrimaryTypeDef::U16 + | PrimaryTypeDef::U32 + ) { + "INTEGER" + } else { + "TEXT" } } @@ -217,7 +192,10 @@ fn is_json_type(type_def: &TypeDef) -> bool { fn create_table_query(table: &SqliteTable) -> String { let primary_type = sqlite_primary_type(&table.primary.type_def); let mut columns = Vec::with_capacity(table.columns.len() + 1); - columns.push(format!(r#""{}" {primary_type} PRIMARY KEY"#, table.primary.name)); + columns.push(format!( + r#""{}" {primary_type} PRIMARY KEY"#, + table.primary.name + )); for column_id in &table.order { let column = &table.columns[column_id]; let col_type = sqlite_column_type(&column.type_def); @@ -246,20 +224,21 @@ fn to_bind_value(value: &Value, type_def: &TypeDef) -> SqliteBindValue { Some(b) => SqliteBindValue::Integer(i64::from(b)), None => SqliteBindValue::Null, }, - TypeDef::I8 | TypeDef::I16 | TypeDef::I32 | TypeDef::U8 | TypeDef::U16 - | TypeDef::U32 => match value.as_i64() { - Some(n) => SqliteBindValue::Integer(n), - None => SqliteBindValue::Null, - }, + TypeDef::I8 | TypeDef::I16 | TypeDef::I32 | TypeDef::U8 | TypeDef::U16 | TypeDef::U32 => { + match value.as_i64() { + Some(n) => SqliteBindValue::Integer(n), + None => SqliteBindValue::Null, + } + } TypeDef::U64 => match value.as_u64() { - Some(n) => SqliteBindValue::Text(format!("0x{:x}", n)), + Some(n) => SqliteBindValue::Text(format!("0x{n:x}")), None => match value.as_str() { Some(s) => SqliteBindValue::Text(s.to_string()), None => SqliteBindValue::Null, }, }, TypeDef::I64 => match value.as_i64() { - Some(n) => SqliteBindValue::Text(format!("0x{:x}", n)), + Some(n) => SqliteBindValue::Text(format!("0x{n:x}")), None => match value.as_str() { Some(s) => SqliteBindValue::Text(s.to_string()), None => SqliteBindValue::Null, @@ -271,12 +250,9 @@ fn to_bind_value(value: &Value, type_def: &TypeDef) -> SqliteBindValue { | TypeDef::ContractAddress | TypeDef::StorageAddress | TypeDef::StorageBaseAddress - | TypeDef::EthAddress => match value.as_str() { - Some(s) => SqliteBindValue::Text(s.to_string()), - None => SqliteBindValue::Null, - }, - - TypeDef::U256 | TypeDef::U512 => match value.as_str() { + | TypeDef::EthAddress + | TypeDef::U256 + | TypeDef::U512 => match value.as_str() { Some(s) => SqliteBindValue::Text(s.to_string()), None => SqliteBindValue::Null, }, @@ -285,7 +261,7 @@ fn to_bind_value(value: &Value, type_def: &TypeDef) -> SqliteBindValue { Some(n) => SqliteBindValue::Text(format!("0x{:032x}", n as u128)), None => match value.as_str() { Some(s) => match s.parse::() { - Ok(n) => SqliteBindValue::Text(format!("0x{:032x}", n)), + Ok(n) => SqliteBindValue::Text(format!("0x{n:032x}")), Err(_) => SqliteBindValue::Text(s.to_string()), }, None => SqliteBindValue::Null, @@ -325,20 +301,24 @@ fn primary_to_bind_value(value: &Value, type_def: &PrimaryTypeDef) -> SqliteBind Some(b) => SqliteBindValue::Integer(i64::from(b)), None => SqliteBindValue::Null, }, - PrimaryTypeDef::I8 | PrimaryTypeDef::I16 | PrimaryTypeDef::I32 | PrimaryTypeDef::U8 - | PrimaryTypeDef::U16 | PrimaryTypeDef::U32 => match value.as_i64() { + PrimaryTypeDef::I8 + | PrimaryTypeDef::I16 + | PrimaryTypeDef::I32 + | PrimaryTypeDef::U8 + | PrimaryTypeDef::U16 + | PrimaryTypeDef::U32 => match value.as_i64() { Some(n) => SqliteBindValue::Integer(n), None => SqliteBindValue::Null, }, PrimaryTypeDef::U64 => match value.as_u64() { - Some(n) => SqliteBindValue::Text(format!("0x{:x}", n)), + Some(n) => SqliteBindValue::Text(format!("0x{n:x}")), None => match value.as_str() { Some(s) => SqliteBindValue::Text(s.to_string()), None => SqliteBindValue::Null, }, }, PrimaryTypeDef::I64 => match value.as_i64() { - Some(n) => SqliteBindValue::Text(format!("0x{:x}", n)), + Some(n) => SqliteBindValue::Text(format!("0x{n:x}")), None => match value.as_str() { Some(s) => SqliteBindValue::Text(s.to_string()), None => SqliteBindValue::Null, @@ -359,7 +339,7 @@ fn primary_to_bind_value(value: &Value, type_def: &PrimaryTypeDef) -> SqliteBind Some(n) => SqliteBindValue::Text(format!("0x{:032x}", n as u128)), None => match value.as_str() { Some(s) => match s.parse::() { - Ok(n) => SqliteBindValue::Text(format!("0x{:032x}", n)), + Ok(n) => SqliteBindValue::Text(format!("0x{n:032x}")), Err(_) => SqliteBindValue::Text(s.to_string()), }, None => SqliteBindValue::Null, @@ -455,32 +435,15 @@ impl IntrospectSqliteDb { Ok(()) } - async fn persist_alive_state(&self, table_id: Felt, alive: bool) -> SqliteDbResult<()> { - let alive = i64::from(alive); - sqlx::query( - r" - UPDATE introspect_sink_schema_state - SET alive = ?1, updated_at = unixepoch() - WHERE table_id = ?2 - ", - ) - .bind(alive) - .bind(format!("{table_id:#x}")) - .execute(self.pool()) - .await?; - Ok(()) - } - - async fn update_table( - &self, - event: impl Into, - ) -> SqliteDbResult<()> { + async fn update_table(&self, event: impl Into) -> SqliteDbResult<()> { let table_schema: TableSchema = event.into(); let id = table_schema.id; let exists_in_memory = self.tables.read()?.contains_key(&id); if !exists_in_memory { - let (_, query) = self.tables.create_table(&self.namespace, table_schema.clone())?; + let (_, query) = self + .tables + .create_table(&self.namespace, table_schema.clone())?; self.execute_queries(&[query]).await?; self.persist_table_state(&table_schema, true).await?; return Ok(()); @@ -537,9 +500,7 @@ impl IntrospectSqliteDb { .await?; Ok(()) } - IntrospectMsg::UpdateTable(event) => { - self.update_table(event.clone()).await - } + IntrospectMsg::UpdateTable(event) => self.update_table(event.clone()).await, IntrospectMsg::AddColumns(event) => { tracing::warn!( target: "torii::introspect_sqlite_sink", @@ -712,10 +673,7 @@ impl IntrospectSqliteDb { for (column_name, type_def) in column_names.iter().skip(1).zip(column_type_defs.iter()) { - let val = object - .get(*column_name) - .cloned() - .unwrap_or(Value::Null); + let val = object.get(*column_name).cloned().unwrap_or(Value::Null); match to_bind_value(&val, type_def) { SqliteBindValue::Null => { query = query.bind(None::); diff --git a/crates/torii-controllers-sink/src/lib.rs b/crates/torii-controllers-sink/src/lib.rs index 4b278325..1e56d498 100644 --- a/crates/torii-controllers-sink/src/lib.rs +++ b/crates/torii-controllers-sink/src/lib.rs @@ -92,11 +92,20 @@ impl TryFrom for StoredController { fn try_from(value: ControllerNode) -> Result { let created_at = DateTime::parse_from_rfc3339(&value.created_at) - .with_context(|| format!("invalid controller createdAt returned by API: {}", value.created_at))? + .with_context(|| { + format!( + "invalid controller createdAt returned by API: {}", + value.created_at + ) + })? .with_timezone(&Utc); - let felt_addr = Felt::from_str(&value.address) - .with_context(|| format!("invalid controller address returned by API: {}", value.address))?; - let normalized = format!("{:#066x}", felt_addr); + let felt_addr = Felt::from_str(&value.address).with_context(|| { + format!( + "invalid controller address returned by API: {}", + value.address + ) + })?; + let normalized = format!("{felt_addr:#066x}"); Ok(Self { id: normalized.clone(), address: normalized, @@ -181,15 +190,16 @@ impl ControllersStore { .fetch_optional(&self.pool) .await?; - Ok(row.and_then(|row| row.try_get::, _>(0).ok()).flatten()) + Ok(row + .and_then(|row| row.try_get::, _>(0).ok()) + .flatten()) } async fn is_empty(&self) -> Result { - let row = sqlx::query_scalar::(&format!( - "SELECT COUNT(*) FROM {CONTROLLERS_TABLE}" - )) - .fetch_one(&self.pool) - .await?; + let row = + sqlx::query_scalar::(&format!("SELECT COUNT(*) FROM {CONTROLLERS_TABLE}")) + .fetch_one(&self.pool) + .await?; Ok(row == 0) } @@ -426,7 +436,9 @@ query {{ stored += 1; } - self.store.store_synced_until(upper_bound.timestamp()).await?; + self.store + .store_synced_until(upper_bound.timestamp()) + .await?; tracing::info!( target: "torii::sinks::controllers", @@ -443,7 +455,7 @@ query {{ #[async_trait] impl Sink for ControllersSink { - fn name(&self) -> &str { + fn name(&self) -> &'static str { "controllers" } @@ -451,7 +463,11 @@ impl Sink for ControllersSink { vec![CONTROLLERS_TYPE] } - async fn process(&self, _envelopes: &[torii::etl::Envelope], batch: &ExtractionBatch) -> Result<()> { + async fn process( + &self, + _envelopes: &[torii::etl::Envelope], + batch: &ExtractionBatch, + ) -> Result<()> { match self.sync_batch(batch).await { Ok(()) => Ok(()), Err(error) => { @@ -514,8 +530,8 @@ mod tests { use serde_json::Value; use sqlx::query_scalar; use tokio::net::TcpListener; - use torii::command::CommandBus; use torii::axum::{extract::State, routing::post, Json, Router}; + use torii::command::CommandBus; use torii::grpc::SubscriptionManager; async fn initialize_sink(sink: &mut ControllersSink) { diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index 0ec1c36d..a391b0f1 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -43,16 +43,16 @@ use crate::proto::world::{ RetrieveControllersRequest, RetrieveControllersResponse, RetrieveEntitiesRequest, RetrieveEntitiesResponse, RetrieveEventsRequest, RetrieveEventsResponse, RetrieveTokenBalancesRequest, RetrieveTokenBalancesResponse, RetrieveTokenContractsRequest, - RetrieveTokenContractsResponse, RetrieveTokenTransfersRequest, - RetrieveTokenTransfersResponse, RetrieveTokensRequest, RetrieveTokensResponse, - RetrieveTransactionsRequest, RetrieveTransactionsResponse, SubscribeContractsRequest, - SubscribeContractsResponse, SubscribeEntitiesRequest, SubscribeEntityResponse, - SubscribeEventsRequest, SubscribeEventsResponse, SubscribeTokenBalancesRequest, - SubscribeTokenBalancesResponse, SubscribeTokenTransfersRequest, - SubscribeTokenTransfersResponse, SubscribeTokensRequest, SubscribeTokensResponse, - SubscribeTransactionsRequest, SubscribeTransactionsResponse, UpdateEntitiesSubscriptionRequest, - UpdateTokenBalancesSubscriptionRequest, UpdateTokenSubscriptionRequest, - UpdateTokenTransfersSubscriptionRequest, WorldsRequest, WorldsResponse, + RetrieveTokenContractsResponse, RetrieveTokenTransfersRequest, RetrieveTokenTransfersResponse, + RetrieveTokensRequest, RetrieveTokensResponse, RetrieveTransactionsRequest, + RetrieveTransactionsResponse, SubscribeContractsRequest, SubscribeContractsResponse, + SubscribeEntitiesRequest, SubscribeEntityResponse, SubscribeEventsRequest, + SubscribeEventsResponse, SubscribeTokenBalancesRequest, SubscribeTokenBalancesResponse, + SubscribeTokenTransfersRequest, SubscribeTokenTransfersResponse, SubscribeTokensRequest, + SubscribeTokensResponse, SubscribeTransactionsRequest, SubscribeTransactionsResponse, + UpdateEntitiesSubscriptionRequest, UpdateTokenBalancesSubscriptionRequest, + UpdateTokenSubscriptionRequest, UpdateTokenTransfersSubscriptionRequest, WorldsRequest, + WorldsResponse, }; #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -232,9 +232,9 @@ impl EcsService { has_erc20, has_erc721, has_erc1155, - erc20_url: erc20_url.map(|s| s.to_string()), - erc721_url: erc721_url.map(|s| s.to_string()), - erc1155_url: erc1155_url.map(|s| s.to_string()), + erc20_url: erc20_url.map(std::string::ToString::to_string), + erc721_url: erc721_url.map(std::string::ToString::to_string), + erc1155_url: erc1155_url.map(std::string::ToString::to_string), managed_tables: Mutex::new(None), entity_subscriptions: Mutex::new(HashMap::new()), event_message_subscriptions: Mutex::new(HashMap::new()), @@ -1014,13 +1014,14 @@ impl EcsService { let order_sql = if direction_is_backward { "DESC" } else { "ASC" }; let mut conn = self.acquire_initialized_connection().await?; - self.ensure_sql_compat_views_on_connection(&mut conn).await?; + self.ensure_sql_compat_views_on_connection(&mut conn) + .await?; let mut builder = QueryBuilder::::new("SELECT address, username, deployed_at FROM controllers"); - let mut has_where = false; - - if !query.contract_addresses.is_empty() { + let mut has_where = if query.contract_addresses.is_empty() { + false + } else { builder.push(" WHERE address IN ("); { let mut separated = builder.separated(", "); @@ -1029,8 +1030,8 @@ impl EcsService { } } builder.push(")"); - has_where = true; - } + true + }; if !query.usernames.is_empty() { if has_where { @@ -1374,8 +1375,7 @@ impl EcsService { pagination .map(|pagination| pagination.limit) .filter(|limit| *limit > 0) - .map(|limit| limit.min(1000) as usize) - .unwrap_or(default) + .map_or(default, |limit| limit.min(1000) as usize) } async fn load_token_contracts( @@ -1387,22 +1387,17 @@ impl EcsService { let mut conn = self.acquire_initialized_connection().await?; let include_erc20 = self.state.has_erc20 && (query.contract_types.is_empty() - || query - .contract_types - .iter() - .any(|kind| *kind == ContractType::Erc20 as i32)); + || query.contract_types.contains(&(ContractType::Erc20 as i32))); let include_erc721 = self.state.has_erc721 && (query.contract_types.is_empty() || query .contract_types - .iter() - .any(|kind| *kind == ContractType::Erc721 as i32)); + .contains(&(ContractType::Erc721 as i32))); let include_erc1155 = self.state.has_erc1155 && (query.contract_types.is_empty() || query .contract_types - .iter() - .any(|kind| *kind == ContractType::Erc1155 as i32)); + .contains(&(ContractType::Erc1155 as i32))); if include_erc20 { let table = self.scoped_table("erc20", "token_metadata"); @@ -1890,7 +1885,7 @@ impl EcsService { query: &types::TransactionQuery, ) -> Result<(Vec, String)> { let limit = Self::pagination_limit(query.pagination.as_ref(), 100); - let filter = query.filter.as_ref().cloned().unwrap_or_default(); + let filter = query.filter.clone().unwrap_or_default(); if !filter.caller_addresses.is_empty() || !filter.entrypoints.is_empty() || !filter.model_selectors.is_empty() @@ -1964,12 +1959,13 @@ impl EcsService { let mut builder = QueryBuilder::::new( "SELECT transaction_hash, block_number, executed_at, world_address FROM torii_ecs_events", ); - let mut has_where = false; - if let Some(from_block) = filter.from_block { + let mut has_where = if let Some(from_block) = filter.from_block { builder.push(" WHERE block_number >= "); builder.push_bind(from_block as i64); - has_where = true; - } + true + } else { + false + }; if let Some(to_block) = filter.to_block { if has_where { builder.push(" AND "); @@ -2046,12 +2042,13 @@ impl EcsService { let mut builder = QueryBuilder::::new(format!( "SELECT tx_hash, block_number, COALESCE(timestamp, '0') AS timestamp, {contract_column} FROM {table}" )); - let mut has_where = false; - if let Some(from_block) = filter.from_block { + let mut has_where = if let Some(from_block) = filter.from_block { builder.push(" WHERE block_number >= "); builder.push_bind(from_block as i64); - has_where = true; - } + true + } else { + false + }; if let Some(to_block) = filter.to_block { if has_where { builder.push(" AND "); @@ -4336,15 +4333,17 @@ impl CairoTypeSerialization for SnapshotJsonSerializer { } fn serialize_u256(&self, serializer: S, value: U256) -> Result { - let U256([a, b, c, d]) = value; - let corrected = U256([d, c, b, a]); + let limbs = value.0; + let corrected = U256([limbs[3], limbs[2], limbs[1], limbs[0]]); let bytes = corrected.to_big_endian(); self.serialize_byte_array(serializer, &bytes) } fn serialize_u512(&self, serializer: S, value: U512) -> Result { - let U512([a, b, c, d, e, f, g, h]) = value; - let corrected = U512([h, g, f, e, d, c, b, a]); + let limbs = value.0; + let corrected = U512([ + limbs[7], limbs[6], limbs[5], limbs[4], limbs[3], limbs[2], limbs[1], limbs[0], + ]); let bytes = corrected.to_big_endian(); self.serialize_byte_array(serializer, &bytes) } @@ -5005,8 +5004,9 @@ fn push_transfer_filters( to_column: &str, token_id_column: Option<&str>, ) { - let mut has_where = false; - if !query.contract_addresses.is_empty() { + let mut has_where = if query.contract_addresses.is_empty() { + false + } else { builder.push(format!(" WHERE hex({contract_column}) IN (")); { let mut separated = builder.separated(", "); @@ -5015,8 +5015,8 @@ fn push_transfer_filters( } } builder.push(")"); - has_where = true; - } + true + }; if !query.account_addresses.is_empty() { if has_where { builder.push(" AND "); diff --git a/crates/torii-erc1155/src/storage.rs b/crates/torii-erc1155/src/storage.rs index f5c3f886..bc6e4f22 100644 --- a/crates/torii-erc1155/src/storage.rs +++ b/crates/torii-erc1155/src/storage.rs @@ -1055,7 +1055,9 @@ impl Erc1155Storage { ) .ok(); - Ok(result.map(|(bytes, block_str)| (blob_to_u256(&bytes), block_str.parse::().unwrap_or(0)))) + Ok(result.map(|(bytes, block_str)| { + (blob_to_u256(&bytes), block_str.parse::().unwrap_or(0)) + })) } /// Get balances for multiple (contract, wallet, token_id) tuples in a single query diff --git a/crates/torii-erc20/src/grpc_service.rs b/crates/torii-erc20/src/grpc_service.rs index 255964e0..8d2bc4e6 100644 --- a/crates/torii-erc20/src/grpc_service.rs +++ b/crates/torii-erc20/src/grpc_service.rs @@ -490,13 +490,15 @@ impl Erc20Trait for Erc20Service { let entries = all .into_iter() - .map(|(token, name, symbol, decimals, total_supply)| TokenMetadataEntry { - token: token.to_bytes_be().to_vec(), - name, - symbol, - decimals: decimals.map(|d| d as u32), - total_supply: total_supply.map(u256_to_bytes), - }) + .map( + |(token, name, symbol, decimals, total_supply)| TokenMetadataEntry { + token: token.to_bytes_be().to_vec(), + name, + symbol, + decimals: decimals.map(|d| d as u32), + total_supply: total_supply.map(u256_to_bytes), + }, + ) .collect(); Ok(Response::new(GetTokenMetadataResponse { diff --git a/crates/torii-erc20/src/storage.rs b/crates/torii-erc20/src/storage.rs index 58737a6a..2810b3c2 100644 --- a/crates/torii-erc20/src/storage.rs +++ b/crates/torii-erc20/src/storage.rs @@ -1503,7 +1503,9 @@ impl Erc20Storage { ) .ok(); - Ok(result.map(|(bytes, block_str)| (blob_to_u256(&bytes), block_str.parse::().unwrap_or(0)))) + Ok(result.map(|(bytes, block_str)| { + (blob_to_u256(&bytes), block_str.parse::().unwrap_or(0)) + })) } /// Get balances with optional token/wallet filters and cursor pagination. @@ -2049,7 +2051,12 @@ impl Erc20Storage { let symbol: Option = row.get(1)?; let decimals: Option = row.get(2)?; let total_supply: Option> = row.get(3)?; - Ok((name, symbol, decimals.and_then(|d| d.parse::().ok()), total_supply.map(|b| blob_to_u256(&b)))) + Ok(( + name, + symbol, + decimals.and_then(|d| d.parse::().ok()), + total_supply.map(|b| blob_to_u256(&b)), + )) }, ) .ok(); @@ -2059,9 +2066,18 @@ impl Erc20Storage { /// Get all token metadata pub async fn get_all_token_metadata( &self, - ) -> Result, Option, Option, Option)>> { + ) -> Result< + Vec<( + Felt, + Option, + Option, + Option, + Option, + )>, + > { let conn = self.conn.lock().unwrap(); - let mut stmt = conn.prepare("SELECT token, name, symbol, decimals, total_supply FROM token_metadata")?; + let mut stmt = + conn.prepare("SELECT token, name, symbol, decimals, total_supply FROM token_metadata")?; let rows = stmt.query_map([], |row| { let token_bytes: Vec = row.get(0)?; let name: Option = row.get(1)?; @@ -2087,7 +2103,13 @@ impl Erc20Storage { cursor: Option, limit: u32, ) -> Result<( - Vec<(Felt, Option, Option, Option, Option)>, + Vec<( + Felt, + Option, + Option, + Option, + Option, + )>, Option, )> { if self.backend == StorageBackend::Postgres { @@ -2435,7 +2457,9 @@ impl Erc20Storage { amount: blob_to_u256(&row.get::>(4)), block_number: row.get::(5).parse::().unwrap_or(0), tx_hash: blob_to_felt(&row.get::>(6)), - timestamp: row.get::>(7).and_then(|s| s.parse::().ok()), + timestamp: row + .get::>(7) + .and_then(|s| s.parse::().ok()), }) .collect(); @@ -2549,7 +2573,9 @@ impl Erc20Storage { amount: blob_to_u256(&row.get::>(4)), block_number: row.get::(5).parse::().unwrap_or(0), tx_hash: blob_to_felt(&row.get::>(6)), - timestamp: row.get::>(7).and_then(|s| s.parse::().ok()), + timestamp: row + .get::>(7) + .and_then(|s| s.parse::().ok()), }) .collect(); @@ -2987,7 +3013,12 @@ impl Erc20Storage { Ok(row.map(|r| { let decimals: Option = r.get(2); let total_supply: Option> = r.get(3); - (r.get(0), r.get(1), decimals.and_then(|d| d.parse::().ok()), total_supply.map(|b| blob_to_u256(&b))) + ( + r.get(0), + r.get(1), + decimals.and_then(|d| d.parse::().ok()), + total_supply.map(|b| blob_to_u256(&b)), + ) })) } @@ -2996,7 +3027,13 @@ impl Erc20Storage { cursor: Option, limit: u32, ) -> Result<( - Vec<(Felt, Option, Option, Option, Option)>, + Vec<( + Felt, + Option, + Option, + Option, + Option, + )>, Option, )> { let client = self.pg_client().await?; @@ -3024,7 +3061,13 @@ impl Erc20Storage { .await? }; - let mut out: Vec<(Felt, Option, Option, Option, Option)> = rows + let mut out: Vec<( + Felt, + Option, + Option, + Option, + Option, + )> = rows .into_iter() .map(|row| { let decimals: Option = row.get(3); From 5cbe9cbc840dde042464092fc31e0ee2fcbe394e Mon Sep 17 00:00:00 2001 From: Bengineer Date: Wed, 25 Mar 2026 18:00:47 +0000 Subject: [PATCH 07/21] feat: Implement SQLite backend for introspection SQL sink - Added `SqliteBackend` struct and its implementation for `IntrospectBackend`. - Introduced `SqliteTable` and related error handling for table operations. - Created utility functions for generating SQL queries, including `create_table_query`. - Implemented JSON serialization for SQLite using `SqliteJsonSerializer`. - Added runtime support for handling introspection messages in SQLite. - Established a new module structure for SQLite backend, including processor, query, and table management. - Integrated metrics tracking for processed introspection envelopes. - Enhanced error handling and type conversions for database interactions. --- .rustfmt.toml | 2 + Cargo.lock | 12 +- Cargo.toml | 14 +- bins/torii-introspect-synth/Cargo.toml | 2 +- crates/dojo/Cargo.toml | 8 +- crates/dojo/src/store/mod.rs | 3 + crates/dojo/src/store/postgres.rs | 42 +- crates/dojo/src/store/sqlite.rs | 9 +- crates/introspect-postgres-sink/Cargo.toml | 1 + .../introspect-postgres-sink/src/backend.rs | 145 ++++ crates/introspect-postgres-sink/src/create.rs | 53 +- crates/introspect-postgres-sink/src/error.rs | 160 ---- .../introspect-postgres-sink/src/handler.rs | 27 + crates/introspect-postgres-sink/src/insert.rs | 77 +- crates/introspect-postgres-sink/src/lib.rs | 15 +- .../introspect-postgres-sink/src/processor.rs | 248 ------- crates/introspect-postgres-sink/src/query.rs | 168 ++--- crates/introspect-postgres-sink/src/table.rs | 157 ---- crates/introspect-postgres-sink/src/tables.rs | 229 ------ crates/introspect-postgres-sink/src/types.rs | 7 +- .../introspect-postgres-sink/src/upgrade.rs | 48 +- crates/introspect-postgres-sink/src/utils.rs | 4 - crates/introspect-sql-sink/Cargo.toml | 9 +- .../migrations/postgres/001_domains.sql | 113 +++ .../postgres/002_metadata_function.sql | 11 + .../migrations/postgres/003_store.sql | 67 ++ .../migrations/sqlite/001_init.sql | 4 + .../migrations/sqlite/002_schema_state.sql | 11 + crates/introspect-sql-sink/src/backend.rs | 125 ++++ crates/introspect-sql-sink/src/error.rs | 43 +- crates/introspect-sql-sink/src/lib.rs | 24 +- crates/introspect-sql-sink/src/namespace.rs | 199 +++++ .../src/postgres/backend.rs | 145 ++++ .../src/postgres/create.rs | 322 ++++++++ .../src/postgres/handler.rs | 28 + .../src/postgres/insert.rs | 89 +++ .../introspect-sql-sink/src/postgres/json.rs | 89 +++ .../introspect-sql-sink/src/postgres/mod.rs | 15 + .../introspect-sql-sink/src/postgres/query.rs | 688 ++++++++++++++++++ .../introspect-sql-sink/src/postgres/types.rs | 185 +++++ .../src/postgres/upgrade.rs | 575 +++++++++++++++ .../src/{ => postgres}/utils.rs | 4 - crates/introspect-sql-sink/src/processor.rs | 232 ++++-- crates/introspect-sql-sink/src/runtime.rs | 82 +++ crates/introspect-sql-sink/src/schema.rs | 188 ----- crates/introspect-sql-sink/src/sink.rs | 28 +- .../introspect-sql-sink/src/sqlite/backend.rs | 142 ++++ crates/introspect-sql-sink/src/sqlite/json.rs | 83 +++ crates/introspect-sql-sink/src/sqlite/mod.rs | 6 + .../src/sqlite/processor.rs | 396 ++++++++++ .../introspect-sql-sink/src/sqlite/query.rs | 23 + .../src/sqlite}/sink.rs | 28 +- .../introspect-sql-sink/src/sqlite/table.rs | 70 ++ crates/introspect-sql-sink/src/table.rs | 90 +-- crates/introspect-sql-sink/src/tables.rs | 118 +-- crates/introspect-sqlite-sink/Cargo.toml | 1 + .../migrations/002_schema_state.sql | 11 +- crates/introspect-sqlite-sink/src/backend.rs | 139 ++++ crates/introspect-sqlite-sink/src/lib.rs | 6 +- .../introspect-sqlite-sink/src/processor.rs | 31 +- crates/introspect-sqlite-sink/src/query.rs | 23 + crates/introspect-sqlite-sink/src/sink.rs | 13 +- crates/postgres/Cargo.toml | 17 - crates/postgres/src/lib.rs | 2 - crates/postgres/src/metadata.rs | 72 -- crates/postgres/src/migration.rs | 250 ------- crates/sql/Cargo.toml | 1 + crates/sql/src/lib.rs | 5 + crates/sql/src/postgres.rs | 51 +- crates/sql/src/sqlite.rs | 59 +- crates/sql/src/types.rs | 22 + crates/sqlite/Cargo.toml | 19 - crates/sqlite/src/db.rs | 73 -- crates/sqlite/src/lib.rs | 4 - crates/sqlite/src/migration.rs | 320 -------- examples/introspect/restart.rs | 5 +- examples/introspect/simple.rs | 2 +- 77 files changed, 4508 insertions(+), 2281 deletions(-) create mode 100644 crates/introspect-postgres-sink/src/backend.rs delete mode 100644 crates/introspect-postgres-sink/src/error.rs create mode 100644 crates/introspect-postgres-sink/src/handler.rs delete mode 100644 crates/introspect-postgres-sink/src/processor.rs delete mode 100644 crates/introspect-postgres-sink/src/table.rs delete mode 100644 crates/introspect-postgres-sink/src/tables.rs create mode 100644 crates/introspect-sql-sink/migrations/postgres/001_domains.sql create mode 100644 crates/introspect-sql-sink/migrations/postgres/002_metadata_function.sql create mode 100644 crates/introspect-sql-sink/migrations/postgres/003_store.sql create mode 100644 crates/introspect-sql-sink/migrations/sqlite/001_init.sql create mode 100644 crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql create mode 100644 crates/introspect-sql-sink/src/backend.rs create mode 100644 crates/introspect-sql-sink/src/namespace.rs create mode 100644 crates/introspect-sql-sink/src/postgres/backend.rs create mode 100644 crates/introspect-sql-sink/src/postgres/create.rs create mode 100644 crates/introspect-sql-sink/src/postgres/handler.rs create mode 100644 crates/introspect-sql-sink/src/postgres/insert.rs create mode 100644 crates/introspect-sql-sink/src/postgres/json.rs create mode 100644 crates/introspect-sql-sink/src/postgres/mod.rs create mode 100644 crates/introspect-sql-sink/src/postgres/query.rs create mode 100644 crates/introspect-sql-sink/src/postgres/types.rs create mode 100644 crates/introspect-sql-sink/src/postgres/upgrade.rs rename crates/introspect-sql-sink/src/{ => postgres}/utils.rs (96%) create mode 100644 crates/introspect-sql-sink/src/runtime.rs delete mode 100644 crates/introspect-sql-sink/src/schema.rs create mode 100644 crates/introspect-sql-sink/src/sqlite/backend.rs create mode 100644 crates/introspect-sql-sink/src/sqlite/json.rs create mode 100644 crates/introspect-sql-sink/src/sqlite/mod.rs create mode 100644 crates/introspect-sql-sink/src/sqlite/processor.rs create mode 100644 crates/introspect-sql-sink/src/sqlite/query.rs rename crates/{introspect-postgres-sink/src => introspect-sql-sink/src/sqlite}/sink.rs (83%) create mode 100644 crates/introspect-sql-sink/src/sqlite/table.rs create mode 100644 crates/introspect-sqlite-sink/src/backend.rs create mode 100644 crates/introspect-sqlite-sink/src/query.rs delete mode 100644 crates/postgres/Cargo.toml delete mode 100644 crates/postgres/src/lib.rs delete mode 100644 crates/postgres/src/metadata.rs delete mode 100644 crates/postgres/src/migration.rs create mode 100644 crates/sql/src/types.rs delete mode 100644 crates/sqlite/Cargo.toml delete mode 100644 crates/sqlite/src/db.rs delete mode 100644 crates/sqlite/src/lib.rs delete mode 100644 crates/sqlite/src/migration.rs diff --git a/.rustfmt.toml b/.rustfmt.toml index 5207c2aa..d01043dc 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -7,3 +7,5 @@ use_small_heuristics = "Default" # Stable options only reorder_imports = true reorder_modules = true + +imports_granularity = "Module" diff --git a/Cargo.lock b/Cargo.lock index 7e7bd732..66a82515 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -917,7 +917,7 @@ dependencies = [ [[package]] name = "dojo-introspect" version = "0.1.0" -source = "git+https://github.com/dojoengine/dojo-introspect?rev=aadc3c9#aadc3c980706596a4a083413813a0a3ab01fded7" +source = "git+https://github.com/dojoengine/dojo-introspect?rev=214eb01#214eb01f5ee8a0f70e209aea8ff729c5cd1c7f0c" dependencies = [ "async-trait", "introspect-rust-macros", @@ -1864,7 +1864,7 @@ dependencies = [ [[package]] name = "introspect-events" version = "0.1.2" -source = "git+https://github.com/cartridge-gg/introspect?rev=34e93c1#34e93c10c867c53c622cce03abb6431c9dae0ef5" +source = "git+https://github.com/cartridge-gg/introspect?rev=4092011#4092011533ef34473ebb8a4ec3e725e3ba779697" dependencies = [ "cainome-cairo-serde", "introspect-types", @@ -1876,7 +1876,7 @@ dependencies = [ [[package]] name = "introspect-rust-macros" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/introspect?rev=34e93c1#34e93c10c867c53c622cce03abb6431c9dae0ef5" +source = "git+https://github.com/cartridge-gg/introspect?rev=4092011#4092011533ef34473ebb8a4ec3e725e3ba779697" dependencies = [ "paste", "proc-macro2", @@ -1888,7 +1888,7 @@ dependencies = [ [[package]] name = "introspect-types" version = "0.1.2" -source = "git+https://github.com/cartridge-gg/introspect?rev=34e93c1#34e93c10c867c53c622cce03abb6431c9dae0ef5" +source = "git+https://github.com/cartridge-gg/introspect?rev=4092011#4092011533ef34473ebb8a4ec3e725e3ba779697" dependencies = [ "blake3", "convert_case", @@ -4623,6 +4623,7 @@ dependencies = [ "torii-erc721", "torii-introspect", "torii-introspect-postgres-sink", + "torii-introspect-sql-sink", "torii-log-sink", "torii-sql", "torii-sql-sink", @@ -4955,6 +4956,7 @@ dependencies = [ "tokio", "torii", "torii-introspect", + "torii-introspect-sql-sink", "torii-sql", "tracing", "xxhash-rust", @@ -5004,6 +5006,7 @@ dependencies = [ "tokio", "torii", "torii-introspect", + "torii-introspect-sql-sink", "torii-sql", "tracing", ] @@ -5072,6 +5075,7 @@ dependencies = [ "futures", "itertools 0.14.0", "sqlx", + "starknet-types-core", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1d9bad29..71d6ec36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,10 +106,10 @@ bigdecimal = "0.4.10" tonic-build = "0.12" # Introspect -introspect-events = { git = "https://github.com/cartridge-gg/introspect", rev = "34e93c1" } -introspect-types = { git = "https://github.com/cartridge-gg/introspect", rev = "34e93c1" } -introspect-rust-macros = { git = "https://github.com/cartridge-gg/introspect", rev = "34e93c1" } -dojo-introspect = { git = "https://github.com/dojoengine/dojo-introspect", rev = "aadc3c9" } +introspect-events = { git = "https://github.com/cartridge-gg/introspect", rev = "4092011" } +introspect-types = { git = "https://github.com/cartridge-gg/introspect", rev = "4092011" } +introspect-rust-macros = { git = "https://github.com/cartridge-gg/introspect", rev = "4092011" } +dojo-introspect = { git = "https://github.com/dojoengine/dojo-introspect", rev = "214eb01" } # Utils @@ -217,12 +217,16 @@ torii-log-sink.workspace = true torii-erc20.workspace = true torii-erc721.workspace = true torii-erc1155.workspace = true -torii-dojo.workspace = true +torii-dojo = { workspace = true, features = ["postgres", "sqlite"] } torii-introspect.workspace = true torii-common.workspace = true torii-introspect-postgres-sink.workspace = true torii-test-utils.workspace = true torii-sql = { workspace = true, features = ["postgres", "sqlite"] } +torii-introspect-sql-sink = { workspace = true, features = [ + "postgres", + "sqlite", +] } # Example dependencies diff --git a/bins/torii-introspect-synth/Cargo.toml b/bins/torii-introspect-synth/Cargo.toml index 8caedd45..df8a3290 100644 --- a/bins/torii-introspect-synth/Cargo.toml +++ b/bins/torii-introspect-synth/Cargo.toml @@ -11,7 +11,7 @@ path = "src/main.rs" torii = { path = "../../" } torii-runtime-common.workspace = true torii-dojo = { path = "../../crates/dojo" } -torii-introspect-postgres-sink = { path = "../../crates/introspect-postgres-sink" } +torii-introspect-postgres-sink.workspace = true tokio = { version = "1", features = ["full"] } tracing = "0.1" diff --git a/crates/dojo/Cargo.toml b/crates/dojo/Cargo.toml index 153ded69..ccf2cf22 100644 --- a/crates/dojo/Cargo.toml +++ b/crates/dojo/Cargo.toml @@ -19,8 +19,6 @@ thiserror.workspace = true hex.workspace = true itertools.workspace = true sqlx = { workspace = true, features = [ - "postgres", - "sqlite", "runtime-tokio-rustls", "macros", "migrate", @@ -30,9 +28,13 @@ dojo-introspect.workspace = true introspect-types.workspace = true torii-introspect.workspace = true -torii-sql = { workspace = true, features = ["postgres", "sqlite"] } +torii-sql.workspace = true +[features] +postgres = ["sqlx/postgres"] +sqlite = ["sqlx/sqlite"] + [build-dependencies] tonic-build.workspace = true diff --git a/crates/dojo/src/store/mod.rs b/crates/dojo/src/store/mod.rs index 148ad129..1a4ab6da 100644 --- a/crates/dojo/src/store/mod.rs +++ b/crates/dojo/src/store/mod.rs @@ -1,5 +1,8 @@ pub mod json; + +#[cfg(feature = "postgres")] pub mod postgres; +#[cfg(feature = "sqlite")] pub mod sqlite; use crate::table::DojoTableInfo; diff --git a/crates/dojo/src/store/postgres.rs b/crates/dojo/src/store/postgres.rs index 351a49bb..05800dda 100644 --- a/crates/dojo/src/store/postgres.rs +++ b/crates/dojo/src/store/postgres.rs @@ -6,17 +6,15 @@ use async_trait::async_trait; use introspect_types::{Attribute, ColumnInfo, ResultInto, TypeDef}; use itertools::Itertools; use sqlx::migrate::Migrator; -use sqlx::postgres::PgArguments; use sqlx::query::Query; use sqlx::types::Json; -use sqlx::{FromRow, Postgres}; +use sqlx::FromRow; use starknet_types_core::felt::Felt; use std::collections::HashMap; -use std::ops::Deref; use torii_introspect::postgres::owned::PgTypeDef; use torii_introspect::postgres::PgFelt; use torii_introspect::schema::ColumnKeyTrait; -use torii_sql::{DbConnection, SqlxResult}; +use torii_sql::{DbConnection, PgArguments, PgPool, Postgres, SqlxResult}; pub const FETCH_TABLES_QUERY: &str = r#" SELECT DISTINCT ON (owner, id) @@ -190,34 +188,6 @@ where } } -// #[async_trait] -// impl PgTypeDef for DojoTableInfo { -// type Row = DojoTableRow; -// async fn get_rows( -// pool: &PgPool, -// query: &'static str, -// owners: &[Felt], -// ) -> SqlxResult> { -// Self::get_pg_rows(pool, query, owners) -// .await -// .map(|rows| rows.into_iter().map_into().collect_vec()) -// } -// } - -// #[async_trait] -// impl PgTypeDef<()> for DojoTable { -// type Row = DojoTableRow; -// async fn get_rows( -// pool: &PgPool, -// query: &'static str, -// owners: &[Felt], -// ) -> SqlxResult> { -// Self::get_pg_rows(pool, query, owners) -// .await -// .map(|rows| rows.into_iter().map_into().collect_vec()) -// } -// } - pub fn table_insert_query( owner: &Felt, id: &Felt, @@ -311,11 +281,9 @@ impl DojoTable { pub struct PgStore(pub T); -impl Deref for PgStore { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.0 +impl> DbConnection for PgStore { + fn pool(&self) -> &PgPool { + &self.0.pool() } } diff --git a/crates/dojo/src/store/sqlite.rs b/crates/dojo/src/store/sqlite.rs index c0a15c74..e585e90a 100644 --- a/crates/dojo/src/store/sqlite.rs +++ b/crates/dojo/src/store/sqlite.rs @@ -14,7 +14,8 @@ use std::io; use std::ops::Deref; use torii_common::{blob_to_felt, felt_to_blob}; use torii_introspect::schema::ColumnKeyTrait; -use torii_sql::{DbConnection, SqlxResult}; +use torii_sql::sqlite::SqliteDbConnection; +use torii_sql::SqlxResult; pub const DOJO_SQLITE_STORE_MIGRATIONS: Migrator = sqlx::migrate!("./migrations/sqlite"); @@ -161,21 +162,21 @@ impl Deref for SqliteStore { } } -impl + Send + Sync> SqliteStore { +impl SqliteStore { pub async fn initialize(&self) -> SqlxResult<()> { self.migrate(Some("dojo"), DOJO_SQLITE_STORE_MIGRATIONS) .await } } -impl> From for SqliteStore { +impl From for SqliteStore { fn from(pool: T) -> Self { Self(pool) } } #[async_trait] -impl + Send + Sync + 'static> DojoStoreTrait for SqliteStore { +impl DojoStoreTrait for SqliteStore { type Error = DojoSqliteStoreError; async fn save_table( diff --git a/crates/introspect-postgres-sink/Cargo.toml b/crates/introspect-postgres-sink/Cargo.toml index 25123775..f3cd11ab 100644 --- a/crates/introspect-postgres-sink/Cargo.toml +++ b/crates/introspect-postgres-sink/Cargo.toml @@ -33,3 +33,4 @@ arrayvec.workspace = true # Local crates torii-introspect.workspace = true torii-sql = { workspace = true, features = ["postgres"] } +torii-introspect-sql-sink.workspace = true diff --git a/crates/introspect-postgres-sink/src/backend.rs b/crates/introspect-postgres-sink/src/backend.rs new file mode 100644 index 00000000..7c3cabcd --- /dev/null +++ b/crates/introspect-postgres-sink/src/backend.rs @@ -0,0 +1,145 @@ +use crate::insert::insert_record_queries; +use crate::query::{insert_columns_query, insert_table_query, CreatePgTable}; +use crate::upgrade::PgTableUpgrade; +use async_trait::async_trait; +use introspect_types::schema::{Names, TypeDefs}; +use introspect_types::{ColumnDef, FeltIds, PrimaryDef}; +use starknet_types_core::felt::Felt; +use torii_introspect::tables::RecordSchema; +use torii_introspect::Record; +use torii_introspect_sql_sink::processor::IntrospectDb; +use torii_introspect_sql_sink::{ + IntrospectQueryMaker, IntrospectSqlSink, RecordResult, Table, TableError, TableResult, +}; +use torii_sql::{DbConnection, PgPool, PgQuery, Postgres}; + +pub type IntrospectPgDb = IntrospectDb>; + +pub struct PostgresBackend>(T); + +impl> From for PostgresBackend { + fn from(value: T) -> Self { + PostgresBackend(value) + } +} + +impl> DbConnection for PostgresBackend { + fn pool(&self) -> &PgPool { + self.0.pool() + } +} + +#[async_trait] +impl + Send + Sync> IntrospectQueryMaker for PostgresBackend { + type DB = Postgres; + + fn create_table_queries( + namespace: &str, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> TableResult<()> { + let ns = namespace.into(); + CreatePgTable::new(&ns, id, name, primary, columns)?.make_queries(queries); + store_table_queries( + namespace, + id, + name, + primary, + columns, + from_address, + block_number, + transaction_hash, + queries, + ) + } + fn update_table_queries( + table: &mut Table, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> TableResult<()> { + let upgrades = table.upgrade_table(name, primary, columns)?; + upgrades.to_queries(block_number, transaction_hash, queries)?; + let columns = table.columns_with_ids(&upgrades.columns_upgraded)?; + store_table_queries( + &table.namespace, + &table.id, + name, + primary, + columns, + from_address, + block_number, + transaction_hash, + queries, + ) + } + fn insert_record_queries( + namespace: &str, + table_name: &str, + schema: &RecordSchema<'_>, + records: &[Record], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> RecordResult<()> { + insert_record_queries( + namespace, + table_name, + schema, + records, + from_address, + block_number, + transaction_hash, + queries, + ) + } +} + +fn store_table_queries( + schema: &str, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: CS, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, +) -> TableResult<()> +where + CS: Names + FeltIds + TypeDefs, +{ + queries.push( + insert_table_query( + &schema, + &id, + &name, + &primary, + from_address, + block_number, + transaction_hash, + ) + .map_err(TableError::Encode)?, + ); + + queries.push( + insert_columns_query(&schema, &id, columns, block_number, transaction_hash) + .map_err(TableError::Encode)?, + ); + Ok(()) +} + +impl> IntrospectSqlSink for PostgresBackend { + const NAME: &'static str = "Introspect Postgres"; +} diff --git a/crates/introspect-postgres-sink/src/create.rs b/crates/introspect-postgres-sink/src/create.rs index 08d2e2df..86d6a7b1 100644 --- a/crates/introspect-postgres-sink/src/create.rs +++ b/crates/introspect-postgres-sink/src/create.rs @@ -1,16 +1,17 @@ use crate::{ query::{make_schema_query, CreatePgTable, CreatesType}, utils::{AsBytes, HasherExt}, - PgTypeError, PgTypeResult, PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, + PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, }; use introspect_types::{ - ArrayDef, ColumnDef, ColumnInfo, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, - PrimaryTypeDef, StructDef, TupleDef, TypeDef, VariantDef, + ArrayDef, ColumnDef, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, PrimaryTypeDef, + StructDef, TupleDef, TypeDef, VariantDef, }; use itertools::Itertools; use starknet_types_core::felt::Felt; use std::rc::Rc; -use torii_common::sql::{PgQuery, Queries}; +use torii_introspect_sql_sink::{TypeError, TypeResult}; +use torii_sql::{postgres::PgQuery, Queries}; use xxhash_rust::xxh3::Xxh3; pub trait PostgresTypeExtractor { @@ -19,7 +20,7 @@ pub trait PostgresTypeExtractor { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult; + ) -> TypeResult; } pub trait PostgresFieldExtractor { @@ -35,7 +36,7 @@ pub trait PostgresFieldExtractor { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult { + ) -> TypeResult { Ok(PostgresField::new( self.name().to_string(), self.type_def() @@ -78,20 +79,6 @@ impl PostgresFieldExtractor for ColumnDef { } } -impl PostgresFieldExtractor for (&Felt, &ColumnInfo) { - type Id = Felt; - fn name(&self) -> &str { - &self.1.name - } - - fn type_def(&self) -> &TypeDef { - &self.1.type_def - } - fn id(&self) -> &Self::Id { - &self.0 - } -} - impl PostgresFieldExtractor for MemberDef { type Id = String; fn name(&self) -> &str { @@ -126,7 +113,7 @@ impl PostgresTypeExtractor for TypeDef { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult { + ) -> TypeResult { match self { TypeDef::None => Ok(PostgresScalar::None.into()), TypeDef::Bool => Ok(PostgresScalar::Boolean.into()), @@ -161,7 +148,7 @@ impl PostgresTypeExtractor for TypeDef { TypeDef::Option(def) => def.type_def.extract_type(schema, branch, creates), TypeDef::Nullable(def) => def.type_def.extract_type(schema, branch, creates), TypeDef::Felt252Dict(_) | TypeDef::Result(_) | TypeDef::Ref(_) | TypeDef::Custom(_) => { - Err(PgTypeError::UnsupportedType(format!("{self:?}"))) + Err(TypeError::UnsupportedType(format!("{self:?}"))) } } } @@ -202,7 +189,7 @@ impl PostgresTypeExtractor for ArrayDef { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult { + ) -> TypeResult { self.type_def .extract_type(schema, branch, creates)? .to_array(None) @@ -215,7 +202,7 @@ impl PostgresTypeExtractor for FixedArrayDef { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult { + ) -> TypeResult { self.type_def .extract_type(schema, branch, creates)? .to_array(Some(self.size)) @@ -228,12 +215,12 @@ impl PostgresTypeExtractor for StructDef { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult { + ) -> TypeResult { let members = self .members .iter() .map(|f| f.extract_field(schema, branch, creates)) - .collect::>>()?; + .collect::>>()?; let name = branch.type_name(&self.name); creates.push(CreatesType::new_struct(schema, &name, members).into()); Ok(PostgresType::composite(schema, name)) @@ -246,7 +233,7 @@ impl PostgresTypeExtractor for EnumDef { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult { + ) -> TypeResult { let name = branch.type_name(&self.name); let variants_type = branch.type_name(&format!("v_{}", self.name)); let variant_names = self.variants.values().map(|v| v.name.clone()).collect_vec(); @@ -274,7 +261,7 @@ impl PostgresTypeExtractor for TupleDef { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult { + ) -> TypeResult { let mut variants = Vec::with_capacity(self.elements.len()); for (i, element) in self.elements.iter().enumerate() { variants.push( @@ -295,7 +282,7 @@ impl PostgresTypeExtractor for OptionDef { schema: &Rc, branch: &Xxh3, creates: &mut Vec>, - ) -> PgTypeResult { + ) -> TypeResult { self.type_def.extract_type(schema, branch, creates) } } @@ -306,15 +293,15 @@ impl CreatePgTable { id: &Felt, name: &str, primary: &PrimaryDef, - columns: Vec<(&Felt, &ColumnInfo)>, - ) -> PgTypeResult { - let mut creates = Vec::new(); + columns: &[ColumnDef], + ) -> TypeResult { + let mut creates: Vec = Vec::new(); let branch = Xxh3::new_based(id); let primary = primary.into(); let columns = columns .iter() .map(|col| col.extract_field(schema, &branch, &mut creates)) - .collect::>>()?; + .collect::>>()?; Ok(Self { name: SchemaName::new(schema, name), primary, diff --git a/crates/introspect-postgres-sink/src/error.rs b/crates/introspect-postgres-sink/src/error.rs deleted file mode 100644 index c5d11d1a..00000000 --- a/crates/introspect-postgres-sink/src/error.rs +++ /dev/null @@ -1,160 +0,0 @@ -use crate::tables::TableKey; -use introspect_types::{PrimaryTypeDef, TypeDef}; -use sqlx::Error as SqlxError; -use starknet_types_core::felt::{Felt, FromStrError}; -use std::sync::PoisonError; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum PgTypeError { - #[error("Unsupported type for {0}")] - UnsupportedType(String), - #[error("Nested arrays are not supported")] - NestedArrays, -} - -pub type PgTypeResult = std::result::Result; - -#[derive(Debug, Error)] -pub enum PgTableError { - #[error("Column with id: {0} not found in table {1}")] - ColumnNotFound(Felt, String), - #[error(transparent)] - TypeError(#[from] PgTypeError), - #[error("Current type mismatch error")] - TypeMismatch, - #[error("Unsupported upgrade for table {table} column {column}: {reason}")] - UnsupportedUpgrade { - table: String, - column: String, - reason: UpgradeError, - }, -} - -pub type TableResult = std::result::Result; - -#[derive(Debug, thiserror::Error)] -pub enum UpgradeError { - #[error("Failed to upgrade type from {old} to {new}")] - TypeUpgradeError { - old: &'static str, - new: &'static str, - }, - #[error("Failed to upgrade primary from {old} to {new}")] - PrimaryUpgradeError { - old: &'static str, - new: &'static str, - }, - #[error(transparent)] - TypeCreationError(#[from] PgTypeError), - #[error("Array length cannot be decreased from {old} to {new}")] - ArrayLengthDecreaseError { old: u32, new: u32 }, - #[error("Cannot reduce element in tuple")] - TupleReductionError, -} - -pub type UpgradeResult = Result; - -impl UpgradeError { - pub fn type_upgrade_err(old: &TypeDef, new: &TypeDef) -> UpgradeResult { - Err(Self::TypeUpgradeError { - old: old.item_name(), - new: new.item_name(), - }) - } - pub fn type_upgrade_to_err(old: &TypeDef, new: &'static str) -> UpgradeResult { - Err(Self::TypeUpgradeError { - old: old.item_name(), - new, - }) - } - pub fn type_cast_err(old: &TypeDef, new: &'static str) -> UpgradeResult { - Err(Self::TypeUpgradeError { - old: old.item_name(), - new, - }) - } - pub fn array_shorten_err(old: u32, new: u32) -> UpgradeResult { - Err(Self::ArrayLengthDecreaseError { old, new }) - } - pub fn primary_upgrade_err(old: &PrimaryTypeDef, new: &PrimaryTypeDef) -> UpgradeResult { - Err(Self::PrimaryUpgradeError { - old: old.item_name(), - new: new.item_name(), - }) - } -} - -pub trait UpgradeResultExt { - fn to_table_result(self, table: &str, column: &str) -> TableResult; -} - -impl UpgradeResultExt for UpgradeResult { - fn to_table_result(self, table: &str, column: &str) -> TableResult { - self.map_err(|err| PgTableError::UnsupportedUpgrade { - table: table.to_string(), - column: column.to_string(), - reason: err, - }) - } -} - -#[derive(Debug, thiserror::Error)] -pub enum PgDbError { - #[error(transparent)] - DatabaseError(#[from] SqlxError), - #[error("Invalid event format: {0}")] - InvalidEventFormat(String), - #[error(transparent)] - JsonError(#[from] serde_json::Error), - #[error(transparent)] - IoError(#[from] std::io::Error), - #[error(transparent)] - TableError(#[from] PgTableError), - #[error(transparent)] - TypeError(#[from] PgTypeError), - #[error("Table with id: {0} already exists, incoming name: {1}, existing name: {2}")] - TableAlreadyExists(TableKey, String, String), - #[error("Table not found with id: {0}")] - TableNotFound(TableKey), - #[error("Table not alive - id: {0}, name: {1}")] - TableNotAlive(Felt, String), - #[error("Manager does not support updating")] - UpdateNotSupported, - #[error("Table poison error: {0}")] - PoisonError(String), - #[error("Schema not found for address: {0:#063x}")] - SchemaNotFound(Felt), -} - -pub type PgDbResult = std::result::Result; - -impl From> for PgDbError { - fn from(err: PoisonError) -> Self { - Self::PoisonError(err.to_string()) - } -} - -#[derive(Debug, thiserror::Error)] -pub enum SchemaError { - #[error("Invalid address length for schema: {0} should be 63 characters long")] - InvalidAddressLength(String), - #[error(transparent)] - AddressFromStrError(#[from] FromStrError), - #[error("Schema {0} does not match expected schema {1}")] - SchemaMismatch(String, String), - #[error("Schema {1} not found for address: {0:#063x}")] - AddressNotFound(Felt, String), -} - -pub type SchemaResult = std::result::Result; - -#[derive(Debug, thiserror::Error)] -pub enum TableLoadError { - #[error(transparent)] - SchemaError(#[from] SchemaError), - #[error("Table {0} {1:#063x} not found for column {2} with id: {3:#063x}")] - ColumnTableNotFound(String, Felt, String, Felt), - #[error("Table {0} {1:#063x} not found for dead field {2} with id: {3}")] - TableDeadNotFound(String, Felt, String, u128), -} diff --git a/crates/introspect-postgres-sink/src/handler.rs b/crates/introspect-postgres-sink/src/handler.rs new file mode 100644 index 00000000..48c5e53d --- /dev/null +++ b/crates/introspect-postgres-sink/src/handler.rs @@ -0,0 +1,27 @@ +use crate::query::{fetch_columns, fetch_dead_fields, fetch_tables}; +use crate::PostgresBackend; +use async_trait::async_trait; +use introspect_types::ResultInto; +use torii_introspect_sql_sink::backend::IntrospectInitialize; +use torii_introspect_sql_sink::{DbColumn, DbDeadField, DbResult, DbTable}; +use torii_sql::{DbConnection, Postgres}; + +pub const INTROSPECT_PG_SINK_MIGRATIONS: sqlx::migrate::Migrator = sqlx::migrate!("./migrations"); + +#[async_trait] +impl + Send + Sync> IntrospectInitialize for PostgresBackend { + async fn load_tables(&self, schemas: &Option>) -> DbResult> { + fetch_tables(self.pool(), schemas).await.err_into() + } + async fn load_columns(&self, schemas: &Option>) -> DbResult> { + fetch_columns(self.pool(), schemas).await.err_into() + } + async fn load_dead_fields(&self, schemas: &Option>) -> DbResult> { + fetch_dead_fields(self.pool(), schemas).await.err_into() + } + async fn initialize(&self) -> DbResult<()> { + self.migrate(Some("introspect"), INTROSPECT_PG_SINK_MIGRATIONS) + .await + .err_into() + } +} diff --git a/crates/introspect-postgres-sink/src/insert.rs b/crates/introspect-postgres-sink/src/insert.rs index 28c16f6a..c750480d 100644 --- a/crates/introspect-postgres-sink/src/insert.rs +++ b/crates/introspect-postgres-sink/src/insert.rs @@ -1,11 +1,15 @@ -use crate::{json::PostgresJsonSerializer, table::PgTable, PgDbResult}; +use crate::json::PostgresJsonSerializer; use introspect_types::ColumnInfo; use serde::ser::SerializeMap; use serde_json::Serializer as JsonSerializer; use starknet_types_core::felt::Felt; use std::io::Write; -use torii_common::sql::{PgQuery, Queries}; -use torii_introspect::{tables::SerializeEntries, InsertsFields}; +use torii_introspect::{ + tables::{RecordSchema, SerializeEntries}, + Record, +}; +use torii_introspect_sql_sink::RecordResult; +use torii_sql::{postgres::PgQuery, Queries}; pub const METADATA_CONFLICTS: &str = "__updated_at = NOW(), __updated_block = EXCLUDED.__updated_block, __updated_tx = EXCLUDED.__updated_tx"; @@ -43,47 +47,44 @@ impl SerializeEntries for MetaData<'_> { } } -impl PgTable { - pub fn insert_fields( - &self, - event: &InsertsFields, - block_number: u64, - transaction_hash: &Felt, - _from_address: &Felt, - queries: &mut Vec, - ) -> PgDbResult<()> { - let record = self.get_record_schema(&event.columns)?; - let table_name = &self.name; - let mut writer = Vec::new(); - let schema = &self.schema; - let metadata = MetaData::new(block_number, transaction_hash); - write!( +pub fn insert_record_queries( + namespace: &str, + table_name: &str, + schema: &RecordSchema<'_>, + records: &[Record], + _from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, +) -> RecordResult<()> { + let mut writer = Vec::new(); + let metadata = MetaData::new(block_number, transaction_hash); + write!( writer, - r#"INSERT INTO "{schema}"."{table_name}" SELECT * FROM jsonb_populate_recordset(NULL::"{schema}"."{table_name}", $$"# + r#"INSERT INTO "{namespace}"."{table_name}" SELECT * FROM jsonb_populate_recordset(NULL::"{namespace}"."{table_name}", $$"# ) .unwrap(); - record.parse_records_with_metadata( - &event.records, - &metadata, - &mut JsonSerializer::new(&mut writer), - &PostgresJsonSerializer, - )?; + schema.parse_records_with_metadata( + records, + &metadata, + &mut JsonSerializer::new(&mut writer), + &PostgresJsonSerializer, + )?; + write!( + writer, + r#"$$) ON CONFLICT ("{}") DO UPDATE SET {METADATA_CONFLICTS}"#, + schema.primary().name + ) + .unwrap(); + for ColumnInfo { name, .. } in schema.columns() { write!( writer, - r#"$$) ON CONFLICT ("{}") DO UPDATE SET {METADATA_CONFLICTS}"#, - record.primary().name + r#", "{name}" = COALESCE(EXCLUDED."{name}", "{table_name}"."{name}")"#, + name = name ) .unwrap(); - for ColumnInfo { name, .. } in record.columns() { - write!( - writer, - r#", "{name}" = COALESCE(EXCLUDED."{name}", "{table_name}"."{name}")"#, - name = name - ) - .unwrap(); - } - let string = unsafe { String::from_utf8_unchecked(writer) }; - queries.add(string); - Ok(()) } + let string = unsafe { String::from_utf8_unchecked(writer) }; + queries.add(string); + Ok(()) } diff --git a/crates/introspect-postgres-sink/src/lib.rs b/crates/introspect-postgres-sink/src/lib.rs index 6dc4effd..bb7c4684 100644 --- a/crates/introspect-postgres-sink/src/lib.rs +++ b/crates/introspect-postgres-sink/src/lib.rs @@ -1,24 +1,15 @@ +pub mod backend; pub mod create; -pub mod error; +pub mod handler; pub mod insert; pub mod json; -pub mod processor; pub mod query; -pub mod sink; -pub mod table; -pub mod tables; pub mod types; pub mod upgrade; pub mod utils; -pub use error::{ - PgDbError, PgDbResult, PgTableError, PgTypeError, PgTypeResult, TableResult, UpgradeError, - UpgradeResult, UpgradeResultExt, -}; -pub use processor::{IntrospectPgDb, SchemaMode}; +pub use backend::{IntrospectPgDb, PostgresBackend}; pub use types::{ PostgresArray, PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, }; pub use utils::{truncate, HasherExt}; - -pub const INTROSPECT_PG_SINK_MIGRATIONS: sqlx::migrate::Migrator = sqlx::migrate!("./migrations"); diff --git a/crates/introspect-postgres-sink/src/processor.rs b/crates/introspect-postgres-sink/src/processor.rs deleted file mode 100644 index b3761a2d..00000000 --- a/crates/introspect-postgres-sink/src/processor.rs +++ /dev/null @@ -1,248 +0,0 @@ -use crate::error::{SchemaError, SchemaResult, TableLoadError}; -use crate::query::{fetch_columns, fetch_dead_fields, fetch_tables, COMMIT_CMD}; -use crate::tables::{PgSchema, PostgresTables, TableKey}; -use crate::utils::felt_to_schema; -use crate::{PgDbError, PgDbResult, INTROSPECT_PG_SINK_MIGRATIONS}; -use introspect_types::ResultInto; -use itertools::Itertools; -use sqlx::PgPool; -use starknet_types_core::felt::Felt; -use std::collections::{HashMap, HashSet}; -use std::sync::Arc; -use torii_common::sql::PgQuery; -use torii_introspect::events::IntrospectBody; -use torii_postgres::PostgresConnection; - -pub struct IntrospectPgDb { - tables: PostgresTables, - schemas: SchemaMode, - pool: T, -} - -pub enum SchemaMode { - Single(Arc), - Address, - Named(HashMap>), - Addresses(HashSet), -} - -impl From for SchemaMode { - fn from(value: String) -> Self { - SchemaMode::Single(value.into()) - } -} - -impl From<&str> for SchemaMode { - fn from(value: &str) -> Self { - SchemaMode::Single(value.into()) - } -} - -impl From> for SchemaMode { - fn from(value: HashMap) -> Self { - SchemaMode::Named( - value - .into_iter() - .map(|(k, v)| (k, v.into())) - .collect::>(), - ) - } -} - -impl From<[(Felt, &str); N]> for SchemaMode { - fn from(value: [(Felt, &str); N]) -> Self { - SchemaMode::Named( - value - .into_iter() - .map(|(k, v)| (k, v.into())) - .collect::>(), - ) - } -} - -impl From<[(Felt, String); N]> for SchemaMode { - fn from(value: [(Felt, String); N]) -> Self { - SchemaMode::Named( - value - .into_iter() - .map(|(k, v)| (k, v.into())) - .collect::>(), - ) - } -} - -impl From<[Felt; N]> for SchemaMode { - fn from(value: [Felt; N]) -> Self { - SchemaMode::Addresses(value.into_iter().collect()) - } -} - -impl From> for SchemaMode { - fn from(value: Vec) -> Self { - SchemaMode::Addresses(value.into_iter().collect()) - } -} - -fn felt_try_from_schema(schema: &str) -> SchemaResult { - match schema.len() == 63 { - true => Felt::from_hex(schema).err_into(), - false => Err(SchemaError::InvalidAddressLength(schema.to_string())), - } -} - -impl SchemaMode { - pub fn schemas(&self) -> Option>> { - match self { - SchemaMode::Single(name) => Some(vec![name.clone()]), - SchemaMode::Address => None, - SchemaMode::Named(map) => Some(map.values().cloned().collect()), - SchemaMode::Addresses(set) => Some(set.iter().map(felt_to_schema).map_into().collect()), - } - } - - pub fn get_schema_key(&self, schema: String, owner: &Felt) -> SchemaResult { - match self { - SchemaMode::Single(s) => match **s == *schema { - true => Ok(PgSchema::Single(s.clone())), - false => Err(SchemaError::SchemaMismatch(schema, s.to_string())), - }, - SchemaMode::Address => felt_try_from_schema(&schema).map(PgSchema::Address), - SchemaMode::Named(map) => match map.get(owner) { - Some(s) if **s == *schema => Ok(PgSchema::Named(s.clone())), - Some(s) => Err(SchemaError::SchemaMismatch(schema, s.to_string())), - None => Err(SchemaError::AddressNotFound(*owner, schema)), - }, - SchemaMode::Addresses(set) => { - let address = felt_try_from_schema(&schema)?; - match set.contains(&address) { - true => Ok(PgSchema::Address(address)), - false => Err(SchemaError::AddressNotFound(address, schema)), - } - } - } - } - - pub fn get_key(&self, schema: String, id: Felt, owner: &Felt) -> SchemaResult { - self.get_schema_key(schema, owner) - .map(|k| TableKey::new(k, id)) - } - - pub fn to_schema(&self, from_address: &Felt) -> PgDbResult { - match self { - SchemaMode::Single(name) => Ok(PgSchema::Single(name.clone())), - SchemaMode::Address => Ok(PgSchema::Address(*from_address)), - SchemaMode::Named(map) => match map.get(from_address) { - Some(schema) => Ok(PgSchema::Named(schema.clone())), - None => Err(PgDbError::SchemaNotFound(*from_address)), - }, - SchemaMode::Addresses(set) => match set.contains(from_address) { - true => Ok(PgSchema::Address(*from_address)), - false => Err(PgDbError::SchemaNotFound(*from_address)), - }, - } - } -} - -impl PostgresConnection for IntrospectPgDb { - fn pool(&self) -> &PgPool { - self.pool.pool() - } -} - -// TODO: Add errors for unknown schema -impl IntrospectPgDb { - pub fn new>(pool: T, schemas: S) -> Self { - Self { - tables: PostgresTables::default(), - schemas: schemas.into(), - pool, - } - } - pub async fn load_store_data(&self) -> PgDbResult> { - let mut errors = Vec::new(); - let schemas = self.schemas.schemas(); - let schemas = schemas - .as_ref() - .map(|s| s.iter().map(AsRef::as_ref).collect()); - let table_rows = fetch_tables(self.pool(), &schemas).await?; - let mut tables = HashMap::with_capacity(table_rows.len()); - for table in table_rows { - let (id, table) = table.into(); - tables.insert((table.schema.clone(), id), table); - } - for (schema, table_id, id, column_info) in fetch_columns(self.pool(), &schemas).await? { - if let Some(table) = tables.get_mut(&(schema.clone(), table_id)) { - table.columns.insert(id, column_info); - } else { - errors.push(TableLoadError::ColumnTableNotFound( - schema, - table_id, - column_info.name, - id, - )); - } - } - for (schema, table_id, id, field) in fetch_dead_fields(self.pool(), &schemas).await? { - if let Some(table) = tables.get_mut(&(schema.clone(), table_id)) { - table.dead.insert(id, field); - } else { - errors.push(TableLoadError::TableDeadNotFound( - schema, table_id, field.name, id, - )); - } - } - let mut map = self.tables.write()?; - for ((schema, id), table) in tables { - match self.schemas.get_key(schema, id, &table.owner) { - Ok(key) => { - map.insert(key, table); - } - Err(err) => errors.push(TableLoadError::SchemaError(err)), - } - } - Ok(errors) - } - - pub async fn initialize_introspect_pg_sink(&self) -> PgDbResult> { - self.migrate(Some("introspect"), INTROSPECT_PG_SINK_MIGRATIONS) - .await?; - self.load_store_data().await - } - - pub async fn process_messages( - &self, - msgs: Vec<&IntrospectBody>, - ) -> PgDbResult>> { - let mut queries = Vec::new(); - let mut results = Vec::with_capacity(msgs.len()); - - for body in msgs { - let (msg, metadata) = body.into(); - results.push(self.tables.handle_message( - self.schemas.to_schema(&metadata.from_address)?, - msg, - &metadata.from_address, - metadata.block_number.unwrap_or(u64::MAX), - &metadata.transaction_hash, - &mut queries, - )); - } - self.process_queries(queries).await?; - Ok(results) - } - - pub async fn process_queries(&self, queries: Vec) -> PgDbResult<()> { - let mut batch = Vec::new(); - for query in queries { - if query == *COMMIT_CMD { - self.execute_queries(std::mem::take(&mut batch)).await?; - } else { - batch.push(query); - } - } - if !batch.is_empty() { - self.execute_queries(batch).await?; - } - Ok(()) - } -} diff --git a/crates/introspect-postgres-sink/src/query.rs b/crates/introspect-postgres-sink/src/query.rs index bde355ac..0f409c9c 100644 --- a/crates/introspect-postgres-sink/src/query.rs +++ b/crates/introspect-postgres-sink/src/query.rs @@ -1,23 +1,25 @@ -use crate::table::PgTable; -use crate::{table::DeadField, PostgresField, PostgresType, PrimaryKey, SchemaName}; -use introspect_types::{ColumnDef, ColumnInfo, MemberDef, PrimaryDef, TypeDef}; +use crate::{PostgresField, PostgresType, PrimaryKey, SchemaName}; +use introspect_types::schema::{Names, TypeDefs}; +use introspect_types::{ColumnDef, FeltIds, MemberDef, PrimaryDef, TypeDef}; use itertools::Itertools; use sqlx::error::BoxDynError; use sqlx::postgres::PgRow; use sqlx::prelude::FromRow; use sqlx::query::QueryAs; -use sqlx::Error::Encode as EncodeError; use sqlx::{postgres::PgArguments, types::Json}; use sqlx::{Arguments, Executor, Postgres}; use starknet_types_core::felt::Felt; -use std::collections::HashMap; use std::{ fmt::{Display, Formatter, Result as FmtResult, Write}, rc::Rc, }; use torii_introspect::postgres::types::{PgPrimary, Uint128}; use torii_introspect::postgres::PgFelt; -use torii_sql::{PgQuery, Queries, SqlxResult}; +use torii_introspect_sql_sink::processor::{DbColumn, DbDeadField, DbTable}; +use torii_introspect_sql_sink::table::DeadFieldDef; +use torii_introspect_sql_sink::{TableError, TableResult}; +use torii_sql::postgres::PgQuery; +use torii_sql::{Queries, SqlxResult}; pub const COMMIT_CMD: &str = "--COMMIT"; @@ -69,14 +71,6 @@ pub struct DeadFieldRow { pub type_def: Json, } -pub struct PgTableHead { - schema: String, - id: Felt, - name: String, - primary: PrimaryDef, - owner: Felt, -} - #[derive(Debug)] pub struct CreatePgTable { pub name: SchemaName, @@ -88,13 +82,14 @@ pub struct CreatePgTable { #[derive(Debug)] pub struct TableUpgrade { pub schema: Rc, + pub id: Felt, pub name: String, pub old_name: Option, pub atomic: Vec, pub alters: Vec, pub columns: Vec, pub columns_upgraded: Vec, - pub dead: Vec, + pub dead: Vec, pub col_alters: Vec, } @@ -102,7 +97,7 @@ pub struct TableUpgrade { pub struct ColumnUpgrade { pub atomic: Vec, pub alters: Vec, - pub dead: Vec, + pub dead: Vec, pub altered: bool, pub upgraded: bool, } @@ -159,35 +154,6 @@ pub struct EnumUpgrade { add: Vec, } -#[derive(Debug)] -pub struct DeadFieldWithId { - pub id: u128, - pub name: String, - pub type_def: TypeDef, -} - -impl From for (u128, DeadField) { - fn from(value: DeadFieldWithId) -> Self { - ( - value.id, - DeadField { - name: value.name, - type_def: value.type_def, - }, - ) - } -} - -impl From<(u128, DeadField)> for DeadFieldWithId { - fn from(value: (u128, DeadField)) -> Self { - DeadFieldWithId { - id: value.0, - name: value.1.name, - type_def: value.1.type_def, - } - } -} - #[derive(Debug)] pub enum CreatesType { Struct(CreateStruct), @@ -264,9 +230,10 @@ impl CreatesType { } impl TableUpgrade { - pub fn new>(schema: &Rc, name: S) -> Self { + pub fn new>(schema: &Rc, id: Felt, name: S) -> Self { Self { schema: schema.clone(), + id, name: name.into(), old_name: None, columns: Vec::new(), @@ -337,22 +304,21 @@ impl TableUpgrade { pub fn to_queries( &self, - table_id: &Felt, block_number: u64, transaction_hash: &Felt, queries: &mut Vec, - ) -> SqlxResult<()> { + ) -> TableResult<()> { let schema = &self.schema; let name = &self.name; queries.add( insert_dead_member_query( &self.schema, - table_id, + &self.id, &self.dead, block_number, transaction_hash, ) - .map_err(EncodeError)?, + .map_err(TableError::Encode)?, ); if let Some(old_name) = &self.old_name { queries.add(format!( @@ -543,7 +509,7 @@ impl ColumnUpgrade { } pub fn add_dead_member(&mut self, id: u128, member: &MemberDef) { self.upgraded = true; - self.dead.push(DeadFieldWithId { + self.dead.push(DeadFieldDef { id, name: member.name.clone(), type_def: member.type_def.clone(), @@ -576,67 +542,49 @@ impl From for TypeMod { } } -impl From for (String, Felt, Felt, ColumnInfo) { +impl From for DbColumn { fn from(value: ColumnRow) -> Self { - ( - value.schema, - value.table.into(), - value.id.into(), - ColumnInfo { - name: value.name, - attributes: Vec::new(), - type_def: value.type_def.0, - }, - ) + DbColumn { + namespace: value.schema, + table: value.table.into(), + id: value.id.into(), + name: value.name, + type_def: value.type_def.0, + } } } -impl From for (String, Felt, u128, DeadField) { +impl From for DbDeadField { fn from(value: DeadFieldRow) -> Self { - ( - value.schema, - value.table.into(), - value.id.into(), - DeadField { - name: value.name, - type_def: value.type_def.0, - }, - ) + DbDeadField { + namespace: value.schema, + table: value.table.into(), + id: value.id.into(), + name: value.name, + type_def: value.type_def.0, + } } } -impl From for PgTableHead { +impl From for DbTable { fn from(value: TableRow) -> Self { - PgTableHead { - schema: value.schema, + DbTable { + namespace: value.schema, id: value.id.into(), + owner: value.owner.into(), name: value.name, primary: value.primary_def.into(), - owner: value.owner.into(), + columns: Vec::new(), + dead: Vec::new(), + alive: true, } } } -impl From for (Felt, PgTable) { - fn from(value: PgTableHead) -> Self { - ( - value.id, - PgTable { - schema: value.schema, - owner: value.owner, - name: value.name, - primary: value.primary, - columns: HashMap::new(), - alive: true, - dead: HashMap::new(), - }, - ) - } -} fn insert_dead_member_query( schema: &str, table: &Felt, - fields: &[DeadFieldWithId], + fields: &[DeadFieldDef], block_number: u64, transaction_hash: &Felt, ) -> Result { @@ -652,24 +600,22 @@ fn insert_dead_member_query( Ok(PgQuery::new(INSERT_DEAD_MEMBER_QUERY, args)) } -pub fn insert_columns_query( +pub fn insert_columns_query( schema: &str, table: &Felt, - columns: Vec<(&Felt, &ColumnInfo)>, + columns: CS, block_number: u64, transaction_hash: &Felt, -) -> Result { +) -> Result +where + CS: Names + FeltIds + TypeDefs, +{ let mut args = PgArguments::default(); args.add(schema.to_string())?; args.add(PgFelt::from(*table))?; - args.add( - columns - .iter() - .map(|(id, _)| PgFelt::from(*id)) - .collect_vec(), - )?; - args.add(columns.iter().map(|(_, c)| c.name.clone()).collect_vec())?; - args.add(columns.iter().map(|(_, c)| Json(&c.type_def)).collect_vec())?; + args.add(columns.ids().iter().map_into::().collect_vec())?; + args.add(columns.names())?; + args.add(columns.type_defs().into_iter().map(Json).collect_vec())?; args.add(block_number.to_string())?; args.add(PgFelt::from(*transaction_hash))?; @@ -699,7 +645,7 @@ pub fn insert_table_query( pub fn schema_query<'a, R>( query: &'a str, - schemas: &'a Option>, + schemas: &'a Option>, ) -> QueryAs<'a, Postgres, R, PgArguments> where R: for<'r> FromRow<'r, PgRow>, @@ -713,8 +659,8 @@ where pub async fn fetch_tables<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( conn: E, - schemas: &Option>, -) -> SqlxResult> { + schemas: &Option>, +) -> SqlxResult> { schema_query::(FETCH_TABLES_QUERY, schemas) .fetch_all(conn) .await @@ -723,8 +669,8 @@ pub async fn fetch_tables<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( pub async fn fetch_columns<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( conn: E, - schemas: &Option>, -) -> SqlxResult> { + schemas: &Option>, +) -> SqlxResult> { schema_query::(FETCH_COLUMNS_QUERY, schemas) .fetch_all(conn) .await @@ -733,8 +679,8 @@ pub async fn fetch_columns<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( pub async fn fetch_dead_fields<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( conn: E, - schemas: &Option>, -) -> SqlxResult> { + schemas: &Option>, +) -> SqlxResult> { schema_query::(FETCH_DEAD_FIELDS_QUERY, schemas) .fetch_all(conn) .await diff --git a/crates/introspect-postgres-sink/src/table.rs b/crates/introspect-postgres-sink/src/table.rs deleted file mode 100644 index 956dbd93..00000000 --- a/crates/introspect-postgres-sink/src/table.rs +++ /dev/null @@ -1,157 +0,0 @@ -use crate::{ - query::{insert_columns_query, insert_table_query, CreatePgTable}, - PgDbResult, PgTableError, TableResult, -}; -use introspect_types::{ColumnInfo, MemberDef, PrimaryDef, ResultInto, TypeDef}; -use itertools::Itertools; -use sqlx::Error::Encode as EncodeError; -use starknet_types_core::felt::Felt; -use std::{collections::HashMap, rc::Rc}; -use torii_common::sql::PgQuery; -use torii_introspect::{schema::TableInfo, tables::RecordSchema}; - -#[derive(Debug)] -pub struct PgTable { - pub schema: String, - pub name: String, - pub owner: Felt, - pub primary: PrimaryDef, - pub columns: HashMap, - pub alive: bool, - pub dead: HashMap, -} - -#[derive(Debug)] -pub struct DeadField { - pub name: String, - pub type_def: TypeDef, -} - -impl From for DeadField { - fn from(value: MemberDef) -> Self { - DeadField { - name: value.name, - type_def: value.type_def, - } - } -} - -impl From for MemberDef { - fn from(value: DeadField) -> Self { - MemberDef { - name: value.name, - attributes: Vec::new(), - type_def: value.type_def, - } - } -} - -impl PgTable { - pub fn column(&self, id: &Felt) -> TableResult<&ColumnInfo> { - self.columns - .get(id) - .ok_or_else(|| PgTableError::ColumnNotFound(*id, self.name.clone())) - } - - pub fn schema(&self) -> Rc { - self.schema.as_str().into() - } - - pub fn columns(&self, ids: &[Felt]) -> TableResult> { - ids.iter() - .map(|id| self.column(id)) - .collect::>>() - } - - pub fn columns_with_ids<'a>( - &'a self, - ids: &'a [Felt], - ) -> TableResult> { - ids.iter() - .map(|id| self.column(id).map(|col| (id, col))) - .collect::>>() - } - - pub fn new( - schema: String, - owner: Felt, - info: TableInfo, - dead: Option>, - ) -> Self { - PgTable { - schema, - owner, - name: info.name, - primary: info.primary, - columns: info.columns.into_iter().map_into().collect(), - alive: true, - dead: dead.unwrap_or_default().into_iter().collect(), - } - } - - pub fn create_table(&self, id: &Felt, order: &[Felt]) -> TableResult { - CreatePgTable::new( - &self.schema(), - id, - &self.name, - &self.primary, - self.columns_with_ids(order)?, - ) - .err_into() - } - - pub fn create_table_queries( - &self, - id: &Felt, - order: &[Felt], - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> PgDbResult<()> { - self.create_table(id, order)?.make_queries(queries); - self.insert_queries( - id, - None, - from_address, - block_number, - transaction_hash, - queries, - ) - } - - pub fn get_record_schema(&self, columns: &[Felt]) -> TableResult> { - Ok(RecordSchema::new(&self.primary, self.columns(columns)?)) - } - pub fn insert_queries( - &self, - id: &Felt, - column_ids: Option<&[Felt]>, - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> PgDbResult<()> { - queries.push( - insert_table_query( - &self.schema, - id, - &self.name, - &self.primary, - from_address, - block_number, - transaction_hash, - ) - .map_err(EncodeError)?, - ); - let columns = match column_ids { - Some(ids) => ids.iter().zip(self.columns(ids)?).collect_vec(), - None => self.columns.iter().collect_vec(), - }; - queries.push( - insert_columns_query(&self.schema, id, columns, block_number, transaction_hash) - .map_err(EncodeError)?, - ); - Ok(()) - } -} diff --git a/crates/introspect-postgres-sink/src/tables.rs b/crates/introspect-postgres-sink/src/tables.rs deleted file mode 100644 index 7691d44d..00000000 --- a/crates/introspect-postgres-sink/src/tables.rs +++ /dev/null @@ -1,229 +0,0 @@ -use crate::table::PgTable; -use crate::{PgDbError, PgDbResult}; -use introspect_types::FeltIds; -use starknet_types_core::felt::Felt; -use std::collections::HashMap; -use std::fmt::Display; -use std::hash::{Hash, Hasher}; -use std::ops::Deref; -use std::sync::{Arc, RwLock}; -use torii_common::sql::PgQuery; -use torii_introspect::events::IntrospectMsg; -use torii_introspect::schema::TableSchema; -use torii_introspect::InsertsFields; - -pub const DEAD_MEMBERS_TABLE: &str = "__introspect_dead_fields"; -pub const TABLES_TABLE: &str = "__introspect_tables"; -pub const COLUMNS_TABLE: &str = "__introspect_columns"; - -#[derive(Debug, Default)] -pub struct PostgresTables(pub RwLock>); - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TableKey { - schema: PgSchema, - id: Felt, -} - -impl TableKey { - pub fn new(schema: PgSchema, id: Felt) -> Self { - Self { schema, id } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum PgSchema { - Single(Arc), - Address(Felt), - Named(Arc), -} - -impl Display for TableKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if !matches!(self.schema, PgSchema::Single(_)) { - write!(f, "{} ", self.schema)?; - } - write!(f, "{:#063x}", self.id) - } -} - -impl Display for PgSchema { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - PgSchema::Address(addr) => write!(f, "{addr:063x}"), - PgSchema::Named(name) | PgSchema::Single(name) => name.fmt(f), - } - } -} - -impl Hash for TableKey { - fn hash(&self, state: &mut H) { - self.schema.hash(state); - self.id.hash(state); - } -} - -impl Hash for PgSchema { - fn hash(&self, state: &mut H) { - match self { - PgSchema::Address(addr) => addr.hash(state), - PgSchema::Named(name) => name.hash(state), - PgSchema::Single(_) => {} - } - } -} - -impl Deref for PostgresTables { - type Target = RwLock>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl PostgresTables { - pub fn create_table( - &self, - schema_key: PgSchema, - to_table: impl Into, - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> PgDbResult<()> { - let (id, info) = Into::::into(to_table).into(); - let schema = schema_key.to_string(); - let key = TableKey::new(schema_key, id); - self.assert_table_not_exists(&key, &info.name)?; - let order = info.columns.ids(); - let table = PgTable::new(schema, *from_address, info, None); - table.create_table_queries( - &id, - &order, - from_address, - block_number, - transaction_hash, - queries, - )?; - let mut tables = self.write()?; - tables.insert(key, table); - Ok(()) - } - - pub fn update_table( - &self, - schema_key: PgSchema, - to_table: impl Into, - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> PgDbResult<()> { - let (id, table) = Into::::into(to_table).into(); - let mut tables = self.write()?; - let key = TableKey::new(schema_key, id); - let existing = tables - .get_mut(&key) - .ok_or_else(|| PgDbError::TableNotFound(key.clone()))?; - let upgrades = existing.update_from_info(&id, &table)?; - upgrades.to_queries(&id, block_number, transaction_hash, queries)?; - existing.insert_queries( - &id, - Some(&upgrades.columns_upgraded), - from_address, - block_number, - transaction_hash, - queries, - ) - } - - pub fn assert_table_not_exists(&self, id: &TableKey, name: &str) -> PgDbResult<()> { - match self.read()?.get(id) { - Some(existing) => Err(PgDbError::TableAlreadyExists( - id.clone(), - name.to_string(), - existing.name.to_string(), - )), - None => Ok(()), - } - } - - pub fn set_table_dead(&self, schema: PgSchema, id: Felt) -> PgDbResult<()> { - let mut tables = self.write()?; - let key = TableKey::new(schema, id); - match tables.get_mut(&key) { - Some(table) => { - table.alive = false; - Ok(()) - } - None => Err(PgDbError::TableNotFound(key)), - } - } - - pub fn insert_fields( - &self, - schema: PgSchema, - event: &InsertsFields, - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> PgDbResult<()> { - let tables = self.read().unwrap(); - let key = TableKey::new(schema, event.table); - let table = match tables.get(&key) { - Some(table) => Ok(table), - None => Err(PgDbError::TableNotFound(key)), - }?; - if !table.alive { - return Ok(()); - } - table.insert_fields(event, block_number, transaction_hash, from_address, queries) - } - - pub fn handle_message( - &self, - schema: PgSchema, - msg: &IntrospectMsg, - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> PgDbResult<()> { - match msg { - IntrospectMsg::CreateTable(event) => self.create_table( - schema, - event.clone(), - from_address, - block_number, - transaction_hash, - queries, - ), - IntrospectMsg::UpdateTable(event) => self.update_table( - schema, - event.clone(), - from_address, - block_number, - transaction_hash, - queries, - ), - IntrospectMsg::AddColumns(event) => self.set_table_dead(schema, event.table), - IntrospectMsg::DropColumns(event) => self.set_table_dead(schema, event.table), - IntrospectMsg::RetypeColumns(event) => self.set_table_dead(schema, event.table), - IntrospectMsg::RetypePrimary(event) => self.set_table_dead(schema, event.table), - IntrospectMsg::RenameTable(_) - | IntrospectMsg::DropTable(_) - | IntrospectMsg::RenameColumns(_) - | IntrospectMsg::RenamePrimary(_) => Ok(()), - IntrospectMsg::InsertsFields(event) => self.insert_fields( - schema, - event, - from_address, - block_number, - transaction_hash, - queries, - ), - IntrospectMsg::DeleteRecords(_) | IntrospectMsg::DeletesFields(_) => Ok(()), - } - } -} diff --git a/crates/introspect-postgres-sink/src/types.rs b/crates/introspect-postgres-sink/src/types.rs index 0e0eecc9..cf3ebfbd 100644 --- a/crates/introspect-postgres-sink/src/types.rs +++ b/crates/introspect-postgres-sink/src/types.rs @@ -4,8 +4,7 @@ use std::{ fmt::{Display, Formatter, Result as FmtResult}, rc::Rc, }; - -use crate::{PgTypeError, PgTypeResult}; +use torii_introspect_sql_sink::{TypeError, TypeResult}; #[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] pub struct SchemaName(pub Rc, pub String); @@ -153,7 +152,7 @@ impl PostgresType { pub fn is_composite(&self) -> bool { matches!(self.scalar, PostgresScalar::Composite(_)) } - pub fn to_array(self, size: Option) -> PgTypeResult { + pub fn to_array(self, size: Option) -> TypeResult { let arr = match (self.array, size) { (PostgresArray::None, None) => PostgresArray::Dynamic, (PostgresArray::None, Some(size)) => PostgresArray::Fixed(VecDeque::from([size])), @@ -161,7 +160,7 @@ impl PostgresType { sizes.push_back(size); PostgresArray::Fixed(sizes) } - _ => return Err(PgTypeError::NestedArrays), + _ => return Err(TypeError::NestedArrays), }; Ok(Self { scalar: self.scalar, diff --git a/crates/introspect-postgres-sink/src/upgrade.rs b/crates/introspect-postgres-sink/src/upgrade.rs index e59190b1..f34dcbdb 100644 --- a/crates/introspect-postgres-sink/src/upgrade.rs +++ b/crates/introspect-postgres-sink/src/upgrade.rs @@ -1,34 +1,38 @@ -use crate::{ - create::PostgresTypeExtractor, - query::{ColumnUpgrade, StructMod, StructMods, TableUpgrade}, - table::{DeadField, PgTable}, - HasherExt, PgTypeError, PgTypeResult, PostgresScalar, PostgresType, TableResult, UpgradeError, - UpgradeResult, UpgradeResultExt, -}; +use crate::create::PostgresTypeExtractor; +use crate::query::{ColumnUpgrade, StructMod, StructMods, TableUpgrade}; +use crate::{HasherExt, PostgresScalar, PostgresType}; use introspect_types::{ ArrayDef, ColumnDef, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, PrimaryTypeDef, ResultInto, StructDef, TupleDef, TypeDef, VariantDef, }; -use starknet_types_core::felt::Felt; -use std::{collections::HashMap, rc::Rc}; -use torii_introspect::schema::TableInfo; +use std::collections::HashMap; +use std::rc::Rc; +use torii_introspect_sql_sink::table::Table; +use torii_introspect_sql_sink::{ + DeadField, TableResult, TypeError, TypeResult, UpgradeError, UpgradeResult, UpgradeResultExt, +}; use xxhash_rust::xxh3::Xxh3; -impl PgTable { - pub fn update_from_info(&mut self, id: &Felt, info: &TableInfo) -> TableResult { - self.update(id, &info.name, &info.primary, &info.columns) - } +pub trait PgTableUpgrade { + fn upgrade_table( + &mut self, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + ) -> TableResult; + fn retype_primary(&mut self, new: &PrimaryTypeDef) -> UpgradeResult>; +} - pub fn update( +impl PgTableUpgrade for Table { + fn upgrade_table( &mut self, - id: &Felt, name: &str, primary: &PrimaryDef, columns: &[ColumnDef], ) -> TableResult { - let branch = Xxh3::new_based(id); - let schema: Rc = self.schema(); - let mut table_mod = TableUpgrade::new(&schema, self.name.clone()); + let branch = Xxh3::new_based(&self.id); + let schema: Rc = self.namespace(); + let mut table_mod = TableUpgrade::new(&schema, self.id, self.name.clone()); table_mod.rename_table(name); table_mod.rename_column(&mut self.primary.name, &primary.name); let pg_type = self @@ -144,7 +148,7 @@ pub trait ExtractItem { dead: &mut HashMap, queries: &mut ColumnUpgrade, ) -> UpgradeResult>; - fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> PgTypeResult; + fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> TypeResult; } impl ExtractItem for TypeDef { @@ -211,7 +215,7 @@ impl ExtractItem for TypeDef { } } } - fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> PgTypeResult { + fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> TypeResult { match self { TypeDef::None => Ok(PostgresScalar::None.into()), TypeDef::Bool => Ok(PostgresScalar::Boolean.into()), @@ -249,7 +253,7 @@ impl ExtractItem for TypeDef { TypeDef::Option(def) => def.get_pg_type(schema, branch), TypeDef::Nullable(def) => def.get_pg_type(schema, branch), TypeDef::Felt252Dict(_) | TypeDef::Result(_) | TypeDef::Ref(_) | TypeDef::Custom(_) => { - Err(PgTypeError::UnsupportedType(format!("{self:?}"))) + Err(TypeError::UnsupportedType(format!("{self:?}"))) } } } diff --git a/crates/introspect-postgres-sink/src/utils.rs b/crates/introspect-postgres-sink/src/utils.rs index 9a68c4c4..a006d44e 100644 --- a/crates/introspect-postgres-sink/src/utils.rs +++ b/crates/introspect-postgres-sink/src/utils.rs @@ -8,10 +8,6 @@ pub fn truncate(s: &str, max_chars: usize) -> &str { } } -pub fn felt_to_schema(address: &Felt) -> String { - format!("{address:063x}") -} - const ALLOWED_TYPE_NAME_CHARS: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; diff --git a/crates/introspect-sql-sink/Cargo.toml b/crates/introspect-sql-sink/Cargo.toml index 86e24faf..4f4522f0 100644 --- a/crates/introspect-sql-sink/Cargo.toml +++ b/crates/introspect-sql-sink/Cargo.toml @@ -11,7 +11,6 @@ sqlx = { workspace = true, features = ["runtime-tokio-rustls", "macros"] } anyhow.workspace = true async-trait.workspace = true metrics.workspace = true -xxhash-rust.workspace = true hex.workspace = true serde.workspace = true serde_json.workspace = true @@ -28,3 +27,11 @@ arrayvec.workspace = true # Local crates torii-introspect.workspace = true torii-sql.workspace = true + +# Postgres features +xxhash-rust = { workspace = true, optional = true } + + +[features] +postgres = ["sqlx/postgres", "dep:xxhash-rust", "torii-sql/postgres"] +sqlite = ["sqlx/sqlite", "torii-sql/sqlite"] diff --git a/crates/introspect-sql-sink/migrations/postgres/001_domains.sql b/crates/introspect-sql-sink/migrations/postgres/001_domains.sql new file mode 100644 index 00000000..96bf76e7 --- /dev/null +++ b/crates/introspect-sql-sink/migrations/postgres/001_domains.sql @@ -0,0 +1,113 @@ +-- Initialize all custom domains for Starknet/Cairo types +-- Using DO blocks for conditional creation since IF NOT EXISTS isn't supported in older PostgreSQL versions + + +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint8') THEN + CREATE DOMAIN uint8 AS SmallInt + CHECK (VALUE >= 0 AND VALUE < 256); + END IF; +END $$; + +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint16') THEN + CREATE DOMAIN uint16 AS Int + CHECK (VALUE >= 0 AND VALUE < 65536); + END IF; +END $$; + +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint32') THEN + CREATE DOMAIN uint32 AS BigInt + CHECK (VALUE >= 0 AND VALUE < 4294967296); + END IF; +END $$; + +-- uint64: Unsigned 64-bit integer (0 to 2^64-1) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint64') THEN + CREATE DOMAIN uint64 AS NUMERIC(20, 0) + CHECK (VALUE >= 0 AND VALUE < power(2::numeric, 64)); + END IF; +END $$; + +-- uint128: Unsigned 128-bit integer (0 to 2^128-1) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint128') THEN + CREATE DOMAIN uint128 AS NUMERIC(39, 0) + CHECK (VALUE >= 0 AND VALUE < power(2::numeric, 128)); + END IF; +END $$; + +-- int128: Signed 128-bit integer (-2^127 to 2^127-1) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'int128') THEN + CREATE DOMAIN int128 AS NUMERIC(39, 0) + CHECK (VALUE >= -power(2::numeric, 127) AND VALUE < power(2::numeric, 127)); + END IF; +END $$; + +-- uint256: Unsigned 256-bit integer (0 to 2^256-1) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint256') THEN + CREATE DOMAIN uint256 AS NUMERIC(78, 0) + CHECK (VALUE >= 0 AND VALUE < power(2::numeric, 256)); + END IF; +END $$; + +-- uint512: Unsigned 512-bit integer (0 to 2^512-1) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint512') THEN + CREATE DOMAIN uint512 AS NUMERIC(155, 0) + CHECK (VALUE >= 0 AND VALUE < power(2::numeric, 512)); + END IF; +END $$; + +-- felt252: Cairo field element (0 to PRIME-1) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'felt252') THEN + CREATE DOMAIN felt252 AS bytea CHECK (octet_length(VALUE) = 32); + END IF; +END $$; + +-- starknet_hash: Starknet addresses and class hashes (uint251) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'starknet_hash') THEN + CREATE DOMAIN starknet_hash AS bytea CHECK (octet_length(VALUE) = 32); + END IF; +END $$; + +-- eth_address: Ethereum address (160-bit / 20 bytes) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'eth_address') THEN + CREATE DOMAIN eth_address AS bytea CHECK (octet_length(VALUE) = 20); + END IF; +END $$; + +-- byte31: 31-byte array +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'byte31') THEN + CREATE DOMAIN byte31 AS bytea CHECK (octet_length(VALUE) = 31); + END IF; +END $$; + +-- char31: character string of max length 31 +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'char31') THEN + CREATE DOMAIN char31 AS varchar(31); + END IF; +END $$; + diff --git a/crates/introspect-sql-sink/migrations/postgres/002_metadata_function.sql b/crates/introspect-sql-sink/migrations/postgres/002_metadata_function.sql new file mode 100644 index 00000000..e593704b --- /dev/null +++ b/crates/introspect-sql-sink/migrations/postgres/002_metadata_function.sql @@ -0,0 +1,11 @@ +CREATE FUNCTION introspect.set_default_timestamps() RETURNS TRIGGER AS $$ +BEGIN + IF NEW.__created_at IS NULL THEN + NEW.__created_at := NOW(); + END IF; + IF NEW.__updated_at IS NULL THEN + NEW.__updated_at := NOW(); + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/crates/introspect-sql-sink/migrations/postgres/003_store.sql b/crates/introspect-sql-sink/migrations/postgres/003_store.sql new file mode 100644 index 00000000..f5a83a78 --- /dev/null +++ b/crates/introspect-sql-sink/migrations/postgres/003_store.sql @@ -0,0 +1,67 @@ +CREATE SCHEMA IF NOT EXISTS introspect; + +DO $$ +BEGIN + IF to_regtype('introspect.attribute') IS NULL THEN + CREATE TYPE introspect.attribute AS ( + name TEXT, + data bytea + ); + END IF; + + IF to_regtype('introspect.primary_def') IS NULL THEN + CREATE TYPE introspect.primary_def AS ( + name TEXT, + attributes introspect.attribute[], + type_def jsonb + ); + END IF; +END $$; + +CREATE TABLE IF NOT EXISTS introspect.db_tables ( + "schema" TEXT NOT NULL, + id felt252 NOT NULL, + name TEXT NOT NULL, + "owner" felt252 NOT NULL, + primary_def introspect.primary_def NOT NULL, + alive BOOLEAN NOT NULL DEFAULT TRUE, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + created_block uint64 NOT NULL, + updated_block uint64 NOT NULL, + created_tx felt252 NOT NULL, + updated_tx felt252 NOT NULL, + PRIMARY KEY ("schema", id) +); + +CREATE TABLE IF NOT EXISTS introspect.db_columns( + "schema" TEXT NOT NULL, + "table" felt252 NOT NULL, + id felt252 NOT NULL, + name TEXT NOT NULL, + type_def JSONB NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + created_block uint64 NOT NULL, + updated_block uint64 NOT NULL, + created_tx felt252 NOT NULL, + updated_tx felt252 NOT NULL, + PRIMARY KEY ("schema", "table", id), + FOREIGN KEY ("schema", "table") REFERENCES introspect.db_tables("schema", id) +); + +CREATE TABLE IF NOT EXISTS introspect.db_dead_fields ( + "schema" TEXT NOT NULL, + "table" felt252, + id uint128, + name TEXT, + type_def JSONB, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + created_block uint64 NOT NULL, + updated_block uint64 NOT NULL, + created_tx felt252 NOT NULL, + updated_tx felt252 NOT NULL, + PRIMARY KEY ("schema", "table", id), + FOREIGN KEY ("schema", "table") REFERENCES introspect.db_tables("schema", id) +); \ No newline at end of file diff --git a/crates/introspect-sql-sink/migrations/sqlite/001_init.sql b/crates/introspect-sql-sink/migrations/sqlite/001_init.sql new file mode 100644 index 00000000..1f3f65bb --- /dev/null +++ b/crates/introspect-sql-sink/migrations/sqlite/001_init.sql @@ -0,0 +1,4 @@ +CREATE TABLE IF NOT EXISTS introspect_sink_metadata ( + id INTEGER PRIMARY KEY CHECK (id = 1), + initialized_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP +); diff --git a/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql b/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql new file mode 100644 index 00000000..6355d19d --- /dev/null +++ b/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS introspect_sink_schema_state ( + namespace TEXT NOT NULL, + id TEXT NOT NULL, + owner TEXT NOT NULL, + "primary" TEXT NOT NULL, + columns TEXT NOT NULL, + dead TEXT NOT NULL, + alive INTEGER NOT NULL DEFAULT 1, + updated_at INTEGER NOT NULL DEFAULT (unixepoch()), + PRIMARY KEY (namespace, id) +); diff --git a/crates/introspect-sql-sink/src/backend.rs b/crates/introspect-sql-sink/src/backend.rs new file mode 100644 index 00000000..7017741b --- /dev/null +++ b/crates/introspect-sql-sink/src/backend.rs @@ -0,0 +1,125 @@ +use crate::processor::{DbColumn, DbDeadField, DbTable, COMMIT_CMD}; +use crate::table::Table; +use crate::tables::Tables; +use crate::{DbResult, NamespaceMode, RecordResult, TableResult}; +use async_trait::async_trait; +use introspect_types::{ColumnDef, PrimaryDef}; +use sqlx::Database; +use starknet_types_core::felt::Felt; +use torii_introspect::events::IntrospectBody; +use torii_introspect::tables::RecordSchema; +use torii_introspect::Record; +use torii_sql::{DbConnection, Executable, FlexQuery}; + +#[async_trait] +pub trait IntrospectProcessor { + async fn process_msgs( + &self, + tables: &Tables, + namespaces: &NamespaceMode, + msgs: Vec<&IntrospectBody>, + ) -> DbResult>>; +} + +#[async_trait] +pub trait IntrospectInitialize { + async fn initialize(&self) -> DbResult<()>; + async fn load_tables(&self, namespaces: &Option>) -> DbResult>; + async fn load_columns(&self, namespaces: &Option>) -> DbResult>; + async fn load_dead_fields( + &self, + namespaces: &Option>, + ) -> DbResult>; +} + +pub trait IntrospectQueryMaker: DbConnection { + type DB: Database; + fn create_table_queries( + namespace: &str, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> TableResult<()>; + fn update_table_queries( + table: &mut Table, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> TableResult<()>; + fn insert_record_queries( + namespace: &str, + table_name: &str, + schema: &RecordSchema<'_>, + records: &[Record], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, + ) -> RecordResult<()>; + fn msgs_to_queries( + tables: &Tables, + namespaces: &NamespaceMode, + msgs: Vec<&IntrospectBody>, + queries: &mut Vec>, + ) -> DbResult>> { + let mut results = Vec::with_capacity(msgs.len()); + for body in msgs { + let (msg, metadata) = body.into(); + results.push(tables.handle_message::( + namespaces.to_namespace(&metadata.from_address)?, + msg, + &metadata.from_address, + metadata.block_number.unwrap_or(u64::MAX), + &metadata.transaction_hash, + queries, + )); + } + Ok(results) + } +} + +#[async_trait] +pub trait IntrospectExecutor: IntrospectQueryMaker + Sized { + async fn process_queries(&self, queries: Vec>) -> DbResult<()>; + async fn execute_msgs( + &self, + tables: &Tables, + namespaces: &NamespaceMode, + msgs: Vec<&IntrospectBody>, + ) -> DbResult>> { + let mut queries = Vec::new(); + let results = Self::msgs_to_queries::(tables, namespaces, msgs, &mut queries)?; + self.process_queries(queries).await?; + Ok(results) + } +} + +#[async_trait] +impl IntrospectExecutor for Backend +where + Vec>: Executable, +{ + async fn process_queries(&self, queries: Vec>) -> DbResult<()> { + let mut batch = Vec::new(); + for query in queries { + if query == *COMMIT_CMD { + self.execute_queries(std::mem::take(&mut batch)).await?; + } else { + batch.push(query); + } + } + if !batch.is_empty() { + self.execute_queries(batch).await?; + } + Ok(()) + } +} diff --git a/crates/introspect-sql-sink/src/error.rs b/crates/introspect-sql-sink/src/error.rs index 09de383a..eb052393 100644 --- a/crates/introspect-sql-sink/src/error.rs +++ b/crates/introspect-sql-sink/src/error.rs @@ -1,5 +1,6 @@ use crate::TableKey; use introspect_types::{PrimaryTypeDef, TypeDef}; +use sqlx::error::BoxDynError; use sqlx::Error as SqlxError; use starknet_types_core::felt::{Felt, FromStrError}; use std::sync::PoisonError; @@ -29,6 +30,8 @@ pub enum TableError { column: String, reason: UpgradeError, }, + #[error("error occurred while encoding a value: {0}")] + Encode(#[source] BoxDynError), } pub type TableResult = std::result::Result; @@ -99,6 +102,24 @@ impl UpgradeResultExt for UpgradeResult { } } +#[derive(Debug, thiserror::Error)] +pub enum RecordError { + #[error(transparent)] + JsonError(#[from] serde_json::Error), +} + +pub type RecordResult = std::result::Result; + +pub trait RecordResultExt { + fn to_db_result(self, table: &str) -> DbResult; +} + +impl RecordResultExt for RecordResult { + fn to_db_result(self, table: &str) -> DbResult { + self.map_err(|err| DbError::RecordError(table.to_string(), err)) + } +} + #[derive(Debug, thiserror::Error)] pub enum DbError { #[error(transparent)] @@ -123,8 +144,12 @@ pub enum DbError { UpdateNotSupported, #[error("Table poison error: {0}")] PoisonError(String), - #[error("Schema not found for address: {0:#063x}")] - SchemaNotFound(Felt), + #[error("Namespace not found for address: {0:#063x}")] + NamespaceNotFound(Felt), + #[error("Could not parse record for table {0}: {1}")] + RecordError(String, RecordError), + #[error("Failed to pass string to felt")] + FeltFromStrError(#[from] FromStrError), } pub type DbResult = std::result::Result; @@ -136,23 +161,23 @@ impl From> for DbError { } #[derive(Debug, thiserror::Error)] -pub enum SchemaError { - #[error("Invalid address length for schema: {0} should be 63 characters long")] +pub enum NamespaceError { + #[error("Invalid address length for address: {0} should be 63 characters long")] InvalidAddressLength(String), #[error(transparent)] AddressFromStrError(#[from] FromStrError), - #[error("Schema {0} does not match expected schema {1}")] - SchemaMismatch(String, String), - #[error("Schema {1} not found for address: {0:#063x}")] + #[error("Namespace {0} does not match expected namespace {1}")] + NamespaceMismatch(String, String), + #[error("Namespace {1} not found for address: {0:#063x}")] AddressNotFound(Felt, String), } -pub type SchemaResult = std::result::Result; +pub type NamespaceResult = std::result::Result; #[derive(Debug, thiserror::Error)] pub enum TableLoadError { #[error(transparent)] - SchemaError(#[from] SchemaError), + NamespaceError(#[from] NamespaceError), #[error("Table {0} {1:#063x} not found for column {2} with id: {3:#063x}")] ColumnTableNotFound(String, Felt, String, Felt), #[error("Table {0} {1:#063x} not found for dead field {2} with id: {3}")] diff --git a/crates/introspect-sql-sink/src/lib.rs b/crates/introspect-sql-sink/src/lib.rs index d27f014b..3605664c 100644 --- a/crates/introspect-sql-sink/src/lib.rs +++ b/crates/introspect-sql-sink/src/lib.rs @@ -1,14 +1,26 @@ +pub mod backend; pub mod error; +pub mod namespace; pub mod processor; -pub mod schema; pub mod sink; pub mod table; pub mod tables; -pub mod utils; +pub use backend::{IntrospectInitialize, IntrospectProcessor, IntrospectQueryMaker}; pub use error::{ - DbError, DbResult, TableError, TableResult, TypeError, TypeResult, UpgradeError, UpgradeResult, - UpgradeResultExt, + DbError, DbResult, RecordError, RecordResult, TableError, TableResult, TypeError, TypeResult, + UpgradeError, UpgradeResult, UpgradeResultExt, }; -pub use schema::{SchemaKey, SchemaMode, TableKey}; -pub use utils::{truncate, HasherExt}; +pub use namespace::{NamespaceKey, NamespaceMode, TableKey}; +pub use processor::{DbColumn, DbDeadField, DbTable, IntrospectDb}; +pub use sink::IntrospectSqlSink; +pub use table::{DeadField, DeadFieldDef, Table}; + +#[cfg(feature = "postgres")] +pub mod postgres; + +#[cfg(feature = "sqlite")] +pub mod sqlite; + +#[cfg(feature = "postgres")] +pub mod runtime; diff --git a/crates/introspect-sql-sink/src/namespace.rs b/crates/introspect-sql-sink/src/namespace.rs new file mode 100644 index 00000000..3ffa6919 --- /dev/null +++ b/crates/introspect-sql-sink/src/namespace.rs @@ -0,0 +1,199 @@ +use crate::error::{NamespaceError, NamespaceResult}; +use crate::{DbError, DbResult}; +use introspect_types::ResultInto; +use itertools::Itertools; +use starknet_types_core::felt::Felt; +use std::collections::{HashMap, HashSet}; +use std::fmt::Display; +use std::hash::{Hash, Hasher}; +use std::sync::Arc; + +pub enum NamespaceMode { + Single(Arc), + Address, + Named(HashMap>), + Addresses(HashSet), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TableKey { + namespace: NamespaceKey, + id: Felt, +} + +impl TableKey { + pub fn new(namespace: NamespaceKey, id: Felt) -> Self { + Self { namespace, id } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum NamespaceKey { + Single(Arc), + Address(Felt), + Named(Arc), +} + +pub fn felt_to_namespace(address: &Felt) -> String { + format!("{address:063x}") +} + +impl Hash for TableKey { + fn hash(&self, state: &mut H) { + self.namespace.hash(state); + self.id.hash(state); + } +} + +impl Hash for NamespaceKey { + fn hash(&self, state: &mut H) { + match self { + NamespaceKey::Address(addr) => addr.hash(state), + NamespaceKey::Named(name) => name.hash(state), + NamespaceKey::Single(_) => {} + } + } +} + +impl Display for NamespaceKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + NamespaceKey::Address(addr) => write!(f, "{addr:063x}"), + NamespaceKey::Named(name) | NamespaceKey::Single(name) => name.fmt(f), + } + } +} + +impl Display for TableKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if !matches!(self.namespace, NamespaceKey::Single(_)) { + write!(f, "{} ", self.namespace)?; + } + write!(f, "{:#063x}", self.id) + } +} + +impl From for NamespaceMode { + fn from(value: String) -> Self { + NamespaceMode::Single(value.into()) + } +} + +impl From<&str> for NamespaceMode { + fn from(value: &str) -> Self { + NamespaceMode::Single(value.into()) + } +} + +impl From> for NamespaceMode { + fn from(value: HashMap) -> Self { + NamespaceMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + } +} + +impl From<[(Felt, &str); N]> for NamespaceMode { + fn from(value: [(Felt, &str); N]) -> Self { + NamespaceMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + } +} + +impl From<[(Felt, String); N]> for NamespaceMode { + fn from(value: [(Felt, String); N]) -> Self { + NamespaceMode::Named( + value + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + } +} + +impl From<[Felt; N]> for NamespaceMode { + fn from(value: [Felt; N]) -> Self { + NamespaceMode::Addresses(value.into_iter().collect()) + } +} + +impl From> for NamespaceMode { + fn from(value: Vec) -> Self { + NamespaceMode::Addresses(value.into_iter().collect()) + } +} + +fn felt_try_from_namespace(namespace: &str) -> NamespaceResult { + match namespace.len() == 63 { + true => Felt::from_hex(namespace).err_into(), + false => Err(NamespaceError::InvalidAddressLength(namespace.to_string())), + } +} + +impl NamespaceMode { + pub fn namespaces(&self) -> Option> { + match self { + NamespaceMode::Single(name) => Some(vec![name.to_string()]), + NamespaceMode::Address => None, + NamespaceMode::Named(map) => { + Some(map.values().unique().map(ToString::to_string).collect()) + } + NamespaceMode::Addresses(set) => Some(set.iter().map(felt_to_namespace).collect()), + } + } + + pub fn get_namespace_key( + &self, + namespace: String, + owner: &Felt, + ) -> NamespaceResult { + match self { + NamespaceMode::Single(s) => match **s == *namespace { + true => Ok(NamespaceKey::Single(s.clone())), + false => Err(NamespaceError::NamespaceMismatch(namespace, s.to_string())), + }, + NamespaceMode::Address => { + felt_try_from_namespace(&namespace).map(NamespaceKey::Address) + } + NamespaceMode::Named(map) => match map.get(owner) { + Some(s) if **s == *namespace => Ok(NamespaceKey::Named(s.clone())), + Some(s) => Err(NamespaceError::NamespaceMismatch(namespace, s.to_string())), + None => Err(NamespaceError::AddressNotFound(*owner, namespace)), + }, + NamespaceMode::Addresses(set) => { + let address = felt_try_from_namespace(&namespace)?; + match set.contains(&address) { + true => Ok(NamespaceKey::Address(address)), + false => Err(NamespaceError::AddressNotFound(address, namespace)), + } + } + } + } + + pub fn get_key(&self, namespace: String, id: Felt, owner: &Felt) -> NamespaceResult { + self.get_namespace_key(namespace, owner) + .map(|k| TableKey::new(k, id)) + } + + pub fn to_namespace(&self, from_address: &Felt) -> DbResult { + match self { + NamespaceMode::Single(name) => Ok(NamespaceKey::Single(name.clone())), + NamespaceMode::Address => Ok(NamespaceKey::Address(*from_address)), + NamespaceMode::Named(map) => match map.get(from_address) { + Some(namespace) => Ok(NamespaceKey::Named(namespace.clone())), + None => Err(DbError::NamespaceNotFound(*from_address)), + }, + NamespaceMode::Addresses(set) => match set.contains(from_address) { + true => Ok(NamespaceKey::Address(*from_address)), + false => Err(DbError::NamespaceNotFound(*from_address)), + }, + } + } +} diff --git a/crates/introspect-sql-sink/src/postgres/backend.rs b/crates/introspect-sql-sink/src/postgres/backend.rs new file mode 100644 index 00000000..8fe705ab --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/backend.rs @@ -0,0 +1,145 @@ +use super::insert::insert_record_queries; +use super::query::{insert_columns_query, insert_table_query, CreatePgTable}; +use super::upgrade::PgTableUpgrade; +use crate::processor::IntrospectDb; +use crate::{ + IntrospectQueryMaker, IntrospectSqlSink, RecordResult, Table, TableError, TableResult, +}; +use async_trait::async_trait; +use introspect_types::schema::{Names, TypeDefs}; +use introspect_types::{ColumnDef, FeltIds, PrimaryDef}; +use starknet_types_core::felt::Felt; +use torii_introspect::tables::RecordSchema; +use torii_introspect::Record; +use torii_sql::{DbConnection, PgPool, PgQuery, Postgres}; + +pub type IntrospectPgDb = IntrospectDb>; + +pub struct PostgresBackend>(T); + +impl> From for PostgresBackend { + fn from(value: T) -> Self { + PostgresBackend(value) + } +} + +impl> DbConnection for PostgresBackend { + fn pool(&self) -> &PgPool { + self.0.pool() + } +} + +#[async_trait] +impl + Send + Sync> IntrospectQueryMaker for PostgresBackend { + type DB = Postgres; + + fn create_table_queries( + namespace: &str, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> TableResult<()> { + let ns = namespace.into(); + CreatePgTable::new(&ns, id, name, primary, columns)?.make_queries(queries); + store_table_queries( + namespace, + id, + name, + primary, + columns, + from_address, + block_number, + transaction_hash, + queries, + ) + } + fn update_table_queries( + table: &mut Table, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> TableResult<()> { + let upgrades = table.upgrade_table(name, primary, columns)?; + upgrades.to_queries(block_number, transaction_hash, queries)?; + let columns = table.columns_with_ids(&upgrades.columns_upgraded)?; + store_table_queries( + &table.namespace, + &table.id, + name, + primary, + columns, + from_address, + block_number, + transaction_hash, + queries, + ) + } + fn insert_record_queries( + namespace: &str, + table_name: &str, + schema: &RecordSchema<'_>, + records: &[Record], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> RecordResult<()> { + insert_record_queries( + namespace, + table_name, + schema, + records, + from_address, + block_number, + transaction_hash, + queries, + ) + } +} + +fn store_table_queries( + schema: &str, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: CS, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, +) -> TableResult<()> +where + CS: Names + FeltIds + TypeDefs, +{ + queries.push( + insert_table_query( + &schema, + &id, + &name, + &primary, + from_address, + block_number, + transaction_hash, + ) + .map_err(TableError::Encode)?, + ); + + queries.push( + insert_columns_query(&schema, &id, columns, block_number, transaction_hash) + .map_err(TableError::Encode)?, + ); + Ok(()) +} + +impl> IntrospectSqlSink for PostgresBackend { + const NAME: &'static str = "Introspect Postgres"; +} diff --git a/crates/introspect-sql-sink/src/postgres/create.rs b/crates/introspect-sql-sink/src/postgres/create.rs new file mode 100644 index 00000000..77b1c055 --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/create.rs @@ -0,0 +1,322 @@ +use super::query::{make_schema_query, CreatePgTable, CreatesType}; +use super::utils::{AsBytes, HasherExt}; +use super::{PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName}; +use crate::{TypeError, TypeResult}; +use introspect_types::{ + ArrayDef, ColumnDef, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, PrimaryTypeDef, + StructDef, TupleDef, TypeDef, VariantDef, +}; +use itertools::Itertools; +use starknet_types_core::felt::Felt; +use std::rc::Rc; +use torii_sql::postgres::PgQuery; +use torii_sql::Queries; +use xxhash_rust::xxh3::Xxh3; + +pub trait PostgresTypeExtractor { + fn extract_type( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult; +} + +pub trait PostgresFieldExtractor { + type Id: AsBytes; + fn name(&self) -> &str; + fn type_def(&self) -> &TypeDef; + fn id(&self) -> &Self::Id; + fn branch(&self, branch: &Xxh3) -> Xxh3 { + branch.branch(self.id()) + } + fn extract_field( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult { + Ok(PostgresField::new( + self.name().to_string(), + self.type_def() + .extract_type(schema, &self.branch(branch), creates)?, + )) + } +} + +impl PostgresField { + pub fn new(name: impl Into, pg_type: PostgresType) -> Self { + Self { + name: name.into(), + pg_type, + } + } + + pub fn new_composite(name: S, schema: &Rc, type_name: T) -> Self + where + S: Into, + T: Into, + { + Self { + name: name.into(), + pg_type: PostgresType::composite(schema, type_name), + } + } +} + +impl PostgresFieldExtractor for ColumnDef { + type Id = Felt; + fn name(&self) -> &str { + &self.name + } + + fn type_def(&self) -> &TypeDef { + &self.type_def + } + fn id(&self) -> &Self::Id { + &self.id + } +} + +impl PostgresFieldExtractor for MemberDef { + type Id = String; + fn name(&self) -> &str { + &self.name + } + + fn type_def(&self) -> &TypeDef { + &self.type_def + } + fn id(&self) -> &Self::Id { + &self.name + } +} + +impl PostgresFieldExtractor for (&Felt, &VariantDef) { + type Id = Felt; + fn name(&self) -> &str { + &self.1.name + } + + fn type_def(&self) -> &TypeDef { + &self.1.type_def + } + fn id(&self) -> &Self::Id { + self.0 + } +} + +impl PostgresTypeExtractor for TypeDef { + fn extract_type( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult { + match self { + TypeDef::None => Ok(PostgresScalar::None.into()), + TypeDef::Bool => Ok(PostgresScalar::Boolean.into()), + TypeDef::I8 | TypeDef::I16 => Ok(PostgresScalar::SmallInt.into()), + TypeDef::I32 => Ok(PostgresScalar::Int.into()), + TypeDef::I64 => Ok(PostgresScalar::BigInt.into()), + TypeDef::U8 => Ok(PostgresScalar::Uint8.into()), + TypeDef::U16 => Ok(PostgresScalar::Uint16.into()), + TypeDef::U32 => Ok(PostgresScalar::Uint32.into()), + TypeDef::U64 => Ok(PostgresScalar::Uint64.into()), + TypeDef::U128 => Ok(PostgresScalar::Uint128.into()), + TypeDef::I128 => Ok(PostgresScalar::Int128.into()), + TypeDef::U256 => Ok(PostgresScalar::Uint256.into()), + TypeDef::U512 => Ok(PostgresScalar::Uint512.into()), + TypeDef::Felt252 => Ok(PostgresScalar::Felt252.into()), + TypeDef::ContractAddress + | TypeDef::ClassHash + | TypeDef::StorageAddress + | TypeDef::StorageBaseAddress => Ok(PostgresScalar::StarknetHash.into()), + TypeDef::EthAddress => Ok(PostgresScalar::EthAddress.into()), + TypeDef::Utf8String => Ok(PostgresScalar::Text.into()), + TypeDef::ShortUtf8 => Ok(PostgresScalar::Char31.into()), + TypeDef::ByteArray | TypeDef::ByteArrayEncoded(_) => Ok(PostgresScalar::Bytea.into()), + TypeDef::Bytes31 | TypeDef::Bytes31Encoded(_) => Ok(PostgresScalar::Bytes31.into()), + TypeDef::Tuple(type_defs) => type_defs.extract_type(schema, branch, creates), + TypeDef::Enum(enum_def) => enum_def.extract_type(schema, branch, creates), + TypeDef::Array(array_def) => array_def.extract_type(schema, branch, creates), + TypeDef::FixedArray(fixed_array_def) => { + fixed_array_def.extract_type(schema, branch, creates) + } + TypeDef::Struct(struct_def) => struct_def.extract_type(schema, branch, creates), + TypeDef::Option(def) => def.type_def.extract_type(schema, branch, creates), + TypeDef::Nullable(def) => def.type_def.extract_type(schema, branch, creates), + TypeDef::Felt252Dict(_) | TypeDef::Result(_) | TypeDef::Ref(_) | TypeDef::Custom(_) => { + Err(TypeError::UnsupportedType(format!("{self:?}"))) + } + } + } +} + +impl From<&PrimaryDef> for PrimaryKey { + fn from(primary: &PrimaryDef) -> Self { + let pg_type = match primary.type_def { + PrimaryTypeDef::Bool => PostgresScalar::Boolean, + PrimaryTypeDef::I8 | PrimaryTypeDef::I16 => PostgresScalar::SmallInt, + PrimaryTypeDef::I32 => PostgresScalar::Int, + PrimaryTypeDef::I64 => PostgresScalar::BigInt, + PrimaryTypeDef::U8 => PostgresScalar::Uint8, + PrimaryTypeDef::U16 => PostgresScalar::Uint16, + PrimaryTypeDef::U32 => PostgresScalar::Uint32, + PrimaryTypeDef::U64 => PostgresScalar::Uint64, + PrimaryTypeDef::U128 => PostgresScalar::Uint128, + PrimaryTypeDef::I128 => PostgresScalar::Int128, + PrimaryTypeDef::Felt252 => PostgresScalar::Felt252, + PrimaryTypeDef::ContractAddress + | PrimaryTypeDef::ClassHash + | PrimaryTypeDef::StorageAddress + | PrimaryTypeDef::StorageBaseAddress => PostgresScalar::StarknetHash, + PrimaryTypeDef::EthAddress => PostgresScalar::EthAddress, + PrimaryTypeDef::ShortUtf8 => PostgresScalar::Char31, + PrimaryTypeDef::Bytes31 | PrimaryTypeDef::Bytes31Encoded(_) => PostgresScalar::Bytes31, + }; + PrimaryKey { + name: primary.name.clone(), + pg_type, + } + } +} + +impl PostgresTypeExtractor for ArrayDef { + fn extract_type( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult { + self.type_def + .extract_type(schema, branch, creates)? + .to_array(None) + } +} + +impl PostgresTypeExtractor for FixedArrayDef { + fn extract_type( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult { + self.type_def + .extract_type(schema, branch, creates)? + .to_array(Some(self.size)) + } +} + +impl PostgresTypeExtractor for StructDef { + fn extract_type( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult { + let members = self + .members + .iter() + .map(|f| f.extract_field(schema, branch, creates)) + .collect::>>()?; + let name = branch.type_name(&self.name); + creates.push(CreatesType::new_struct(schema, &name, members).into()); + Ok(PostgresType::composite(schema, name)) + } +} + +impl PostgresTypeExtractor for EnumDef { + fn extract_type( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult { + let name = branch.type_name(&self.name); + let variants_type = branch.type_name(&format!("v_{}", self.name)); + let variant_names = self.variants.values().map(|v| v.name.clone()).collect_vec(); + creates.push(CreatesType::new_enum(schema, &variants_type, variant_names).into()); + let mut fields = Vec::with_capacity(self.variants.len() + 1); + fields.push(PostgresField::new_composite( + "_variant", + schema, + variants_type, + )); + for variant in &self.variants { + match variant.1.type_def { + TypeDef::None => {} + _ => fields.push(variant.extract_field(schema, branch, creates)?), + } + } + creates.push(CreatesType::new_struct(schema, &name, fields).into()); + Ok(PostgresType::composite(schema, name)) + } +} + +impl PostgresTypeExtractor for TupleDef { + fn extract_type( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult { + let mut variants = Vec::with_capacity(self.elements.len()); + for (i, element) in self.elements.iter().enumerate() { + variants.push( + element + .extract_type(schema, &branch.branch(&(i as u32)), creates)? + .to_field(format!("_{}", i)), + ); + } + let name = branch.type_name("tuple"); + creates.push(CreatesType::new_struct(schema, &name, variants).into()); + Ok(PostgresType::composite(schema, name)) + } +} + +impl PostgresTypeExtractor for OptionDef { + fn extract_type( + &self, + schema: &Rc, + branch: &Xxh3, + creates: &mut Vec>, + ) -> TypeResult { + self.type_def.extract_type(schema, branch, creates) + } +} + +impl CreatePgTable { + pub fn new( + schema: &Rc, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + ) -> TypeResult { + let mut creates: Vec = Vec::new(); + let branch = Xxh3::new_based(id); + let primary = primary.into(); + let columns = columns + .iter() + .map(|col| col.extract_field(schema, &branch, &mut creates)) + .collect::>>()?; + Ok(Self { + name: SchemaName::new(schema, name), + primary, + columns, + pg_types: creates, + }) + } + pub fn make_queries(&self, queries: &mut Vec) { + queries.add(make_schema_query(&self.name.0)); + for pg_type in &self.pg_types { + queries.add(pg_type.to_string()); + } + queries.add(self.to_string()); + queries.add(format!( + r#"CREATE TRIGGER set_timestamps BEFORE INSERT ON {} FOR EACH ROW EXECUTE FUNCTION introspect.set_default_timestamps();"#, + self.name + )); + } +} diff --git a/crates/introspect-sql-sink/src/postgres/handler.rs b/crates/introspect-sql-sink/src/postgres/handler.rs new file mode 100644 index 00000000..d511a12f --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/handler.rs @@ -0,0 +1,28 @@ +use super::query::{fetch_columns, fetch_dead_fields, fetch_tables}; +use super::PostgresBackend; +use crate::backend::IntrospectInitialize; +use crate::{DbColumn, DbDeadField, DbResult, DbTable}; +use async_trait::async_trait; +use introspect_types::ResultInto; +use torii_sql::{DbConnection, Postgres}; + +pub const INTROSPECT_PG_SINK_MIGRATIONS: sqlx::migrate::Migrator = + sqlx::migrate!("./migrations/postgres"); + +#[async_trait] +impl + Send + Sync> IntrospectInitialize for PostgresBackend { + async fn load_tables(&self, schemas: &Option>) -> DbResult> { + fetch_tables(self.pool(), schemas).await.err_into() + } + async fn load_columns(&self, schemas: &Option>) -> DbResult> { + fetch_columns(self.pool(), schemas).await.err_into() + } + async fn load_dead_fields(&self, schemas: &Option>) -> DbResult> { + fetch_dead_fields(self.pool(), schemas).await.err_into() + } + async fn initialize(&self) -> DbResult<()> { + self.migrate(Some("introspect"), INTROSPECT_PG_SINK_MIGRATIONS) + .await + .err_into() + } +} diff --git a/crates/introspect-sql-sink/src/postgres/insert.rs b/crates/introspect-sql-sink/src/postgres/insert.rs new file mode 100644 index 00000000..f1b5ebf8 --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/insert.rs @@ -0,0 +1,89 @@ +use super::json::PostgresJsonSerializer; +use crate::RecordResult; +use introspect_types::ColumnInfo; +use serde::ser::SerializeMap; +use serde_json::Serializer as JsonSerializer; +use starknet_types_core::felt::Felt; +use std::io::Write; +use torii_introspect::tables::{RecordSchema, SerializeEntries}; +use torii_introspect::Record; +use torii_sql::postgres::PgQuery; +use torii_sql::Queries; + +pub const METADATA_CONFLICTS: &str = "__updated_at = NOW(), __updated_block = EXCLUDED.__updated_block, __updated_tx = EXCLUDED.__updated_tx"; + +pub struct MetaData<'a> { + pub block_number: u64, + pub transaction_hash: &'a Felt, +} + +impl<'a> MetaData<'a> { + pub fn new(block_number: u64, transaction_hash: &'a Felt) -> Self { + Self { + block_number, + transaction_hash, + } + } +} + +pub fn pg_json_felt252(value: &Felt) -> String { + format!("\\x{}", hex::encode(value.to_bytes_be())) +} + +impl SerializeEntries for MetaData<'_> { + fn entry_count(&self) -> usize { + 4 + } + fn serialize_entries( + &self, + map: &mut ::SerializeMap, + ) -> Result<(), S::Error> { + let tx_hash = pg_json_felt252(&self.transaction_hash); + map.serialize_entry("__created_block", &self.block_number)?; + map.serialize_entry("__updated_block", &self.block_number)?; + map.serialize_entry("__created_tx", &tx_hash)?; + map.serialize_entry("__updated_tx", &tx_hash) + } +} + +pub fn insert_record_queries( + namespace: &str, + table_name: &str, + schema: &RecordSchema<'_>, + records: &[Record], + _from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, +) -> RecordResult<()> { + let mut writer = Vec::new(); + let metadata = MetaData::new(block_number, transaction_hash); + write!( + writer, + r#"INSERT INTO "{namespace}"."{table_name}" SELECT * FROM jsonb_populate_recordset(NULL::"{namespace}"."{table_name}", $$"# + ) + .unwrap(); + schema.parse_records_with_metadata( + records, + &metadata, + &mut JsonSerializer::new(&mut writer), + &PostgresJsonSerializer, + )?; + write!( + writer, + r#"$$) ON CONFLICT ("{}") DO UPDATE SET {METADATA_CONFLICTS}"#, + schema.primary().name + ) + .unwrap(); + for ColumnInfo { name, .. } in schema.columns() { + write!( + writer, + r#", "{name}" = COALESCE(EXCLUDED."{name}", "{table_name}"."{name}")"#, + name = name + ) + .unwrap(); + } + let string = unsafe { String::from_utf8_unchecked(writer) }; + queries.add(string); + Ok(()) +} diff --git a/crates/introspect-sql-sink/src/postgres/json.rs b/crates/introspect-sql-sink/src/postgres/json.rs new file mode 100644 index 00000000..7e8cc911 --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/json.rs @@ -0,0 +1,89 @@ +use introspect_types::serialize::ToCairoDeSeFrom; +use introspect_types::serialize_def::CairoTypeSerialization; +use introspect_types::{CairoDeserializer, ResultDef, TupleDef, TypeDef}; +use serde::ser::SerializeMap; +use serde::Serializer; + +pub struct PostgresJsonSerializer; + +impl CairoTypeSerialization for PostgresJsonSerializer { + fn serialize_byte_array( + &self, + serializer: S, + value: &[u8], + ) -> Result { + serializer.serialize_str(&format!("\\x{}", hex::encode(value))) + } + fn serialize_string( + &self, + serializer: S, + value: &str, + ) -> Result { + serializer.serialize_str(&value.replace('\0', "\u{FFFD}")) + } + fn serialize_felt( + &self, + serializer: S, + value: &[u8; 32], + ) -> Result { + self.serialize_byte_array(serializer, value) + } + fn serialize_eth_address( + &self, + serializer: S, + value: &[u8; 20], + ) -> Result { + self.serialize_byte_array(serializer, value) + } + fn serialize_tuple<'a, S: Serializer>( + &'a self, + data: &mut impl CairoDeserializer, + serializer: S, + tuple: &'a TupleDef, + ) -> Result { + let mut seq = serializer.serialize_map(Some(tuple.elements.len()))?; + for (i, element) in tuple.elements.iter().enumerate() { + seq.serialize_entry(&format!("_{i}"), &element.to_de_se(data, self))?; + } + seq.end() + } + + fn serialize_variant<'a, S: Serializer>( + &'a self, + data: &mut impl CairoDeserializer, + serializer: S, + name: &str, + type_def: &'a TypeDef, + ) -> Result { + match type_def { + TypeDef::None => { + let mut map = serializer.serialize_map(Some(1))?; + map.serialize_entry("_variant", name)?; + map + } + _ => { + let mut map = serializer.serialize_map(Some(2))?; + map.serialize_entry("_variant", name)?; + map.serialize_entry(name, &type_def.to_de_se(data, self))?; + map + } + } + .end() + } + + fn serialize_result<'a, S: Serializer>( + &'a self, + data: &mut impl CairoDeserializer, + serializer: S, + result: &'a ResultDef, + is_ok: bool, + ) -> Result { + let mut map = serializer.serialize_map(Some(1))?; + map.serialize_entry("is_ok", &is_ok)?; + match is_ok { + true => map.serialize_entry("Ok", &result.ok.to_de_se(data, self))?, + false => map.serialize_entry("Err", &result.err.to_de_se(data, self))?, + } + map.end() + } +} diff --git a/crates/introspect-sql-sink/src/postgres/mod.rs b/crates/introspect-sql-sink/src/postgres/mod.rs new file mode 100644 index 00000000..bb7c4684 --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/mod.rs @@ -0,0 +1,15 @@ +pub mod backend; +pub mod create; +pub mod handler; +pub mod insert; +pub mod json; +pub mod query; +pub mod types; +pub mod upgrade; +pub mod utils; + +pub use backend::{IntrospectPgDb, PostgresBackend}; +pub use types::{ + PostgresArray, PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, +}; +pub use utils::{truncate, HasherExt}; diff --git a/crates/introspect-sql-sink/src/postgres/query.rs b/crates/introspect-sql-sink/src/postgres/query.rs new file mode 100644 index 00000000..d844774a --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/query.rs @@ -0,0 +1,688 @@ +use super::{PostgresField, PostgresType, PrimaryKey, SchemaName}; +use crate::{DbColumn, DbDeadField, DbTable, DeadFieldDef, TableError, TableResult}; +use introspect_types::schema::{Names, TypeDefs}; +use introspect_types::{ColumnDef, FeltIds, MemberDef, PrimaryDef, TypeDef}; +use itertools::Itertools; +use sqlx::error::BoxDynError; +use sqlx::postgres::{PgArguments, PgRow}; +use sqlx::prelude::FromRow; +use sqlx::query::QueryAs; +use sqlx::types::Json; +use sqlx::{Arguments, Executor, Postgres}; +use starknet_types_core::felt::Felt; +use std::fmt::{Display, Formatter, Result as FmtResult, Write}; +use std::rc::Rc; +use torii_introspect::postgres::types::{PgPrimary, Uint128}; +use torii_introspect::postgres::PgFelt; +use torii_sql::postgres::PgQuery; +use torii_sql::{Queries, SqlxResult}; + +pub const COMMIT_CMD: &str = "--COMMIT"; + +const CREATE_METADATA_COLUMNS: &str = "__created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __created_block public.uint64 NOT NULL, __updated_block public.uint64 NOT NULL, __created_tx public.felt252 NOT NULL, __updated_tx public.felt252 NOT NULL);"; +const INSERT_DEAD_MEMBER_QUERY: &str = r#"INSERT INTO introspect.db_dead_fields + ("schema", "table", id, name, type_def, updated_at, created_block, updated_block, created_tx, updated_tx) + SELECT $1, $2, unnest($3::bigint[]), unnest($4::text[]), unnest($5::jsonb[]), NOW(), $6::uint64, $6::uint64, $7, $7 + ON CONFLICT ("schema", "table", id) DO UPDATE SET + name = EXCLUDED.name, type_def = EXCLUDED.type_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; +const INSERT_TABLE_QUERY: &str = r#"INSERT INTO introspect.db_tables + ("schema", id, owner, name, primary_def, updated_at, created_block, updated_block, created_tx, updated_tx) + VALUES ($1, $2, $3, $4, $5, NOW(), $6::uint64, $6::uint64, $7, $7) + ON CONFLICT ("schema", id) DO UPDATE SET + name = EXCLUDED.name, primary_def = EXCLUDED.primary_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; +const INSERT_COLUMN_QUERY: &str = r#"INSERT INTO introspect.db_columns + ("schema", "table", id, name, type_def, updated_at, created_block, updated_block, created_tx, updated_tx) + SELECT $1, $2, unnest($3::felt252[]), unnest($4::text[]), unnest($5::jsonb[]), NOW(), $6::uint64, $6::uint64, $7, $7 + ON CONFLICT ("schema", "table", id) DO UPDATE SET + name = EXCLUDED.name, type_def = EXCLUDED.type_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; + +const FETCH_TABLES_QUERY: &str = r#"SELECT "schema", id, name, primary_def, owner FROM introspect.db_tables WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; +const FETCH_COLUMNS_QUERY: &str = r#"SELECT "schema", "table", id, name, type_def FROM introspect.db_columns WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; +const FETCH_DEAD_FIELDS_QUERY: &str = r#"SELECT "schema", "table", id, name, type_def FROM introspect.db_dead_fields WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; + +#[derive(FromRow)] +pub struct TableRow { + pub schema: String, + pub id: PgFelt, + pub name: String, + pub primary_def: PgPrimary, + pub owner: PgFelt, +} + +#[derive(FromRow)] +pub struct ColumnRow { + pub schema: String, + pub table: PgFelt, + pub id: PgFelt, + pub name: String, + pub type_def: Json, +} + +#[derive(FromRow)] +pub struct DeadFieldRow { + pub schema: String, + pub table: PgFelt, + pub id: Uint128, + pub name: String, + pub type_def: Json, +} + +#[derive(Debug)] +pub struct CreatePgTable { + pub name: SchemaName, + pub primary: PrimaryKey, + pub columns: Vec, + pub pg_types: Vec, +} + +#[derive(Debug)] +pub struct TableUpgrade { + pub schema: Rc, + pub id: Felt, + pub name: String, + pub old_name: Option, + pub atomic: Vec, + pub alters: Vec, + pub columns: Vec, + pub columns_upgraded: Vec, + pub dead: Vec, + pub col_alters: Vec, +} + +#[derive(Debug)] +pub struct ColumnUpgrade { + pub atomic: Vec, + pub alters: Vec, + pub dead: Vec, + pub altered: bool, + pub upgraded: bool, +} + +#[derive(Debug)] +pub struct CreateStruct { + pub name: SchemaName, + pub fields: Vec, +} + +#[derive(Debug)] +pub struct CreateEnum { + pub name: SchemaName, + pub variants: Vec, +} + +#[derive(Debug)] +pub enum StructMod { + Add(PostgresField), + Rename(String, String), +} + +#[derive(Debug)] +pub enum TypeMod { + Struct(StructUpgrade), + Enum(EnumUpgrade), + Create(CreatesType), +} + +#[derive(Debug)] +pub enum ColumnMod { + Add(PostgresField), + Rename(String, String), + Alter(PostgresField), +} + +#[derive(Debug)] +pub struct StructUpgrade { + name: SchemaName, + mods: Vec, +} + +#[derive(Debug)] +pub struct StructAlter { + name: SchemaName, + field: String, + pg_type: PostgresType, +} + +#[derive(Debug)] +pub struct EnumUpgrade { + name: SchemaName, + rename: Vec<(String, String)>, + add: Vec, +} + +#[derive(Debug)] +pub enum CreatesType { + Struct(CreateStruct), + Enum(CreateEnum), +} + +impl Display for CreatePgTable { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + r#"CREATE TABLE IF NOT EXISTS {} ({}, "#, + self.name, self.primary + )?; + for column in &self.columns { + write!(f, "{column}, ")?; + } + CREATE_METADATA_COLUMNS.fmt(f) + } +} + +impl Display for CreateStruct { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "CREATE TYPE {} AS (", self.name)?; + if let Some((last, batch)) = self.fields.split_last() { + for field in batch { + write!(f, "{field}, ")?; + } + last.fmt(f)?; + } + write!(f, ");") + } +} + +impl Display for CreateEnum { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "CREATE TYPE {} AS ENUM (", self.name)?; + if let Some((last, batch)) = self.variants.split_last() { + for field in batch { + write!(f, "'{field}', ")?; + } + write!(f, "'{last}'")?; + } + write!(f, ");") + } +} + +impl Display for CreatesType { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + match self { + CreatesType::Struct(s) => s.fmt(f), + CreatesType::Enum(e) => e.fmt(f), + } + } +} + +impl CreatesType { + pub fn new_struct>( + schema: &Rc, + name: S, + fields: Vec, + ) -> Self { + Self::Struct(CreateStruct { + name: SchemaName::new(schema, name), + fields, + }) + } + + pub fn new_enum>(schema: &Rc, name: S, variants: Vec) -> Self { + Self::Enum(CreateEnum { + name: SchemaName::new(schema, name), + variants, + }) + } +} + +impl TableUpgrade { + pub fn new>(schema: &Rc, id: Felt, name: S) -> Self { + Self { + schema: schema.clone(), + id, + name: name.into(), + old_name: None, + columns: Vec::new(), + columns_upgraded: Vec::new(), + alters: Vec::new(), + atomic: Vec::new(), + dead: Vec::new(), + col_alters: Vec::new(), + } + } + pub fn rename_column(&mut self, old: &mut String, new: &str) -> bool { + let renamed = old != new; + if renamed { + let old = std::mem::replace(old, new.to_string()); + self.columns.push(ColumnMod::Rename(old, new.to_string())); + } + renamed + } + pub fn rename_table(&mut self, new: &str) { + if self.name != new { + self.old_name = Some(std::mem::replace(&mut self.name, new.into())); + } + } + pub fn retype_primary(&mut self, name: &str, pg_type: Option) { + if let Some(pg_type) = pg_type { + self.columns.push(ColumnMod::Alter(pg_type.to_field(name))); + } + } + pub fn retype_column( + &mut self, + column: &ColumnDef, + pg_type: Option, + upgrade: ColumnUpgrade, + field: PostgresType, + ) { + if let Some(pg_type) = pg_type { + self.columns + .push(ColumnMod::Alter(pg_type.to_field(&column.name))); + } + if upgrade.altered { + self.col_alters.push(field.to_field(&column.name)); + } + if upgrade.upgraded { + self.columns_upgraded.push(column.id); + } + self.atomic = upgrade.atomic; + self.alters = upgrade.alters; + self.dead = upgrade.dead; + } + + pub fn add_column(&mut self, id: Felt, name: &str, pg_type: PostgresType) { + self.columns.push(ColumnMod::Add(PostgresField::new( + name.to_string(), + pg_type, + ))); + self.columns_upgraded.push(id); + } + + pub fn column_upgrade(&mut self, upgraded: bool) -> ColumnUpgrade { + ColumnUpgrade { + atomic: std::mem::take(&mut self.atomic), + alters: std::mem::take(&mut self.alters), + dead: std::mem::take(&mut self.dead), + altered: false, + upgraded, + } + } + + pub fn to_queries( + &self, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, + ) -> TableResult<()> { + let schema = &self.schema; + let name = &self.name; + queries.add( + insert_dead_member_query( + &self.schema, + &self.id, + &self.dead, + block_number, + transaction_hash, + ) + .map_err(TableError::Encode)?, + ); + if let Some(old_name) = &self.old_name { + queries.add(format!( + r#"ALTER TABLE "{schema}"."{old_name}" RENAME TO "{name}";"# + )); + } + self.atomic.iter().for_each(|m| m.to_queries(queries)); + if let Some((last, columns)) = self.columns.split_last() { + let mut alterations = format!(r#"ALTER TABLE "{schema}"."{name}" "#); + columns + .iter() + .for_each(|m| write!(alterations, "{m}, ").unwrap()); + write!(alterations, "{last};").unwrap(); + queries.add(alterations); + } + self.alter_queries(queries); + Ok(()) + } + + fn alter_queries(&self, queries: &mut Vec) { + if let Some((last, others)) = self.col_alters.split_last() { + let (schema, name) = (&self.schema, &self.name); + let mut forward = format!(r#"ALTER TABLE "{schema}"."{name}" "#); + let mut reverse = forward.clone(); + for PostgresField { name: col, pg_type } in others { + write!( + forward, + r#"ALTER COLUMN "{col}" TYPE jsonb USING to_jsonb("{col}"),"# + ) + .unwrap(); + write!( + reverse, + r#"ALTER COLUMN "{col}" TYPE {pg_type} USING jsonb_populate_record(null::{pg_type}, "{col}"),"# + ) + .unwrap(); + } + let PostgresField { name: col, pg_type } = last; + write!( + forward, + r#"ALTER COLUMN "{col}" TYPE jsonb USING to_jsonb("{col}");"# + ) + .unwrap(); + write!( + reverse, + r#"ALTER COLUMN "{col}" TYPE {pg_type} USING jsonb_populate_record(null::{pg_type}, "{col}");"# + ) + .unwrap(); + queries.add(forward); + self.alters.iter().for_each(|a| queries.add(a.to_string())); + queries.add(reverse); + } + } +} + +impl Display for ColumnMod { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + match self { + ColumnMod::Add(field) => write!(f, r#"ADD COLUMN {field}"#), + ColumnMod::Alter(PostgresField { name, pg_type }) => { + write!(f, r#"ALTER COLUMN "{name}" TYPE {pg_type}"#,) + } + ColumnMod::Rename(old, new) => write!(f, r#"RENAME COLUMN "{old}" TO "{new}""#), + } + } +} + +impl StructUpgrade { + fn to_queries(&self, queries: &mut Vec) { + let name = &self.name; + self.mods + .iter() + .for_each(|m| queries.add(format!("ALTER TYPE {name} {m};"))); + } +} + +impl Display for StructMod { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + match self { + StructMod::Add(field) => write!(f, "ADD ATTRIBUTE {field}"), + StructMod::Rename(old, new) => write!(f, r#"RENAME ATTRIBUTE "{old}" TO "{new}""#), + } + } +} + +impl Display for StructAlter { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + r#"ALTER TYPE {} ALTER ATTRIBUTE "{}" TYPE {};"#, + self.name, self.field, self.pg_type + ) + } +} + +impl EnumUpgrade { + fn to_queries(&self, queries: &mut Vec) { + let name = &self.name; + for (old, new) in &self.rename { + queries.add(format!( + r#"ALTER TYPE {name} RENAME VALUE '{old}' TO '{new}';"# + )); + } + for variant in &self.add { + queries.add(format!(r#"ALTER TYPE {name} ADD VALUE '{variant}';"#)); + } + queries.add(COMMIT_CMD); + } +} + +impl TypeMod { + fn to_queries(&self, queries: &mut Vec) { + match self { + TypeMod::Struct(upgrade) => upgrade.to_queries(queries), + TypeMod::Enum(upgrade) => upgrade.to_queries(queries), + TypeMod::Create(create) => queries.add(create.to_string()), + } + } +} + +impl StructMod { + pub fn add>(name: S, pg_type: PostgresType) -> Self { + StructMod::Add(PostgresField::new(name.into(), pg_type)) + } + + pub fn add_field(field: PostgresField) -> Self { + StructMod::Add(field) + } +} + +pub trait TypeMods { + fn add_mod(&mut self, type_mod: TypeMod); +} + +impl TypeMods for Vec { + fn add_mod(&mut self, type_mod: TypeMod) { + self.push(type_mod); + } +} + +impl ColumnUpgrade { + pub fn maybe_alter( + &mut self, + schema: &Rc, + name: &str, + field: &str, + pg_type: Option, + ) { + if let Some(pg_type) = pg_type { + self.alters.push(StructAlter { + name: SchemaName::new(schema, name), + field: field.to_string(), + pg_type, + }); + self.upgraded = true; + } + } + + pub fn add_struct_mod>( + &mut self, + schema: &Rc, + name: S, + mods: Vec, + ) { + if !mods.is_empty() { + self.upgraded = true; + self.atomic.push(TypeMod::Struct(StructUpgrade { + name: SchemaName::new(schema, name), + mods, + })) + } + } + pub fn add_enum_mod>( + &mut self, + schema: &Rc, + name: S, + rename: Vec<(String, String)>, + add: Vec, + ) { + if !rename.is_empty() || !add.is_empty() { + self.upgraded = true; + + self.atomic.push(TypeMod::Enum(EnumUpgrade { + name: SchemaName::new(schema, name), + rename, + add, + })) + } + } + pub fn add_dead_member(&mut self, id: u128, member: &MemberDef) { + self.upgraded = true; + self.dead.push(DeadFieldDef { + id, + name: member.name.clone(), + type_def: member.type_def.clone(), + }); + } +} + +pub trait StructMods { + fn add_mod(&mut self, struct_mod: StructMod); + fn add>(&mut self, name: S, pg_type: PostgresType) { + self.add_mod(StructMod::add(name, pg_type)); + } + fn add_field(&mut self, field: PostgresField) { + self.add_mod(StructMod::add_field(field)); + } + fn rename, S: Into>(&mut self, old: T, new: S) { + self.add_mod(StructMod::Rename(old.into(), new.into())); + } +} + +impl StructMods for Vec { + fn add_mod(&mut self, struct_mod: StructMod) { + self.push(struct_mod); + } +} + +impl From for TypeMod { + fn from(value: CreatesType) -> Self { + TypeMod::Create(value) + } +} + +impl From for DbColumn { + fn from(value: ColumnRow) -> Self { + DbColumn { + namespace: value.schema, + table: value.table.into(), + id: value.id.into(), + name: value.name, + type_def: value.type_def.0, + } + } +} + +impl From for DbDeadField { + fn from(value: DeadFieldRow) -> Self { + DbDeadField { + namespace: value.schema, + table: value.table.into(), + id: value.id.into(), + name: value.name, + type_def: value.type_def.0, + } + } +} + +impl From for DbTable { + fn from(value: TableRow) -> Self { + DbTable { + namespace: value.schema, + id: value.id.into(), + owner: value.owner.into(), + name: value.name, + primary: value.primary_def.into(), + columns: Vec::new(), + dead: Vec::new(), + alive: true, + } + } +} + +fn insert_dead_member_query( + schema: &str, + table: &Felt, + fields: &[DeadFieldDef], + block_number: u64, + transaction_hash: &Felt, +) -> Result { + let mut args = PgArguments::default(); + args.add(schema.to_string())?; + args.add(PgFelt::from(*table))?; + args.add(fields.iter().map(|f| f.id.to_string()).collect::>())?; + args.add(fields.iter().map(|f| f.name.clone()).collect::>())?; + args.add(fields.iter().map(|f| Json(&f.type_def)).collect::>())?; + args.add(block_number.to_string())?; + args.add(PgFelt::from(*transaction_hash))?; + + Ok(PgQuery::new(INSERT_DEAD_MEMBER_QUERY, args)) +} + +pub fn insert_columns_query( + schema: &str, + table: &Felt, + columns: CS, + block_number: u64, + transaction_hash: &Felt, +) -> Result +where + CS: Names + FeltIds + TypeDefs, +{ + let mut args = PgArguments::default(); + args.add(schema.to_string())?; + args.add(PgFelt::from(*table))?; + args.add(columns.ids().iter().map_into::().collect_vec())?; + args.add(columns.names())?; + args.add(columns.type_defs().into_iter().map(Json).collect_vec())?; + args.add(block_number.to_string())?; + args.add(PgFelt::from(*transaction_hash))?; + + Ok(PgQuery::new(INSERT_COLUMN_QUERY, args)) +} + +pub fn insert_table_query( + schema: &str, + id: &Felt, + name: &str, + primary_def: &PrimaryDef, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, +) -> Result { + let mut args = PgArguments::default(); + args.add(schema.to_string())?; + args.add(PgFelt::from(*id))?; + args.add(PgFelt::from(*from_address))?; + args.add(name.to_owned())?; + args.add(PgPrimary::from(primary_def))?; + args.add(block_number.to_string())?; + args.add(PgFelt::from(*transaction_hash))?; + + Ok(PgQuery::new(INSERT_TABLE_QUERY, args)) +} + +pub fn schema_query<'a, R>( + query: &'a str, + schemas: &'a Option>, +) -> QueryAs<'a, Postgres, R, PgArguments> +where + R: for<'r> FromRow<'r, PgRow>, +{ + let query = sqlx::query_as::<_, R>(query); + match schemas { + Some(schemas) => query.bind(schemas), + None => query.bind("{}".to_string()), + } +} + +pub async fn fetch_tables<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( + conn: E, + schemas: &Option>, +) -> SqlxResult> { + schema_query::(FETCH_TABLES_QUERY, schemas) + .fetch_all(conn) + .await + .map(|rows| rows.into_iter().map_into().collect()) +} + +pub async fn fetch_columns<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( + conn: E, + schemas: &Option>, +) -> SqlxResult> { + schema_query::(FETCH_COLUMNS_QUERY, schemas) + .fetch_all(conn) + .await + .map(|rows| rows.into_iter().map_into().collect()) +} + +pub async fn fetch_dead_fields<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( + conn: E, + schemas: &Option>, +) -> SqlxResult> { + schema_query::(FETCH_DEAD_FIELDS_QUERY, schemas) + .fetch_all(conn) + .await + .map(|rows| rows.into_iter().map_into().collect()) +} + +pub fn make_schema_query(schema: &str) -> String { + format!(r#"CREATE SCHEMA IF NOT EXISTS "{schema}""#) +} diff --git a/crates/introspect-sql-sink/src/postgres/types.rs b/crates/introspect-sql-sink/src/postgres/types.rs new file mode 100644 index 00000000..519cd009 --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/types.rs @@ -0,0 +1,185 @@ +use crate::{TypeError, TypeResult}; +use serde::{Deserialize, Serialize}; +use std::collections::VecDeque; +use std::fmt::{Display, Formatter, Result as FmtResult}; +use std::rc::Rc; + +#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] +pub struct SchemaName(pub Rc, pub String); + +#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] +pub enum PostgresScalar { + None, + Boolean, + SmallInt, // i16 + Int, // i32 + BigInt, // i64 + Int128, + Uint8, + Uint16, + Uint32, + Uint64, + Uint128, + Uint256, + Uint512, + Felt252, + StarknetHash, + EthAddress, + Text, + Char31, + Bytes31, + Bytea, + Composite(SchemaName), +} + +#[derive(Debug)] +pub struct PrimaryKey { + pub name: String, + pub pg_type: PostgresScalar, +} + +#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] +pub struct PostgresType { + pub scalar: PostgresScalar, + pub array: PostgresArray, +} + +#[derive(Deserialize, Serialize, Debug)] +pub struct PostgresField { + pub name: String, + pub pg_type: PostgresType, +} + +#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] +pub enum PostgresArray { + None, + Dynamic, + Fixed(VecDeque), +} + +impl From for PostgresType { + fn from(value: PostgresScalar) -> Self { + PostgresType { + scalar: value, + array: PostgresArray::None, + } + } +} + +impl Display for SchemaName { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, r#""{}"."{}""#, self.0, self.1) + } +} + +impl Display for PostgresScalar { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + match self { + PostgresScalar::None => f.write_str("VOID"), + PostgresScalar::Boolean => f.write_str("BOOLEAN"), + PostgresScalar::SmallInt => f.write_str("SMALLINT"), + PostgresScalar::Int => f.write_str("INTEGER"), + PostgresScalar::BigInt => f.write_str("BIGINT"), + PostgresScalar::Int128 => f.write_str("public.int128"), + PostgresScalar::Uint8 => f.write_str("public.uint8"), + PostgresScalar::Uint16 => f.write_str("public.uint16"), + PostgresScalar::Uint32 => f.write_str("public.uint32"), + PostgresScalar::Uint64 => f.write_str("public.uint64"), + PostgresScalar::Uint128 => f.write_str("public.uint128"), + PostgresScalar::Uint256 => f.write_str("public.uint256"), + PostgresScalar::Uint512 => f.write_str("public.uint512"), + PostgresScalar::Felt252 => f.write_str("public.felt252"), + PostgresScalar::Char31 => f.write_str("public.char31"), + PostgresScalar::Bytes31 => f.write_str("public.byte31"), + PostgresScalar::StarknetHash => f.write_str("public.starknet_hash"), + PostgresScalar::EthAddress => f.write_str("public.eth_address"), + PostgresScalar::Text => f.write_str("TEXT"), + PostgresScalar::Bytea => f.write_str("BYTEA"), + PostgresScalar::Composite(name) => name.fmt(f), + } + } +} + +impl Display for PostgresArray { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + match self { + PostgresArray::None => Ok(()), + PostgresArray::Dynamic => write!(f, "[]"), + PostgresArray::Fixed(sizes) => sizes.iter().try_for_each(|size| write!(f, "[{size}]")), + } + } +} + +impl Display for PostgresType { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "{}{}", self.scalar, self.array) + } +} + +impl Display for PrimaryKey { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, r#""{}" {} PRIMARY KEY"#, self.name, self.pg_type) + } +} + +impl Display for PostgresField { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, r#""{}" {}"#, self.name, self.pg_type) + } +} + +impl From for PostgresType { + fn from(value: SchemaName) -> Self { + PostgresType { + scalar: PostgresScalar::Composite(value), + array: PostgresArray::None, + } + } +} + +impl SchemaName { + pub fn new>(schema: &Rc, name: T) -> Self { + Self(schema.clone(), name.into()) + } + pub fn replace>(&mut self, name: S) -> String { + std::mem::replace(&mut self.1, name.into()) + } +} + +impl PostgresType { + pub fn is_composite(&self) -> bool { + matches!(self.scalar, PostgresScalar::Composite(_)) + } + pub fn to_array(self, size: Option) -> TypeResult { + let arr = match (self.array, size) { + (PostgresArray::None, None) => PostgresArray::Dynamic, + (PostgresArray::None, Some(size)) => PostgresArray::Fixed(VecDeque::from([size])), + (PostgresArray::Fixed(mut sizes), Some(size)) => { + sizes.push_back(size); + PostgresArray::Fixed(sizes) + } + _ => return Err(TypeError::NestedArrays), + }; + Ok(Self { + scalar: self.scalar, + array: arr, + }) + } + + pub fn composite>(schema: &Rc, name: S) -> Self { + Self { + scalar: PostgresScalar::Composite(SchemaName::new(schema, name)), + array: PostgresArray::None, + } + } + + pub fn to_field(self, name: impl Into) -> PostgresField { + PostgresField::new(name, self) + } +} + +impl From for (String, PostgresType) { + fn from(val: PostgresField) -> Self { + (val.name, val.pg_type) + } +} diff --git a/crates/introspect-sql-sink/src/postgres/upgrade.rs b/crates/introspect-sql-sink/src/postgres/upgrade.rs new file mode 100644 index 00000000..e580ffd7 --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/upgrade.rs @@ -0,0 +1,575 @@ +use super::create::PostgresTypeExtractor; +use super::query::{ColumnUpgrade, StructMod, StructMods, TableUpgrade}; +use super::{HasherExt, PostgresScalar, PostgresType}; +use crate::{ + DeadField, Table, TableResult, TypeError, TypeResult, UpgradeError, UpgradeResult, + UpgradeResultExt, +}; +use introspect_types::{ + ArrayDef, ColumnDef, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, PrimaryTypeDef, + ResultInto, StructDef, TupleDef, TypeDef, VariantDef, +}; +use std::collections::HashMap; +use std::rc::Rc; +use xxhash_rust::xxh3::Xxh3; + +pub trait PgTableUpgrade { + fn upgrade_table( + &mut self, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + ) -> TableResult; + fn retype_primary(&mut self, new: &PrimaryTypeDef) -> UpgradeResult>; +} + +impl PgTableUpgrade for Table { + fn upgrade_table( + &mut self, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + ) -> TableResult { + let branch = Xxh3::new_based(&self.id); + let schema: Rc = self.namespace(); + let mut table_mod = TableUpgrade::new(&schema, self.id, self.name.clone()); + table_mod.rename_table(name); + table_mod.rename_column(&mut self.primary.name, &primary.name); + let pg_type = self + .retype_primary(&primary.type_def) + .to_table_result(&self.name, &self.primary.name)?; + table_mod.retype_primary(&self.primary.name, pg_type); + for column in columns { + let branch = branch.branch(&column.id); + if let Some(current) = self.columns.get_mut(&column.id) { + let upgraded = table_mod.rename_column(&mut current.name, &column.name); + let mut column_upgrade = table_mod.column_upgrade(upgraded); + let pg_type = current + .type_def + .compare_type( + &schema, + &branch, + &column.type_def, + &mut self.dead, + &mut column_upgrade, + ) + .to_table_result(&self.name, ¤t.name)?; + let type_name = current.type_def.get_pg_type(&schema, &branch)?; + table_mod.retype_column(column, pg_type, column_upgrade, type_name); + } else { + let (column_id, info) = column.clone().into(); + self.columns.insert(column_id, info); + let pg_type = + column + .type_def + .extract_type(&schema, &branch, &mut table_mod.atomic)?; + table_mod.add_column(column_id, &column.name, pg_type); + } + } + Ok(table_mod) + } + fn retype_primary(&mut self, new: &PrimaryTypeDef) -> UpgradeResult> { + use super::PostgresScalar::{ + BigInt, Felt252 as PgFelt252, Int, Int128, SmallInt, Uint128, Uint16, Uint32, Uint64, + Uint8, + }; + use introspect_types::PrimaryTypeDef::{ + Bool, Bytes31, Bytes31Encoded, ClassHash, ContractAddress, EthAddress, Felt252, + ShortUtf8, StorageAddress, StorageBaseAddress, I128, I16, I32, I64, I8, U128, U16, U32, + U64, U8, + }; + match (&self.primary.type_def, new) { + (Bool, Bool) + | (U8, U8) + | (U16, U16) + | (U32, U32) + | (U64, U64) + | (U128, U128) + | (I8, I8) + | (I16, I16) + | (I32, I32) + | (I64, I64) + | (I128, I128) + | (ShortUtf8, ShortUtf8) + | (EthAddress, EthAddress) + | (ClassHash, ClassHash) + | (ContractAddress, ContractAddress) + | (StorageAddress, StorageAddress) + | (StorageBaseAddress, StorageBaseAddress) + | (Bytes31, Bytes31) + | (Bytes31Encoded(_), Bytes31Encoded(_)) + | (Felt252, Felt252) => Ok(None), + (Bool, U8) => self.primary.type_def.update_as(U8, Uint8), + (Bool | U8, U16) => self.primary.type_def.update_as(U16, Uint16), + (Bool | U8 | U16, U32) => self.primary.type_def.update_as(U32, Uint32), + (Bool | U8 | U16 | U32, U64) => self.primary.type_def.update_as(U64, Uint64), + (Bool | U8 | U16 | U32 | U64, U128) => self.primary.type_def.update_as(U128, Uint128), + (Bool | U8, I8) => self.primary.type_def.update_as(I8, SmallInt), + (Bool | U8 | I8, I16) => self.primary.type_def.update_as(I16, SmallInt), + (Bool | U8 | U16 | I8 | I16, I32) => self.primary.type_def.update_as(I32, Int), + (Bool | U8 | U16 | U32 | I8 | I16 | I32, I64) => { + self.primary.type_def.update_as(I64, BigInt) + } + (Bool | U8 | U16 | U32 | U64 | I8 | I16 | I32 | I64, I128) => { + self.primary.type_def.update_as(I128, Int128) + } + ( + EthAddress, + ClassHash | ContractAddress | StorageAddress | StorageBaseAddress | Felt252, + ) => self.primary.type_def.update_to(new, PgFelt252), + ( + ClassHash | ContractAddress | StorageAddress | StorageBaseAddress | Felt252, + ClassHash | ContractAddress | StorageAddress | StorageBaseAddress | Felt252, + ) => self.primary.type_def.update_no_change(new), + _ => UpgradeError::primary_upgrade_err(&self.primary.type_def, new), + } + } +} + +pub trait ExtractItem { + fn as_struct(&mut self) -> UpgradeResult<&mut StructDef>; + fn as_enum(&mut self) -> UpgradeResult<&mut EnumDef>; + fn as_fixed_array(&mut self) -> UpgradeResult<&mut FixedArrayDef>; + fn as_array(&mut self) -> UpgradeResult<&mut TypeDef>; + fn as_tuple(&mut self) -> UpgradeResult<&mut TupleDef>; + fn update_as_array( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &ArrayDef, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult>; + fn update_as_option( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &TypeDef, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult>; + fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> TypeResult; +} + +impl ExtractItem for TypeDef { + fn as_struct(&mut self) -> UpgradeResult<&mut StructDef> { + match self { + TypeDef::Struct(def) => Ok(def), + item => UpgradeError::type_upgrade_to_err(item, "Struct"), + } + } + fn as_enum(&mut self) -> UpgradeResult<&mut EnumDef> { + match self { + TypeDef::Enum(def) => Ok(def), + item => UpgradeError::type_upgrade_to_err(item, "Enum"), + } + } + fn as_fixed_array(&mut self) -> UpgradeResult<&mut FixedArrayDef> { + match self { + TypeDef::FixedArray(def) => Ok(def), + item => UpgradeError::type_upgrade_to_err(item, "FixedArray"), + } + } + fn as_array(&mut self) -> UpgradeResult<&mut TypeDef> { + match self { + TypeDef::Array(def) => Ok(&mut def.type_def), + TypeDef::FixedArray(def) => Ok(&mut def.type_def), + item => UpgradeError::type_upgrade_to_err(item, "Array"), + } + } + fn as_tuple(&mut self) -> UpgradeResult<&mut TupleDef> { + match self { + TypeDef::Tuple(def) => Ok(def), + item => UpgradeError::type_upgrade_to_err(item, "Tuple"), + } + } + + fn update_as_array( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &ArrayDef, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult> { + self.as_array()? + .compare_type(schema, branch, new, dead, queries)? + .map(|a| a.to_array(None)) + .transpose() + .err_into() + } + fn update_as_option( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &TypeDef, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult> { + match self { + TypeDef::Option(def) => def.compare_type(schema, branch, new, dead, queries), + _ => { + let pg_type = self.compare_type(schema, branch, new, dead, queries); + *self = OptionDef::new_type_def(std::mem::take(self)); + pg_type + } + } + } + fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> TypeResult { + match self { + TypeDef::None => Ok(PostgresScalar::None.into()), + TypeDef::Bool => Ok(PostgresScalar::Boolean.into()), + TypeDef::I8 | TypeDef::I16 => Ok(PostgresScalar::SmallInt.into()), + TypeDef::I32 => Ok(PostgresScalar::Int.into()), + TypeDef::I64 => Ok(PostgresScalar::BigInt.into()), + TypeDef::U8 => Ok(PostgresScalar::Uint8.into()), + TypeDef::U16 => Ok(PostgresScalar::Uint16.into()), + TypeDef::U32 => Ok(PostgresScalar::Uint32.into()), + TypeDef::U64 => Ok(PostgresScalar::Uint64.into()), + TypeDef::U128 => Ok(PostgresScalar::Uint128.into()), + TypeDef::I128 => Ok(PostgresScalar::Int128.into()), + TypeDef::U256 => Ok(PostgresScalar::Uint256.into()), + TypeDef::U512 => Ok(PostgresScalar::Uint512.into()), + TypeDef::Felt252 => Ok(PostgresScalar::Felt252.into()), + TypeDef::ContractAddress + | TypeDef::ClassHash + | TypeDef::StorageAddress + | TypeDef::StorageBaseAddress => Ok(PostgresScalar::StarknetHash.into()), + TypeDef::EthAddress => Ok(PostgresScalar::EthAddress.into()), + TypeDef::Utf8String => Ok(PostgresScalar::Text.into()), + TypeDef::ShortUtf8 => Ok(PostgresScalar::Char31.into()), + TypeDef::ByteArray | TypeDef::ByteArrayEncoded(_) => Ok(PostgresScalar::Bytea.into()), + TypeDef::Bytes31 | TypeDef::Bytes31Encoded(_) => Ok(PostgresScalar::Bytes31.into()), + TypeDef::Tuple(_) => Ok(PostgresType::composite(schema, branch.tuple_name())), + TypeDef::Enum(def) => Ok(PostgresType::composite(schema, branch.type_name(&def.name))), + TypeDef::Array(def) => def.get_pg_type(schema, branch)?.to_array(None), + TypeDef::FixedArray(def) => def + .type_def + .get_pg_type(schema, branch)? + .to_array(Some(def.size)), + TypeDef::Struct(def) => { + Ok(PostgresType::composite(schema, branch.type_name(&def.name))) + } + TypeDef::Option(def) => def.get_pg_type(schema, branch), + TypeDef::Nullable(def) => def.get_pg_type(schema, branch), + TypeDef::Felt252Dict(_) | TypeDef::Result(_) | TypeDef::Ref(_) | TypeDef::Custom(_) => { + Err(TypeError::UnsupportedType(format!("{self:?}"))) + } + } + } +} + +pub trait CompareType { + fn compare_type( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &Self, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult>; +} + +pub trait UpdateType: Clone { + fn update_no_change(&mut self, new: &Self) -> UpgradeResult> { + *self = new.clone(); + Ok(None) + } + fn update_to( + &mut self, + def: &Self, + pg: impl Into, + ) -> UpgradeResult> { + *self = def.clone(); + Ok(Some(pg.into())) + } + fn update_as( + &mut self, + def: Self, + pg: impl Into, + ) -> UpgradeResult> { + *self = def; + Ok(Some(pg.into())) + } +} + +impl UpdateType for TypeDef {} +impl UpdateType for PrimaryTypeDef {} + +pub trait UpgradeField { + fn type_def(&self) -> &TypeDef; + fn type_def_mut(&mut self) -> &mut TypeDef; + fn name(&self) -> &str; + fn upgrade_field( + &mut self, + schema: &Rc, + name: &str, + branch: &Xxh3, + new: &Self, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult<()> { + let pg_type = + self.type_def_mut() + .compare_type(schema, branch, new.type_def(), dead, queries)?; + queries.maybe_alter(schema, name, self.name(), pg_type); + Ok(()) + } + fn add_field( + &self, + schema: &Rc, + branch: &Xxh3, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult { + let pg_type = self + .type_def() + .extract_type(schema, branch, &mut queries.atomic)?; + Ok(StructMod::add(self.name(), pg_type)) + } +} + +impl UpgradeField for MemberDef { + fn type_def(&self) -> &TypeDef { + &self.type_def + } + fn type_def_mut(&mut self) -> &mut TypeDef { + &mut self.type_def + } + fn name(&self) -> &str { + &self.name + } +} + +impl UpgradeField for VariantDef { + fn type_def(&self) -> &TypeDef { + &self.type_def + } + fn type_def_mut(&mut self) -> &mut TypeDef { + &mut self.type_def + } + fn name(&self) -> &str { + &self.name + } +} + +impl CompareType for TypeDef { + fn compare_type( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &TypeDef, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult> { + use introspect_types::TypeDef::{ + Array, Bool, ByteArray, ByteArrayEncoded, Bytes31, Bytes31Encoded, ClassHash, + ContractAddress, Enum, EthAddress, Felt252, FixedArray, None as TDNone, ShortUtf8, + StorageAddress, StorageBaseAddress, Struct, Tuple, Utf8String, I128, I16, I32, I64, I8, + U128, U16, U256, U32, U512, U64, U8, + }; + use PostgresScalar::{ + BigInt, Felt252 as PgFelt252, Int, Int128, SmallInt, Uint128, Uint16, Uint256, Uint32, + Uint512, Uint64, Uint8, + }; + match (&*self, new) { + (TDNone, TDNone) + | (Utf8String, Utf8String) + | (ShortUtf8, ShortUtf8) + | (Bool, Bool) + | (U8, U8) + | (U16, U16) + | (U32, U32) + | (U64, U64) + | (U128, U128) + | (U256, U256) + | (U512, U512) + | (I8, I8) + | (I16, I16) + | (I32, I32) + | (I64, I64) + | (I128, I128) + | (Felt252, Felt252) + | (EthAddress, EthAddress) + | (ClassHash, ClassHash) + | (ContractAddress, ContractAddress) + | (StorageAddress, StorageAddress) + | (StorageBaseAddress, StorageBaseAddress) + | (Bytes31, Bytes31) + | (ByteArray, ByteArray) => Ok(None), + (I8, I16) + | (Bytes31, Bytes31Encoded(_)) + | (ByteArray, ByteArrayEncoded(_)) + | ( + ClassHash | ContractAddress | StorageAddress | StorageBaseAddress, + ClassHash | ContractAddress | StorageAddress | StorageBaseAddress, + ) => self.update_no_change(new), + (Bool, U8) => self.update_as(U8, Uint8), + (Bool | U8, U16) => self.update_as(U16, Uint16), + (Bool | U8 | U16, U32) => self.update_as(U32, Uint32), + (Bool | U8 | U16 | U32, U64) => self.update_as(U64, Uint64), + (Bool | U8 | U16 | U32 | U64, U128) => self.update_as(U128, Uint128), + (Bool | U8 | U16 | U32 | U64 | U128, U256) => self.update_as(U256, Uint256), + (Bool | U8 | U16 | U32 | U64 | U128 | U256, U512) => self.update_as(U512, Uint512), + (Bool | U8, I8) => self.update_as(I8, SmallInt), + (Bool | U8, I16) => self.update_as(I16, SmallInt), + (Bool | U8 | U16 | I8 | I16, I32) => self.update_as(I32, Int), + (Bool | U8 | U16 | U32 | I8 | I16 | I32, I64) => self.update_as(I64, BigInt), + (Bool | U8 | U16 | U32 | U64 | I8 | I16 | I32 | I64, I128) => { + self.update_as(I128, Int128) + } + (ClassHash | ContractAddress | StorageAddress | StorageBaseAddress, Felt252) => { + self.update_as(Felt252, PgFelt252) + } + (_, Struct(new_def)) => self + .as_struct()? + .compare_type(schema, branch, new_def, dead, queries), + (_, Enum(new_def)) => self + .as_enum()? + .compare_type(schema, branch, new_def, dead, queries), + (_, FixedArray(new_def)) => self + .as_fixed_array()? + .compare_type(schema, branch, new_def, dead, queries), + (_, Array(new_def)) => self.update_as_array(schema, branch, new_def, dead, queries), + (_, Tuple(new_def)) => self + .as_tuple()? + .compare_type(schema, branch, new_def, dead, queries), + (_, TypeDef::Option(new_def)) => { + self.update_as_option(schema, branch, new_def, dead, queries) + } + _ => UpgradeError::type_upgrade_err(self, new), + } + } +} + +impl CompareType for StructDef { + fn compare_type( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &StructDef, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult> { + let mut mods: Vec = Vec::new(); + let mut current_map: HashMap = std::mem::take(&mut self.members) + .into_iter() + .map(|m| (m.name.clone(), m)) + .collect(); + let struct_name = branch.type_name(&self.name); + for member in &new.members { + let branch = branch.branch(&member.name); + if let Some(mut current) = current_map + .remove(&member.name) + .or_else(|| dead.remove(&branch.digest128()).map(Into::into)) + { + current.upgrade_field(schema, &struct_name, &branch, member, dead, queries)?; + self.members.push(current); + } else { + mods.push(member.add_field(schema, &branch, queries)?); + self.members.push(member.clone()); + } + } + for (_, dead_member) in current_map.drain() { + let id = branch.branch(&dead_member.name).digest128(); + queries.add_dead_member(id, &dead_member); + dead.insert(id, dead_member.into()); + } + queries.add_struct_mod(schema, struct_name, mods); + Ok(None) + } +} + +impl CompareType for EnumDef { + fn compare_type( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &EnumDef, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult> { + let mut rename = Vec::new(); + let mut add = Vec::new(); + let mut mods = Vec::new(); + let enum_name = branch.type_name(&self.name); + for (id, variant) in &new.variants { + let branch = branch.branch(id); + if let Some(current) = self.variants.get_mut(id) { + if current.name != variant.name { + rename.push((current.name.clone(), variant.name.clone())); + mods.rename(¤t.name, &variant.name); + current.name = variant.name.clone(); + } + current.upgrade_field(schema, &enum_name, &branch, variant, dead, queries)?; + } else { + add.push(variant.name.clone()); + variant.add_field(schema, &branch, queries)?; + self.variants.insert(*id, variant.clone()); + self.order.push(*id); + } + } + queries.add_enum_mod( + schema, + branch.type_name(&format!("v_{}", self.name)), + rename, + add, + ); + queries.add_struct_mod(schema, enum_name, mods); + Ok(None) + } +} + +impl CompareType for FixedArrayDef { + fn compare_type( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &Self, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult> { + let pg_type = self + .type_def + .compare_type(schema, branch, &new.type_def, dead, queries)?; + if self.size > new.size { + return UpgradeError::array_shorten_err(self.size, new.size); + } + self.size = new.size; + pg_type + .map(|pg_type| pg_type.to_array(Some(self.size))) + .transpose() + .err_into() + } +} + +impl CompareType for TupleDef { + fn compare_type( + &mut self, + schema: &Rc, + branch: &Xxh3, + new: &Self, + dead: &mut HashMap, + queries: &mut ColumnUpgrade, + ) -> UpgradeResult> { + let mut mods = Vec::new(); + let name = branch.tuple_name(); + if self.elements.len() > new.elements.len() { + return Err(UpgradeError::TupleReductionError); + } + for (n, ty) in new.elements.iter().enumerate() { + let branch = branch.branch(&(n as u32)); + if let Some(current) = self.elements.get_mut(n) { + let pg_type = current.compare_type(schema, &branch, ty, dead, queries)?; + queries.maybe_alter(schema, &name, &format!("_{}", n), pg_type); + } else { + self.elements.push(ty.clone()); + mods.add( + format!("_{}", n), + ty.extract_type(schema, &branch, &mut queries.atomic)?, + ); + } + } + queries.add_struct_mod(schema, name, mods); + Ok(None) + } +} diff --git a/crates/introspect-sql-sink/src/utils.rs b/crates/introspect-sql-sink/src/postgres/utils.rs similarity index 96% rename from crates/introspect-sql-sink/src/utils.rs rename to crates/introspect-sql-sink/src/postgres/utils.rs index 9a68c4c4..a006d44e 100644 --- a/crates/introspect-sql-sink/src/utils.rs +++ b/crates/introspect-sql-sink/src/postgres/utils.rs @@ -8,10 +8,6 @@ pub fn truncate(s: &str, max_chars: usize) -> &str { } } -pub fn felt_to_schema(address: &Felt) -> String { - format!("{address:063x}") -} - const ALLOWED_TYPE_NAME_CHARS: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; diff --git a/crates/introspect-sql-sink/src/processor.rs b/crates/introspect-sql-sink/src/processor.rs index e92cddea..52b2d384 100644 --- a/crates/introspect-sql-sink/src/processor.rs +++ b/crates/introspect-sql-sink/src/processor.rs @@ -1,122 +1,196 @@ -use crate::error::{SchemaError, SchemaResult, TableLoadError}; -use crate::tables::DbTables; -use crate::utils::felt_to_schema; -use introspect_types::ResultInto; +use crate::backend::{ + IntrospectExecutor, IntrospectInitialize, IntrospectProcessor, IntrospectQueryMaker, +}; +use crate::error::TableLoadError; +use crate::table::{DeadField, DeadFieldDef, Table}; +use crate::tables::Tables; +use crate::{DbResult, NamespaceMode}; +use async_trait::async_trait; +use introspect_types::{ColumnDef, ColumnInfo, PrimaryDef, TypeDef}; use itertools::Itertools; -use sqlx::{Database, PgPool}; +use sqlx::Pool; use starknet_types_core::felt::Felt; -use std::collections::{HashMap, HashSet}; -use std::sync::Arc; -use torii_common::sql::PgQuery; +use std::collections::HashMap; use torii_introspect::events::IntrospectBody; -use torii_postgres::PostgresConnection; +use torii_sql::{DbConnection, Executable, FlexQuery}; -pub struct IntrospectDb { - tables: DbTables, - schemas: SchemaMode, - pool: T, +pub const COMMIT_CMD: &str = "--COMMIT"; + +pub struct IntrospectDb { + tables: Tables, + namespaces: NamespaceMode, + db: Backend, +} + +pub struct DbTable { + pub namespace: String, + pub id: Felt, + pub owner: Felt, + pub name: String, + pub primary: PrimaryDef, + pub columns: Vec, + pub dead: Vec, + pub alive: bool, +} + +pub struct DbColumn { + pub namespace: String, + pub table: Felt, + pub id: Felt, + pub name: String, + pub type_def: TypeDef, +} + +pub struct DbDeadField { + pub namespace: String, + pub table: Felt, + pub id: u128, + pub name: String, + pub type_def: TypeDef, +} + +impl DbConnection for IntrospectDb { + fn pool(&self) -> &Pool { + self.db.pool() + } } -impl PostgresConnection for IntrospectDb { - fn pool(&self) -> &PgPool { - self.pool.pool() +pub trait IntoHashMap { + fn into_hash_map(self) -> HashMap; +} + +impl IntoHashMap for Vec +where + T: Into<(K, V)>, + K: std::hash::Hash + Eq, +{ + fn into_hash_map(self) -> HashMap { + self.into_iter().map_into().collect() + } +} + +#[async_trait] +impl IntrospectProcessor for Backend +where + Vec>: Executable, +{ + async fn process_msgs( + &self, + tables: &Tables, + namespaces: &NamespaceMode, + msgs: Vec<&IntrospectBody>, + ) -> DbResult>> { + self.execute_msgs(tables, namespaces, msgs).await } } -// TODO: Add errors for unknown schema -impl IntrospectDb { - pub fn new>(pool: T, schemas: S) -> Self { +impl IntrospectDb { + pub fn new(pool: impl Into, namespaces: impl Into) -> Self { Self { - tables: PostgresTables::default(), - schemas: schemas.into(), - pool, + tables: Tables::default(), + namespaces: namespaces.into(), + db: pool.into(), } } - pub async fn load_store_data(&self) -> PgDbResult> { + + pub async fn initialize_introspect_sql_sink(&self) -> DbResult> { + self.db.initialize().await?; + self.load_store_data().await + } + + pub async fn process_messages( + &self, + msgs: Vec<&IntrospectBody>, + ) -> DbResult>> { + self.db + .process_msgs(&self.tables, &self.namespaces, msgs) + .await + } + + pub async fn load_store_data(&self) -> DbResult> { let mut errors = Vec::new(); - let schemas = self.schemas.schemas(); - let schemas = schemas - .as_ref() - .map(|s| s.iter().map(AsRef::as_ref).collect()); - let table_rows = fetch_tables(self.pool(), &schemas).await?; - let mut tables = HashMap::with_capacity(table_rows.len()); - for table in table_rows { - let (id, table) = table.into(); - tables.insert((table.schema.clone(), id), table); - } - for (schema, table_id, id, column_info) in fetch_columns(self.pool(), &schemas).await? { - if let Some(table) = tables.get_mut(&(schema.clone(), table_id)) { + let namespaces = self.namespaces.namespaces(); + let mut tables: HashMap<(String, Felt), Table> = + self.db.load_tables(&namespaces).await?.into_hash_map(); + for column in self.db.load_columns(&namespaces).await? { + let (namespace, table_id, id, column_info) = column.into(); + if let Some(table) = tables.get_mut(&(namespace.clone(), table_id)) { table.columns.insert(id, column_info); } else { errors.push(TableLoadError::ColumnTableNotFound( - schema, + namespace, table_id, column_info.name, id, )); } } - for (schema, table_id, id, field) in fetch_dead_fields(self.pool(), &schemas).await? { - if let Some(table) = tables.get_mut(&(schema.clone(), table_id)) { + for dead_field in self.db.load_dead_fields(&namespaces).await? { + let (namespace, table_id, id, field) = dead_field.into(); + if let Some(table) = tables.get_mut(&(namespace.clone(), table_id)) { table.dead.insert(id, field); } else { errors.push(TableLoadError::TableDeadNotFound( - schema, table_id, field.name, id, + namespace, table_id, field.name, id, )); } } let mut map = self.tables.write()?; - for ((schema, id), table) in tables { - match self.schemas.get_key(schema, id, &table.owner) { + for ((namespace, id), table) in tables { + match self.namespaces.get_key(namespace, id, &table.owner) { Ok(key) => { map.insert(key, table); } - Err(err) => errors.push(TableLoadError::SchemaError(err)), + Err(err) => errors.push(TableLoadError::NamespaceError(err)), } } Ok(errors) } +} - pub async fn initialize_introspect_pg_sink(&self) -> PgDbResult> { - self.migrate(Some("introspect"), INTROSPECT_PG_SINK_MIGRATIONS) - .await?; - self.load_store_data().await +impl From for ((String, Felt), Table) { + fn from(value: DbTable) -> Self { + ( + (value.namespace.clone(), value.id), + Table { + id: value.id, + namespace: value.namespace, + name: value.name, + owner: value.owner, + primary: value.primary, + columns: value.columns.into_hash_map(), + dead: value.dead.into_hash_map(), + alive: value.alive, + }, + ) } +} - pub async fn process_messages( - &self, - msgs: Vec<&IntrospectBody>, - ) -> PgDbResult>> { - let mut queries = Vec::new(); - let mut results = Vec::with_capacity(msgs.len()); - - for body in msgs { - let (msg, metadata) = body.into(); - results.push(self.tables.handle_message( - self.schemas.to_schema(&metadata.from_address)?, - msg, - &metadata.from_address, - metadata.block_number.unwrap_or(u64::MAX), - &metadata.transaction_hash, - &mut queries, - )); - } - self.process_queries(queries).await?; - Ok(results) +impl From for (String, Felt, Felt, ColumnInfo) { + fn from(value: DbColumn) -> Self { + ( + value.namespace, + value.table, + value.id, + ColumnInfo { + name: value.name, + attributes: Vec::new(), + type_def: value.type_def, + }, + ) } +} - pub async fn process_queries(&self, queries: Vec) -> PgDbResult<()> { - let mut batch = Vec::new(); - for query in queries { - if query == *COMMIT_CMD { - self.execute_queries(std::mem::take(&mut batch)).await?; - } else { - batch.push(query); - } - } - if !batch.is_empty() { - self.execute_queries(batch).await?; - } - Ok(()) +impl From for (String, Felt, u128, DeadField) { + fn from(value: DbDeadField) -> Self { + ( + value.namespace, + value.table, + value.id, + DeadField { + name: value.name, + type_def: value.type_def, + }, + ) } } diff --git a/crates/introspect-sql-sink/src/runtime.rs b/crates/introspect-sql-sink/src/runtime.rs new file mode 100644 index 00000000..4d6b7460 --- /dev/null +++ b/crates/introspect-sql-sink/src/runtime.rs @@ -0,0 +1,82 @@ +use crate::postgres::PostgresBackend; +use crate::sqlite::backend::SqliteBackend; +use crate::tables::Tables; +use crate::{ + DbColumn, DbDeadField, DbResult, DbTable, IntrospectInitialize, IntrospectProcessor, + NamespaceMode, +}; +use async_trait::async_trait; +use sqlx::{Postgres, Sqlite}; +use torii_introspect::events::IntrospectBody; +use torii_sql::DbConnection; + +pub enum RuntimeBackend { + Postgres(Pg), + Sqlite(Site), +} + +#[async_trait] +impl + IntrospectInitialize for RuntimeBackend +{ + async fn initialize(&self) -> DbResult<()> { + match self { + RuntimeBackend::Postgres(pg) => pg.initialize().await, + RuntimeBackend::Sqlite(site) => site.initialize().await, + } + } + async fn load_tables(&self, namespaces: &Option>) -> DbResult> { + match self { + RuntimeBackend::Postgres(pg) => pg.load_tables(namespaces).await, + RuntimeBackend::Sqlite(site) => site.load_tables(namespaces).await, + } + } + async fn load_columns(&self, namespaces: &Option>) -> DbResult> { + match self { + RuntimeBackend::Postgres(pg) => pg.load_columns(namespaces).await, + RuntimeBackend::Sqlite(site) => site.load_columns(namespaces).await, + } + } + async fn load_dead_fields( + &self, + namespaces: &Option>, + ) -> DbResult> { + match self { + RuntimeBackend::Postgres(pg) => pg.load_dead_fields(namespaces).await, + RuntimeBackend::Sqlite(site) => site.load_dead_fields(namespaces).await, + } + } +} + +#[async_trait] +impl + IntrospectProcessor for RuntimeBackend +{ + async fn process_msgs( + &self, + tables: &Tables, + namespaces: &NamespaceMode, + msgs: Vec<&IntrospectBody>, + ) -> DbResult>> { + match self { + RuntimeBackend::Postgres(pg) => pg.process_msgs(tables, namespaces, msgs).await, + RuntimeBackend::Sqlite(site) => site.process_msgs(tables, namespaces, msgs).await, + } + } +} + +impl, Site> From> + for RuntimeBackend, Site> +{ + fn from(pg: PostgresBackend) -> Self { + RuntimeBackend::Postgres(pg) + } +} + +impl, Pg> From> + for RuntimeBackend> +{ + fn from(site: SqliteBackend) -> Self { + RuntimeBackend::Sqlite(site) + } +} diff --git a/crates/introspect-sql-sink/src/schema.rs b/crates/introspect-sql-sink/src/schema.rs deleted file mode 100644 index ce96b696..00000000 --- a/crates/introspect-sql-sink/src/schema.rs +++ /dev/null @@ -1,188 +0,0 @@ -use crate::error::{SchemaError, SchemaResult}; -use crate::utils::felt_to_schema; -use crate::{DbError, DbResult}; -use introspect_types::ResultInto; -use itertools::Itertools; -use starknet_types_core::felt::Felt; -use std::collections::{HashMap, HashSet}; -use std::fmt::Display; -use std::hash::{Hash, Hasher}; -use std::sync::Arc; - -pub enum SchemaMode { - Single(Arc), - Address, - Named(HashMap>), - Addresses(HashSet), -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TableKey { - schema: SchemaKey, - id: Felt, -} - -impl TableKey { - pub fn new(schema: SchemaKey, id: Felt) -> Self { - Self { schema, id } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum SchemaKey { - Single(Arc), - Address(Felt), - Named(Arc), -} - -impl Hash for TableKey { - fn hash(&self, state: &mut H) { - self.schema.hash(state); - self.id.hash(state); - } -} - -impl Hash for SchemaKey { - fn hash(&self, state: &mut H) { - match self { - SchemaKey::Address(addr) => addr.hash(state), - SchemaKey::Named(name) => name.hash(state), - SchemaKey::Single(_) => {} - } - } -} - -impl Display for SchemaKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - SchemaKey::Address(addr) => write!(f, "{addr:063x}"), - SchemaKey::Named(name) | SchemaKey::Single(name) => name.fmt(f), - } - } -} - -impl Display for TableKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if !matches!(self.schema, SchemaKey::Single(_)) { - write!(f, "{} ", self.schema)?; - } - write!(f, "{:#063x}", self.id) - } -} - -impl From for SchemaMode { - fn from(value: String) -> Self { - SchemaMode::Single(value.into()) - } -} - -impl From<&str> for SchemaMode { - fn from(value: &str) -> Self { - SchemaMode::Single(value.into()) - } -} - -impl From> for SchemaMode { - fn from(value: HashMap) -> Self { - SchemaMode::Named( - value - .into_iter() - .map(|(k, v)| (k, v.into())) - .collect::>(), - ) - } -} - -impl From<[(Felt, &str); N]> for SchemaMode { - fn from(value: [(Felt, &str); N]) -> Self { - SchemaMode::Named( - value - .into_iter() - .map(|(k, v)| (k, v.into())) - .collect::>(), - ) - } -} - -impl From<[(Felt, String); N]> for SchemaMode { - fn from(value: [(Felt, String); N]) -> Self { - SchemaMode::Named( - value - .into_iter() - .map(|(k, v)| (k, v.into())) - .collect::>(), - ) - } -} - -impl From<[Felt; N]> for SchemaMode { - fn from(value: [Felt; N]) -> Self { - SchemaMode::Addresses(value.into_iter().collect()) - } -} - -impl From> for SchemaMode { - fn from(value: Vec) -> Self { - SchemaMode::Addresses(value.into_iter().collect()) - } -} - -fn felt_try_from_schema(schema: &str) -> SchemaResult { - match schema.len() == 63 { - true => Felt::from_hex(schema).err_into(), - false => Err(SchemaError::InvalidAddressLength(schema.to_string())), - } -} - -impl SchemaMode { - pub fn schemas(&self) -> Option>> { - match self { - SchemaMode::Single(name) => Some(vec![name.clone()]), - SchemaMode::Address => None, - SchemaMode::Named(map) => Some(map.values().cloned().collect()), - SchemaMode::Addresses(set) => Some(set.iter().map(felt_to_schema).map_into().collect()), - } - } - - pub fn get_schema_key(&self, schema: String, owner: &Felt) -> SchemaResult { - match self { - SchemaMode::Single(s) => match **s == *schema { - true => Ok(SchemaKey::Single(s.clone())), - false => Err(SchemaError::SchemaMismatch(schema, s.to_string())), - }, - SchemaMode::Address => felt_try_from_schema(&schema).map(SchemaKey::Address), - SchemaMode::Named(map) => match map.get(owner) { - Some(s) if **s == *schema => Ok(SchemaKey::Named(s.clone())), - Some(s) => Err(SchemaError::SchemaMismatch(schema, s.to_string())), - None => Err(SchemaError::AddressNotFound(*owner, schema)), - }, - SchemaMode::Addresses(set) => { - let address = felt_try_from_schema(&schema)?; - match set.contains(&address) { - true => Ok(SchemaKey::Address(address)), - false => Err(SchemaError::AddressNotFound(address, schema)), - } - } - } - } - - pub fn get_key(&self, schema: String, id: Felt, owner: &Felt) -> SchemaResult { - self.get_schema_key(schema, owner) - .map(|k| TableKey::new(k, id)) - } - - pub fn to_schema(&self, from_address: &Felt) -> DbResult { - match self { - SchemaMode::Single(name) => Ok(SchemaKey::Single(name.clone())), - SchemaMode::Address => Ok(SchemaKey::Address(*from_address)), - SchemaMode::Named(map) => match map.get(from_address) { - Some(schema) => Ok(SchemaKey::Named(schema.clone())), - None => Err(DbError::SchemaNotFound(*from_address)), - }, - SchemaMode::Addresses(set) => match set.contains(from_address) { - true => Ok(SchemaKey::Address(*from_address)), - false => Err(DbError::SchemaNotFound(*from_address)), - }, - } - } -} diff --git a/crates/introspect-sql-sink/src/sink.rs b/crates/introspect-sql-sink/src/sink.rs index 8fd0afa8..d399d57c 100644 --- a/crates/introspect-sql-sink/src/sink.rs +++ b/crates/introspect-sql-sink/src/sink.rs @@ -2,21 +2,26 @@ use anyhow::Result; use async_trait::async_trait; use std::sync::Arc; use torii::axum::Router; -use torii::etl::{ - envelope::{Envelope, TypeId}, - extractor::ExtractionBatch, - sink::{EventBus, Sink, SinkContext, TopicInfo}, -}; +use torii::etl::envelope::{Envelope, TypeId}; +use torii::etl::extractor::ExtractionBatch; +use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; use torii_introspect::events::{IntrospectBody, IntrospectMsg}; -use torii_postgres::PostgresConnection; -pub const LOGGING_TARGET: &str = "torii::sinks::introspect::postgres"; +use crate::{IntrospectDb, IntrospectInitialize, IntrospectProcessor}; + +pub const LOGGING_TARGET: &str = "torii::sinks::introspect-sql"; const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); +pub trait IntrospectSqlSink { + const NAME: &'static str; +} + #[async_trait] -impl Sink for IntrospectPgDb { +impl Sink + for IntrospectDb +{ fn name(&self) -> &'static str { - "introspect-postgres" + Backend::NAME } fn interested_types(&self) -> Vec { @@ -91,10 +96,11 @@ impl Sink for IntrospectPgDb { _event_bus: Arc, _context: &SinkContext, ) -> Result<()> { - self.initialize_introspect_pg_sink().await?; + self.initialize_introspect_sql_sink().await?; tracing::info!( target: LOGGING_TARGET, - "Initialized introspect Postgres sink" + "Connected to introspect SQL sink with database: {}", + Backend::NAME ); Ok(()) } diff --git a/crates/introspect-sql-sink/src/sqlite/backend.rs b/crates/introspect-sql-sink/src/sqlite/backend.rs new file mode 100644 index 00000000..c10576b8 --- /dev/null +++ b/crates/introspect-sql-sink/src/sqlite/backend.rs @@ -0,0 +1,142 @@ +use crate::{ + DbColumn, DbDeadField, DbResult, DbTable, DeadField, IntrospectDb, IntrospectInitialize, + IntrospectQueryMaker, IntrospectSqlSink, RecordResult, Table, TableResult, +}; +use async_trait::async_trait; +use introspect_types::{ColumnDef, ColumnInfo, PrimaryDef, ResultInto}; +use itertools::Itertools; +use sqlx::prelude::FromRow; +use sqlx::types::Json; +use starknet_types_core::felt::{Felt, FromStrError}; +use std::collections::HashMap; +use torii_introspect::tables::RecordSchema; +use torii_introspect::Record; +use torii_sql::{DbConnection, Queries, Sqlite, SqlitePool, SqliteQuery}; + +use super::query::create_table_query; + +pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: sqlx::migrate::Migrator = + sqlx::migrate!("./migrations/sqlite"); + +pub type IntrospectSqliteDb = IntrospectDb>; + +pub struct SqliteBackend>(T); + +impl> From for SqliteBackend { + fn from(value: T) -> Self { + SqliteBackend(value) + } +} + +impl> DbConnection for SqliteBackend { + fn pool(&self) -> &SqlitePool { + self.0.pool() + } +} + +#[derive(FromRow)] +pub struct SqliteTableRow { + namespace: String, + id: String, + owner: String, + name: String, + primary: Json, + columns: Json>, + dead: Json>, + alive: bool, +} + +impl TryFrom for DbTable { + type Error = FromStrError; + fn try_from(value: SqliteTableRow) -> Result { + Ok(DbTable { + namespace: value.namespace, + id: Felt::from_hex(&value.id)?, + owner: Felt::from_hex(&value.owner)?, + name: value.name, + primary: value.primary.0, + columns: value.columns.0.into_iter().map_into().collect(), + dead: value.dead.0.into_iter().map_into().collect(), + alive: value.alive, + }) + } +} + +#[async_trait] +impl + Send + Sync> IntrospectQueryMaker for SqliteBackend { + type DB = Sqlite; + fn create_table_queries( + namespace: &str, + _id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + _from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + queries: &mut Vec, + ) -> TableResult<()> { + queries.add(create_table_query(namespace, name, primary, columns)); + Ok(()) + } + fn update_table_queries( + _table: &mut Table, + _name: &str, + _primary: &PrimaryDef, + _columns: &[ColumnDef], + _from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + _queries: &mut Vec, + ) -> TableResult<()> { + Ok(()) + } + fn insert_record_queries( + _namespace: &str, + _table_name: &str, + _schema: &RecordSchema<'_>, + _records: &[Record], + _from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + _queries: &mut Vec, + ) -> RecordResult<()> { + Ok(()) + } +} + +impl> IntrospectSqlSink for SqliteBackend { + const NAME: &'static str = "Introspect Sqlite"; +} + +#[async_trait] +impl + Send + Sync> IntrospectInitialize for SqliteBackend { + async fn load_tables(&self, _schemas: &Option>) -> DbResult> { + let rows: Vec = sqlx::query_as( + r" + SELECT namespace, id, owner, name, primary, columns, dead, alive + FROM introspect_sink_schema_state + ORDER BY updated_at ASC + ", + ) + .fetch_all(self.pool()) + .await?; + + let tables: Vec = rows + .into_iter() + .map(|row| row.try_into()) + .collect::>()?; + Ok(tables) + } + async fn load_columns(&self, _schemas: &Option>) -> DbResult> { + Ok(Vec::new()) + } + async fn load_dead_fields(&self, _schemas: &Option>) -> DbResult> { + Ok(Vec::new()) + } + async fn initialize(&self) -> DbResult<()> { + self.migrate(Some("introspect"), INTROSPECT_SQLITE_SINK_MIGRATIONS) + .await + .err_into() + } +} diff --git a/crates/introspect-sql-sink/src/sqlite/json.rs b/crates/introspect-sql-sink/src/sqlite/json.rs new file mode 100644 index 00000000..64c4668e --- /dev/null +++ b/crates/introspect-sql-sink/src/sqlite/json.rs @@ -0,0 +1,83 @@ +use introspect_types::serialize::ToCairoDeSeFrom; +use introspect_types::serialize_def::CairoTypeSerialization; +use introspect_types::{CairoDeserializer, ResultDef, TupleDef, TypeDef}; +use serde::ser::SerializeMap; +use serde::Serializer; + +pub struct SqliteJsonSerializer; + +impl CairoTypeSerialization for SqliteJsonSerializer { + fn serialize_byte_array( + &self, + serializer: S, + value: &[u8], + ) -> Result { + serializer.serialize_str(&format!("0x{}", hex::encode(value))) + } + + fn serialize_felt( + &self, + serializer: S, + value: &[u8; 32], + ) -> Result { + self.serialize_byte_array(serializer, value) + } + + fn serialize_eth_address( + &self, + serializer: S, + value: &[u8; 20], + ) -> Result { + self.serialize_byte_array(serializer, value) + } + + fn serialize_tuple<'a, S: Serializer>( + &'a self, + data: &mut impl CairoDeserializer, + serializer: S, + tuple: &'a TupleDef, + ) -> Result { + let mut seq = serializer.serialize_map(Some(tuple.elements.len()))?; + for (index, element) in tuple.elements.iter().enumerate() { + seq.serialize_entry(&format!("_{index}"), &element.to_de_se(data, self))?; + } + seq.end() + } + + fn serialize_variant<'a, S: Serializer>( + &'a self, + data: &mut impl CairoDeserializer, + serializer: S, + name: &str, + type_def: &'a TypeDef, + ) -> Result { + if type_def == &TypeDef::None { + let mut map = serializer.serialize_map(Some(1))?; + map.serialize_entry("variant", name)?; + map + } else { + let mut map = serializer.serialize_map(Some(2))?; + map.serialize_entry("variant", name)?; + map.serialize_entry(&format!("_{name}"), &type_def.to_de_se(data, self))?; + map + } + .end() + } + + fn serialize_result<'a, S: Serializer>( + &'a self, + data: &mut impl CairoDeserializer, + serializer: S, + result: &'a ResultDef, + is_ok: bool, + ) -> Result { + let mut map = serializer.serialize_map(Some(1))?; + map.serialize_entry("is_ok", &is_ok)?; + if is_ok { + map.serialize_entry("Ok", &result.ok.to_de_se(data, self))?; + } else { + map.serialize_entry("Err", &result.err.to_de_se(data, self))?; + } + map.end() + } +} diff --git a/crates/introspect-sql-sink/src/sqlite/mod.rs b/crates/introspect-sql-sink/src/sqlite/mod.rs new file mode 100644 index 00000000..265fc5e1 --- /dev/null +++ b/crates/introspect-sql-sink/src/sqlite/mod.rs @@ -0,0 +1,6 @@ +pub mod backend; +pub mod json; +pub mod query; +use sqlx::migrate::Migrator; + +pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: Migrator = sqlx::migrate!("./migrations"); diff --git a/crates/introspect-sql-sink/src/sqlite/processor.rs b/crates/introspect-sql-sink/src/sqlite/processor.rs new file mode 100644 index 00000000..f655e432 --- /dev/null +++ b/crates/introspect-sql-sink/src/sqlite/processor.rs @@ -0,0 +1,396 @@ +use crate::json::SqliteJsonSerializer; +use crate::table::{SqliteTable, SqliteTableError}; +use crate::INTROSPECT_SQLITE_SINK_MIGRATIONS; +use introspect_types::{ColumnDef, PrimaryDef}; +use serde_json::{Serializer as JsonSerializer, Value}; +use sqlx::{Error as SqlxError, Row, Sqlite}; +use starknet_types_core::felt::Felt; +use std::collections::HashMap; +use std::fmt::Display; +use std::ops::Deref; +use std::sync::{PoisonError, RwLock}; +use torii::etl::envelope::MetaData; +use torii_introspect::events::{IntrospectBody, IntrospectMsg}; +use torii_introspect::schema::TableSchema; +use torii_introspect::InsertsFields; +use torii_introspect_sql_sink::{table, Table}; +use torii_sql::DbConnection; + +#[derive(Debug, thiserror::Error)] +pub enum SqliteDbError { + #[error(transparent)] + DatabaseError(#[from] SqlxError), + #[error(transparent)] + JsonError(#[from] serde_json::Error), + #[error(transparent)] + TableError(#[from] SqliteTableError), + #[error("record frame must serialize to an object")] + InvalidRecordFrame, + #[error("Table with id: {0} already exists, incoming name: {1}, existing name: {2}")] + TableAlreadyExists(Felt, String, String), + #[error("Table not found with id: {0}")] + TableNotFound(Felt), + #[error("Table poison error: {0}")] + PoisonError(String), +} + +type SqliteDbResult = std::result::Result; + +impl From> for SqliteDbError { + fn from(err: PoisonError) -> Self { + Self::PoisonError(err.to_string()) + } +} + +#[derive(Debug, Default)] +pub struct SqliteTables(pub RwLock>); + +impl Deref for SqliteTables { + type Target = RwLock>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Clone, Default)] +pub enum SqliteNamespace { + #[default] + None, + Custom(String), +} + +impl SqliteNamespace { + pub fn prefix(&self) -> &str { + match self { + Self::None => "", + Self::Custom(prefix) => prefix, + } + } +} + +impl From<()> for SqliteNamespace { + fn from((): ()) -> Self { + Self::None + } +} + +impl From for SqliteNamespace { + fn from(value: String) -> Self { + if value.is_empty() { + Self::None + } else { + Self::Custom(value) + } + } +} + +impl From<&str> for SqliteNamespace { + fn from(value: &str) -> Self { + if value.is_empty() { + Self::None + } else { + Self::Custom(value.to_string()) + } + } +} + +impl Display for SqliteNamespace { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::None => f.write_str("main"), + Self::Custom(prefix) => f.write_str(prefix), + } + } +} + +impl SqliteTables { + pub fn assert_table_not_exists(&self, id: &Felt, name: &str) -> SqliteDbResult<()> { + match self.read()?.get(id) { + Some(existing) => Err(SqliteDbError::TableAlreadyExists( + *id, + name.to_string(), + existing.name.clone(), + )), + None => Ok(()), + } + } + + pub fn create_table( + &self, + namespace: &SqliteNamespace, + to_table: impl Into, + ) -> SqliteDbResult<(Felt, String)> { + let table = to_table.into(); + self.assert_table_not_exists(&table.id, &table.name)?; + let (id, sqlite_table) = SqliteTable::new_from_table(namespace.prefix(), table); + let create_query = create_table_query(&sqlite_table); + self.write()?.insert(id, sqlite_table); + Ok((id, create_query)) + } + + pub fn set_table_dead(&self, id: &Felt) -> SqliteDbResult<()> { + if let Some(table) = self.write()?.get_mut(id) { + table.alive = false; + return Ok(()); + } + Err(SqliteDbError::TableNotFound(*id)) + } +} + +fn create_table_query( + namespace: &str, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], +) -> String { + let mut columns_sql = Vec::with_capacity(columns.len() + 1); + columns_sql.push(format!(r#""{}" TEXT PRIMARY KEY"#, primary.name)); + for column in columns { + columns_sql.push(format!(r#""{}" TEXT"#, column.name)); + } + format!( + r#"CREATE TABLE IF NOT EXISTS "{}" ({});"#, + table_name(&namespace, name), + columns_sql.join(", ") + ) +} + +fn serialize_sqlite_value(value: &Value) -> Option { + match value { + Value::Null => None, + Value::String(value) => Some(value.clone()), + _ => Some(value.to_string()), + } +} + +pub struct IntrospectSqliteDb { + tables: SqliteTables, + namespace: SqliteNamespace, + pool: T, +} + +impl> DbConnection for IntrospectSqliteDb { + fn pool(&self) -> &sqlx::SqlitePool { + self.pool.pool() + } +} + +impl + Send + Sync> IntrospectSqliteDb { + pub fn new(pool: T, namespace: impl Into) -> Self { + Self { + tables: SqliteTables::default(), + namespace: namespace.into(), + pool, + } + } + + pub async fn initialize_introspect_sqlite_sink(&self) -> SqliteDbResult<()> { + self.migrate(Some("introspect"), INTROSPECT_SQLITE_SINK_MIGRATIONS) + .await?; + self.load_persisted_state().await?; + Ok(()) + } + + async fn load_persisted_state(&self) -> SqliteDbResult<()> { + let rows = sqlx::query( + r" + SELECT table_schema_json, alive + FROM introspect_sink_schema_state + ORDER BY updated_at ASC + ", + ) + .fetch_all(self.pool()) + .await?; + + let mut tables = self.tables.write()?; + for row in rows { + let schema_json: String = row.try_get("table_schema_json")?; + let alive: i64 = row.try_get("alive")?; + let table_schema: TableSchema = serde_json::from_str(&schema_json)?; + let (id, mut table) = + SqliteTable::new_from_table(self.namespace.prefix(), table_schema); + table.alive = alive != 0; + tables.insert(id, table); + } + + Ok(()) + } + + async fn persist_table_state(&self, table: &TableSchema, alive: bool) -> SqliteDbResult<()> { + let schema_json = serde_json::to_string(table)?; + let alive = i64::from(alive); + sqlx::query( + r" + INSERT INTO introspect_sink_schema_state (table_id, table_schema_json, alive, updated_at) + VALUES (?1, ?2, ?3, unixepoch()) + ON CONFLICT (table_id) + DO UPDATE SET + table_schema_json = excluded.table_schema_json, + alive = excluded.alive, + updated_at = unixepoch() + ", + ) + .bind(format!("{:#x}", table.id)) + .bind(schema_json) + .bind(alive) + .execute(self.pool()) + .await?; + Ok(()) + } + + async fn persist_alive_state(&self, table_id: Felt, alive: bool) -> SqliteDbResult<()> { + let alive = i64::from(alive); + sqlx::query( + r" + UPDATE introspect_sink_schema_state + SET alive = ?1, updated_at = unixepoch() + WHERE table_id = ?2 + ", + ) + .bind(alive) + .bind(format!("{table_id:#x}")) + .execute(self.pool()) + .await?; + Ok(()) + } + + pub fn load_tables_no_commit(&self, table_schemas: Vec) -> SqliteDbResult<()> { + let mut tables = self.tables.write()?; + for table in table_schemas { + let (id, sqlite_table) = SqliteTable::new_from_table(self.namespace.prefix(), table); + tables.insert(id, sqlite_table); + } + Ok(()) + } + + pub async fn process_message( + &self, + msg: &IntrospectMsg, + metadata: &MetaData, + ) -> SqliteDbResult<()> { + match msg { + IntrospectMsg::CreateTable(event) => { + let (_, query) = self.tables.create_table(&self.namespace, event.clone())?; + self.execute_queries(&[query]).await?; + self.persist_table_state(&event.clone().into(), true) + .await?; + Ok(()) + } + IntrospectMsg::UpdateTable(event) => { + self.tables.set_table_dead(&event.id)?; + self.persist_alive_state(event.id, false).await + } + IntrospectMsg::AddColumns(event) => { + self.tables.set_table_dead(&event.table)?; + self.persist_alive_state(event.table, false).await + } + IntrospectMsg::DropColumns(event) => { + self.tables.set_table_dead(&event.table)?; + self.persist_alive_state(event.table, false).await + } + IntrospectMsg::RetypeColumns(event) => { + self.tables.set_table_dead(&event.table)?; + self.persist_alive_state(event.table, false).await + } + IntrospectMsg::RetypePrimary(event) => { + self.tables.set_table_dead(&event.table)?; + self.persist_alive_state(event.table, false).await + } + IntrospectMsg::RenameTable(_) + | IntrospectMsg::DropTable(_) + | IntrospectMsg::RenameColumns(_) + | IntrospectMsg::RenamePrimary(_) + | IntrospectMsg::DeleteRecords(_) + | IntrospectMsg::DeletesFields(_) => Ok(()), + IntrospectMsg::InsertsFields(event) => self.insert_fields(event, metadata).await, + } + } + + pub async fn process_messages( + &self, + msgs: Vec<&IntrospectBody>, + ) -> SqliteDbResult>> { + let mut results = Vec::with_capacity(msgs.len()); + for body in msgs { + let (msg, metadata) = body.into(); + results.push(self.process_message(msg, metadata).await); + } + Ok(results) + } + + async fn insert_fields( + &self, + event: &InsertsFields, + _metadata: &MetaData, + ) -> SqliteDbResult<()> { + let table = self + .tables + .read()? + .get(&event.table) + .ok_or(SqliteDbError::TableNotFound(event.table))? + .clone(); + if !table.alive { + return Ok(()); + } + + let record_schema = table.get_schema(&event.columns)?; + let column_names = std::iter::once(table.primary.name.as_str()) + .chain( + event + .columns + .iter() + .map(|id| table.columns[id].name.as_str()), + ) + .collect::>(); + + let update_columns = column_names + .iter() + .skip(1) + .map(|name| { + format!( + r#""{name}" = COALESCE(excluded."{name}", "{table_name}"."{name}")"#, + table_name = table.storage_name + ) + }) + .collect::>() + .join(", "); + + let sql = format!( + r#"INSERT INTO "{}" ({}) VALUES ({}) ON CONFLICT("{}") DO UPDATE SET {}"#, + table.storage_name, + column_names + .iter() + .map(|name| format!(r#""{name}""#)) + .collect::>() + .join(", "), + vec!["?"; column_names.len()].join(", "), + table.primary.name, + update_columns + ); + + let mut bytes = Vec::new(); + let mut serializer = JsonSerializer::new(&mut bytes); + record_schema.parse_records_with_metadata( + &event.records, + &(), + &mut serializer, + &SqliteJsonSerializer, + )?; + let rows = serde_json::from_slice::>(&bytes)?; + + let mut tx = self.begin().await?; + for value in rows { + let object = value.as_object().ok_or(SqliteDbError::InvalidRecordFrame)?; + + let mut query = sqlx::query(&sql); + for column_name in &column_names { + let value = object.get(*column_name).and_then(serialize_sqlite_value); + query = query.bind(value); + } + query.execute(&mut *tx).await?; + } + tx.commit().await?; + Ok(()) + } +} diff --git a/crates/introspect-sql-sink/src/sqlite/query.rs b/crates/introspect-sql-sink/src/sqlite/query.rs new file mode 100644 index 00000000..49a6a000 --- /dev/null +++ b/crates/introspect-sql-sink/src/sqlite/query.rs @@ -0,0 +1,23 @@ +use introspect_types::{ColumnDef, PrimaryDef}; + +pub fn create_table_query( + namespace: &str, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], +) -> String { + let mut columns_sql = Vec::with_capacity(columns.len() + 1); + columns_sql.push(format!(r#""{}" TEXT PRIMARY KEY"#, primary.name)); + for column in columns { + columns_sql.push(format!(r#""{}" TEXT"#, column.name)); + } + format!( + r#"CREATE TABLE IF NOT EXISTS "{}" ({});"#, + table_name(&namespace, name), + columns_sql.join(", ") + ) +} + +pub fn table_name(namespace: &str, name: &str) -> String { + format!("{namespace}__{name}") +} diff --git a/crates/introspect-postgres-sink/src/sink.rs b/crates/introspect-sql-sink/src/sqlite/sink.rs similarity index 83% rename from crates/introspect-postgres-sink/src/sink.rs rename to crates/introspect-sql-sink/src/sqlite/sink.rs index d33b260b..fc0b2717 100644 --- a/crates/introspect-postgres-sink/src/sink.rs +++ b/crates/introspect-sql-sink/src/sqlite/sink.rs @@ -1,32 +1,31 @@ -use crate::processor::IntrospectPgDb; +use crate::processor::IntrospectSqliteDb; use anyhow::Result; use async_trait::async_trait; +use sqlx::Sqlite; use std::sync::Arc; use torii::axum::Router; -use torii::etl::{ - envelope::{Envelope, TypeId}, - extractor::ExtractionBatch, - sink::{EventBus, Sink, SinkContext, TopicInfo}, -}; +use torii::etl::envelope::{Envelope, TypeId}; +use torii::etl::extractor::ExtractionBatch; +use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; use torii_introspect::events::{IntrospectBody, IntrospectMsg}; -use torii_postgres::PostgresConnection; +use torii_sql::DbConnection; -pub const LOGGING_TARGET: &str = "torii::sinks::introspect::postgres"; +pub const LOGGING_TARGET: &str = "torii::sinks::introspect::sqlite"; const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); #[async_trait] -impl Sink for IntrospectPgDb { +impl> Sink for IntrospectSqliteDb { fn name(&self) -> &'static str { - "introspect-postgres" + "introspect-sqlite" } fn interested_types(&self) -> Vec { - vec![INTROSPECT_TYPE] + vec![TypeId::new("introspect")] } async fn process(&self, envelopes: &[Envelope], _batch: &ExtractionBatch) -> Result<()> { let mut processed = 0usize; - let mut create_tables: usize = 0usize; + let mut create_tables = 0usize; let mut update_tables = 0usize; let mut inserts_fields = 0usize; let mut inserted_records = 0usize; @@ -53,6 +52,7 @@ impl Sink for IntrospectPgDb { } } self.process_messages(msgs).await?; + if processed > 0 { tracing::info!( target: LOGGING_TARGET, @@ -92,10 +92,10 @@ impl Sink for IntrospectPgDb { _event_bus: Arc, _context: &SinkContext, ) -> Result<()> { - self.initialize_introspect_pg_sink().await?; + self.initialize_introspect_sqlite_sink().await?; tracing::info!( target: LOGGING_TARGET, - "Initialized introspect Postgres sink" + "Initialized introspect SQLite sink" ); Ok(()) } diff --git a/crates/introspect-sql-sink/src/sqlite/table.rs b/crates/introspect-sql-sink/src/sqlite/table.rs new file mode 100644 index 00000000..14b7a559 --- /dev/null +++ b/crates/introspect-sql-sink/src/sqlite/table.rs @@ -0,0 +1,70 @@ +use introspect_types::{ColumnDef, ColumnInfo, FeltIds, PrimaryDef}; +use itertools::Itertools; +use starknet_types_core::felt::Felt; +use std::collections::HashMap; +use thiserror::Error; +use torii_introspect::schema::TableSchema; +use torii_introspect::tables::RecordSchema; + +#[derive(Debug, Error)] +pub enum SqliteTableError { + #[error("Column with id: {0} not found in table {1}")] + ColumnNotFound(Felt, String), +} + +pub type TableResult = std::result::Result; + +#[derive(Debug, Clone)] +pub struct SqliteTable { + pub name: String, + pub storage_name: String, + pub primary: PrimaryDef, + pub columns: HashMap, + pub order: Vec, + pub alive: bool, +} + +impl SqliteTable { + pub fn new( + storage_name: String, + name: String, + primary: PrimaryDef, + columns: Vec, + ) -> Self { + Self { + name, + storage_name, + primary, + order: columns.ids(), + columns: columns.into_iter().map_into().collect(), + alive: true, + } + } + + pub fn new_from_table(namespace: &str, table: impl Into) -> (Felt, Self) { + let table = table.into(); + let storage_name = if namespace.is_empty() { + table.name.clone() + } else { + format!("{namespace}__{}", table.name) + }; + ( + table.id, + Self::new(storage_name, table.name, table.primary, table.columns), + ) + } + + pub fn get_column(&self, selector: &Felt) -> TableResult<&ColumnInfo> { + self.columns + .get(selector) + .ok_or_else(|| SqliteTableError::ColumnNotFound(*selector, self.name.clone())) + } + + pub fn get_schema(&self, column_ids: &[Felt]) -> TableResult> { + let columns = column_ids + .iter() + .map(|selector| self.get_column(selector)) + .collect::, _>>()?; + Ok(RecordSchema::new(&self.primary, columns)) + } +} diff --git a/crates/introspect-sql-sink/src/table.rs b/crates/introspect-sql-sink/src/table.rs index 49903c30..1f0c9ece 100644 --- a/crates/introspect-sql-sink/src/table.rs +++ b/crates/introspect-sql-sink/src/table.rs @@ -1,15 +1,17 @@ -use crate::{DbResult, TableError, TableResult}; -use introspect_types::{ColumnDef, ColumnInfo, MemberDef, PrimaryDef, TypeDef}; +use crate::{TableError, TableResult}; +use introspect_types::{ColumnInfo, MemberDef, PrimaryDef, TypeDef}; use itertools::Itertools; -use sqlx::Database; +use serde::{Deserialize, Serialize}; use starknet_types_core::felt::Felt; -use std::{collections::HashMap, rc::Rc}; -use torii_common::sql::FlexQuery; -use torii_introspect::{schema::TableInfo, tables::RecordSchema, Record}; +use std::collections::HashMap; +use std::rc::Rc; +use torii_introspect::schema::TableInfo; +use torii_introspect::tables::RecordSchema; #[derive(Debug)] -pub struct DbTable { - pub schema: String, +pub struct Table { + pub id: Felt, + pub namespace: String, pub name: String, pub owner: Felt, pub primary: PrimaryDef, @@ -18,12 +20,19 @@ pub struct DbTable { pub dead: HashMap, } -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub struct DeadField { pub name: String, pub type_def: TypeDef, } +#[derive(Debug)] +pub struct DeadFieldDef { + pub id: u128, + pub name: String, + pub type_def: TypeDef, +} + impl From for DeadField { fn from(value: MemberDef) -> Self { DeadField { @@ -43,46 +52,37 @@ impl From for MemberDef { } } -pub trait DbTableTrait { - fn create_table_queries( - &self, - id: &Felt, - order: &[Felt], - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec>, - ) -> DbResult<()>; - fn update_table_queries( - &mut self, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec>, - ) -> DbResult<()>; - fn insert_fields_queries( - &self, - columns: &[Felt], - records: &[Record], - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec>, - ) -> DbResult<()>; +impl From for (u128, DeadField) { + fn from(value: DeadFieldDef) -> Self { + ( + value.id, + DeadField { + name: value.name, + type_def: value.type_def, + }, + ) + } +} + +impl From<(u128, DeadField)> for DeadFieldDef { + fn from(value: (u128, DeadField)) -> Self { + DeadFieldDef { + id: value.0, + name: value.1.name, + type_def: value.1.type_def, + } + } } -impl DbTable { +impl Table { pub fn column(&self, id: &Felt) -> TableResult<&ColumnInfo> { self.columns .get(id) .ok_or_else(|| TableError::ColumnNotFound(*id, self.name.clone())) } - pub fn schema(&self) -> Rc { - self.schema.as_str().into() + pub fn namespace(&self) -> Rc { + self.namespace.as_str().into() } pub fn columns(&self, ids: &[Felt]) -> TableResult> { @@ -101,13 +101,15 @@ impl DbTable { } pub fn new( - schema: String, + id: Felt, + namespace: String, owner: Felt, info: TableInfo, dead: Option>, ) -> Self { - DbTable { - schema, + Table { + id, + namespace, owner, name: info.name, primary: info.primary, diff --git a/crates/introspect-sql-sink/src/tables.rs b/crates/introspect-sql-sink/src/tables.rs index e60b342c..b25f157e 100644 --- a/crates/introspect-sql-sink/src/tables.rs +++ b/crates/introspect-sql-sink/src/tables.rs @@ -1,90 +1,86 @@ -use crate::schema::{SchemaKey, TableKey}; -use crate::table::{DbTable, DbTableTrait}; +use crate::backend::IntrospectQueryMaker; +use crate::error::RecordResultExt; +use crate::namespace::{NamespaceKey, TableKey}; +use crate::table::Table; use crate::{DbError, DbResult}; -use introspect_types::FeltIds; -use sqlx::Database; +use introspect_types::ResultInto; use starknet_types_core::felt::Felt; use std::collections::HashMap; -use std::marker::PhantomData; use std::ops::Deref; use std::sync::RwLock; -use torii_common::sql::FlexQuery; use torii_introspect::events::IntrospectMsg; use torii_introspect::schema::TableSchema; use torii_introspect::InsertsFields; - -pub const DEAD_MEMBERS_TABLE: &str = "__introspect_dead_fields"; -pub const TABLES_TABLE: &str = "__introspect_tables"; -pub const COLUMNS_TABLE: &str = "__introspect_columns"; +use torii_sql::FlexQuery; #[derive(Debug, Default)] -pub struct DbTables(pub RwLock>, PhantomData); +pub struct Tables(pub RwLock>); -impl Deref for DbTables { - type Target = RwLock>; +impl Deref for Tables { + type Target = RwLock>; fn deref(&self) -> &Self::Target { &self.0 } } -impl DbTables -where - DB: Database, - DbTable: DbTableTrait, -{ - pub fn create_table( +impl Tables { + pub fn create_table( &self, - schema_key: SchemaKey, + namespace_key: NamespaceKey, to_table: impl Into, from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult<()> { let (id, info) = Into::::into(to_table).into(); - let schema = schema_key.to_string(); - let key = TableKey::new(schema_key, id); + let namespace = namespace_key.to_string(); + + let key = TableKey::new(namespace_key, id); self.assert_table_not_exists(&key, &info.name)?; - let order = info.columns.ids(); - let table = DbTable::new(schema, *from_address, info, None); - table.create_table_queries( + Backend::create_table_queries( + &namespace, &id, - &order, + &info.name, + &info.primary, + &info.columns, from_address, block_number, transaction_hash, queries, )?; let mut tables = self.write()?; - tables.insert(key, table); + tables.insert(key, Table::new(id, namespace, *from_address, info, None)); Ok(()) } - pub fn update_table( + pub fn update_table( &self, - schema_key: SchemaKey, + namespace_key: NamespaceKey, to_table: impl Into, from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult<()> { - let (id, table) = Into::::into(to_table).into(); + let (id, new) = Into::::into(to_table).into(); let mut tables = self.write()?; - let key = TableKey::new(schema_key, id); - let existing = tables + let key = TableKey::new(namespace_key, id); + let table = tables .get_mut(&key) .ok_or_else(|| DbError::TableNotFound(key.clone()))?; - existing.update_table_queries( - &table.name, - &table.primary, - &table.columns, + Backend::update_table_queries( + table, + &new.name, + &new.primary, + &new.columns, from_address, block_number, transaction_hash, queries, ) + .err_into() } pub fn assert_table_not_exists(&self, id: &TableKey, name: &str) -> DbResult<()> { @@ -98,9 +94,9 @@ where } } - pub fn set_table_dead(&self, schema: SchemaKey, id: Felt) -> DbResult<()> { + pub fn set_table_dead(&self, namespace: NamespaceKey, id: Felt) -> DbResult<()> { let mut tables = self.write()?; - let key = TableKey::new(schema, id); + let key = TableKey::new(namespace, id); match tables.get_mut(&key) { Some(table) => { table.alive = false; @@ -110,17 +106,17 @@ where } } - pub fn insert_fields( + pub fn insert_fields( &self, - schema: SchemaKey, + namespace: NamespaceKey, event: &InsertsFields, from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult<()> { let tables = self.read().unwrap(); - let key = TableKey::new(schema, event.table); + let key = TableKey::new(namespace, event.table); let table = match tables.get(&key) { Some(table) => Ok(table), None => Err(DbError::TableNotFound(key)), @@ -128,52 +124,56 @@ where if !table.alive { return Ok(()); } - table.insert_fields_queries( - &event.columns, + let schema = table.get_record_schema(&event.columns)?; + Backend::insert_record_queries( + &table.namespace, + &table.name, + &schema, &event.records, from_address, block_number, transaction_hash, queries, ) + .to_db_result(&table.name) } - pub fn handle_message( + pub fn handle_message( &self, - schema: SchemaKey, + namespace: NamespaceKey, msg: &IntrospectMsg, from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult<()> { match msg { - IntrospectMsg::CreateTable(event) => self.create_table( - schema, + IntrospectMsg::CreateTable(event) => self.create_table::( + namespace, event.clone(), from_address, block_number, transaction_hash, queries, ), - IntrospectMsg::UpdateTable(event) => self.update_table( - schema, + IntrospectMsg::UpdateTable(event) => self.update_table::( + namespace, event.clone(), from_address, block_number, transaction_hash, queries, ), - IntrospectMsg::AddColumns(event) => self.set_table_dead(schema, event.table), - IntrospectMsg::DropColumns(event) => self.set_table_dead(schema, event.table), - IntrospectMsg::RetypeColumns(event) => self.set_table_dead(schema, event.table), - IntrospectMsg::RetypePrimary(event) => self.set_table_dead(schema, event.table), + IntrospectMsg::AddColumns(event) => self.set_table_dead(namespace, event.table), + IntrospectMsg::DropColumns(event) => self.set_table_dead(namespace, event.table), + IntrospectMsg::RetypeColumns(event) => self.set_table_dead(namespace, event.table), + IntrospectMsg::RetypePrimary(event) => self.set_table_dead(namespace, event.table), IntrospectMsg::RenameTable(_) | IntrospectMsg::DropTable(_) | IntrospectMsg::RenameColumns(_) | IntrospectMsg::RenamePrimary(_) => Ok(()), - IntrospectMsg::InsertsFields(event) => self.insert_fields( - schema, + IntrospectMsg::InsertsFields(event) => self.insert_fields::( + namespace, event, from_address, block_number, diff --git a/crates/introspect-sqlite-sink/Cargo.toml b/crates/introspect-sqlite-sink/Cargo.toml index f0ad8059..508e8364 100644 --- a/crates/introspect-sqlite-sink/Cargo.toml +++ b/crates/introspect-sqlite-sink/Cargo.toml @@ -30,6 +30,7 @@ itertools.workspace = true torii-introspect.workspace = true torii-sql = { workspace = true, features = ["sqlite"] } +torii-introspect-sql-sink.workspace = true [lints] workspace = true diff --git a/crates/introspect-sqlite-sink/migrations/002_schema_state.sql b/crates/introspect-sqlite-sink/migrations/002_schema_state.sql index 83df4af8..6355d19d 100644 --- a/crates/introspect-sqlite-sink/migrations/002_schema_state.sql +++ b/crates/introspect-sqlite-sink/migrations/002_schema_state.sql @@ -1,8 +1,11 @@ CREATE TABLE IF NOT EXISTS introspect_sink_schema_state ( - "schema" TEXT NOT NULL, - table_id TEXT NOT NULL, - table_schema_json TEXT NOT NULL, + namespace TEXT NOT NULL, + id TEXT NOT NULL, + owner TEXT NOT NULL, + "primary" TEXT NOT NULL, + columns TEXT NOT NULL, + dead TEXT NOT NULL, alive INTEGER NOT NULL DEFAULT 1, updated_at INTEGER NOT NULL DEFAULT (unixepoch()), - PRIMARY KEY ("schema", table_id) + PRIMARY KEY (namespace, id) ); diff --git a/crates/introspect-sqlite-sink/src/backend.rs b/crates/introspect-sqlite-sink/src/backend.rs new file mode 100644 index 00000000..feb0f8c3 --- /dev/null +++ b/crates/introspect-sqlite-sink/src/backend.rs @@ -0,0 +1,139 @@ +use async_trait::async_trait; +use introspect_types::{ColumnDef, ColumnInfo, PrimaryDef, ResultInto}; +use itertools::Itertools; +use sqlx::prelude::FromRow; +use sqlx::types::Json; +use starknet_types_core::felt::{Felt, FromStrError}; +use std::collections::HashMap; +use torii_introspect::tables::RecordSchema; +use torii_introspect::Record; +use torii_introspect_sql_sink::processor::IntrospectDb; +use torii_introspect_sql_sink::{ + DbColumn, DbDeadField, DbResult, DbTable, DeadField, IntrospectBackend, IntrospectSqlSink, + RecordResult, Table, TableResult, +}; +use torii_sql::{DbConnection, Queries, Sqlite, SqlitePool, SqliteQuery}; + +use crate::query::create_table_query; + +pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: sqlx::migrate::Migrator = + sqlx::migrate!("./migrations"); + +pub type IntrospectSqliteDb = IntrospectDb>; + +pub struct SqliteBackend>(T); + +impl> From for SqliteBackend { + fn from(value: T) -> Self { + SqliteBackend(value) + } +} + +impl> DbConnection for SqliteBackend { + fn pool(&self) -> &SqlitePool { + self.0.pool() + } +} + +#[derive(FromRow)] +pub struct SqliteTableRow { + namespace: String, + id: String, + owner: String, + name: String, + primary: Json, + columns: Json>, + dead: Json>, + alive: bool, +} + +impl TryFrom for DbTable { + type Error = FromStrError; + fn try_from(value: SqliteTableRow) -> Result { + Ok(DbTable { + namespace: value.namespace, + id: Felt::from_hex(&value.id)?, + owner: Felt::from_hex(&value.owner)?, + name: value.name, + primary: value.primary.0, + columns: value.columns.0.into_iter().map_into().collect(), + dead: value.dead.0.into_iter().map_into().collect(), + alive: value.alive, + }) + } +} + +#[async_trait] +impl + Send + Sync> IntrospectBackend for SqliteBackend { + type DB = Sqlite; + async fn load_tables(&self, _schemas: &Option>) -> DbResult> { + let rows: Vec = sqlx::query_as( + r" + SELECT namespace, id, owner, name, primary, columns, dead, alive + FROM introspect_sink_schema_state + ORDER BY updated_at ASC + ", + ) + .fetch_all(self.pool()) + .await?; + + let tables: Vec = rows + .into_iter() + .map(|row| row.try_into()) + .collect::>()?; + Ok(tables) + } + async fn load_columns(&self, _schemas: &Option>) -> DbResult> { + Ok(Vec::new()) + } + async fn load_dead_fields(&self, _schemas: &Option>) -> DbResult> { + Ok(Vec::new()) + } + async fn initialize(&self) -> DbResult<()> { + self.migrate(Some("introspect"), INTROSPECT_SQLITE_SINK_MIGRATIONS) + .await + .err_into() + } + fn create_table_queries( + namespace: &str, + _id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + _from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + queries: &mut Vec, + ) -> TableResult<()> { + queries.add(create_table_query(namespace, name, primary, columns)); + Ok(()) + } + fn update_table_queries( + _table: &mut Table, + _name: &str, + _primary: &PrimaryDef, + _columns: &[ColumnDef], + _from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + _queries: &mut Vec, + ) -> TableResult<()> { + Ok(()) + } + fn insert_record_queries( + _namespace: &str, + _table_name: &str, + _schema: &RecordSchema<'_>, + _records: &[Record], + _from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + _queries: &mut Vec, + ) -> RecordResult<()> { + Ok(()) + } +} + +impl> IntrospectSqlSink for SqliteBackend { + const NAME: &'static str = "Introspect Sqlite"; +} diff --git a/crates/introspect-sqlite-sink/src/lib.rs b/crates/introspect-sqlite-sink/src/lib.rs index ac41c665..265fc5e1 100644 --- a/crates/introspect-sqlite-sink/src/lib.rs +++ b/crates/introspect-sqlite-sink/src/lib.rs @@ -1,8 +1,6 @@ +pub mod backend; pub mod json; -pub mod processor; -pub mod sink; -pub mod table; - +pub mod query; use sqlx::migrate::Migrator; pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: Migrator = sqlx::migrate!("./migrations"); diff --git a/crates/introspect-sqlite-sink/src/processor.rs b/crates/introspect-sqlite-sink/src/processor.rs index 4eaaf92a..f655e432 100644 --- a/crates/introspect-sqlite-sink/src/processor.rs +++ b/crates/introspect-sqlite-sink/src/processor.rs @@ -1,9 +1,9 @@ use crate::json::SqliteJsonSerializer; use crate::table::{SqliteTable, SqliteTableError}; use crate::INTROSPECT_SQLITE_SINK_MIGRATIONS; +use introspect_types::{ColumnDef, PrimaryDef}; use serde_json::{Serializer as JsonSerializer, Value}; -use sqlx::Error as SqlxError; -use sqlx::Row; +use sqlx::{Error as SqlxError, Row, Sqlite}; use starknet_types_core::felt::Felt; use std::collections::HashMap; use std::fmt::Display; @@ -13,7 +13,8 @@ use torii::etl::envelope::MetaData; use torii_introspect::events::{IntrospectBody, IntrospectMsg}; use torii_introspect::schema::TableSchema; use torii_introspect::InsertsFields; -use torii_sqlite::SqliteConnection; +use torii_introspect_sql_sink::{table, Table}; +use torii_sql::DbConnection; #[derive(Debug, thiserror::Error)] pub enum SqliteDbError { @@ -137,17 +138,21 @@ impl SqliteTables { } } -fn create_table_query(table: &SqliteTable) -> String { - let mut columns = Vec::with_capacity(table.columns.len() + 1); - columns.push(format!(r#""{}" TEXT PRIMARY KEY"#, table.primary.name)); - for column_id in &table.order { - let column = &table.columns[column_id]; - columns.push(format!(r#""{}" TEXT"#, column.name)); +fn create_table_query( + namespace: &str, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], +) -> String { + let mut columns_sql = Vec::with_capacity(columns.len() + 1); + columns_sql.push(format!(r#""{}" TEXT PRIMARY KEY"#, primary.name)); + for column in columns { + columns_sql.push(format!(r#""{}" TEXT"#, column.name)); } format!( r#"CREATE TABLE IF NOT EXISTS "{}" ({});"#, - table.storage_name, - columns.join(", ") + table_name(&namespace, name), + columns_sql.join(", ") ) } @@ -165,13 +170,13 @@ pub struct IntrospectSqliteDb { pool: T, } -impl SqliteConnection for IntrospectSqliteDb { +impl> DbConnection for IntrospectSqliteDb { fn pool(&self) -> &sqlx::SqlitePool { self.pool.pool() } } -impl IntrospectSqliteDb { +impl + Send + Sync> IntrospectSqliteDb { pub fn new(pool: T, namespace: impl Into) -> Self { Self { tables: SqliteTables::default(), diff --git a/crates/introspect-sqlite-sink/src/query.rs b/crates/introspect-sqlite-sink/src/query.rs new file mode 100644 index 00000000..49a6a000 --- /dev/null +++ b/crates/introspect-sqlite-sink/src/query.rs @@ -0,0 +1,23 @@ +use introspect_types::{ColumnDef, PrimaryDef}; + +pub fn create_table_query( + namespace: &str, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], +) -> String { + let mut columns_sql = Vec::with_capacity(columns.len() + 1); + columns_sql.push(format!(r#""{}" TEXT PRIMARY KEY"#, primary.name)); + for column in columns { + columns_sql.push(format!(r#""{}" TEXT"#, column.name)); + } + format!( + r#"CREATE TABLE IF NOT EXISTS "{}" ({});"#, + table_name(&namespace, name), + columns_sql.join(", ") + ) +} + +pub fn table_name(namespace: &str, name: &str) -> String { + format!("{namespace}__{name}") +} diff --git a/crates/introspect-sqlite-sink/src/sink.rs b/crates/introspect-sqlite-sink/src/sink.rs index 53de7d7c..fc0b2717 100644 --- a/crates/introspect-sqlite-sink/src/sink.rs +++ b/crates/introspect-sqlite-sink/src/sink.rs @@ -1,21 +1,20 @@ use crate::processor::IntrospectSqliteDb; use anyhow::Result; use async_trait::async_trait; +use sqlx::Sqlite; use std::sync::Arc; use torii::axum::Router; -use torii::etl::{ - envelope::{Envelope, TypeId}, - extractor::ExtractionBatch, - sink::{EventBus, Sink, SinkContext, TopicInfo}, -}; +use torii::etl::envelope::{Envelope, TypeId}; +use torii::etl::extractor::ExtractionBatch; +use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; use torii_introspect::events::{IntrospectBody, IntrospectMsg}; -use torii_sqlite::SqliteConnection; +use torii_sql::DbConnection; pub const LOGGING_TARGET: &str = "torii::sinks::introspect::sqlite"; const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); #[async_trait] -impl Sink for IntrospectSqliteDb { +impl> Sink for IntrospectSqliteDb { fn name(&self) -> &'static str { "introspect-sqlite" } diff --git a/crates/postgres/Cargo.toml b/crates/postgres/Cargo.toml deleted file mode 100644 index c2ae223c..00000000 --- a/crates/postgres/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "torii-postgres" -version = "0.1.0" -edition = "2021" -description = "PostgreSQL utils for Torii runtime" -authors = ["Torii Runtime "] -license = "Apache-2.0" - -[dependencies] -sqlx = { workspace = true, features = [ - "postgres", - "runtime-tokio-rustls", - "macros", - "migrate", -] } -futures.workspace = true -torii-sql.workspace = true diff --git a/crates/postgres/src/lib.rs b/crates/postgres/src/lib.rs deleted file mode 100644 index 5ff2b5ce..00000000 --- a/crates/postgres/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod migration; -pub use db::PostgresConnection; diff --git a/crates/postgres/src/metadata.rs b/crates/postgres/src/metadata.rs deleted file mode 100644 index 3368b76c..00000000 --- a/crates/postgres/src/metadata.rs +++ /dev/null @@ -1,72 +0,0 @@ -use sqlx::{postgres::PgArguments, query::Query, Postgres}; -use std::fmt::Write; -use torii::etl::EventContext; - -pub const INSERTS: &str = "__created_block, __updated_block, __created_tx, __updated_tx"; -pub const CONFLICTS: &str = "__updated_at = NOW(), __updated_block = EXCLUDED.__updated_block, __updated_tx = EXCLUDED.__updated_tx"; - -pub trait PgMetadata { - fn insert_string( - &self, - schema: &str, - table: &str, - primary_name: &str, - primary_value: String, - ) -> String; - fn static_insert_query(schema: &str, table: &str, primary_name: &str) -> String { - format!( - r#" - INSERT INTO "{schema}"."{table}" ("{primary_name}", {INSERTS}) - VALUES ($1, $2, $2, $3, $3) - ON CONFLICT ({primary_name}) DO UPDATE SET {CONFLICTS}"# - ) - } - fn insert_values(&self, string: &mut String); - fn bind_query<'a>( - &self, - query: &'a str, - primary_value: String, - ) -> Query<'a, Postgres, PgArguments>; -} - -impl PgMetadata for EventContext { - fn insert_string( - &self, - schema: &str, - table: &str, - primary_name: &str, - primary_value: String, - ) -> String { - let mut string = format!( - r#"INSERT INTO "{schema}"."{table}" ("{primary_name}", {INSERTS}) VALUES ({primary_value}, "# - ); - self.insert_values(&mut string); - write!( - string, - ") ON CONFLICT ({primary_name}) DO UPDATE SET {CONFLICTS}" - ) - .unwrap(); - string - } - fn bind_query<'a>( - &self, - query: &'a str, - primary_value: String, - ) -> Query<'a, Postgres, PgArguments> { - let block_number = self.block.number.to_string(); - let tx_hash = self.transaction.hash.to_bytes_be(); - sqlx::query::(query) - .bind(primary_value.clone()) - .bind(block_number) - .bind(tx_hash) - } - fn insert_values(&self, string: &mut String) { - let block_number = self.block.number; - let tx_hash = hex::encode(self.transaction.hash.to_bytes_be()); - write!( - string, - "{block_number}, {block_number}, '\\x{tx_hash}', '\\x{tx_hash}'" - ) - .unwrap(); - } -} diff --git a/crates/postgres/src/migration.rs b/crates/postgres/src/migration.rs deleted file mode 100644 index 3c430c91..00000000 --- a/crates/postgres/src/migration.rs +++ /dev/null @@ -1,250 +0,0 @@ -use futures::future::BoxFuture; -use sqlx::{ - migrate::{AppliedMigration, Migrate, MigrateError, Migration, MigrationSource, Migrator}, - query, query_scalar, Acquire, Connection, Database, PgConnection, Postgres, -}; -use sqlx::{query_as, Executor}; -use std::{ - collections::{HashMap, HashSet}, - ops::{Deref, DerefMut}, - slice, - time::{Duration, Instant}, -}; -use torii_sql::AcquiredSchema; - -impl Migrate for AcquiredSchema -where - DB: Database, - C: Connection, -{ - fn ensure_migrations_table(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { - Box::pin(async move { - // language=SQL - self.connection - .execute( - format!( - r#" -CREATE SCHEMA IF NOT EXISTS {schema}; -CREATE TABLE IF NOT EXISTS {schema}._sqlx_migrations ( - version BIGINT PRIMARY KEY, - description TEXT NOT NULL, - installed_on TIMESTAMPTZ NOT NULL DEFAULT now(), - success BOOLEAN NOT NULL, - checksum BYTEA NOT NULL, - execution_time BIGINT NOT NULL -); - "#, - schema = self.schema - ) - .as_str(), - ) - .await?; - - Ok(()) - }) - } - - fn dirty_version(&mut self) -> BoxFuture<'_, Result, MigrateError>> { - Box::pin(async move { - // language=SQL - - let row: Option<(i64,)> = query_as( - format!("SELECT version FROM {schema}._sqlx_migrations WHERE success = false ORDER BY version LIMIT 1", schema = self.schema).as_str() - ) - .fetch_optional(&mut *self.connection) - .await?; - - Ok(row.map(|r: (i64,)| r.0)) - }) - } - - fn list_applied_migrations( - &mut self, - ) -> BoxFuture<'_, Result, MigrateError>> { - Box::pin(async move { - // language=SQL - let rows: Vec<(i64, Vec)> = query_as( - format!( - "SELECT version, checksum FROM {schema}._sqlx_migrations ORDER BY version", - schema = self.schema - ) - .as_str(), - ) - .fetch_all(&mut *self.connection) - .await?; - - let migrations = rows - .into_iter() - .map(|(version, checksum)| AppliedMigration { - version, - checksum: checksum.into(), - }) - .collect(); - - Ok(migrations) - }) - } - - fn lock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { - Box::pin(async move { - let database_name = current_database(&mut self.connection).await?; - let lock_id = generate_lock_id(&database_name); - - // create an application lock over the database - // this function will not return until the lock is acquired - - // https://www.postgresql.org/docs/current/explicit-locking.html#ADVISORY-LOCKS - // https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS-TABLE - - // language=SQL - let _ = query("SELECT pg_advisory_lock($1)") - .bind(lock_id) - .execute(&mut *self.connection) - .await?; - - Ok(()) - }) - } - - fn unlock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { - Box::pin(async move { - let database_name = current_database(self).await?; - let lock_id = generate_lock_id(&database_name); - - // language=SQL - let _ = query("SELECT pg_advisory_unlock($1)") - .bind(lock_id) - .execute(&mut *self.connection) - .await?; - - Ok(()) - }) - } - - fn apply<'e: 'm, 'm>( - &'e mut self, - migration: &'m Migration, - ) -> BoxFuture<'m, Result> { - Box::pin(async move { - let start = Instant::now(); - let schema = self.schema; - // execute migration queries - if migration.no_tx { - execute_migration(self, schema, migration).await?; - } else { - // Use a single transaction for the actual migration script and the essential bookeeping so we never - // execute migrations twice. See https://github.com/launchbadge/sqlx/issues/1966. - // The `execution_time` however can only be measured for the whole transaction. This value _only_ exists for - // data lineage and debugging reasons, so it is not super important if it is lost. So we initialize it to -1 - // and update it once the actual transaction completed. - let mut tx = self.begin().await?; - execute_migration(&mut tx, schema, migration).await?; - tx.commit().await?; - } - - // Update `elapsed_time`. - // NOTE: The process may disconnect/die at this point, so the elapsed time value might be lost. We accept - // this small risk since this value is not super important. - let elapsed = start.elapsed(); - - // language=SQL - #[allow(clippy::cast_possible_truncation)] - let _ = query(&format!( - r#" - UPDATE {schema}._sqlx_migrations - SET execution_time = $1 - WHERE version = $2 - "#, - schema = self.schema - )) - .bind(elapsed.as_nanos() as i64) - .bind(migration.version) - .execute(&mut *self.connection) - .await?; - - Ok(elapsed) - }) - } - - fn revert<'e: 'm, 'm>( - &'e mut self, - migration: &'m Migration, - ) -> BoxFuture<'m, Result> { - Box::pin(async move { - let start = Instant::now(); - let schema = self.schema; - // execute migration queries - if migration.no_tx { - revert_migration(&mut self.connection, schema, migration).await?; - } else { - // Use a single transaction for the actual migration script and the essential bookeeping so we never - // execute migrations twice. See https://github.com/launchbadge/sqlx/issues/1966. - let mut tx = self.begin().await?; - revert_migration(&mut tx, schema, migration).await?; - tx.commit().await?; - } - - let elapsed = start.elapsed(); - - Ok(elapsed) - }) - } -} - -async fn current_database(conn: &mut PgConnection) -> Result { - // language=SQL - Ok(query_scalar("SELECT current_database()") - .fetch_one(conn) - .await?) -} - -fn generate_lock_id(database_name: &str) -> i64 { - const CRC_IEEE: crc::Crc = crc::Crc::::new(&crc::CRC_32_ISO_HDLC); - // 0x3d32ad9e chosen by fair dice roll - 0x3d32ad9e * (CRC_IEEE.checksum(database_name.as_bytes()) as i64) -} - -async fn execute_migration( - conn: &mut PgConnection, - schema: &'static str, - migration: &Migration, -) -> Result<(), MigrateError> { - let _ = conn - .execute(&*migration.sql) - .await - .map_err(|e| MigrateError::ExecuteMigration(e, migration.version))?; - - // language=SQL - let _ = query( - format!(r#" - INSERT INTO {schema}._sqlx_migrations ( version, description, success, checksum, execution_time ) - VALUES ( $1, $2, TRUE, $3, -1 ) - "#).as_str() - ) - .bind(migration.version) - .bind(&*migration.description) - .bind(&*migration.checksum) - .execute(conn) - .await?; - - Ok(()) -} - -async fn revert_migration( - conn: &mut PgConnection, - schema: &'static str, - migration: &Migration, -) -> Result<(), MigrateError> { - let _ = conn - .execute(&*migration.sql) - .await - .map_err(|e| MigrateError::ExecuteMigration(e, migration.version))?; - - // language=SQL - let _ = query(format!(r#"DELETE FROM {schema}._sqlx_migrations WHERE version = $1"#).as_str()) - .bind(migration.version) - .execute(conn) - .await?; - - Ok(()) -} diff --git a/crates/sql/Cargo.toml b/crates/sql/Cargo.toml index 8d43fa41..2e5717ff 100644 --- a/crates/sql/Cargo.toml +++ b/crates/sql/Cargo.toml @@ -10,6 +10,7 @@ sqlx = { workspace = true, features = ["runtime-tokio-rustls"] } itertools.workspace = true futures.workspace = true crc.workspace = true +starknet-types-core.workspace = true [features] postgres = ["sqlx/postgres"] diff --git a/crates/sql/src/lib.rs b/crates/sql/src/lib.rs index 2553d821..24dbf605 100644 --- a/crates/sql/src/lib.rs +++ b/crates/sql/src/lib.rs @@ -1,6 +1,7 @@ pub mod connection; pub mod migrate; pub mod query; +pub mod types; pub use connection::DbConnection; pub use migrate::{AcquiredSchema, SchemaMigrator}; @@ -11,9 +12,13 @@ pub type SqlxResult = std::result::Result; #[cfg(feature = "postgres")] pub mod postgres; +#[cfg(feature = "postgres")] +pub use postgres::{PgArguments, PgDbConnection, PgPool, PgQuery, Postgres}; #[cfg(feature = "sqlite")] pub mod sqlite; +#[cfg(feature = "sqlite")] +pub use sqlite::{Sqlite, SqliteArguments, SqliteDbConnection, SqlitePool, SqliteQuery}; // #[cfg(feature = "mysql")] // pub mod mysql; diff --git a/crates/sql/src/postgres.rs b/crates/sql/src/postgres.rs index a38ae923..0af5f39d 100644 --- a/crates/sql/src/postgres.rs +++ b/crates/sql/src/postgres.rs @@ -1,11 +1,22 @@ -use crate::{AcquiredSchema, FlexQuery}; +use crate::types::SqlFelt; +use crate::{AcquiredSchema, DbConnection, FlexQuery}; use futures::future::BoxFuture; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; use sqlx::migrate::{AppliedMigration, Migrate, MigrateError, Migration}; -use sqlx::{query, query_scalar, Connection, PgConnection, Postgres}; -use sqlx::{query_as, Executor}; +use sqlx::postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef}; +use sqlx::{ + query, query_as, query_scalar, Connection, Decode, Encode, Executor, PgConnection, Type, +}; use std::time::{Duration, Instant}; -pub type PgQuery = FlexQuery; +pub use sqlx::postgres::PgArguments; +pub use sqlx::{PgPool, Postgres}; + +pub type PgQuery = FlexQuery; + +pub trait PgDbConnection: DbConnection {} +impl PgDbConnection for T {} impl Migrate for AcquiredSchema { fn ensure_migrations_table(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { @@ -239,3 +250,35 @@ async fn revert_migration( Ok(()) } + +impl Type for SqlFelt { + fn type_info() -> PgTypeInfo { + PgTypeInfo::with_name("felt252") + } + + fn compatible(ty: &PgTypeInfo) -> bool { + *ty == PgTypeInfo::with_name("felt252") || <[u8] as Type>::compatible(ty) + } +} + +impl PgHasArrayType for SqlFelt { + fn array_type_info() -> PgTypeInfo { + PgTypeInfo::with_name("_felt252") + } +} + +impl Encode<'_, Postgres> for SqlFelt { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result { + <&[u8] as Encode>::encode(self.0.as_slice(), buf) + } +} + +impl Decode<'_, Postgres> for SqlFelt { + fn decode(value: PgValueRef<'_>) -> Result { + let bytes = <&[u8] as Decode>::decode(value)?; + let arr: [u8; 32] = bytes + .try_into() + .map_err(|_| format!("expected 32 bytes for felt252, got {}", bytes.len()))?; + Ok(SqlFelt(arr)) + } +} diff --git a/crates/sql/src/sqlite.rs b/crates/sql/src/sqlite.rs index 70fca0bd..0599574f 100644 --- a/crates/sql/src/sqlite.rs +++ b/crates/sql/src/sqlite.rs @@ -1,13 +1,21 @@ -use crate::{AcquiredSchema, FlexQuery}; +use crate::types::SqlFelt; +use crate::{AcquiredSchema, DbConnection, FlexQuery}; use futures::future::BoxFuture; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; use sqlx::migrate::{AppliedMigration, Migrate, MigrateError, Migration}; use sqlx::sqlite::SqliteConnectOptions; -use sqlx::{query, query_as, Acquire, Executor, Sqlite, SqliteConnection}; +use sqlx::{query, query_as, Acquire, Decode, Encode, Executor, SqliteConnection, Type}; use std::borrow::Cow; use std::str::FromStr; use std::time::{Duration, Instant}; +pub use sqlx::sqlite::SqliteArguments; +pub use sqlx::{Sqlite, SqlitePool}; + pub type SqliteQuery = FlexQuery; +pub trait SqliteDbConnection: DbConnection {} +impl> SqliteDbConnection for T {} impl AcquiredSchema { fn table_name(&self) -> Cow<'static, str> { @@ -187,3 +195,50 @@ pub fn sqlite_connect_options(path: &str) -> Result for SqlFelt { + fn type_info() -> ::TypeInfo { + >::type_info() + } +} + +impl<'q> Encode<'q, Sqlite> for SqlFelt { + fn encode_by_ref( + &self, + buf: &mut ::ArgumentBuffer<'q>, + ) -> Result { + let mut hex = String::with_capacity(66); + hex.push_str("0x"); + for byte in &self.0 { + use std::fmt::Write; + write!(hex, "{byte:02x}").unwrap(); + } + Encode::::encode(hex, buf) + } +} + +impl Decode<'_, Sqlite> for SqlFelt { + fn decode(value: ::ValueRef<'_>) -> Result { + let s = >::decode(value)?; + let s = s.strip_prefix("0x").unwrap_or(&s); + if s.len() != 64 { + return Err(format!("expected 64 hex chars for felt252, got {}", s.len()).into()); + } + let mut arr = [0u8; 32]; + for (i, chunk) in s.as_bytes().chunks(2).enumerate() { + let hi = hex_nibble(chunk[0])?; + let lo = hex_nibble(chunk[1])?; + arr[i] = (hi << 4) | lo; + } + Ok(SqlFelt(arr)) + } +} + +fn hex_nibble(c: u8) -> Result { + match c { + b'0'..=b'9' => Ok(c - b'0'), + b'a'..=b'f' => Ok(c - b'a' + 10), + b'A'..=b'F' => Ok(c - b'A' + 10), + _ => Err(format!("invalid hex char: {}", c as char).into()), + } +} diff --git a/crates/sql/src/types.rs b/crates/sql/src/types.rs new file mode 100644 index 00000000..74837070 --- /dev/null +++ b/crates/sql/src/types.rs @@ -0,0 +1,22 @@ +use starknet_types_core::felt::Felt; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct SqlFelt(pub [u8; 32]); + +impl From for Felt { + fn from(value: SqlFelt) -> Self { + Felt::from_bytes_be(&value.0) + } +} + +impl From for SqlFelt { + fn from(value: Felt) -> Self { + SqlFelt(value.to_bytes_be()) + } +} + +impl From<&Felt> for SqlFelt { + fn from(value: &Felt) -> Self { + SqlFelt(value.to_bytes_be()) + } +} diff --git a/crates/sqlite/Cargo.toml b/crates/sqlite/Cargo.toml deleted file mode 100644 index 576e3b6a..00000000 --- a/crates/sqlite/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "torii-sqlite" -version = "0.1.0" -edition = "2021" -description = "SQLite connection helpers for Torii storage crates" - -[dependencies] -async-trait.workspace = true -futures.workspace = true -sqlx = { workspace = true, features = [ - "sqlite", - "runtime-tokio-rustls", - "migrate", -] } - -torii-sql.workspace = true - -[lints] -workspace = true diff --git a/crates/sqlite/src/db.rs b/crates/sqlite/src/db.rs deleted file mode 100644 index e1c5989c..00000000 --- a/crates/sqlite/src/db.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::ops::Deref; -use std::str::FromStr; - -pub use async_trait::async_trait; -use sqlx::migrate::Migrator; -use sqlx::sqlite::SqliteConnectOptions; -use sqlx::Sqlite; -pub use sqlx::{SqlitePool, Transaction}; -use torii_sql::SqlxResult; - -use crate::migration::NamespaceMigrator; - -#[async_trait] -pub trait SqliteConnection { - fn pool(&self) -> &SqlitePool; - - async fn begin(&self) -> SqlxResult> { - Ok(self.pool().begin().await?) - } - - async fn migrate(&self, namespace: Option<&'static str>, migrator: Migrator) -> SqlxResult<()> { - let result = match namespace { - Some(namespace) => { - NamespaceMigrator::new(namespace, migrator) - .run(self.pool()) - .await - } - None => migrator.run(self.pool()).await, - }; - Ok(result?) - } - - async fn execute_queries(&self, queries: &[String]) -> SqlxResult<()> { - let mut transaction = self.begin().await?; - for query in queries { - sqlx::query(query).execute(&mut *transaction).await?; - } - transaction.commit().await - } -} - -#[allow(clippy::explicit_auto_deref)] -#[async_trait] -impl + Send + Sync + 'static> SqliteConnection for T { - fn pool(&self) -> &SqlitePool { - &**self - } -} - -pub fn is_sqlite_memory_path(path: &str) -> bool { - path == ":memory:" - || path == "sqlite::memory:" - || path == "sqlite://:memory:" - || path.contains("mode=memory") -} - -pub fn sqlite_connect_options(path: &str) -> Result { - if path == ":memory:" || path == "sqlite::memory:" { - return SqliteConnectOptions::from_str("sqlite::memory:"); - } - - let options = if path.starts_with("sqlite:") { - SqliteConnectOptions::from_str(path)? - } else { - SqliteConnectOptions::new().filename(path) - }; - - if path.starts_with("sqlite:") && path.contains("mode=") { - Ok(options) - } else { - Ok(options.create_if_missing(true)) - } -} diff --git a/crates/sqlite/src/lib.rs b/crates/sqlite/src/lib.rs deleted file mode 100644 index e0e1dc65..00000000 --- a/crates/sqlite/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod db; -pub mod migration; - -pub use db::{is_sqlite_memory_path, sqlite_connect_options, SqliteConnection}; diff --git a/crates/sqlite/src/migration.rs b/crates/sqlite/src/migration.rs deleted file mode 100644 index 8b9e3eef..00000000 --- a/crates/sqlite/src/migration.rs +++ /dev/null @@ -1,320 +0,0 @@ -use futures::future::BoxFuture; -use sqlx::migrate::{ - AppliedMigration, Migrate, MigrateError, Migration, MigrationSource, Migrator, -}; -use sqlx::sqlite::SqliteConnection; -use sqlx::{query, query_as, Acquire, Executor, Sqlite}; -use std::borrow::Cow; -use std::collections::{HashMap, HashSet}; -use std::ops::{Deref, DerefMut}; -use std::slice; -use std::time::{Duration, Instant}; - -pub struct NamespaceMigrator { - pub migrator: Migrator, - pub namespace: &'static str, -} - -pub struct SqliteAcquiredNamespace<'a, A> -where - A: Acquire<'a>, -{ - pub connection: >::Connection, - pub namespace: &'static str, -} - -impl<'a, A> Deref for SqliteAcquiredNamespace<'a, A> -where - A: Acquire<'a, Database = Sqlite>, -{ - type Target = SqliteConnection; - - fn deref(&self) -> &Self::Target { - &self.connection - } -} - -impl<'a, A> DerefMut for SqliteAcquiredNamespace<'a, A> -where - A: Acquire<'a, Database = Sqlite>, -{ - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.connection - } -} - -impl<'a, A> SqliteAcquiredNamespace<'a, A> -where - A: Acquire<'a, Database = Sqlite>, -{ - fn table_name(&self) -> Cow<'static, str> { - Cow::Owned(format!("_sqlx_migrations_{}", self.namespace)) - } -} - -impl<'a, A> Migrate for SqliteAcquiredNamespace<'a, A> -where - A: Acquire<'a, Database = Sqlite> + Executor<'a, Database = Sqlite>, -{ - fn ensure_migrations_table(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { - Box::pin(async move { - let table_name = self.table_name(); - self.connection - .execute( - format!( - r#" -CREATE TABLE IF NOT EXISTS "{table_name}" ( - version BIGINT PRIMARY KEY, - description TEXT NOT NULL, - installed_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - success BOOLEAN NOT NULL, - checksum BLOB NOT NULL, - execution_time BIGINT NOT NULL -); - "# - ) - .as_str(), - ) - .await?; - - Ok(()) - }) - } - - fn dirty_version(&mut self) -> BoxFuture<'_, Result, MigrateError>> { - Box::pin(async move { - let table_name = self.table_name(); - let row: Option<(i64,)> = query_as( - format!( - r#"SELECT version FROM "{table_name}" WHERE success = false ORDER BY version LIMIT 1"# - ) - .as_str(), - ) - .fetch_optional(&mut *self.connection) - .await?; - - Ok(row.map(|row| row.0)) - }) - } - - fn list_applied_migrations( - &mut self, - ) -> BoxFuture<'_, Result, MigrateError>> { - Box::pin(async move { - let table_name = self.table_name(); - let rows: Vec<(i64, Vec)> = query_as( - format!(r#"SELECT version, checksum FROM "{table_name}" ORDER BY version"#) - .as_str(), - ) - .fetch_all(&mut *self.connection) - .await?; - - Ok(rows - .into_iter() - .map(|(version, checksum)| AppliedMigration { - version, - checksum: checksum.into(), - }) - .collect()) - }) - } - - fn lock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { - Box::pin(async move { Ok(()) }) - } - - fn unlock(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { - Box::pin(async move { Ok(()) }) - } - - fn apply<'e: 'm, 'm>( - &'e mut self, - migration: &'m Migration, - ) -> BoxFuture<'m, Result> { - Box::pin(async move { - let table_name = self.table_name(); - let mut tx = self.begin().await?; - let start = Instant::now(); - - let _ = tx - .execute(&*migration.sql) - .await - .map_err(|e| MigrateError::ExecuteMigration(e, migration.version))?; - - let _ = query( - format!( - r#" -INSERT INTO "{table_name}" (version, description, success, checksum, execution_time) -VALUES (?1, ?2, TRUE, ?3, -1) - "# - ) - .as_str(), - ) - .bind(migration.version) - .bind(&*migration.description) - .bind(&*migration.checksum) - .execute(&mut *tx) - .await?; - - tx.commit().await?; - - let elapsed = start.elapsed(); - - #[allow(clippy::cast_possible_truncation)] - let _ = query( - format!( - r#" -UPDATE "{table_name}" -SET execution_time = ?1 -WHERE version = ?2 - "# - ) - .as_str(), - ) - .bind(elapsed.as_nanos() as i64) - .bind(migration.version) - .execute(&mut *self.connection) - .await?; - - Ok(elapsed) - }) - } - - fn revert<'e: 'm, 'm>( - &'e mut self, - migration: &'m Migration, - ) -> BoxFuture<'m, Result> { - Box::pin(async move { - let table_name = self.table_name(); - let mut tx = self.begin().await?; - let start = Instant::now(); - - let _ = tx.execute(&*migration.sql).await?; - - let _ = query(format!(r#"DELETE FROM "{table_name}" WHERE version = ?1"#).as_str()) - .bind(migration.version) - .execute(&mut *tx) - .await?; - - tx.commit().await?; - - Ok(start.elapsed()) - }) - } -} - -impl NamespaceMigrator { - pub const fn new(namespace: &'static str, migrator: Migrator) -> Self { - Self { - migrator, - namespace, - } - } - - pub async fn new_from_source<'s, S>( - namespace: &'static str, - source: S, - ) -> Result - where - S: MigrationSource<'s>, - { - Migrator::new(source).await.map(|migrator| Self { - migrator, - namespace, - }) - } - - pub fn set_ignore_missing(&mut self, ignore_missing: bool) -> &Self { - self.migrator.ignore_missing = ignore_missing; - self - } - - pub fn set_locking(&mut self, locking: bool) -> &Self { - self.migrator.locking = locking; - self - } - - pub fn iter(&self) -> slice::Iter<'_, Migration> { - self.migrator.migrations.iter() - } - - pub fn version_exists(&self, version: i64) -> bool { - self.iter().any(|migration| migration.version == version) - } - - pub async fn run<'a, A>(&self, migrator: A) -> Result<(), MigrateError> - where - A: Acquire<'a, Database = Sqlite>, - SqliteAcquiredNamespace<'a, A>: Migrate, - { - let mut conn = SqliteAcquiredNamespace { - connection: migrator.acquire().await?, - namespace: self.namespace, - }; - self.migrator.run_direct(&mut conn).await - } - - pub async fn undo<'a, A>(&self, migrator: A, target: i64) -> Result<(), MigrateError> - where - A: Acquire<'a, Database = Sqlite>, - SqliteAcquiredNamespace<'a, A>: Migrate, - { - let mut conn = SqliteAcquiredNamespace { - connection: migrator.acquire().await?, - namespace: self.namespace, - }; - - if self.migrator.locking { - conn.lock().await?; - } - - conn.ensure_migrations_table().await?; - - if let Some(version) = conn.dirty_version().await? { - return Err(MigrateError::Dirty(version)); - } - - let applied_migrations = conn.list_applied_migrations().await?; - validate_applied_migrations(&applied_migrations, &self.migrator)?; - - let applied_migrations: HashMap<_, _> = applied_migrations - .into_iter() - .map(|migration| (migration.version, migration)) - .collect(); - - for migration in self - .iter() - .rev() - .filter(|migration| migration.migration_type.is_down_migration()) - .filter(|migration| applied_migrations.contains_key(&migration.version)) - .filter(|migration| migration.version > target) - { - conn.revert(migration).await?; - } - - if self.migrator.locking { - conn.unlock().await?; - } - - Ok(()) - } -} - -fn validate_applied_migrations( - applied_migrations: &[AppliedMigration], - migrator: &Migrator, -) -> Result<(), MigrateError> { - if migrator.ignore_missing { - return Ok(()); - } - - let migrations: HashSet<_> = migrator.iter().map(|migration| migration.version).collect(); - - for applied_migration in applied_migrations { - if !migrations.contains(&applied_migration.version) { - return Err(MigrateError::VersionMissing(applied_migration.version)); - } - } - - Ok(()) -} diff --git a/examples/introspect/restart.rs b/examples/introspect/restart.rs index cf254d65..0b0e7157 100644 --- a/examples/introspect/restart.rs +++ b/examples/introspect/restart.rs @@ -1,5 +1,6 @@ use itertools::Itertools; -use sqlx::{postgres::PgPoolOptions, PgPool}; +use sqlx::postgres::PgPoolOptions; +use sqlx::PgPool; use starknet::core::types::Felt; use std::sync::Arc; use torii_dojo::decoder::DojoDecoder; @@ -37,7 +38,7 @@ async fn run_events( let db = IntrospectPgDb::new(pool.clone(), ADDRESSES); decoder.store.initialize().await.unwrap(); decoder.load_tables(&[]).await.unwrap(); - let results = db.initialize_introspect_pg_sink().await.unwrap(); + let results = db.initialize_introspect_sql_sink().await.unwrap(); if results.len() > 0 { for err in results { println!("Error loading table: {err}"); diff --git a/examples/introspect/simple.rs b/examples/introspect/simple.rs index cbe2b205..0ed581ea 100644 --- a/examples/introspect/simple.rs +++ b/examples/introspect/simple.rs @@ -26,7 +26,7 @@ async fn main() { let decoder = DojoDecoder::, _>::new(pool.clone(), provider); let db = IntrospectPgDb::new(pool.clone(), SCHEMA_NAME); decoder.store.initialize().await.unwrap(); - db.initialize_introspect_pg_sink().await.unwrap(); + db.initialize_introspect_sql_sink().await.unwrap(); let mut event_n = 0; let mut success = 0; From 4c58e2cbf3f76ee3c1ab8eb0dd1b7a2d5028fb8c Mon Sep 17 00:00:00 2001 From: MartianGreed Date: Wed, 25 Mar 2026 15:41:00 +0100 Subject: [PATCH 08/21] feat(entities-historical): create sink & bootstrap --- Cargo.lock | 20 + Cargo.toml | 2 + PLAN.md | 226 ++++ bins/torii-arcade/Cargo.toml | 1 + bins/torii-arcade/src/config.rs | 27 + bins/torii-arcade/src/main.rs | 100 +- bins/torii-introspect-bin/Cargo.toml | 1 + bins/torii-introspect-bin/src/config.rs | 51 + bins/torii-introspect-bin/src/main.rs | 261 +++- crates/dojo/src/decoder.rs | 69 +- crates/dojo/src/external_contract.rs | 382 ++++++ crates/dojo/src/lib.rs | 7 + crates/torii-ecs-sink/src/sink.rs | 134 +- .../torii-entities-historical-sink/Cargo.toml | 25 + .../torii-entities-historical-sink/src/lib.rs | 1118 +++++++++++++++++ src/etl/engine_db.rs | 54 + src/etl/extractor/event.rs | 77 ++ 17 files changed, 2502 insertions(+), 53 deletions(-) create mode 100644 PLAN.md create mode 100644 crates/dojo/src/external_contract.rs create mode 100644 crates/torii-entities-historical-sink/Cargo.toml create mode 100644 crates/torii-entities-historical-sink/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 4b7a23f4..600f4eea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4652,6 +4652,7 @@ dependencies = [ "torii-config-common", "torii-dojo", "torii-ecs-sink", + "torii-entities-historical-sink", "torii-erc1155", "torii-erc20", "torii-erc721", @@ -4786,6 +4787,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "torii-entities-historical-sink" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "introspect-types", + "serde", + "serde_json", + "sqlx", + "starknet", + "thiserror 2.0.18", + "tokio", + "torii", + "torii-introspect", + "tracing", +] + [[package]] name = "torii-erc1155" version = "0.1.0" @@ -4944,6 +4963,7 @@ dependencies = [ "torii-controllers-sink", "torii-dojo", "torii-ecs-sink", + "torii-entities-historical-sink", "torii-erc1155", "torii-erc20", "torii-erc721", diff --git a/Cargo.toml b/Cargo.toml index 3750ca3a..bbe4ceb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ members = [ "crates/torii-controllers-sink", "crates/arcade-sink", "crates/torii-ecs-sink", + "crates/torii-entities-historical-sink", "crates/torii-erc20", "crates/torii-erc721", "crates/torii-erc1155", @@ -134,6 +135,7 @@ torii-log-sink.path = "crates/torii-log-sink" torii-controllers-sink.path = "crates/torii-controllers-sink" torii-arcade-sink.path = "crates/arcade-sink" torii-ecs-sink.path = "crates/torii-ecs-sink" +torii-entities-historical-sink.path = "crates/torii-entities-historical-sink" torii-erc20.path = "crates/torii-erc20" torii-erc721.path = "crates/torii-erc721" torii-erc1155.path = "crates/torii-erc1155" diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 00000000..001e6311 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,226 @@ +# ExternalContractRegistered Implementation Plan + +## Overview +We need to handle the Dojo world event `ExternalContractRegistered` in the current ETL architecture and begin indexing the registered contract without restarting the process. In the old Torii processor model, this event only registered contract metadata and seeded indexing state; in the new architecture, the same behavior spans decoder output, contract-to-decoder routing, extractor enrollment, and sink-side contract classification. + +## Goals +- Detect and decode `ExternalContractRegistered` emitted by a Dojo world. +- Start extracting events for the registered contract from the registration block onward. +- Route the new contract to the correct decoder set without requiring a restart. +- Preserve correct contract typing in ECS/storage APIs once external contract events arrive. +- Keep the flow idempotent across retries and restarts. + +## Non-Goals +- Backfill external contract history from before the registration block. +- Support arbitrary contract kinds beyond decoders/sinks that are actually registered in the process. +- Migrate the whole Dojo indexer to `GlobalEventExtractor` as part of this change. +- Recreate the full old processor framework. + +## Assumptions and Constraints +- The event payload is still equivalent to the old processor input: namespace, contract name, instance name, contract selector, class hash, contract address, and block number. +- Old behavior used `block_number - 1` as stored head, which means new indexing effectively starts at the registration block. In the new extractor model, the equivalent is `from_block = registration_block`. +- The current Dojo path is built around a static `EventExtractor` contract list in [`bins/torii-introspect-bin/src/main.rs`](/Users/valentindosimont/www/c7e/torii-core/bins/torii-introspect-bin/src/main.rs), so “start indexing” now requires runtime extractor enrollment, not just metadata persistence. +- `EcsSink` currently records every raw event contract as `WORLD`, which will be wrong for dynamically indexed external contracts. +- External contract indexing should be gated somehow. The old code used `should_index_external_contract(namespace, instance_name)`; the current binary has no equivalent yet. + +## Requirements + +### Functional +- Decode `ExternalContractRegistered` from world events in `torii-dojo`. +- Produce a typed control signal that downstream code can act on. +- Map the registered contract to the appropriate decoder IDs based on `contract_name`. +- Persist the decoder mapping so restarts preserve the registration. +- Enroll the contract into the event extractor starting at the registration block. +- Avoid duplicate registration work if the same event is replayed. +- Record the registered contract with the right `ContractType` in ECS storage. + +### Non-Functional +- No missing events from the registration block because of cursor advancement. +- No restart required after registration. +- Minimal changes to existing sink APIs. +- Safe behavior when the registered contract type is unsupported or no matching decoder is installed. + +## Technical Design + +### Data Model +- Reuse `engine.contract_decoders` for persisted contract-to-decoder routing. +- Reuse `engine.extractor_state` for per-contract event extractor progress, but add the ability for `EventExtractor` to discover dynamically added contract states. +- Add an in-memory contract-type registry shared with `EcsSink` so external contracts are not later overwritten as `WORLD`. + +### API Design +- Add a new typed envelope/body in `torii-dojo`, for example `dojo.external_contract_registered`. +- Add a command, for example `RegisterExternalContractCommand`, carrying: + - world address + - contract address + - contract name / resolved contract type + - namespace + - instance name + - registration block + - resolved decoder IDs +- Add a command handler that: + - updates `engine.contract_decoders` + - writes dynamic extractor state for the contract + - updates the shared contract-type registry + +### Architecture +```text +World event (ExternalContractRegistered) + -> DojoDecoder + -> control envelope: dojo.external_contract_registered + -> sink/handler path + -> RegisterExternalContractCommand + -> command handler + -> persist contract_decoders + -> add dynamic event extractor state (from registration block) + -> update shared contract type registry + -> next ETL cycle + -> EventExtractor sees new contract state + -> fetches events from external contract + -> DecoderContext routes events using persisted mapping + -> token / other sinks process them normally +``` + +### Recommended Fit +- Handle event parsing in `torii-dojo`, not in `EcsSink`. + - Reason: this is a Dojo-specific world event, and the decoder is already the component that understands Dojo event selectors. +- Trigger extractor enrollment via command bus, not direct sink-to-extractor mutation. + - Reason: this keeps ETL control-plane work asynchronous and avoids coupling sinks to a concrete extractor instance. +- Extend `EventExtractor` to load dynamically added contract states from `EngineDb`. + - Reason: this works with the existing extractor persistence model and survives restart. + +### Alternative Considered +- Switch the Dojo indexer to `GlobalEventExtractor` and rely only on runtime decoder routing. + - Pros: no dynamic extractor enrollment needed. + - Cons: much larger behavior and cost change; not aligned with the current targeted-contract design of `torii-introspect-bin`. + +--- + +## Implementation Plan + +### Serial Dependencies (Must Complete First) + +These tasks create foundations that other work depends on. Complete in order. + +#### Phase 0: Control-Plane Foundations +**Prerequisite for:** All subsequent phases + +| Task | Description | Output | +|------|-------------|--------| +| 0.1 | Add a typed `ExternalContractRegistered` control body in `torii-dojo` and teach `DojoDecoder` to emit it instead of treating the selector as unknown. | Decoder can parse the new world event into a control envelope. | +| 0.2 | Add a shared contract-type mapping helper (`contract_name` -> `ContractType` + decoder IDs). | Single source of truth for dynamic routing and ECS classification. | +| 0.3 | Add `EngineDb` support for discovering dynamic event extractor states, or another minimal persisted lookup used by `EventExtractor`. | Extractor can load runtime-added contracts on startup and during steady state. | + +--- + +### Parallel Workstreams + +These workstreams can be executed independently after Phase 0. + +#### Workstream A: Dynamic Extractor Enrollment +**Dependencies:** Phase 0 +**Can parallelize with:** Workstreams B, C + +| Task | Description | Output | +|------|-------------|--------| +| A.1 | Extend `EventExtractor` so it can hydrate unknown contracts from persisted state, not only its static config list. | Runtime-added contracts become fetch targets without restart. | +| A.2 | Ensure newly added contracts start from the registration block inclusive and follow head (`to_block = u64::MAX`). | No missed same-block follow-up events. | +| A.3 | Make extractor refresh dynamic contracts on each cycle or before each extraction attempt. | Newly registered contracts begin indexing promptly. | + +#### Workstream B: Runtime Registration Command Path +**Dependencies:** Phase 0 +**Can parallelize with:** Workstreams A, C + +| Task | Description | Output | +|------|-------------|--------| +| B.1 | Add `RegisterExternalContractCommand` and a dedicated `CommandHandler`. | Background registration work can be triggered from sinks. | +| B.2 | Persist `contract -> decoder_ids` into `engine.contract_decoders` and update the shared registry cache. | `DecoderContext` routes future external contract events correctly. | +| B.3 | Persist extractor state for the new contract starting at the registration block. | Extractor enrollment survives restarts and replay. | +| B.4 | Handle unsupported contract types or missing installed decoders by logging and skipping extractor enrollment. | Safe failure mode instead of partial broken indexing. | + +#### Workstream C: Sink Classification and Wiring +**Dependencies:** Phase 0 +**Can parallelize with:** Workstreams A, B + +| Task | Description | Output | +|------|-------------|--------| +| C.1 | Extend the Dojo/ECS sink path to consume the new control envelope and dispatch the registration command. | External registrations trigger runtime indexing. | +| C.2 | Replace `EcsSink`’s hardcoded `ContractType::World` classification with a lookup against shared contract-type state. | External contract events are stored as ERC20/ERC721/ERC1155 instead of WORLD. | +| C.3 | Seed that shared contract-type state from both static CLI targets and runtime registrations. | Static and dynamic contracts use the same classification path. | +| C.4 | Add config gating for external contract indexing, ideally restoring old whitelist semantics or a simpler opt-in flag. | Runtime registration is explicit and controlled. | + +--- + +### Merge Phase + +After parallel workstreams complete, these tasks integrate the work. + +#### Phase N: Integration +**Dependencies:** Workstreams A, B, C + +| Task | Description | Output | +|------|-------------|--------| +| N.1 | Wire the new command handler and shared registries into `bins/torii-introspect-bin`. | Binary boots with dynamic external contract registration enabled. | +| N.2 | Ensure decoder mappings, extractor state, and ECS contract typing all agree for dynamically added contracts. | End-to-end runtime registration flow works coherently. | +| N.3 | Verify logs and metrics for registration success, duplicate replay, unsupported contract types, and extractor enrollment. | Operable runtime behavior. | + +--- + +## Testing and Validation + +- Unit test `DojoDecoder` on an `ExternalContractRegistered` raw event. +- Unit test contract-name resolution to `(ContractType, DecoderId set)`. +- Unit test command handler idempotence when the same contract is registered twice. +- Unit test `EventExtractor` dynamic contract discovery from persisted state. +- Unit test `EcsSink` contract-type lookup so external contract events do not overwrite type to `WORLD`. +- Add an integration test with a synthetic sequence: + - world emits `ExternalContractRegistered` at block `N` + - command persists mapping and extractor state + - extractor later fetches external contract events from block `N` + - token sink processes those events + - ECS contract record shows the external contract type, not `WORLD` + +## Rollout and Migration + +- Gate the feature behind explicit config at first. +- Preserve existing behavior for static contract lists when the feature is disabled. +- On restart, rely on persisted `contract_decoders` and extractor state so dynamically registered contracts resume normally. +- Rollback path: disable the feature flag and ignore control envelopes; existing static indexing remains unchanged. + +## Verification Checklist + +- `cargo test -p torii-dojo` +- `cargo test -p torii-ecs-sink` +- `cargo test -p torii -- extractor::event` +- Synthetic end-to-end test for dynamic external contract registration +- Manual verification in `torii-introspect-bin`: + - start with only a world contract configured + - emit `ExternalContractRegistered` + - confirm extractor state appears for the external contract + - confirm subsequent external contract events are fetched and decoded + - confirm ECS contract query reports the expected `ContractType` + +## Risk Assessment + +| Risk | Likelihood | Impact | Mitigation | +|------|------------|--------|------------| +| Registered contract starts indexing too late and misses same-block events | Med | High | Start dynamic extractor state at the registration block, not the next block. | +| ECS contract type gets overwritten back to `WORLD` on raw-event ingest | High | High | Replace hardcoded classification with shared contract-type lookup before enabling the feature. | +| Unsupported contract names produce partial state | Med | Med | Resolve type before persistence; skip extractor enrollment if no installed decoder matches. | +| EventExtractor never sees dynamically added contracts | Med | High | Add explicit extractor refresh/load path plus tests around persisted state discovery. | +| Replay of the registration event creates duplicate work | High | Med | Keep handler idempotent via upsert semantics in `EngineDb` and in-memory maps. | + +## Open Questions + +- [ ] Do we want strict parity with the old `should_index_external_contract(namespace, instance_name)` whitelist, or is a coarse feature flag enough? +- [ ] Which `contract_name` strings should be considered supported initially: only `ERC20`/`ERC721`/`ERC1155`, or also `UDC`/others? +- [ ] Should unsupported registrations still appear in ECS contract listings as `OTHER`, even if no extractor enrollment happens? +- [ ] Do we want this feature only in `torii-introspect-bin`, or as reusable core plumbing for any Torii app using `EventExtractor`? + +## Decision Log + +| Decision | Rationale | Alternatives Considered | +|----------|-----------|------------------------| +| Decode `ExternalContractRegistered` in `torii-dojo` | The decoder already owns Dojo world event semantics. | Parse raw events directly in `EcsSink`. | +| Use a command-handler path for runtime registration | Keeps control-plane mutation out of sink hot paths and fits existing async background-work design. | Direct sink mutation of extractor/cache. | +| Keep `EventExtractor` and add dynamic enrollment | Smallest change that matches current targeted-contract architecture. | Replace the binary with `GlobalEventExtractor`. | +| Fix ECS contract typing as part of this feature | Dynamic external events will otherwise be misclassified immediately. | Postpone classification cleanup until later. | diff --git a/bins/torii-arcade/Cargo.toml b/bins/torii-arcade/Cargo.toml index a3f47206..d3a56e75 100644 --- a/bins/torii-arcade/Cargo.toml +++ b/bins/torii-arcade/Cargo.toml @@ -15,6 +15,7 @@ torii-config-common.workspace = true torii-arcade-sink = { path = "../../crates/arcade-sink" } torii-dojo = { path = "../../crates/dojo" } torii-ecs-sink = { path = "../../crates/torii-ecs-sink" } +torii-entities-historical-sink.workspace = true torii-erc20 = { path = "../../crates/torii-erc20" } torii-erc721 = { path = "../../crates/torii-erc721" } torii-erc1155 = { path = "../../crates/torii-erc1155" } diff --git a/bins/torii-arcade/src/config.rs b/bins/torii-arcade/src/config.rs index f2faebf5..b490d903 100644 --- a/bins/torii-arcade/src/config.rs +++ b/bins/torii-arcade/src/config.rs @@ -177,6 +177,9 @@ pub struct Config { #[arg(long, value_delimiter = ',', default_values = DEFAULT_ERC1155_CONTRACTS)] pub erc1155: Vec, + + #[arg(long, value_delimiter = ',')] + pub historical: Vec, } impl Config { @@ -220,6 +223,16 @@ impl Config { parse_unique_addresses(&self.erc1155, "ERC1155 contract") } + pub fn historical_models(&self) -> Vec { + let mut models = Vec::with_capacity(self.historical.len()); + for model in &self.historical { + if !model.is_empty() && !models.contains(model) { + models.push(model.clone()); + } + } + models + } + pub fn well_known_erc20_contracts() -> Vec<(Felt, &'static str)> { vec![ ( @@ -438,4 +451,18 @@ mod tests { assert_eq!(cfg.max_prefetch_batches, 4); assert_eq!(cfg.rpc_parallelism, 6); } + + #[test] + fn historical_models_parse_as_exact_names() { + let cfg = Config::parse_from([ + "torii-arcade", + "--historical", + "NUMS-Game,NUMS-Config,NUMS-Game", + ]); + + assert_eq!( + cfg.historical_models(), + vec!["NUMS-Game".to_string(), "NUMS-Config".to_string()] + ); + } } diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index acc3ba05..c6f5bb09 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -6,9 +6,10 @@ use config::{Config, MetadataMode}; use sqlx::postgres::PgPoolOptions; use sqlx::sqlite::SqlitePoolOptions; use starknet::core::types::Felt; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::path::Path; use std::sync::Arc; +use tokio::sync::RwLock; use tonic::codec::CompressionEncoding; use tonic_reflection::server::Builder as ReflectionBuilder; use torii::axum::Router; @@ -24,10 +25,12 @@ use torii_arcade_sink::{ArcadeSink, FILE_DESCRIPTOR_SET as ARCADE_DESCRIPTOR_SET use torii_common::{MetadataFetcher, TokenUriService}; use torii_config_common::apply_observability_env; use torii_dojo::decoder::DojoDecoder; +use torii_dojo::external_contract::RegisteredContractType; use torii_dojo::store::postgres::PgStore; use torii_dojo::store::sqlite::SqliteStore; use torii_ecs_sink::proto::world::world_server::WorldServer; use torii_ecs_sink::{EcsSink, FILE_DESCRIPTOR_SET as ECS_DESCRIPTOR_SET}; +use torii_entities_historical_sink::EntitiesHistoricalSink; use torii_erc1155::proto::erc1155_server::Erc1155Server; use torii_erc1155::{ Erc1155Decoder, Erc1155MetadataCommandHandler, Erc1155Service, Erc1155Sink, Erc1155Storage, @@ -56,17 +59,35 @@ const TOKEN_METADATA_COMMAND_PARALLELISM: usize = 1; const TOKEN_METADATA_MAX_RETRIES: u8 = 3; const TOKEN_URI_FETCH_PARALLELISM: usize = 8; +fn build_contract_type_registry( + dojo_event_contracts: &[Felt], + erc20_addresses: &[Felt], + erc721_addresses: &[Felt], + erc1155_addresses: &[Felt], +) -> Arc>> { + let mut contract_types = HashMap::new(); + for &contract in dojo_event_contracts { + contract_types.insert(contract, RegisteredContractType::World); + } + for &contract in erc20_addresses { + contract_types.insert(contract, RegisteredContractType::Erc20); + } + for &contract in erc721_addresses { + contract_types.insert(contract, RegisteredContractType::Erc721); + } + for &contract in erc1155_addresses { + contract_types.insert(contract, RegisteredContractType::Erc1155); + } + Arc::new(RwLock::new(contract_types)) +} + struct ArcadeProjectionPipeline { - introspect_sink: Box, - arcade_sink: Box, + sinks: Vec>, } impl ArcadeProjectionPipeline { - fn new(introspect_sink: Box, arcade_sink: Box) -> Self { - Self { - introspect_sink, - arcade_sink, - } + fn new(sinks: Vec>) -> Self { + Self { sinks } } fn abort_on_sink_failure(stage: &str, sink_name: &str, error: anyhow::Error) -> ! { @@ -90,12 +111,7 @@ impl Sink for ArcadeProjectionPipeline { fn interested_types(&self) -> Vec { let mut seen = HashSet::new(); let mut interested = Vec::new(); - for type_id in self - .introspect_sink - .interested_types() - .into_iter() - .chain(self.arcade_sink.interested_types()) - { + for type_id in self.sinks.iter().flat_map(|sink| sink.interested_types()) { if seen.insert(type_id) { interested.push(type_id); } @@ -108,25 +124,28 @@ impl Sink for ArcadeProjectionPipeline { envelopes: &[torii::etl::Envelope], batch: &torii::etl::extractor::ExtractionBatch, ) -> anyhow::Result<()> { - if let Err(error) = self.introspect_sink.process(envelopes, batch).await { - Self::abort_on_sink_failure("process", self.introspect_sink.name(), error); - } - if let Err(error) = self.arcade_sink.process(envelopes, batch).await { - Self::abort_on_sink_failure("process", self.arcade_sink.name(), error); + for sink in &self.sinks { + if let Err(error) = sink.process(envelopes, batch).await { + Self::abort_on_sink_failure("process", sink.name(), error); + } } Ok(()) } fn topics(&self) -> Vec { - let mut topics = self.introspect_sink.topics(); - topics.extend(self.arcade_sink.topics()); + let mut topics = Vec::new(); + for sink in &self.sinks { + topics.extend(sink.topics()); + } topics } fn build_routes(&self) -> Router { - self.introspect_sink - .build_routes() - .merge(self.arcade_sink.build_routes()) + let mut router = Router::new(); + for sink in &self.sinks { + router = router.merge(sink.build_routes()); + } + router } async fn initialize( @@ -134,10 +153,9 @@ impl Sink for ArcadeProjectionPipeline { event_bus: Arc, context: &SinkContext, ) -> anyhow::Result<()> { - self.introspect_sink - .initialize(event_bus.clone(), context) - .await?; - self.arcade_sink.initialize(event_bus, context).await?; + for sink in &mut self.sinks { + sink.initialize(event_bus.clone(), context).await?; + } Ok(()) } } @@ -185,6 +203,7 @@ async fn run_indexer(config: Config) -> Result<()> { let dojo_event_contracts = config.dojo_event_contract_addresses()?; let introspect_contracts = config.introspect_contract_addresses()?; + let historical_models = config.historical_models(); let mut erc20_addresses = config.erc20_addresses()?; let erc721_addresses = config.erc721_addresses()?; let erc1155_addresses = config.erc1155_addresses()?; @@ -247,6 +266,7 @@ async fn run_indexer(config: Config) -> Result<()> { "disabled" } ); + tracing::info!("Historical models tracked: {}", historical_models.len()); let excluded_dojo_contracts: Vec = dojo_event_contracts .iter() @@ -327,6 +347,14 @@ async fn run_indexer(config: Config) -> Result<()> { Some(erc20_db_url.as_str()), Some(erc721_db_url.as_str()), Some(erc1155_db_url.as_str()), + build_contract_type_registry( + &dojo_event_contracts, + &erc20_addresses, + &erc721_addresses, + &erc1155_addresses, + ), + false, + HashSet::new(), ) .await?; let ecs_grpc_service = ecs_sink.get_grpc_service_impl(); @@ -343,8 +371,20 @@ async fn run_indexer(config: Config) -> Result<()> { .register_encoded_file_descriptor_set(ECS_DESCRIPTOR_SET) .register_encoded_file_descriptor_set(ARCADE_DESCRIPTOR_SET); - let arcade_projection_pipeline = - ArcadeProjectionPipeline::new(introspect_sink, Box::new(arcade_sink)); + let historical_sink = Box::new( + EntitiesHistoricalSink::new( + &storage_database_url, + config.max_db_connections, + (), + historical_models, + ) + .await?, + ); + let arcade_projection_pipeline = ArcadeProjectionPipeline::new(vec![ + introspect_sink, + historical_sink, + Box::new(arcade_sink), + ]); let mut torii_config = torii::ToriiConfig::builder() .port(config.port) diff --git a/bins/torii-introspect-bin/Cargo.toml b/bins/torii-introspect-bin/Cargo.toml index bffe1bdb..df05fd10 100644 --- a/bins/torii-introspect-bin/Cargo.toml +++ b/bins/torii-introspect-bin/Cargo.toml @@ -18,6 +18,7 @@ torii-erc20 = { path = "../../crates/torii-erc20" } torii-erc721 = { path = "../../crates/torii-erc721" } torii-erc1155 = { path = "../../crates/torii-erc1155" } torii-ecs-sink = { path = "../../crates/torii-ecs-sink" } +torii-entities-historical-sink.workspace = true torii-introspect-postgres-sink = { path = "../../crates/introspect-postgres-sink" } torii-introspect-sqlite-sink = { path = "../../crates/introspect-sqlite-sink" } torii-runtime-common.workspace = true diff --git a/bins/torii-introspect-bin/src/config.rs b/bins/torii-introspect-bin/src/config.rs index 88d6ce0a..6fb58b41 100644 --- a/bins/torii-introspect-bin/src/config.rs +++ b/bins/torii-introspect-bin/src/config.rs @@ -119,6 +119,14 @@ pub struct Config { /// Ignore persisted extractor state and force extraction from `from_block`. #[arg(long)] pub ignore_saved_state: bool, + + /// Enable runtime indexing for Dojo `ExternalContractRegistered` events. + #[arg(long)] + pub index_external_contracts: bool, + + /// Exact Dojo model names to mirror into append-only `_historical` tables. + #[arg(long, value_delimiter = ',')] + pub historical: Vec, } impl Config { @@ -148,6 +156,16 @@ impl Config { Self::parse_addresses("ERC1155", &self.erc1155) } + pub fn historical_models(&self) -> Vec { + let mut models = Vec::with_capacity(self.historical.len()); + for model in &self.historical { + if !model.is_empty() && !models.contains(model) { + models.push(model.clone()); + } + } + models + } + pub fn storage_backend(&self) -> StorageBackend { if self.storage_database_url.is_some() { StorageBackend::Postgres @@ -278,4 +296,37 @@ mod tests { assert_eq!(cfg.erc721_addresses().unwrap(), vec![Felt::from(3_u64)]); assert_eq!(cfg.erc1155_addresses().unwrap(), vec![Felt::from(4_u64)]); } + + #[test] + fn external_contract_indexing_defaults_to_disabled() { + let cfg = Config::parse_from(["torii-server", "--contract", "0x1"]); + assert!(!cfg.index_external_contracts); + } + + #[test] + fn external_contract_indexing_flag_enables_runtime_registration() { + let cfg = Config::parse_from([ + "torii-server", + "--contract", + "0x1", + "--index-external-contracts", + ]); + assert!(cfg.index_external_contracts); + } + + #[test] + fn historical_models_parse_as_exact_names() { + let cfg = Config::parse_from([ + "torii-server", + "--contract", + "0x1", + "--historical", + "NUMS-Game,NUMS-Config,NUMS-Game", + ]); + + assert_eq!( + cfg.historical_models(), + vec!["NUMS-Game".to_string(), "NUMS-Config".to_string()] + ); + } } diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index 95595491..e9c561d7 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -11,20 +11,27 @@ use starknet::core::types::Felt; use std::collections::{HashMap, HashSet}; use std::path::Path; use std::sync::Arc; +use tokio::sync::RwLock; use tonic::codec::CompressionEncoding; use torii::etl::decoder::DecoderId; use torii::etl::extractor::{ ContractEventConfig, EventExtractor, EventExtractorConfig, Extractor, RetryPolicy, }; +use torii::etl::EngineDb; use torii::{EtlConcurrencyConfig, ToriiConfigBuilder}; use torii_common::{MetadataFetcher, TokenUriService}; use torii_config_common::apply_observability_env; use torii_controllers_sink::ControllersSink; use torii_dojo::decoder::DojoDecoder; +use torii_dojo::external_contract::{ + contract_type_from_decoder_ids, RegisterExternalContractCommandHandler, RegisteredContractType, + SharedContractTypeRegistry, SharedDecoderRegistry, +}; use torii_dojo::store::postgres::PgStore; use torii_dojo::store::sqlite::SqliteStore; use torii_ecs_sink::proto::world::world_server::WorldServer; use torii_ecs_sink::{EcsSink, FILE_DESCRIPTOR_SET as ECS_DESCRIPTOR_SET}; +use torii_entities_historical_sink::EntitiesHistoricalSink; use torii_erc1155::proto::erc1155_server::Erc1155Server; use torii_erc1155::{ Erc1155Decoder, Erc1155MetadataCommandHandler, Erc1155Service, Erc1155Sink, Erc1155Storage, @@ -54,6 +61,85 @@ const TOKEN_METADATA_COMMAND_PARALLELISM: usize = 1; const TOKEN_METADATA_MAX_RETRIES: u8 = 3; const TOKEN_URI_FETCH_PARALLELISM: usize = 8; +struct OrderedSinkPipeline { + name: String, + sinks: Vec>, +} + +impl OrderedSinkPipeline { + fn new(name: impl Into) -> Self { + Self { + name: name.into(), + sinks: Vec::new(), + } + } + + fn push(mut self, sink: Box) -> Self { + self.sinks.push(sink); + self + } +} + +#[torii::async_trait] +impl torii::etl::sink::Sink for OrderedSinkPipeline { + fn name(&self) -> &str { + &self.name + } + + fn interested_types(&self) -> Vec { + let mut seen = HashSet::new(); + let mut interested = Vec::new(); + for type_id in self + .sinks + .iter() + .flat_map(|sink| sink.interested_types().into_iter()) + { + if seen.insert(type_id) { + interested.push(type_id); + } + } + interested + } + + async fn process( + &self, + envelopes: &[torii::etl::Envelope], + batch: &torii::etl::extractor::ExtractionBatch, + ) -> Result<()> { + for sink in &self.sinks { + sink.process(envelopes, batch).await?; + } + Ok(()) + } + + fn topics(&self) -> Vec { + let mut topics = Vec::new(); + for sink in &self.sinks { + topics.extend(sink.topics()); + } + topics + } + + fn build_routes(&self) -> torii::axum::Router { + let mut router = torii::axum::Router::new(); + for sink in &self.sinks { + router = router.merge(sink.build_routes()); + } + router + } + + async fn initialize( + &mut self, + event_bus: Arc, + context: &torii::etl::sink::SinkContext, + ) -> Result<()> { + for sink in &mut self.sinks { + sink.initialize(event_bus.clone(), context).await?; + } + Ok(()) + } +} + #[derive(Clone, Debug, Default)] struct TokenTargets { erc20: Vec, @@ -86,6 +172,57 @@ struct TokenGrpcServices { erc1155: Option, } +fn build_static_contract_type_registry( + contracts: &[Felt], + token_targets: &TokenTargets, +) -> SharedContractTypeRegistry { + let mut contract_types = HashMap::new(); + for &contract in contracts { + contract_types.insert(contract, RegisteredContractType::World); + } + for &contract in &token_targets.erc20 { + contract_types.insert(contract, RegisteredContractType::Erc20); + } + for &contract in &token_targets.erc721 { + contract_types.insert(contract, RegisteredContractType::Erc721); + } + for &contract in &token_targets.erc1155 { + contract_types.insert(contract, RegisteredContractType::Erc1155); + } + Arc::new(RwLock::new(contract_types)) +} + +async fn load_persisted_contract_registries( + engine_db: &EngineDb, + decoder_registry: &SharedDecoderRegistry, + contract_type_registry: &SharedContractTypeRegistry, +) -> Result<()> { + let mappings = engine_db.get_all_contract_decoders().await?; + let mut decoders = decoder_registry.write().await; + let mut contract_types = contract_type_registry.write().await; + + for (contract, decoder_ids, _) in mappings { + decoders.insert(contract, decoder_ids.clone()); + if let Some(contract_type) = contract_type_from_decoder_ids(&decoder_ids) { + contract_types.insert(contract, contract_type); + } + } + + Ok(()) +} + +fn installed_external_decoder_ids(enabled: bool) -> HashSet { + if !enabled { + return HashSet::new(); + } + + HashSet::from([ + DecoderId::new("erc20"), + DecoderId::new("erc721"), + DecoderId::new("erc1155"), + ]) +} + fn append_unique_contract_configs( configs: &mut Vec, seen: &mut HashSet, @@ -155,6 +292,7 @@ fn apply_contract_mappings( async fn configure_token_support( token_targets: &TokenTargets, token_db_setup: Option<&TokenDbSetup>, + enable_external_contracts: bool, provider: Arc, mut torii_config: ToriiConfigBuilder, mut reflection_builder: ReflectionBuilder, @@ -166,8 +304,11 @@ async fn configure_token_support( )> { let mut services = TokenGrpcServices::default(); let mut token_uri_services = Vec::new(); + let install_erc20 = enable_external_contracts || !token_targets.erc20.is_empty(); + let install_erc721 = enable_external_contracts || !token_targets.erc721.is_empty(); + let install_erc1155 = enable_external_contracts || !token_targets.erc1155.is_empty(); - if !token_targets.has_any() { + if !install_erc20 && !install_erc721 && !install_erc1155 { return Ok(( torii_config, reflection_builder, @@ -177,9 +318,9 @@ async fn configure_token_support( } let db_setup = - token_db_setup.expect("token DB setup must exist when token targets are configured"); + token_db_setup.expect("token DB setup must exist when token support is configured"); - if !token_targets.erc20.is_empty() { + if install_erc20 { let storage = Arc::new(Erc20Storage::new(&db_setup.erc20_url).await?); tracing::info!("ERC20 database initialized: {}", db_setup.erc20_url); @@ -209,7 +350,7 @@ async fn configure_token_support( reflection_builder.register_encoded_file_descriptor_set(ERC20_DESCRIPTOR_SET); } - if !token_targets.erc721.is_empty() { + if install_erc721 { let storage = Arc::new(Erc721Storage::new(&db_setup.erc721_url).await?); tracing::info!("ERC721 database initialized: {}", db_setup.erc721_url); @@ -244,7 +385,7 @@ async fn configure_token_support( reflection_builder.register_encoded_file_descriptor_set(ERC721_DESCRIPTOR_SET); } - if !token_targets.erc1155.is_empty() { + if install_erc1155 { let storage = Arc::new(Erc1155Storage::new(&db_setup.erc1155_url).await?); tracing::info!("ERC1155 database initialized: {}", db_setup.erc1155_url); @@ -311,7 +452,8 @@ async fn run_indexer(config: Config) -> Result<()> { let engine_database_url = config.engine_database_url(db_dir); let contracts = config.contract_addresses()?; let token_targets = TokenTargets::from_config(&config)?; - let token_db_setup = if token_targets.has_any() { + let historical_models = config.historical_models(); + let token_db_setup = if token_targets.has_any() || config.index_external_contracts { Some(resolve_token_db_setup( db_dir, config.database_url.as_deref(), @@ -378,6 +520,32 @@ async fn run_indexer(config: Config) -> Result<()> { "disabled" } ); + tracing::info!( + "External contract indexing: {}", + if config.index_external_contracts { + "enabled" + } else { + "disabled" + } + ); + tracing::info!("Historical models tracked: {}", historical_models.len()); + + let registry_engine_db = Arc::new( + EngineDb::new(torii::etl::engine_db::EngineDbConfig { + path: engine_database_url.clone(), + }) + .await?, + ); + let decoder_registry: SharedDecoderRegistry = Arc::new(RwLock::new(HashMap::new())); + let contract_type_registry = build_static_contract_type_registry(&contracts, &token_targets); + load_persisted_contract_registries( + registry_engine_db.as_ref(), + &decoder_registry, + &contract_type_registry, + ) + .await?; + let installed_external_decoders = + installed_external_decoder_ids(config.index_external_contracts); let provider = starknet::providers::jsonrpc::JsonRpcClient::new( starknet::providers::jsonrpc::HttpTransport::new( @@ -442,6 +610,11 @@ async fn run_indexer(config: Config) -> Result<()> { contracts, token_targets, token_db_setup, + registry_engine_db.clone(), + decoder_registry.clone(), + contract_type_registry.clone(), + installed_external_decoders.clone(), + historical_models.clone(), provider, extractor, ) @@ -455,6 +628,11 @@ async fn run_indexer(config: Config) -> Result<()> { contracts, token_targets, token_db_setup, + registry_engine_db.clone(), + decoder_registry.clone(), + contract_type_registry.clone(), + installed_external_decoders.clone(), + historical_models.clone(), provider, extractor, ) @@ -473,6 +651,11 @@ async fn run_with_postgres( contracts: Vec, token_targets: TokenTargets, token_db_setup: Option, + registry_engine_db: Arc, + decoder_registry: SharedDecoderRegistry, + contract_type_registry: SharedContractTypeRegistry, + installed_external_decoders: HashSet, + historical_models: Vec, provider: StarknetProvider, extractor: Box, ) -> Result<()> { @@ -486,9 +669,8 @@ async fn run_with_postgres( ); let decoder = DojoDecoder::, _>::new(pool.clone(), provider); - let sink = IntrospectPgDb::new(pool.clone(), ()); + let introspect_sink = IntrospectPgDb::new(pool.clone(), ()); decoder.store.initialize().await?; - sink.initialize_introspect_pg_sink().await?; decoder.load_tables(&[]).await?; let decoder: Arc = Arc::new(decoder); @@ -511,6 +693,9 @@ async fn run_with_postgres( erc20_url, erc721_url, erc1155_url, + contract_type_registry.clone(), + config.index_external_contracts, + installed_external_decoders.clone(), ) .await?; let ecs_grpc_service = ecs_sink.get_grpc_service_impl(); @@ -519,7 +704,7 @@ async fn run_with_postgres( .register_encoded_file_descriptor_set(torii::TORII_DESCRIPTOR_SET) .register_encoded_file_descriptor_set(ECS_DESCRIPTOR_SET); - let torii_config = torii::ToriiConfig::builder() + let mut torii_config = torii::ToriiConfig::builder() .port(config.port) .command_bus_queue_size(TOKEN_COMMAND_QUEUE_SIZE) .with_custom_reflection(true) @@ -530,7 +715,28 @@ async fn run_with_postgres( .with_extractor(extractor) .add_decoder(decoder) .add_sink_boxed(Box::new(ecs_sink)) - .add_sink_boxed(Box::new(sink)); + .add_sink_boxed(Box::new( + OrderedSinkPipeline::new("introspect-projection-pipeline") + .push(Box::new(introspect_sink)) + .push(Box::new( + EntitiesHistoricalSink::new( + storage_database_url, + config.max_db_connections, + (), + historical_models, + ) + .await?, + )), + )); + if config.index_external_contracts { + torii_config = torii_config + .with_registry_cache(decoder_registry.clone()) + .with_command_handler(Box::new(RegisterExternalContractCommandHandler::new( + registry_engine_db.clone(), + decoder_registry.clone(), + contract_type_registry.clone(), + ))); + } let torii_config = if config.controllers { torii_config.add_sink_boxed(Box::new( ControllersSink::new( @@ -548,6 +754,7 @@ async fn run_with_postgres( configure_token_support( &token_targets, token_db_setup.as_ref(), + config.index_external_contracts, token_provider, torii_config, reflection_builder, @@ -637,6 +844,11 @@ async fn run_with_sqlite( contracts: Vec, token_targets: TokenTargets, token_db_setup: Option, + registry_engine_db: Arc, + decoder_registry: SharedDecoderRegistry, + contract_type_registry: SharedContractTypeRegistry, + installed_external_decoders: HashSet, + historical_models: Vec, provider: StarknetProvider, extractor: Box, ) -> Result<()> { @@ -688,6 +900,9 @@ async fn run_with_sqlite( erc20_url, erc721_url, erc1155_url, + contract_type_registry.clone(), + config.index_external_contracts, + installed_external_decoders.clone(), ) .await?; let ecs_grpc_service = ecs_sink.get_grpc_service_impl(); @@ -696,7 +911,7 @@ async fn run_with_sqlite( .register_encoded_file_descriptor_set(torii::TORII_DESCRIPTOR_SET) .register_encoded_file_descriptor_set(ECS_DESCRIPTOR_SET); - let torii_config = torii::ToriiConfig::builder() + let mut torii_config = torii::ToriiConfig::builder() .port(config.port) .command_bus_queue_size(TOKEN_COMMAND_QUEUE_SIZE) .with_custom_reflection(true) @@ -707,7 +922,28 @@ async fn run_with_sqlite( .with_extractor(extractor) .add_decoder(decoder) .add_sink_boxed(Box::new(ecs_sink)) - .add_sink_boxed(Box::new(IntrospectSqliteDb::new(pool.clone(), ()))); + .add_sink_boxed(Box::new( + OrderedSinkPipeline::new("introspect-projection-pipeline") + .push(Box::new(IntrospectSqliteDb::new(pool.clone(), ()))) + .push(Box::new( + EntitiesHistoricalSink::new( + storage_database_url, + config.max_db_connections, + (), + historical_models, + ) + .await?, + )), + )); + if config.index_external_contracts { + torii_config = torii_config + .with_registry_cache(decoder_registry.clone()) + .with_command_handler(Box::new(RegisterExternalContractCommandHandler::new( + registry_engine_db.clone(), + decoder_registry.clone(), + contract_type_registry.clone(), + ))); + } let torii_config = if config.controllers { torii_config.add_sink_boxed(Box::new( ControllersSink::new( @@ -725,6 +961,7 @@ async fn run_with_sqlite( configure_token_support( &token_targets, token_db_setup.as_ref(), + config.index_external_contracts, token_provider, torii_config, reflection_builder, diff --git a/crates/dojo/src/decoder.rs b/crates/dojo/src/decoder.rs index 5a60293b..1b95122d 100644 --- a/crates/dojo/src/decoder.rs +++ b/crates/dojo/src/decoder.rs @@ -1,3 +1,4 @@ +use crate::external_contract::{ExternalContractRegistered, ExternalContractRegisteredEvent}; use crate::store::DojoStoreTrait; use crate::table::{sort_columns, DojoTableInfo}; use crate::{DojoTable, DojoToriiError, DojoToriiResult}; @@ -243,6 +244,14 @@ where .ok_into() } + fn process_external_contract_event<'a>( + &self, + keys: &'a [Felt], + values: &'a [Felt], + ) -> DojoToriiResult { + deserialize_data::(keys, values).map(Into::into) + } + pub async fn decode_event_data( &self, raw: &EmittedEvent, @@ -314,9 +323,20 @@ where } async fn decode_event(&self, event: &EmittedEvent) -> AnyResult> { - self.decode_raw_event(event) + let (selector, keys) = event + .split_keys() + .ok_or(DojoToriiError::MissingEventSelector)?; + + if selector.to_raw() == ExternalContractRegisteredEvent::SELECTOR_RAW { + return self + .process_external_contract_event(keys, &event.data) + .map(|msg| vec![msg.to_envelope(event)]) + .err_into(); + } + + self.decode_event_data(event, selector, keys, &event.data) .await - .map(|msg| vec![msg.into()]) + .map(|msg| vec![msg.to_body(event).into()]) .err_into() } } @@ -324,9 +344,12 @@ where #[cfg(test)] mod tests { use super::*; + use crate::ExternalContractRegisteredBody; use async_trait::async_trait; use dojo_introspect::DojoIntrospectError; - use introspect_types::{Attribute, ColumnDef, TypeDef}; + use introspect_types::{ + utils::string_to_cairo_serialize_byte_array, Attribute, ColumnDef, TypeDef, + }; use std::sync::Mutex; #[derive(Debug, thiserror::Error)] @@ -422,4 +445,44 @@ mod tests { assert_eq!(parsed, 3); assert_eq!(*decoder.store.saved_blocks.lock().unwrap(), vec![42]); } + + #[tokio::test] + async fn decode_external_contract_registered_event_emits_control_envelope() { + let decoder: DojoDecoder = + DojoDecoder::with_tables(FakeStore::default(), PanicFetcher, Vec::new()); + + let mut keys = vec![ExternalContractRegisteredEvent::SELECTOR]; + keys.extend(string_to_cairo_serialize_byte_array("tokens")); + keys.extend(string_to_cairo_serialize_byte_array("ERC20")); + keys.extend(string_to_cairo_serialize_byte_array("eth")); + keys.push(Felt::from_hex("0x99").unwrap()); + + let event = EmittedEvent { + from_address: Felt::from_hex("0x1").unwrap(), + keys, + data: vec![ + Felt::from_hex("0xabc").unwrap(), + Felt::from_hex("0x1234").unwrap(), + Felt::from(42_u64), + ], + block_hash: None, + block_number: Some(42), + transaction_hash: Felt::from_hex("0xbeef").unwrap(), + }; + + let envelopes = decoder.decode_event(&event).await.unwrap(); + assert_eq!(envelopes.len(), 1); + let body = envelopes[0] + .downcast_ref::() + .unwrap(); + + assert_eq!(body.msg.namespace, "tokens"); + assert_eq!(body.msg.contract_name, "ERC20"); + assert_eq!(body.msg.instance_name, "eth"); + assert_eq!(body.msg.contract_selector, Felt::from_hex("0x99").unwrap()); + assert_eq!(body.msg.class_hash, Felt::from_hex("0xabc").unwrap()); + assert_eq!(body.msg.contract_address, Felt::from_hex("0x1234").unwrap()); + assert_eq!(body.msg.registration_block, 42); + assert_eq!(body.metadata.from_address, Felt::from_hex("0x1").unwrap()); + } } diff --git a/crates/dojo/src/external_contract.rs b/crates/dojo/src/external_contract.rs new file mode 100644 index 00000000..70f8aaaa --- /dev/null +++ b/crates/dojo/src/external_contract.rs @@ -0,0 +1,382 @@ +use anyhow::{Context, Result}; +use async_trait::async_trait; +use introspect_types::{ + cairo_event_name_and_selector, CairoDeserialize, CairoDeserializer, CairoEvent, CairoSerde, + DecodeResult, FeltSource, +}; +use serde::{Deserialize, Serialize}; +use starknet::core::types::Felt; +use std::collections::{HashMap, HashSet}; +use std::sync::Arc; +use tokio::sync::RwLock; +use torii::command::{Command, CommandHandler}; +use torii::etl::decoder::DecoderId; +use torii::etl::engine_db::EngineDb; +use torii::etl::{EventBody, EventMsg, TypeId}; + +const EVENT_EXTRACTOR_TYPE: &str = "event"; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum RegisteredContractType { + World, + Erc20, + Erc721, + Erc1155, + Other, +} + +pub type SharedContractTypeRegistry = Arc>>; +pub type SharedDecoderRegistry = Arc>>>; + +#[derive(Debug)] +pub struct ExternalContractRegisteredEvent { + pub namespace: String, + pub contract_name: String, + pub instance_name: String, + pub contract_selector: Felt, + pub class_hash: Felt, + pub contract_address: Felt, + pub block_number: u64, +} + +impl CairoEvent> for ExternalContractRegisteredEvent { + fn deserialize_event( + keys: &mut K, + data: &mut CairoSerde, + ) -> DecodeResult { + let mut keys: CairoSerde<_> = keys.into(); + let namespace = keys.next_string()?; + let contract_name = keys.next_string()?; + let instance_name = keys.next_string()?; + let contract_selector = keys.next()?; + let class_hash = data.next()?; + let contract_address = data.next()?; + let block_number = >::deserialize(data)?; + Ok(Self { + namespace, + contract_name, + instance_name, + contract_selector, + class_hash, + contract_address, + block_number, + }) + } +} + +cairo_event_name_and_selector!( + ExternalContractRegisteredEvent, + "ExternalContractRegistered" +); + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ExternalContractRegistered { + pub namespace: String, + pub contract_name: String, + pub instance_name: String, + pub contract_selector: Felt, + pub class_hash: Felt, + pub contract_address: Felt, + pub registration_block: u64, +} + +impl From for ExternalContractRegistered { + fn from(value: ExternalContractRegisteredEvent) -> Self { + Self { + namespace: value.namespace, + contract_name: value.contract_name, + instance_name: value.instance_name, + contract_selector: value.contract_selector, + class_hash: value.class_hash, + contract_address: value.contract_address, + registration_block: value.block_number, + } + } +} + +pub type ExternalContractRegisteredBody = EventBody; + +impl EventMsg for ExternalContractRegistered { + fn event_id(&self) -> String { + format!( + "dojo.external_contract_registered.{:064x}.{}", + self.contract_address, self.registration_block + ) + } + + fn envelope_type_id(&self) -> TypeId { + TypeId::new("dojo.external_contract_registered") + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ResolvedExternalContract { + pub contract_type: RegisteredContractType, + pub decoder_ids: Vec, +} + +pub fn resolve_external_contract(contract_name: &str) -> Option { + let normalized = contract_name + .chars() + .filter(|ch| ch.is_ascii_alphanumeric()) + .collect::() + .to_ascii_uppercase(); + + match normalized.as_str() { + "ERC20" => Some(ResolvedExternalContract { + contract_type: RegisteredContractType::Erc20, + decoder_ids: vec![DecoderId::new("erc20")], + }), + "ERC721" => Some(ResolvedExternalContract { + contract_type: RegisteredContractType::Erc721, + decoder_ids: vec![DecoderId::new("erc721")], + }), + "ERC1155" => Some(ResolvedExternalContract { + contract_type: RegisteredContractType::Erc1155, + decoder_ids: vec![DecoderId::new("erc1155")], + }), + _ => None, + } +} + +pub fn contract_type_from_decoder_ids(decoder_ids: &[DecoderId]) -> Option { + let ids: HashSet<_> = decoder_ids.iter().copied().collect(); + if ids.len() != 1 { + return None; + } + + if ids.contains(&DecoderId::new("erc20")) { + Some(RegisteredContractType::Erc20) + } else if ids.contains(&DecoderId::new("erc721")) { + Some(RegisteredContractType::Erc721) + } else if ids.contains(&DecoderId::new("erc1155")) { + Some(RegisteredContractType::Erc1155) + } else { + None + } +} + +#[derive(Debug, Clone)] +pub struct RegisterExternalContractCommand { + pub world_address: Felt, + pub contract_address: Felt, + pub contract_name: String, + pub namespace: String, + pub instance_name: String, + pub registration_block: u64, + pub contract_type: RegisteredContractType, + pub decoder_ids: Vec, +} + +pub struct RegisterExternalContractCommandHandler { + engine_db: Arc, + decoder_registry: SharedDecoderRegistry, + contract_type_registry: SharedContractTypeRegistry, +} + +impl RegisterExternalContractCommandHandler { + pub fn new( + engine_db: Arc, + decoder_registry: SharedDecoderRegistry, + contract_type_registry: SharedContractTypeRegistry, + ) -> Self { + Self { + engine_db, + decoder_registry, + contract_type_registry, + } + } +} + +#[async_trait] +impl CommandHandler for RegisterExternalContractCommandHandler { + fn supports(&self, command: &dyn Command) -> bool { + command.as_any().is::() + } + + async fn handle_command(&self, command: Box) -> Result<()> { + let command = command + .into_any() + .downcast::() + .map_err(|_| anyhow::anyhow!("invalid external contract registration command"))?; + let command = *command; + + self.engine_db + .set_contract_decoders(command.contract_address, &command.decoder_ids) + .await + .with_context(|| { + format!( + "failed to persist decoder mapping for {:#x}", + command.contract_address + ) + })?; + + let state_key = format!("{:#x}", command.contract_address); + let existing_state = self + .engine_db + .get_extractor_state(EVENT_EXTRACTOR_TYPE, &state_key) + .await + .with_context(|| { + format!( + "failed to load extractor state for {:#x}", + command.contract_address + ) + })?; + + if existing_state.is_none() { + self.engine_db + .set_extractor_state( + EVENT_EXTRACTOR_TYPE, + &state_key, + &format!("block:{}", command.registration_block), + ) + .await + .with_context(|| { + format!( + "failed to persist extractor state for {:#x}", + command.contract_address + ) + })?; + } else { + tracing::debug!( + target: "torii::dojo::external_contract", + world = format!("{:#x}", command.world_address), + contract = format!("{:#x}", command.contract_address), + "External contract already has extractor state; keeping current progress" + ); + } + + self.decoder_registry + .write() + .await + .insert(command.contract_address, command.decoder_ids); + self.contract_type_registry + .write() + .await + .insert(command.contract_address, command.contract_type); + + tracing::info!( + target: "torii::dojo::external_contract", + world = format!("{:#x}", command.world_address), + contract = format!("{:#x}", command.contract_address), + namespace = command.namespace, + contract_name = command.contract_name, + instance_name = command.instance_name, + registration_block = command.registration_block, + "Registered external contract for runtime indexing" + ); + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use torii::etl::engine_db::EngineDbConfig; + + #[test] + fn resolves_supported_contract_names() { + let erc20 = resolve_external_contract("ERC20").unwrap(); + assert_eq!(erc20.contract_type, RegisteredContractType::Erc20); + assert_eq!(erc20.decoder_ids, vec![DecoderId::new("erc20")]); + + let erc721 = resolve_external_contract("erc_721").unwrap(); + assert_eq!(erc721.contract_type, RegisteredContractType::Erc721); + + let erc1155 = resolve_external_contract("Erc-1155").unwrap(); + assert_eq!(erc1155.contract_type, RegisteredContractType::Erc1155); + + assert!(resolve_external_contract("udc").is_none()); + } + + #[tokio::test] + async fn registration_handler_is_idempotent_for_existing_progress() { + let engine_db = Arc::new( + EngineDb::new(EngineDbConfig { + path: "sqlite::memory:".to_string(), + }) + .await + .unwrap(), + ); + let decoder_registry = Arc::new(RwLock::new(HashMap::new())); + let contract_type_registry = Arc::new(RwLock::new(HashMap::new())); + let handler = RegisterExternalContractCommandHandler::new( + engine_db.clone(), + decoder_registry.clone(), + contract_type_registry.clone(), + ); + let contract_address = Felt::from_hex("0x1234").unwrap(); + + handler + .handle_command(Box::new(RegisterExternalContractCommand { + world_address: Felt::ONE, + contract_address, + contract_name: "ERC20".to_string(), + namespace: "tokens".to_string(), + instance_name: "eth".to_string(), + registration_block: 77, + contract_type: RegisteredContractType::Erc20, + decoder_ids: vec![DecoderId::new("erc20")], + })) + .await + .unwrap(); + + engine_db + .set_extractor_state( + EVENT_EXTRACTOR_TYPE, + &format!("{contract_address:#x}"), + "block:91", + ) + .await + .unwrap(); + + handler + .handle_command(Box::new(RegisterExternalContractCommand { + world_address: Felt::ONE, + contract_address, + contract_name: "ERC20".to_string(), + namespace: "tokens".to_string(), + instance_name: "eth".to_string(), + registration_block: 77, + contract_type: RegisteredContractType::Erc20, + decoder_ids: vec![DecoderId::new("erc20")], + })) + .await + .unwrap(); + + assert_eq!( + engine_db + .get_extractor_state(EVENT_EXTRACTOR_TYPE, &format!("{contract_address:#x}")) + .await + .unwrap() + .as_deref(), + Some("block:91") + ); + assert_eq!( + engine_db + .get_contract_decoders(contract_address) + .await + .unwrap() + .unwrap(), + vec![DecoderId::new("erc20")] + ); + assert_eq!( + decoder_registry + .read() + .await + .get(&contract_address) + .cloned() + .unwrap(), + vec![DecoderId::new("erc20")] + ); + assert_eq!( + contract_type_registry + .read() + .await + .get(&contract_address) + .copied(), + Some(RegisteredContractType::Erc20) + ); + } +} diff --git a/crates/dojo/src/lib.rs b/crates/dojo/src/lib.rs index 37a69a77..042aab65 100644 --- a/crates/dojo/src/lib.rs +++ b/crates/dojo/src/lib.rs @@ -1,7 +1,14 @@ pub mod decoder; pub mod error; pub mod event; +pub mod external_contract; pub mod store; pub mod table; pub use error::{DojoToriiError, DojoToriiResult}; +pub use external_contract::{ + contract_type_from_decoder_ids, resolve_external_contract, ExternalContractRegistered, + ExternalContractRegisteredBody, RegisterExternalContractCommand, + RegisterExternalContractCommandHandler, RegisteredContractType, SharedContractTypeRegistry, + SharedDecoderRegistry, +}; pub use table::DojoTable; diff --git a/crates/torii-ecs-sink/src/sink.rs b/crates/torii-ecs-sink/src/sink.rs index 8b48c473..8802c374 100644 --- a/crates/torii-ecs-sink/src/sink.rs +++ b/crates/torii-ecs-sink/src/sink.rs @@ -1,4 +1,5 @@ -use std::sync::Arc; +use std::collections::HashSet; +use std::sync::{Arc, RwLock}; use anyhow::Result; use async_trait::async_trait; @@ -8,17 +9,27 @@ use dojo_introspect::events::{ use introspect_types::event::CairoEventInfo; use starknet::core::types::Felt; use torii::axum::Router; +use torii::command::CommandBusSender; +use torii::etl::decoder::DecoderId; use torii::etl::{ envelope::{Envelope, TypeId}, extractor::ExtractionBatch, sink::{EventBus, Sink, SinkContext, TopicInfo}, }; +use torii_dojo::external_contract::{ + resolve_external_contract, ExternalContractRegisteredBody, RegisterExternalContractCommand, + RegisteredContractType, SharedContractTypeRegistry, +}; use torii_introspect::events::{IntrospectBody, IntrospectMsg}; use crate::grpc_service::{EcsService, TableKind}; pub struct EcsSink { service: Arc, + contract_types: SharedContractTypeRegistry, + external_contract_indexing: bool, + installed_external_decoders: HashSet, + command_bus: RwLock>, } impl EcsSink { @@ -28,6 +39,9 @@ impl EcsSink { erc20_url: Option<&str>, erc721_url: Option<&str>, erc1155_url: Option<&str>, + contract_types: SharedContractTypeRegistry, + external_contract_indexing: bool, + installed_external_decoders: HashSet, ) -> Result { Ok(Self { service: Arc::new( @@ -40,12 +54,107 @@ impl EcsSink { ) .await?, ), + contract_types, + external_contract_indexing, + installed_external_decoders, + command_bus: RwLock::new(None), }) } pub fn get_grpc_service_impl(&self) -> Arc { self.service.clone() } + + async fn contract_type_for(&self, contract_address: Felt) -> crate::proto::types::ContractType { + let contract_type = self + .contract_types + .read() + .await + .get(&contract_address) + .copied() + .unwrap_or(RegisteredContractType::World); + + match contract_type { + RegisteredContractType::World => crate::proto::types::ContractType::World, + RegisteredContractType::Erc20 => crate::proto::types::ContractType::Erc20, + RegisteredContractType::Erc721 => crate::proto::types::ContractType::Erc721, + RegisteredContractType::Erc1155 => crate::proto::types::ContractType::Erc1155, + RegisteredContractType::Other => crate::proto::types::ContractType::Other, + } + } + + async fn handle_external_contract_registered(&self, body: &ExternalContractRegisteredBody) { + if !self.external_contract_indexing { + tracing::debug!( + target: "torii::ecs_sink", + contract = format!("{:#x}", body.msg.contract_address), + "External contract registration ignored because runtime indexing is disabled" + ); + return; + } + + let Some(resolved) = resolve_external_contract(&body.msg.contract_name) else { + tracing::warn!( + target: "torii::ecs_sink", + world = format!("{:#x}", body.metadata.from_address), + contract = format!("{:#x}", body.msg.contract_address), + contract_name = %body.msg.contract_name, + "Unsupported external contract registration; skipping runtime indexing" + ); + return; + }; + + let missing_decoders: Vec<_> = resolved + .decoder_ids + .iter() + .copied() + .filter(|decoder_id| !self.installed_external_decoders.contains(decoder_id)) + .collect(); + if !missing_decoders.is_empty() { + tracing::warn!( + target: "torii::ecs_sink", + world = format!("{:#x}", body.metadata.from_address), + contract = format!("{:#x}", body.msg.contract_address), + contract_name = %body.msg.contract_name, + missing_decoders = ?missing_decoders, + "External contract registration skipped because matching decoders are not installed" + ); + return; + } + + let command_bus = self + .command_bus + .read() + .ok() + .and_then(|guard| guard.as_ref().cloned()); + let Some(command_bus) = command_bus else { + tracing::warn!( + target: "torii::ecs_sink", + contract = format!("{:#x}", body.msg.contract_address), + "External contract registration dropped because the command bus is unavailable" + ); + return; + }; + + if let Err(error) = command_bus.dispatch(RegisterExternalContractCommand { + world_address: body.metadata.from_address, + contract_address: body.msg.contract_address, + contract_name: body.msg.contract_name.clone(), + namespace: body.msg.namespace.clone(), + instance_name: body.msg.instance_name.clone(), + registration_block: body.msg.registration_block, + contract_type: resolved.contract_type, + decoder_ids: resolved.decoder_ids, + }) { + tracing::warn!( + target: "torii::ecs_sink", + world = format!("{:#x}", body.metadata.from_address), + contract = format!("{:#x}", body.msg.contract_address), + error = %error, + "Failed to enqueue external contract registration command" + ); + } + } } #[async_trait] @@ -55,7 +164,10 @@ impl Sink for EcsSink { } fn interested_types(&self) -> Vec { - vec![TypeId::new("introspect")] + vec![ + TypeId::new("introspect"), + TypeId::new("dojo.external_contract_registered"), + ] } async fn process(&self, envelopes: &[Envelope], batch: &ExtractionBatch) -> Result<()> { @@ -78,7 +190,7 @@ impl Sink for EcsSink { self.service .record_contract_progress( event.from_address, - crate::proto::types::ContractType::World, + self.contract_type_for(event.from_address).await, context.transaction.block_number, context.block.timestamp, None, @@ -119,6 +231,13 @@ impl Sink for EcsSink { } for envelope in envelopes { + if envelope.type_id == TypeId::new("dojo.external_contract_registered") { + if let Some(body) = envelope.downcast_ref::() { + self.handle_external_contract_registered(body).await; + } + continue; + } + if envelope.type_id != TypeId::new("introspect") { continue; } @@ -232,11 +351,10 @@ impl Sink for EcsSink { Router::new() } - async fn initialize( - &mut self, - _event_bus: Arc, - _context: &SinkContext, - ) -> Result<()> { + async fn initialize(&mut self, _event_bus: Arc, context: &SinkContext) -> Result<()> { + if let Ok(mut command_bus) = self.command_bus.write() { + *command_bus = Some(context.command_bus.clone()); + } self.service.attach_erc_databases().await?; Ok(()) } diff --git a/crates/torii-entities-historical-sink/Cargo.toml b/crates/torii-entities-historical-sink/Cargo.toml new file mode 100644 index 00000000..162195c2 --- /dev/null +++ b/crates/torii-entities-historical-sink/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "torii-entities-historical-sink" +version = "0.1.0" +edition = "2021" +description = "Append-only historical entity sink for Torii introspect models" +authors = ["Torii Runtime "] +license = "Apache-2.0" + +[dependencies] +anyhow.workspace = true +async-trait.workspace = true +serde.workspace = true +serde_json.workspace = true +sqlx = { workspace = true, features = ["any", "postgres", "sqlite", "runtime-tokio-rustls"] } +starknet.workspace = true +tokio.workspace = true +torii.workspace = true +tracing.workspace = true +thiserror.workspace = true +introspect-types.workspace = true + +torii-introspect.workspace = true + +[lints] +workspace = true diff --git a/crates/torii-entities-historical-sink/src/lib.rs b/crates/torii-entities-historical-sink/src/lib.rs new file mode 100644 index 00000000..79976dbf --- /dev/null +++ b/crates/torii-entities-historical-sink/src/lib.rs @@ -0,0 +1,1118 @@ +use std::collections::{HashMap, HashSet}; +use std::sync::Arc; + +use anyhow::{anyhow, Context, Result}; +use async_trait::async_trait; +use sqlx::any::AnyPoolOptions; +use sqlx::{Any, Pool, Row}; +use starknet::core::types::Felt; +use tokio::sync::RwLock; +use torii::axum::Router; +use torii::etl::envelope::{Envelope, TypeId}; +use torii::etl::extractor::ExtractionBatch; +use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; +use torii_introspect::events::{CreateTable, IntrospectBody, IntrospectMsg, UpdateTable}; +use torii_introspect::schema::TableSchema; + +const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); +const SQLITE_SCHEMA_STATE_TABLE: &str = "introspect_sink_schema_state"; +const PG_METADATA_SCHEMA: &str = "introspect"; +const PG_METADATA_TABLES: &str = "db_tables"; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum DbBackend { + Sqlite, + Postgres, +} + +impl DbBackend { + fn detect(database_url: &str) -> Self { + if database_url.starts_with("postgres://") || database_url.starts_with("postgresql://") { + Self::Postgres + } else { + Self::Sqlite + } + } +} + +#[derive(Clone, Debug, Default)] +pub enum HistoricalNamespace { + #[default] + Default, + Custom(String), +} + +impl HistoricalNamespace { + fn sqlite_prefix(&self) -> &str { + match self { + Self::Default => "", + Self::Custom(prefix) => prefix, + } + } + + fn postgres_schema(&self) -> &str { + match self { + Self::Default => "public", + Self::Custom(schema) => schema, + } + } +} + +impl From<()> for HistoricalNamespace { + fn from(_: ()) -> Self { + Self::Default + } +} + +impl From for HistoricalNamespace { + fn from(value: String) -> Self { + if value.is_empty() { + Self::Default + } else { + Self::Custom(value) + } + } +} + +impl From<&str> for HistoricalNamespace { + fn from(value: &str) -> Self { + if value.is_empty() { + Self::Default + } else { + Self::Custom(value.to_string()) + } + } +} + +#[derive(Clone, Debug)] +struct HistoryColumn { + name: String, + type_sql: String, +} + +#[derive(Clone, Debug)] +struct TrackedTable { + logical_name: String, + base_name: String, + history_name: String, + columns: Vec, +} + +#[derive(Clone)] +pub struct EntitiesHistoricalSink { + pool: Pool, + backend: DbBackend, + namespace: HistoricalNamespace, + tracked_names: HashSet, + tracked_tables: Arc>>, +} + +impl EntitiesHistoricalSink { + pub async fn new( + database_url: &str, + max_connections: Option, + namespace: impl Into, + tracked_models: Vec, + ) -> Result { + sqlx::any::install_default_drivers(); + + let backend = DbBackend::detect(database_url); + let database_url = match backend { + DbBackend::Postgres => database_url.to_string(), + DbBackend::Sqlite => sqlite_url(database_url)?, + }; + let pool = AnyPoolOptions::new() + .max_connections(max_connections.unwrap_or(if backend == DbBackend::Sqlite { + 1 + } else { + 5 + })) + .connect(&database_url) + .await?; + + Ok(Self { + pool, + backend, + namespace: namespace.into(), + tracked_names: tracked_models + .into_iter() + .filter(|name| !name.is_empty()) + .collect(), + tracked_tables: Arc::new(RwLock::new(HashMap::new())), + }) + } + + async fn bootstrap(&self) -> Result<()> { + if self.tracked_names.is_empty() { + return Ok(()); + } + + if self.backend == DbBackend::Sqlite { + sqlx::query("PRAGMA journal_mode=WAL") + .execute(&self.pool) + .await + .ok(); + } + + match self.backend { + DbBackend::Sqlite => { + let rows = sqlx::query(&format!( + "SELECT table_schema_json FROM {SQLITE_SCHEMA_STATE_TABLE} WHERE alive != 0" + )) + .fetch_all(&self.pool) + .await?; + for row in rows { + let schema_json: String = row.try_get("table_schema_json")?; + let schema: TableSchema = serde_json::from_str(&schema_json)?; + if self.tracked_names.contains(&schema.name) { + self.sync_tracked_table(schema.id, &schema.name).await?; + } + } + } + DbBackend::Postgres => { + let rows = sqlx::query(&format!( + "SELECT id, name FROM {PG_METADATA_SCHEMA}.{PG_METADATA_TABLES} WHERE \"schema\" = $1" + )) + .bind(self.namespace.postgres_schema()) + .fetch_all(&self.pool) + .await?; + for row in rows { + let table_name: String = row.try_get("name")?; + if !self.tracked_names.contains(&table_name) { + continue; + } + let table_id = felt_from_row_hex(&row, "id")?; + self.sync_tracked_table(table_id, &table_name).await?; + } + } + } + + Ok(()) + } + + async fn resolve_tracked_table(&self, table_id: Felt) -> Result> { + if let Some(table) = self.tracked_tables.read().await.get(&table_id).cloned() { + return Ok(Some(table)); + } + + let resolved = self.lookup_table_name(table_id).await?; + let Some(table_name) = resolved else { + return Ok(None); + }; + if !self.tracked_names.contains(&table_name) { + return Ok(None); + } + + let tracked = self.sync_tracked_table(table_id, &table_name).await?; + Ok(Some(tracked)) + } + + async fn lookup_table_name(&self, table_id: Felt) -> Result> { + let (canonical_table_id, compact_table_id) = felt_hex_variants(table_id); + match self.backend { + DbBackend::Sqlite => { + let row = sqlx::query(&format!( + "SELECT table_schema_json FROM {SQLITE_SCHEMA_STATE_TABLE} \ + WHERE table_id = ?1 OR table_id = ?2 LIMIT 1" + )) + .bind(canonical_table_id) + .bind(compact_table_id) + .fetch_optional(&self.pool) + .await?; + row.map(|row| { + let schema_json: String = row.try_get("table_schema_json")?; + let schema: TableSchema = serde_json::from_str(&schema_json)?; + Ok::<_, anyhow::Error>(schema.name) + }) + .transpose() + } + DbBackend::Postgres => { + let row = sqlx::query(&format!( + "SELECT name FROM {PG_METADATA_SCHEMA}.{PG_METADATA_TABLES} \ + WHERE \"schema\" = $1 AND (id::text = $2 OR id::text = $3) LIMIT 1" + )) + .bind(self.namespace.postgres_schema()) + .bind(canonical_table_id) + .bind(compact_table_id) + .fetch_optional(&self.pool) + .await?; + row.map(|row| row.try_get("name").map_err(Into::into)) + .transpose() + } + } + } + + async fn sync_tracked_table(&self, table_id: Felt, logical_name: &str) -> Result { + let base_name = match self.backend { + DbBackend::Sqlite => sqlite_storage_name(self.namespace.sqlite_prefix(), logical_name), + DbBackend::Postgres => logical_name.to_string(), + }; + let history_name = match self.backend { + DbBackend::Sqlite => sqlite_storage_name( + self.namespace.sqlite_prefix(), + &format!("{logical_name}_historical"), + ), + DbBackend::Postgres => format!("{logical_name}_historical"), + }; + let columns = self.load_source_columns(&base_name).await?; + if !columns.iter().any(|column| column.name == "entity_id") { + return Err(anyhow!( + "tracked table '{logical_name}' does not expose entity_id column" + )); + } + let tracked = TrackedTable { + logical_name: logical_name.to_string(), + base_name, + history_name, + columns, + }; + self.ensure_history_table(&tracked).await?; + self.tracked_tables + .write() + .await + .insert(table_id, tracked.clone()); + Ok(tracked) + } + + async fn load_source_columns(&self, base_name: &str) -> Result> { + match self.backend { + DbBackend::Sqlite => { + let rows = sqlx::query(&format!( + "PRAGMA table_info({})", + quote_sqlite_identifier(base_name) + )) + .fetch_all(&self.pool) + .await?; + let mut columns = Vec::with_capacity(rows.len()); + for row in rows { + let name: String = row.try_get("name")?; + let type_sql: String = row.try_get("type")?; + columns.push(HistoryColumn { name, type_sql }); + } + Ok(columns) + } + DbBackend::Postgres => { + let rows = sqlx::query( + "SELECT a.attname AS column_name, + pg_catalog.format_type(a.atttypid, a.atttypmod) AS column_type + FROM pg_catalog.pg_attribute a + JOIN pg_catalog.pg_class c ON c.oid = a.attrelid + JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace + WHERE n.nspname = $1 + AND c.relname = $2 + AND a.attnum > 0 + AND NOT a.attisdropped + ORDER BY a.attnum", + ) + .bind(self.namespace.postgres_schema()) + .bind(base_name) + .fetch_all(&self.pool) + .await?; + + let mut columns = Vec::new(); + for row in rows { + let name: String = row.try_get("column_name")?; + if name.starts_with("__") { + continue; + } + let type_sql: String = row.try_get("column_type")?; + columns.push(HistoryColumn { name, type_sql }); + } + Ok(columns) + } + } + } + + async fn ensure_history_table(&self, tracked: &TrackedTable) -> Result<()> { + let create_sql = match self.backend { + DbBackend::Sqlite => self.create_history_table_sqlite(tracked), + DbBackend::Postgres => self.create_history_table_postgres(tracked), + }; + sqlx::query(&create_sql).execute(&self.pool).await?; + + let existing_columns = self.load_existing_history_columns(tracked).await?; + for column in &tracked.columns { + if existing_columns.contains(&column.name) { + continue; + } + let add_sql = match self.backend { + DbBackend::Sqlite => format!( + "ALTER TABLE {} ADD COLUMN {} {}", + quote_sqlite_identifier(&tracked.history_name), + quote_ident(&column.name), + column.type_sql + ), + DbBackend::Postgres => format!( + "ALTER TABLE {} ADD COLUMN IF NOT EXISTS {} {}", + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name), + quote_ident(&column.name), + column.type_sql + ), + }; + sqlx::query(&add_sql).execute(&self.pool).await?; + } + + for meta_sql in self.ensure_history_meta_columns_sql(tracked, &existing_columns) { + sqlx::query(&meta_sql).execute(&self.pool).await?; + } + + for index_sql in self.ensure_history_indexes_sql(tracked) { + sqlx::query(&index_sql).execute(&self.pool).await?; + } + + Ok(()) + } + + async fn load_existing_history_columns( + &self, + tracked: &TrackedTable, + ) -> Result> { + let rows = match self.backend { + DbBackend::Sqlite => { + sqlx::query(&format!( + "PRAGMA table_info({})", + quote_sqlite_identifier(&tracked.history_name) + )) + .fetch_all(&self.pool) + .await? + } + DbBackend::Postgres => { + sqlx::query( + "SELECT a.attname AS column_name + FROM pg_catalog.pg_attribute a + JOIN pg_catalog.pg_class c ON c.oid = a.attrelid + JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace + WHERE n.nspname = $1 + AND c.relname = $2 + AND a.attnum > 0 + AND NOT a.attisdropped", + ) + .bind(self.namespace.postgres_schema()) + .bind(&tracked.history_name) + .fetch_all(&self.pool) + .await? + } + }; + let mut columns = HashSet::with_capacity(rows.len()); + for row in rows { + let name = if self.backend == DbBackend::Sqlite { + row.try_get("name")? + } else { + row.try_get("column_name")? + }; + columns.insert(name); + } + Ok(columns) + } + + fn create_history_table_sqlite(&self, tracked: &TrackedTable) -> String { + let model_columns = tracked + .columns + .iter() + .map(|column| { + if column.name == "entity_id" { + format!("{} {} NOT NULL", quote_ident(&column.name), column.type_sql) + } else { + format!("{} {}", quote_ident(&column.name), column.type_sql) + } + }) + .collect::>() + .join(", "); + format!( + "CREATE TABLE IF NOT EXISTS {} ({model_columns}, \ + \"revision\" INTEGER NOT NULL DEFAULT 0, \ + \"historical_deleted\" INTEGER NOT NULL DEFAULT 0, \ + \"historical_block_number\" INTEGER, \ + \"historical_tx_hash\" TEXT NOT NULL DEFAULT '', \ + \"historical_executed_at\" INTEGER NOT NULL DEFAULT 0)", + quote_sqlite_identifier(&tracked.history_name) + ) + } + + fn create_history_table_postgres(&self, tracked: &TrackedTable) -> String { + let model_columns = tracked + .columns + .iter() + .map(|column| { + if column.name == "entity_id" { + format!("{} {} NOT NULL", quote_ident(&column.name), column.type_sql) + } else { + format!("{} {}", quote_ident(&column.name), column.type_sql) + } + }) + .collect::>() + .join(", "); + format!( + "CREATE TABLE IF NOT EXISTS {} ({model_columns}, \ + \"revision\" BIGINT NOT NULL DEFAULT 0, \ + \"historical_deleted\" BOOLEAN NOT NULL DEFAULT FALSE, \ + \"historical_block_number\" BIGINT, \ + \"historical_tx_hash\" TEXT NOT NULL DEFAULT '', \ + \"historical_executed_at\" BIGINT NOT NULL DEFAULT 0)", + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ) + } + + fn ensure_history_meta_columns_sql( + &self, + tracked: &TrackedTable, + existing_columns: &HashSet, + ) -> Vec { + match self.backend { + DbBackend::Sqlite => { + let mut sql = Vec::new(); + let target = quote_sqlite_identifier(&tracked.history_name); + if !existing_columns.contains("revision") { + sql.push(format!( + "ALTER TABLE {target} ADD COLUMN \"revision\" INTEGER NOT NULL DEFAULT 0" + )); + } + if !existing_columns.contains("historical_deleted") { + sql.push(format!( + "ALTER TABLE {target} ADD COLUMN \"historical_deleted\" INTEGER NOT NULL DEFAULT 0" + )); + } + if !existing_columns.contains("historical_block_number") { + sql.push(format!( + "ALTER TABLE {target} ADD COLUMN \"historical_block_number\" INTEGER" + )); + } + if !existing_columns.contains("historical_tx_hash") { + sql.push(format!( + "ALTER TABLE {target} ADD COLUMN \"historical_tx_hash\" TEXT NOT NULL DEFAULT ''" + )); + } + if !existing_columns.contains("historical_executed_at") { + sql.push(format!( + "ALTER TABLE {target} ADD COLUMN \"historical_executed_at\" INTEGER NOT NULL DEFAULT 0" + )); + } + sql + } + DbBackend::Postgres => vec![ + format!( + "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"revision\" BIGINT NOT NULL DEFAULT 0", + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ), + format!( + "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"historical_deleted\" BOOLEAN NOT NULL DEFAULT FALSE", + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ), + format!( + "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"historical_block_number\" BIGINT", + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ), + format!( + "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"historical_tx_hash\" TEXT NOT NULL DEFAULT ''", + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ), + format!( + "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"historical_executed_at\" BIGINT NOT NULL DEFAULT 0", + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ), + ], + } + } + + fn ensure_history_indexes_sql(&self, tracked: &TrackedTable) -> Vec { + let unique_index = format!("{}_entity_revision_idx", tracked.history_name); + let entity_index = format!("{}_entity_idx", tracked.history_name); + match self.backend { + DbBackend::Sqlite => vec![ + format!( + "CREATE UNIQUE INDEX IF NOT EXISTS {} ON {} (\"entity_id\", \"revision\")", + quote_ident(&unique_index), + quote_sqlite_identifier(&tracked.history_name) + ), + format!( + "CREATE INDEX IF NOT EXISTS {} ON {} (\"entity_id\")", + quote_ident(&entity_index), + quote_sqlite_identifier(&tracked.history_name) + ), + ], + DbBackend::Postgres => vec![ + format!( + "CREATE UNIQUE INDEX IF NOT EXISTS {} ON {} (\"entity_id\", \"revision\")", + quote_ident(&unique_index), + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ), + format!( + "CREATE INDEX IF NOT EXISTS {} ON {} (\"entity_id\")", + quote_ident(&entity_index), + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ), + ], + } + } + + async fn next_revision( + &self, + tracked: &TrackedTable, + canonical_entity_id_hex: &str, + compact_entity_id_hex: &str, + ) -> Result { + let sql = match self.backend { + DbBackend::Sqlite => format!( + "SELECT COALESCE(MAX(\"revision\"), 0) + 1 AS next_revision \ + FROM {} WHERE \"entity_id\" = ?1 OR \"entity_id\" = ?2", + quote_sqlite_identifier(&tracked.history_name) + ), + DbBackend::Postgres => format!( + "SELECT COALESCE(MAX(\"revision\"), 0) + 1 AS next_revision \ + FROM {} WHERE \"entity_id\"::text = $1 OR \"entity_id\"::text = $2", + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + ), + }; + let row = sqlx::query(&sql) + .bind(canonical_entity_id_hex) + .bind(compact_entity_id_hex) + .fetch_one(&self.pool) + .await?; + Ok(row.try_get::("next_revision")?) + } + + async fn persist_snapshot( + &self, + tracked: &TrackedTable, + entity_id: Felt, + block_number: Option, + tx_hash: Felt, + executed_at: u64, + deleted: bool, + ) -> Result<()> { + let (canonical_entity_id_hex, compact_entity_id_hex) = felt_hex_variants(entity_id); + let revision = self + .next_revision(tracked, &canonical_entity_id_hex, &compact_entity_id_hex) + .await?; + let copied = self + .copy_current_row_into_history( + tracked, + &canonical_entity_id_hex, + &compact_entity_id_hex, + revision, + block_number, + tx_hash, + executed_at, + deleted, + ) + .await?; + if copied == 0 { + if deleted { + self.insert_tombstone_only( + tracked, + &canonical_entity_id_hex, + revision, + block_number, + tx_hash, + executed_at, + ) + .await?; + return Ok(()); + } + return Err(anyhow!( + "unable to load latest row for tracked model '{}' entity {}", + tracked.logical_name, + canonical_entity_id_hex + )); + } + Ok(()) + } + + async fn copy_current_row_into_history( + &self, + tracked: &TrackedTable, + canonical_entity_id_hex: &str, + compact_entity_id_hex: &str, + revision: i64, + block_number: Option, + tx_hash: Felt, + executed_at: u64, + deleted: bool, + ) -> Result { + let source_columns = tracked + .columns + .iter() + .map(|column| quote_ident(&column.name)) + .collect::>() + .join(", "); + let insert_columns = format!( + "{source_columns}, \"revision\", \"historical_deleted\", \ + \"historical_block_number\", \"historical_tx_hash\", \"historical_executed_at\"" + ); + let history_target = match self.backend { + DbBackend::Sqlite => quote_sqlite_identifier(&tracked.history_name), + DbBackend::Postgres => { + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + } + }; + let source_target = match self.backend { + DbBackend::Sqlite => quote_sqlite_identifier(&tracked.base_name), + DbBackend::Postgres => { + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.base_name) + } + }; + let where_entity = match self.backend { + DbBackend::Sqlite => "(\"entity_id\" = ?6 OR \"entity_id\" = ?7)", + DbBackend::Postgres => "(\"entity_id\"::text = $6 OR \"entity_id\"::text = $7)", + }; + let placeholder = match self.backend { + DbBackend::Sqlite => "?", + DbBackend::Postgres => "$", + }; + let revision_ph = format!("{placeholder}1"); + let deleted_ph = format!("{placeholder}2"); + let block_ph = format!("{placeholder}3"); + let tx_ph = format!("{placeholder}4"); + let executed_ph = format!("{placeholder}5"); + let sql = format!( + "INSERT INTO {history_target} ({insert_columns}) \ + SELECT {source_columns}, {revision_ph}, {deleted_ph}, {block_ph}, {tx_ph}, {executed_ph} \ + FROM {source_target} WHERE {where_entity} LIMIT 1" + ); + let mut query = sqlx::query(&sql).bind(revision); + query = match self.backend { + DbBackend::Sqlite => query.bind(i64::from(deleted)), + DbBackend::Postgres => query.bind(deleted), + }; + let result = query + .bind(block_number.map(|value| value as i64)) + .bind(felt_hex(tx_hash)) + .bind(executed_at as i64) + .bind(canonical_entity_id_hex) + .bind(compact_entity_id_hex) + .execute(&self.pool) + .await?; + Ok(result.rows_affected()) + } + + async fn insert_tombstone_only( + &self, + tracked: &TrackedTable, + entity_id_hex: &str, + revision: i64, + block_number: Option, + tx_hash: Felt, + executed_at: u64, + ) -> Result<()> { + let mut columns = Vec::with_capacity(tracked.columns.len() + 5); + let mut values_sql = Vec::with_capacity(tracked.columns.len() + 5); + + let mut bind_index = 1_usize; + for column in &tracked.columns { + columns.push(quote_ident(&column.name)); + if column.name == "entity_id" { + values_sql.push(self.entity_cast_placeholder(bind_index, &column.type_sql)); + bind_index += 1; + } else { + values_sql.push("NULL".to_string()); + } + } + + columns.extend([ + "\"revision\"".to_string(), + "\"historical_deleted\"".to_string(), + "\"historical_block_number\"".to_string(), + "\"historical_tx_hash\"".to_string(), + "\"historical_executed_at\"".to_string(), + ]); + values_sql.push(self.value_placeholder(bind_index)); + bind_index += 1; + values_sql.push(self.value_placeholder(bind_index)); + bind_index += 1; + values_sql.push(self.value_placeholder(bind_index)); + bind_index += 1; + values_sql.push(self.value_placeholder(bind_index)); + bind_index += 1; + values_sql.push(self.value_placeholder(bind_index)); + + let target = match self.backend { + DbBackend::Sqlite => quote_sqlite_identifier(&tracked.history_name), + DbBackend::Postgres => { + quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) + } + }; + let sql = format!( + "INSERT INTO {target} ({}) VALUES ({})", + columns.join(", "), + values_sql.join(", ") + ); + + let mut query = sqlx::query(&sql).bind(entity_id_hex).bind(revision); + query = match self.backend { + DbBackend::Sqlite => query.bind(1_i64), + DbBackend::Postgres => query.bind(true), + }; + query + .bind(block_number.map(|value| value as i64)) + .bind(felt_hex(tx_hash)) + .bind(executed_at as i64) + .execute(&self.pool) + .await?; + + Ok(()) + } + + fn value_placeholder(&self, index: usize) -> String { + match self.backend { + DbBackend::Sqlite => "?".to_string(), + DbBackend::Postgres => format!("${index}"), + } + } + + fn entity_cast_placeholder(&self, index: usize, type_sql: &str) -> String { + match self.backend { + DbBackend::Sqlite => "?".to_string(), + DbBackend::Postgres => format!("CAST(${index} AS {type_sql})"), + } + } + + async fn process_table_schema(&self, table: &CreateTable) -> Result<()> { + if self.tracked_names.contains(&table.name) { + self.sync_tracked_table(table.id, &table.name).await?; + } + Ok(()) + } + + async fn process_table_update(&self, table: &UpdateTable) -> Result<()> { + if self.tracked_names.contains(&table.name) { + self.sync_tracked_table(table.id, &table.name).await?; + } + Ok(()) + } +} + +#[async_trait] +impl Sink for EntitiesHistoricalSink { + fn name(&self) -> &'static str { + "entities-historical" + } + + fn interested_types(&self) -> Vec { + vec![INTROSPECT_TYPE] + } + + async fn process(&self, envelopes: &[Envelope], batch: &ExtractionBatch) -> Result<()> { + for envelope in envelopes { + if envelope.type_id != INTROSPECT_TYPE { + continue; + } + let Some(body) = envelope.downcast_ref::() else { + continue; + }; + let context = batch + .get_event_context(&body.metadata.transaction_hash, body.metadata.from_address) + .unwrap_or_default(); + let block_number = body + .metadata + .block_number + .or(Some(context.transaction.block_number)); + let executed_at = context.block.timestamp; + + match &body.msg { + IntrospectMsg::CreateTable(table) => { + self.process_table_schema(table).await?; + } + IntrospectMsg::UpdateTable(table) => { + self.process_table_update(table).await?; + } + IntrospectMsg::InsertsFields(insert) => { + let Some(tracked) = self.resolve_tracked_table(insert.table).await? else { + continue; + }; + for record in &insert.records { + self.persist_snapshot( + &tracked, + Felt::from_bytes_be(&record.id), + block_number, + body.metadata.transaction_hash, + executed_at, + false, + ) + .await + .with_context(|| { + format!( + "failed to persist historical snapshot for '{}' insert", + tracked.logical_name + ) + })?; + } + } + IntrospectMsg::DeleteRecords(delete) => { + let Some(tracked) = self.resolve_tracked_table(delete.table).await? else { + continue; + }; + for row in &delete.rows { + self.persist_snapshot( + &tracked, + row.to_felt(), + block_number, + body.metadata.transaction_hash, + executed_at, + true, + ) + .await + .with_context(|| { + format!( + "failed to persist historical tombstone for '{}'", + tracked.logical_name + ) + })?; + } + } + _ => {} + } + } + + Ok(()) + } + + fn topics(&self) -> Vec { + Vec::new() + } + + fn build_routes(&self) -> Router { + Router::new() + } + + async fn initialize( + &mut self, + _event_bus: Arc, + _context: &SinkContext, + ) -> Result<()> { + self.bootstrap().await?; + Ok(()) + } +} + +fn sqlite_storage_name(prefix: &str, logical_name: &str) -> String { + if prefix.is_empty() { + logical_name.to_string() + } else { + format!("{prefix}__{logical_name}") + } +} + +fn sqlite_url(database_url: &str) -> Result { + if database_url == ":memory:" { + return Ok("sqlite::memory:".to_string()); + } + if database_url.starts_with("sqlite:") { + return Ok(database_url.to_string()); + } + Ok(format!("sqlite://{database_url}")) +} + +fn quote_ident(identifier: &str) -> String { + format!("\"{}\"", identifier.replace('"', "\"\"")) +} + +fn quote_sqlite_identifier(table: &str) -> String { + quote_ident(table) +} + +fn quote_pg_qualified(schema: &str, table: &str) -> String { + format!("{}.{}", quote_ident(schema), quote_ident(table)) +} + +fn felt_hex(value: Felt) -> String { + format!("{value:#x}") +} + +fn canonical_felt_hex(value: Felt) -> String { + format!("{value:#066x}") +} + +fn compact_hex_str(value: &str) -> String { + let value = value.trim(); + let Some(hex) = value.strip_prefix("0x") else { + return value.to_string(); + }; + let trimmed = hex.trim_start_matches('0'); + if trimmed.is_empty() { + "0x0".to_string() + } else { + format!("0x{trimmed}") + } +} + +fn felt_hex_variants(value: Felt) -> (String, String) { + let canonical = canonical_felt_hex(value); + let compact = compact_hex_str(&canonical); + (canonical, compact) +} + +fn felt_from_row_hex(row: &sqlx::any::AnyRow, column: &str) -> Result { + let value: String = row.try_get(column)?; + Felt::from_hex(&value).map_err(Into::into) +} + +#[cfg(test)] +mod tests { + use super::*; + use introspect_types::{ColumnDef, PrimaryDef, PrimaryTypeDef, TypeDef}; + use torii::etl::envelope::{EventBody, MetaData}; + use torii::etl::extractor::ExtractionBatch; + use torii_introspect::events::{DeleteRecords, InsertsFields, IntrospectMsg, Record}; + + fn sqlite_table_schema(name: &str, id: Felt) -> TableSchema { + TableSchema { + id, + name: name.to_string(), + attributes: Vec::new(), + primary: PrimaryDef { + name: "entity_id".to_string(), + attributes: Vec::new(), + type_def: PrimaryTypeDef::Felt252, + }, + columns: vec![ + ColumnDef { + id: Felt::from(1_u8), + name: "name".to_string(), + attributes: Vec::new(), + type_def: TypeDef::ByteArray, + }, + ColumnDef { + id: Felt::from(2_u8), + name: "score".to_string(), + attributes: Vec::new(), + type_def: TypeDef::U32, + }, + ], + } + } + + async fn sqlite_sink() -> Result { + let sink = EntitiesHistoricalSink::new( + "sqlite::memory:", + Some(1), + (), + vec!["NUMS-Game".to_string()], + ) + .await?; + sqlx::query( + "CREATE TABLE introspect_sink_schema_state ( + table_id TEXT PRIMARY KEY, + table_schema_json TEXT NOT NULL, + alive INTEGER NOT NULL DEFAULT 1, + updated_at INTEGER NOT NULL DEFAULT (unixepoch()) + )", + ) + .execute(&sink.pool) + .await?; + sqlx::query( + "CREATE TABLE \"NUMS-Game\" ( + \"entity_id\" TEXT PRIMARY KEY, + \"name\" TEXT, + \"score\" INTEGER + )", + ) + .execute(&sink.pool) + .await?; + let schema = sqlite_table_schema("NUMS-Game", Felt::from(9_u8)); + sqlx::query( + "INSERT INTO introspect_sink_schema_state (table_id, table_schema_json, alive, updated_at) + VALUES (?1, ?2, 1, unixepoch())", + ) + .bind(canonical_felt_hex(schema.id)) + .bind(serde_json::to_string(&schema)?) + .execute(&sink.pool) + .await?; + Ok(sink) + } + + #[tokio::test] + async fn initializes_history_table_from_sqlite_schema_state() -> Result<()> { + let sink = sqlite_sink().await?; + sink.bootstrap().await?; + + let row = sqlx::query( + "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'NUMS-Game_historical'", + ) + .fetch_one(&sink.pool) + .await?; + let name: String = row.try_get("name")?; + assert_eq!(name, "NUMS-Game_historical"); + Ok(()) + } + + #[tokio::test] + async fn appends_revisions_and_delete_tombstones_in_sqlite() -> Result<()> { + let sink = sqlite_sink().await?; + sink.bootstrap().await?; + + let entity_id = Felt::from(77_u8); + sqlx::query( + "INSERT INTO \"NUMS-Game\" (\"entity_id\", \"name\", \"score\") VALUES (?1, ?2, ?3)", + ) + .bind(canonical_felt_hex(entity_id)) + .bind("first") + .bind(10_i64) + .execute(&sink.pool) + .await?; + + let insert = EventBody { + metadata: MetaData { + block_number: Some(1), + transaction_hash: Felt::from(100_u16), + from_address: Felt::ZERO, + }, + msg: IntrospectMsg::InsertsFields(InsertsFields::new( + Felt::from(9_u8), + Vec::new(), + vec![Record::new(entity_id, Vec::new())], + )), + }; + sink.process(&[Envelope::from(insert)], &ExtractionBatch::empty()) + .await?; + + sqlx::query("UPDATE \"NUMS-Game\" SET \"score\" = 25 WHERE \"entity_id\" = ?1") + .bind(canonical_felt_hex(entity_id)) + .execute(&sink.pool) + .await?; + let update = EventBody { + metadata: MetaData { + block_number: Some(2), + transaction_hash: Felt::from(101_u16), + from_address: Felt::ZERO, + }, + msg: IntrospectMsg::InsertsFields(InsertsFields::new( + Felt::from(9_u8), + Vec::new(), + vec![Record::new(entity_id, Vec::new())], + )), + }; + sink.process(&[Envelope::from(update)], &ExtractionBatch::empty()) + .await?; + + let delete = EventBody { + metadata: MetaData { + block_number: Some(3), + transaction_hash: Felt::from(102_u16), + from_address: Felt::ZERO, + }, + msg: IntrospectMsg::DeleteRecords(DeleteRecords::new( + Felt::from(9_u8), + vec![entity_id.into()], + )), + }; + sink.process(&[Envelope::from(delete)], &ExtractionBatch::empty()) + .await?; + + let rows = sqlx::query( + "SELECT revision, historical_deleted, score FROM \"NUMS-Game_historical\" ORDER BY revision", + ) + .fetch_all(&sink.pool) + .await?; + + assert_eq!(rows.len(), 3); + assert_eq!(rows[0].try_get::("revision")?, 1); + assert_eq!(rows[0].try_get::("historical_deleted")?, 0); + assert_eq!(rows[0].try_get::("score")?, 10); + assert_eq!(rows[1].try_get::("revision")?, 2); + assert_eq!(rows[1].try_get::("score")?, 25); + assert_eq!(rows[2].try_get::("revision")?, 3); + assert_eq!(rows[2].try_get::("historical_deleted")?, 1); + assert_eq!(rows[2].try_get::("score")?, 25); + Ok(()) + } +} diff --git a/src/etl/engine_db.rs b/src/etl/engine_db.rs index 81c40059..94215a7d 100644 --- a/src/etl/engine_db.rs +++ b/src/etl/engine_db.rs @@ -353,6 +353,32 @@ impl EngineDb { Ok(()) } + /// List all extractor state rows for an extractor type. + pub async fn get_all_extractor_states( + &self, + extractor_type: &str, + ) -> Result> { + let table = self.table("extractor_state", "engine.extractor_state"); + let sql = match self.backend { + DbBackend::Sqlite => { + format!("SELECT state_key, state_value FROM {table} WHERE extractor_type = ?") + } + DbBackend::Postgres => { + format!("SELECT state_key, state_value FROM {table} WHERE extractor_type = $1") + } + }; + + let rows = sqlx::query(&sql) + .bind(extractor_type) + .fetch_all(&self.pool) + .await?; + + Ok(rows + .into_iter() + .map(|row| (row.get(0), row.get(1))) + .collect()) + } + /// Delete extractor state /// /// # Arguments @@ -789,6 +815,34 @@ mod tests { assert_eq!(missing, None); } + #[tokio::test] + async fn test_get_all_extractor_states() { + let config = EngineDbConfig { + path: ":memory:".to_string(), + }; + + let db = EngineDb::new(config).await.unwrap(); + db.set_extractor_state("event", "0x1", "block:10") + .await + .unwrap(); + db.set_extractor_state("event", "0x2", "block:20") + .await + .unwrap(); + db.set_extractor_state("other", "cursor", "block:30") + .await + .unwrap(); + + let mut rows = db.get_all_extractor_states("event").await.unwrap(); + rows.sort(); + assert_eq!( + rows, + vec![ + ("0x1".to_string(), "block:10".to_string()), + ("0x2".to_string(), "block:20".to_string()) + ] + ); + } + #[tokio::test] async fn test_engine_db_creates_file_backed_sqlite_database() { let dir = tempdir().unwrap(); diff --git a/src/etl/extractor/event.rs b/src/etl/extractor/event.rs index d5ad0804..48e7e8c3 100644 --- a/src/etl/extractor/event.rs +++ b/src/etl/extractor/event.rs @@ -386,10 +386,57 @@ impl EventExtractor { self.contract_states.insert(address, state); } + self.refresh_dynamic_contract_states(engine_db).await?; + self.initialized = true; Ok(()) } + async fn refresh_dynamic_contract_states(&mut self, engine_db: &EngineDb) -> Result<()> { + let persisted_states = engine_db.get_all_extractor_states(EXTRACTOR_TYPE).await?; + + for (state_key, state_value) in persisted_states { + let Ok(address) = Felt::from_hex(&state_key) else { + tracing::debug!( + target: "torii::etl::event", + state_key, + "Skipping non-contract extractor state" + ); + continue; + }; + + if self.contract_states.contains_key(&address) { + continue; + } + + let to_block = self + .config + .contracts + .iter() + .find(|contract| contract.address == address) + .map_or(u64::MAX, |contract| contract.to_block); + let state = + ContractState::deserialize(address, to_block, &state_value).with_context(|| { + format!("failed to deserialize extractor state for {state_key}") + })?; + + if state.is_following_head() { + self.has_following_contracts = true; + } + + tracing::info!( + target: "torii::etl::event", + contract = state_key, + state = state_value, + to_block, + "Loaded dynamic contract extractor state" + ); + self.contract_states.insert(address, state); + } + + Ok(()) + } + /// Build batch request for all active contracts. fn build_batch_requests(&self) -> Vec<(Felt, ProviderRequestData)> { self.contract_states @@ -493,6 +540,7 @@ impl Extractor for EventExtractor { ) -> Result { // Initialize on first call self.initialize(engine_db).await?; + self.refresh_dynamic_contract_states(engine_db).await?; // Check if all contracts are finished (only possible when no following contracts) if self.is_finished() { @@ -990,4 +1038,33 @@ mod tests { 7 ); } + + #[tokio::test] + async fn test_refresh_dynamic_contract_states_loads_runtime_contracts() { + let provider = Arc::new(JsonRpcClient::new(HttpTransport::new( + starknet::providers::Url::parse("http://localhost:5050").unwrap(), + ))); + let mut extractor = EventExtractor::new(provider, EventExtractorConfig::default()); + let engine_db = EngineDb::new(crate::etl::engine_db::EngineDbConfig { + path: "sqlite::memory:".to_string(), + }) + .await + .unwrap(); + let address = Felt::from_hex("0xdead").unwrap(); + + engine_db + .set_extractor_state(EXTRACTOR_TYPE, &format!("{address:#x}"), "block:42") + .await + .unwrap(); + + extractor + .refresh_dynamic_contract_states(&engine_db) + .await + .unwrap(); + + let state = extractor.contract_states.get(&address).unwrap(); + assert_eq!(state.current_block, 42); + assert_eq!(state.to_block, u64::MAX); + assert!(!state.finished); + } } From 2bdc62c0d22d81c9a1f348df134f629a820566ab Mon Sep 17 00:00:00 2001 From: Bengineer Date: Thu, 26 Mar 2026 08:32:53 +0000 Subject: [PATCH 09/21] Refactor SQL execution traits and implement SQLite migration support - Changed the `Executable` trait to return a `BoxFuture` instead of using `async_trait`, improving performance and flexibility. - Introduced `FlexStr` and `FlexQuery` types to handle SQL strings and bind arguments more effectively. - Implemented SQLite migration functionality in the `AcquiredSchema` struct, including methods for managing migration tables and applying migrations. - Updated SQLite connection options and added utility functions for memory database detection. - Added custom types for SQLx integration, including encoding and decoding for `SqlFelt`. - Refactored dependencies in `Cargo.toml` files to streamline SQLx feature usage. - Removed unnecessary `Arc` wrapping for database connection pools in various services. --- Cargo.lock | 62 +- Cargo.toml | 5 - bins/torii-arcade/Cargo.toml | 6 +- bins/torii-arcade/src/main.rs | 40 +- bins/torii-introspect-bin/Cargo.toml | 8 +- bins/torii-introspect-bin/src/main.rs | 43 +- bins/torii-introspect-synth/Cargo.toml | 10 +- bins/torii-introspect-synth/src/main.rs | 16 +- crates/dojo/src/store/postgres.rs | 10 +- crates/introspect-postgres-sink/Cargo.toml | 36 - .../migrations/001_domains.sql | 113 --- .../migrations/002_metadata_function.sql | 11 - .../migrations/003_store.sql | 67 -- .../introspect-postgres-sink/src/backend.rs | 145 ---- crates/introspect-postgres-sink/src/create.rs | 323 -------- .../introspect-postgres-sink/src/handler.rs | 27 - crates/introspect-postgres-sink/src/insert.rs | 90 --- crates/introspect-postgres-sink/src/json.rs | 89 --- crates/introspect-postgres-sink/src/lib.rs | 15 - crates/introspect-postgres-sink/src/query.rs | 692 ------------------ crates/introspect-postgres-sink/src/types.rs | 187 ----- .../introspect-postgres-sink/src/upgrade.rs | 575 --------------- crates/introspect-postgres-sink/src/utils.rs | 95 --- crates/introspect-sql-sink/src/backend.rs | 4 +- crates/introspect-sql-sink/src/lib.rs | 5 + .../src/postgres/backend.rs | 18 +- .../src/postgres/handler.rs | 4 +- crates/introspect-sql-sink/src/processor.rs | 9 +- crates/introspect-sql-sink/src/runtime.rs | 28 +- .../introspect-sql-sink/src/sqlite/backend.rs | 28 +- crates/introspect-sql-sink/src/sqlite/mod.rs | 4 +- crates/introspect-sqlite-sink/Cargo.toml | 36 - .../migrations/001_init.sql | 4 - .../migrations/002_schema_state.sql | 11 - crates/introspect-sqlite-sink/src/backend.rs | 139 ---- crates/introspect-sqlite-sink/src/json.rs | 83 --- crates/introspect-sqlite-sink/src/lib.rs | 6 - .../introspect-sqlite-sink/src/processor.rs | 396 ---------- crates/introspect-sqlite-sink/src/query.rs | 23 - crates/introspect-sqlite-sink/src/sink.rs | 102 --- crates/introspect-sqlite-sink/src/table.rs | 70 -- crates/sql/src/connection.rs | 26 +- crates/sql/src/lib.rs | 2 +- .../src/{postgres.rs => postgres/migrate.rs} | 50 +- crates/sql/src/postgres/mod.rs | 10 + crates/sql/src/postgres/types.rs | 38 + crates/sql/src/query.rs | 245 ++++--- .../sql/src/{sqlite.rs => sqlite/migrate.rs} | 88 +-- crates/sql/src/sqlite/mod.rs | 38 + crates/sql/src/sqlite/types.rs | 51 ++ crates/torii-common/Cargo.toml | 7 - crates/torii-ecs-sink/Cargo.toml | 9 +- crates/torii-ecs-sink/src/grpc_service.rs | 20 +- examples/introspect/restart.rs | 7 +- examples/introspect/simple.rs | 5 +- 55 files changed, 443 insertions(+), 3788 deletions(-) delete mode 100644 crates/introspect-postgres-sink/Cargo.toml delete mode 100644 crates/introspect-postgres-sink/migrations/001_domains.sql delete mode 100644 crates/introspect-postgres-sink/migrations/002_metadata_function.sql delete mode 100644 crates/introspect-postgres-sink/migrations/003_store.sql delete mode 100644 crates/introspect-postgres-sink/src/backend.rs delete mode 100644 crates/introspect-postgres-sink/src/create.rs delete mode 100644 crates/introspect-postgres-sink/src/handler.rs delete mode 100644 crates/introspect-postgres-sink/src/insert.rs delete mode 100644 crates/introspect-postgres-sink/src/json.rs delete mode 100644 crates/introspect-postgres-sink/src/lib.rs delete mode 100644 crates/introspect-postgres-sink/src/query.rs delete mode 100644 crates/introspect-postgres-sink/src/types.rs delete mode 100644 crates/introspect-postgres-sink/src/upgrade.rs delete mode 100644 crates/introspect-postgres-sink/src/utils.rs delete mode 100644 crates/introspect-sqlite-sink/Cargo.toml delete mode 100644 crates/introspect-sqlite-sink/migrations/001_init.sql delete mode 100644 crates/introspect-sqlite-sink/migrations/002_schema_state.sql delete mode 100644 crates/introspect-sqlite-sink/src/backend.rs delete mode 100644 crates/introspect-sqlite-sink/src/json.rs delete mode 100644 crates/introspect-sqlite-sink/src/lib.rs delete mode 100644 crates/introspect-sqlite-sink/src/processor.rs delete mode 100644 crates/introspect-sqlite-sink/src/query.rs delete mode 100644 crates/introspect-sqlite-sink/src/sink.rs delete mode 100644 crates/introspect-sqlite-sink/src/table.rs rename crates/sql/src/{postgres.rs => postgres/migrate.rs} (84%) create mode 100644 crates/sql/src/postgres/mod.rs create mode 100644 crates/sql/src/postgres/types.rs rename crates/sql/src/{sqlite.rs => sqlite/migrate.rs} (63%) create mode 100644 crates/sql/src/sqlite/mod.rs create mode 100644 crates/sql/src/sqlite/types.rs diff --git a/Cargo.lock b/Cargo.lock index 66a82515..906c61b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4622,7 +4622,6 @@ dependencies = [ "torii-erc20", "torii-erc721", "torii-introspect", - "torii-introspect-postgres-sink", "torii-introspect-sql-sink", "torii-log-sink", "torii-sql", @@ -4656,8 +4655,7 @@ dependencies = [ "torii-erc1155", "torii-erc20", "torii-erc721", - "torii-introspect-postgres-sink", - "torii-introspect-sqlite-sink", + "torii-introspect-sql-sink", "torii-runtime-common", "torii-sql", "tracing", @@ -4694,11 +4692,9 @@ dependencies = [ "anyhow", "async-trait", "base64 0.22.1", - "itertools 0.14.0", "reqwest", "serde", "serde_json", - "sqlx", "starknet", "tokio", "tracing", @@ -4927,8 +4923,7 @@ dependencies = [ "torii-erc1155", "torii-erc20", "torii-erc721", - "torii-introspect-postgres-sink", - "torii-introspect-sqlite-sink", + "torii-introspect-sql-sink", "torii-runtime-common", "torii-sql", "tracing", @@ -4936,32 +4931,6 @@ dependencies = [ "url", ] -[[package]] -name = "torii-introspect-postgres-sink" -version = "0.1.0" -dependencies = [ - "anyhow", - "arrayvec", - "async-trait", - "hex", - "introspect-types", - "itertools 0.14.0", - "metrics", - "serde", - "serde_json", - "sqlx", - "starknet", - "starknet-types-core", - "thiserror 2.0.18", - "tokio", - "torii", - "torii-introspect", - "torii-introspect-sql-sink", - "torii-sql", - "tracing", - "xxhash-rust", -] - [[package]] name = "torii-introspect-sql-sink" version = "0.1.0" @@ -4987,30 +4956,6 @@ dependencies = [ "xxhash-rust", ] -[[package]] -name = "torii-introspect-sqlite-sink" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "hex", - "introspect-types", - "itertools 0.14.0", - "metrics", - "serde", - "serde_json", - "sqlx", - "starknet", - "starknet-types-core", - "thiserror 2.0.18", - "tokio", - "torii", - "torii-introspect", - "torii-introspect-sql-sink", - "torii-sql", - "tracing", -] - [[package]] name = "torii-introspect-synth" version = "0.1.0" @@ -5029,8 +4974,7 @@ dependencies = [ "tokio", "torii", "torii-dojo", - "torii-introspect-postgres-sink", - "torii-runtime-common", + "torii-introspect-sql-sink", "tracing", "tracing-subscriber", ] diff --git a/Cargo.toml b/Cargo.toml index 71d6ec36..9d0d5b26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,6 @@ members = [ "crates/introspect", "crates/dojo", "crates/introspect-sql-sink", - "crates/introspect-postgres-sink", - "crates/introspect-sqlite-sink", "crates/testing", "bins/torii-erc20", "bins/torii-erc20-synth", @@ -135,8 +133,6 @@ torii-erc1155.path = "crates/torii-erc1155" torii-dojo.path = "./crates/dojo" torii-introspect.path = "crates/introspect" torii-introspect-sql-sink.path = "./crates/introspect-sql-sink" -torii-introspect-postgres-sink.path = "./crates/introspect-postgres-sink" -torii-introspect-sqlite-sink.path = "./crates/introspect-sqlite-sink" torii-test-utils.path = "crates/testing" [lib] @@ -220,7 +216,6 @@ torii-erc1155.workspace = true torii-dojo = { workspace = true, features = ["postgres", "sqlite"] } torii-introspect.workspace = true torii-common.workspace = true -torii-introspect-postgres-sink.workspace = true torii-test-utils.workspace = true torii-sql = { workspace = true, features = ["postgres", "sqlite"] } torii-introspect-sql-sink = { workspace = true, features = [ diff --git a/bins/torii-arcade/Cargo.toml b/bins/torii-arcade/Cargo.toml index d9436245..9464967a 100644 --- a/bins/torii-arcade/Cargo.toml +++ b/bins/torii-arcade/Cargo.toml @@ -18,8 +18,10 @@ torii-ecs-sink = { path = "../../crates/torii-ecs-sink" } torii-erc20 = { path = "../../crates/torii-erc20" } torii-erc721 = { path = "../../crates/torii-erc721" } torii-erc1155 = { path = "../../crates/torii-erc1155" } -torii-introspect-postgres-sink = { path = "../../crates/introspect-postgres-sink" } -torii-introspect-sqlite-sink = { path = "../../crates/introspect-sqlite-sink" } +torii-introspect-sql-sink = { workspace = true, features = [ + "postgres", + "sqlite", +] } torii-runtime-common.workspace = true torii-sql = { workspace = true, features = ["postgres", "sqlite"] } diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index a9b611d7..c6f24418 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -42,10 +42,9 @@ use torii_erc721::{ Erc721Decoder, Erc721MetadataCommandHandler, Erc721Service, Erc721Sink, Erc721Storage, FILE_DESCRIPTOR_SET as ERC721_DESCRIPTOR_SET, }; -use torii_introspect_postgres_sink::processor::IntrospectPgDb; -use torii_introspect_sqlite_sink::processor::IntrospectSqliteDb; +use torii_introspect_sql_sink::{IntrospectPgDb, IntrospectSqliteDb, NamespaceMode}; use torii_runtime_common::database::{validate_uniform_backends, DatabaseBackend}; -use torii_sqlite::{is_sqlite_memory_path, sqlite_connect_options}; +use torii_sql::sqlite::{is_sqlite_memory_path, sqlite_connect_options}; type StarknetProvider = starknet::providers::jsonrpc::JsonRpcClient; @@ -268,15 +267,13 @@ async fn run_indexer(config: Config) -> Result<()> { ) = match backend { DatabaseBackend::Postgres => { let max_db_connections = config.max_db_connections.unwrap_or(5); - let pool = Arc::new( - PgPoolOptions::new() - .max_connections(max_db_connections) - .connect(&storage_database_url) - .await?, - ); + let pool = PgPoolOptions::new() + .max_connections(max_db_connections) + .connect(&storage_database_url) + .await?; let decoder = DojoDecoder::, _>::new(pool.clone(), (*provider).clone()); - let sink = IntrospectPgDb::new(pool.clone(), ()); + let sink = IntrospectPgDb::new(pool.clone(), NamespaceMode::Address); decoder.store.initialize().await?; decoder.load_tables(&[]).await?; @@ -292,22 +289,18 @@ async fn run_indexer(config: Config) -> Result<()> { None if is_sqlite_memory_path(&storage_database_url) => 1, None => 1, }; - let pool = Arc::new( - SqlitePoolOptions::new() - .max_connections(max_db_connections) - .connect_with(options) - .await?, - ); + let pool = SqlitePoolOptions::new() + .max_connections(max_db_connections) + .connect_with(options) + .await?; sqlx::query("PRAGMA journal_mode=WAL") - .execute(pool.as_ref()) + .execute(&pool) .await?; sqlx::query("PRAGMA synchronous=NORMAL") - .execute(pool.as_ref()) - .await?; - sqlx::query("PRAGMA foreign_keys=ON") - .execute(pool.as_ref()) + .execute(&pool) .await?; + sqlx::query("PRAGMA foreign_keys=ON").execute(&pool).await?; let decoder = DojoDecoder::, _>::new(pool.clone(), (*provider).clone()); decoder.store.initialize().await?; @@ -315,7 +308,10 @@ async fn run_indexer(config: Config) -> Result<()> { ( Arc::new(decoder) as Arc, - Box::new(IntrospectSqliteDb::new(pool.clone(), ())), + Box::new(IntrospectSqliteDb::new( + pool.clone(), + NamespaceMode::Address, + )), ) } }; diff --git a/bins/torii-introspect-bin/Cargo.toml b/bins/torii-introspect-bin/Cargo.toml index c75d7dc7..bcb45c12 100644 --- a/bins/torii-introspect-bin/Cargo.toml +++ b/bins/torii-introspect-bin/Cargo.toml @@ -17,10 +17,12 @@ torii-erc20 = { path = "../../crates/torii-erc20" } torii-erc721 = { path = "../../crates/torii-erc721" } torii-erc1155 = { path = "../../crates/torii-erc1155" } torii-ecs-sink = { path = "../../crates/torii-ecs-sink" } -torii-introspect-postgres-sink = { path = "../../crates/introspect-postgres-sink" } -torii-introspect-sqlite-sink = { path = "../../crates/introspect-sqlite-sink" } +torii-introspect-sql-sink = { path = "../../crates/introspect-sql-sink", features = [ + "postgres", + "sqlite", +] } torii-runtime-common.workspace = true -torii-sql = { path = "../../crates/sql" } +torii-sql = { path = "../../crates/sql", features = ["postgres", "sqlite"] } tokio = { version = "1", features = ["full"] } tracing = "0.1" diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index a862a8ba..06b2b08b 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -38,11 +38,9 @@ use torii_erc721::{ Erc721Decoder, Erc721MetadataCommandHandler, Erc721Service, Erc721Sink, Erc721Storage, FILE_DESCRIPTOR_SET as ERC721_DESCRIPTOR_SET, }; -use torii_introspect_postgres_sink::processor::IntrospectPgDb; -use torii_introspect_postgres_sink::SchemaMode; -use torii_introspect_sqlite_sink::processor::IntrospectSqliteDb; +use torii_introspect_sql_sink::{IntrospectPgDb, IntrospectSqliteDb, NamespaceMode}; use torii_runtime_common::database::{resolve_token_db_setup, TokenDbSetup}; -use torii_sqlite::{is_sqlite_memory_path, sqlite_connect_options}; +use torii_sql::sqlite::{is_sqlite_memory_path, sqlite_connect_options}; type StarknetProvider = starknet::providers::jsonrpc::JsonRpcClient; @@ -466,17 +464,15 @@ async fn run_with_postgres( ) -> Result<()> { let token_provider = Arc::new(provider.clone()); let max_db_connections = config.max_db_connections.unwrap_or(5); - let pool = Arc::new( - PgPoolOptions::new() - .max_connections(max_db_connections) - .connect(storage_database_url) - .await?, - ); + let pool = PgPoolOptions::new() + .max_connections(max_db_connections) + .connect(storage_database_url) + .await?; let decoder = DojoDecoder::, _>::new(pool.clone(), provider); - let sink = IntrospectPgDb::new(pool.clone(), SchemaMode::Address); + let sink = IntrospectPgDb::new(pool.clone(), NamespaceMode::Address); decoder.store.initialize().await?; - sink.initialize_introspect_pg_sink().await?; + sink.initialize_introspect_sql_sink().await?; decoder.load_tables(&[]).await?; let decoder: Arc = Arc::new(decoder); @@ -597,22 +593,18 @@ async fn run_with_sqlite( None if is_sqlite_memory_path(storage_database_url) => 1, None => 1, }; - let pool = Arc::new( - SqlitePoolOptions::new() - .max_connections(max_db_connections) - .connect_with(options) - .await?, - ); + let pool = SqlitePoolOptions::new() + .max_connections(max_db_connections) + .connect_with(options) + .await?; sqlx::query("PRAGMA journal_mode=WAL") - .execute(pool.as_ref()) + .execute(&pool) .await?; sqlx::query("PRAGMA synchronous=NORMAL") - .execute(pool.as_ref()) - .await?; - sqlx::query("PRAGMA foreign_keys=ON") - .execute(pool.as_ref()) + .execute(&pool) .await?; + sqlx::query("PRAGMA foreign_keys=ON").execute(&pool).await?; let decoder = DojoDecoder::, _>::new(pool.clone(), provider); decoder.store.initialize().await?; @@ -638,7 +630,10 @@ async fn run_with_sqlite( .with_extractor(extractor) .add_decoder(decoder) .add_sink_boxed(Box::new(ecs_sink)) - .add_sink_boxed(Box::new(IntrospectSqliteDb::new(pool.clone(), ()))); + .add_sink_boxed(Box::new(IntrospectSqliteDb::new( + pool.clone(), + NamespaceMode::Address, + ))); let (torii_config, reflection_builder, token_services, _token_uri_services) = configure_token_support( diff --git a/bins/torii-introspect-synth/Cargo.toml b/bins/torii-introspect-synth/Cargo.toml index df8a3290..ee1da853 100644 --- a/bins/torii-introspect-synth/Cargo.toml +++ b/bins/torii-introspect-synth/Cargo.toml @@ -8,10 +8,12 @@ name = "torii-introspect-synth" path = "src/main.rs" [dependencies] -torii = { path = "../../" } -torii-runtime-common.workspace = true -torii-dojo = { path = "../../crates/dojo" } -torii-introspect-postgres-sink.workspace = true +torii.workspace = true +torii-dojo.workspace = true +torii-introspect-sql-sink = { workspace = true, features = [ + "postgres", + "sqlite", +] } tokio = { version = "1", features = ["full"] } tracing = "0.1" diff --git a/bins/torii-introspect-synth/src/main.rs b/bins/torii-introspect-synth/src/main.rs index 9078bd37..4970a0b5 100644 --- a/bins/torii-introspect-synth/src/main.rs +++ b/bins/torii-introspect-synth/src/main.rs @@ -27,7 +27,7 @@ use torii::etl::Decoder; use torii::grpc::SubscriptionManager; use torii_dojo::decoder::DojoDecoder; use torii_dojo::store::postgres::PgStore; -use torii_introspect_postgres_sink::IntrospectPgDb; +use torii_introspect_sql_sink::IntrospectPgDb; const EXTRACTOR_TYPE: &str = "synthetic_introspect"; const STATE_KEY: &str = "last_block"; @@ -414,14 +414,12 @@ async fn main() -> Result<()> { fs::create_dir_all(&output_dir) .with_context(|| format!("failed to create output dir {}", output_dir.display()))?; - let pool = Arc::new( - PgPoolOptions::new() - .max_connections(5) - .connect(&config.db_url) - .await?, - ); + let pool = PgPoolOptions::new() + .max_connections(5) + .connect(&config.db_url) + .await?; if config.reset_schema { - reset_schema(pool.as_ref()).await?; + reset_schema(&pool).await?; } let started = Instant::now(); @@ -482,7 +480,7 @@ async fn main() -> Result<()> { } } - let verification = verify_run(pool.as_ref(), &config).await?; + let verification = verify_run(&pool, &config).await?; let summary = Summary { run_id: run_id.clone(), duration_ms: started.elapsed().as_millis(), diff --git a/crates/dojo/src/store/postgres.rs b/crates/dojo/src/store/postgres.rs index 05800dda..6fbe009b 100644 --- a/crates/dojo/src/store/postgres.rs +++ b/crates/dojo/src/store/postgres.rs @@ -14,7 +14,7 @@ use std::collections::HashMap; use torii_introspect::postgres::owned::PgTypeDef; use torii_introspect::postgres::PgFelt; use torii_introspect::schema::ColumnKeyTrait; -use torii_sql::{DbConnection, PgArguments, PgPool, Postgres, SqlxResult}; +use torii_sql::{DbPool, PgArguments, PgPool, Postgres, SqlxResult}; pub const FETCH_TABLES_QUERY: &str = r#" SELECT DISTINCT ON (owner, id) @@ -281,26 +281,26 @@ impl DojoTable { pub struct PgStore(pub T); -impl> DbConnection for PgStore { +impl> DbPool for PgStore { fn pool(&self) -> &PgPool { &self.0.pool() } } -impl + Send + Sync> PgStore { +impl + Send + Sync> PgStore { pub async fn initialize(&self) -> SqlxResult<()> { self.migrate(Some("dojo"), DOJO_STORE_MIGRATIONS).await } } -impl> From for PgStore { +impl> From for PgStore { fn from(pool: T) -> Self { PgStore(pool) } } #[async_trait] -impl + Send + Sync + 'static> DojoStoreTrait for PgStore { +impl + Send + Sync + 'static> DojoStoreTrait for PgStore { type Error = DojoPgStoreError; async fn save_table( diff --git a/crates/introspect-postgres-sink/Cargo.toml b/crates/introspect-postgres-sink/Cargo.toml deleted file mode 100644 index f3cd11ab..00000000 --- a/crates/introspect-postgres-sink/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "torii-introspect-postgres-sink" -version = "0.1.0" -edition = "2021" -description = "PostgreSQL sink implementation for Torii runtime" -authors = ["Torii Runtime "] -license = "Apache-2.0" - -[dependencies] -sqlx = { workspace = true, features = [ - "postgres", - "runtime-tokio-rustls", - "macros", - "migrate", -] } -anyhow.workspace = true -async-trait.workspace = true -metrics.workspace = true -xxhash-rust.workspace = true -hex.workspace = true -serde.workspace = true -serde_json.workspace = true -starknet.workspace = true -tokio.workspace = true -torii.workspace = true -tracing.workspace = true -starknet-types-core.workspace = true -thiserror.workspace = true -introspect-types.workspace = true -itertools.workspace = true -arrayvec.workspace = true - -# Local crates -torii-introspect.workspace = true -torii-sql = { workspace = true, features = ["postgres"] } -torii-introspect-sql-sink.workspace = true diff --git a/crates/introspect-postgres-sink/migrations/001_domains.sql b/crates/introspect-postgres-sink/migrations/001_domains.sql deleted file mode 100644 index 96bf76e7..00000000 --- a/crates/introspect-postgres-sink/migrations/001_domains.sql +++ /dev/null @@ -1,113 +0,0 @@ --- Initialize all custom domains for Starknet/Cairo types --- Using DO blocks for conditional creation since IF NOT EXISTS isn't supported in older PostgreSQL versions - - -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint8') THEN - CREATE DOMAIN uint8 AS SmallInt - CHECK (VALUE >= 0 AND VALUE < 256); - END IF; -END $$; - -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint16') THEN - CREATE DOMAIN uint16 AS Int - CHECK (VALUE >= 0 AND VALUE < 65536); - END IF; -END $$; - -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint32') THEN - CREATE DOMAIN uint32 AS BigInt - CHECK (VALUE >= 0 AND VALUE < 4294967296); - END IF; -END $$; - --- uint64: Unsigned 64-bit integer (0 to 2^64-1) -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint64') THEN - CREATE DOMAIN uint64 AS NUMERIC(20, 0) - CHECK (VALUE >= 0 AND VALUE < power(2::numeric, 64)); - END IF; -END $$; - --- uint128: Unsigned 128-bit integer (0 to 2^128-1) -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint128') THEN - CREATE DOMAIN uint128 AS NUMERIC(39, 0) - CHECK (VALUE >= 0 AND VALUE < power(2::numeric, 128)); - END IF; -END $$; - --- int128: Signed 128-bit integer (-2^127 to 2^127-1) -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'int128') THEN - CREATE DOMAIN int128 AS NUMERIC(39, 0) - CHECK (VALUE >= -power(2::numeric, 127) AND VALUE < power(2::numeric, 127)); - END IF; -END $$; - --- uint256: Unsigned 256-bit integer (0 to 2^256-1) -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint256') THEN - CREATE DOMAIN uint256 AS NUMERIC(78, 0) - CHECK (VALUE >= 0 AND VALUE < power(2::numeric, 256)); - END IF; -END $$; - --- uint512: Unsigned 512-bit integer (0 to 2^512-1) -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'uint512') THEN - CREATE DOMAIN uint512 AS NUMERIC(155, 0) - CHECK (VALUE >= 0 AND VALUE < power(2::numeric, 512)); - END IF; -END $$; - --- felt252: Cairo field element (0 to PRIME-1) -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'felt252') THEN - CREATE DOMAIN felt252 AS bytea CHECK (octet_length(VALUE) = 32); - END IF; -END $$; - --- starknet_hash: Starknet addresses and class hashes (uint251) -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'starknet_hash') THEN - CREATE DOMAIN starknet_hash AS bytea CHECK (octet_length(VALUE) = 32); - END IF; -END $$; - --- eth_address: Ethereum address (160-bit / 20 bytes) -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'eth_address') THEN - CREATE DOMAIN eth_address AS bytea CHECK (octet_length(VALUE) = 20); - END IF; -END $$; - --- byte31: 31-byte array -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'byte31') THEN - CREATE DOMAIN byte31 AS bytea CHECK (octet_length(VALUE) = 31); - END IF; -END $$; - --- char31: character string of max length 31 -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'char31') THEN - CREATE DOMAIN char31 AS varchar(31); - END IF; -END $$; - diff --git a/crates/introspect-postgres-sink/migrations/002_metadata_function.sql b/crates/introspect-postgres-sink/migrations/002_metadata_function.sql deleted file mode 100644 index e593704b..00000000 --- a/crates/introspect-postgres-sink/migrations/002_metadata_function.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE FUNCTION introspect.set_default_timestamps() RETURNS TRIGGER AS $$ -BEGIN - IF NEW.__created_at IS NULL THEN - NEW.__created_at := NOW(); - END IF; - IF NEW.__updated_at IS NULL THEN - NEW.__updated_at := NOW(); - END IF; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/crates/introspect-postgres-sink/migrations/003_store.sql b/crates/introspect-postgres-sink/migrations/003_store.sql deleted file mode 100644 index f5a83a78..00000000 --- a/crates/introspect-postgres-sink/migrations/003_store.sql +++ /dev/null @@ -1,67 +0,0 @@ -CREATE SCHEMA IF NOT EXISTS introspect; - -DO $$ -BEGIN - IF to_regtype('introspect.attribute') IS NULL THEN - CREATE TYPE introspect.attribute AS ( - name TEXT, - data bytea - ); - END IF; - - IF to_regtype('introspect.primary_def') IS NULL THEN - CREATE TYPE introspect.primary_def AS ( - name TEXT, - attributes introspect.attribute[], - type_def jsonb - ); - END IF; -END $$; - -CREATE TABLE IF NOT EXISTS introspect.db_tables ( - "schema" TEXT NOT NULL, - id felt252 NOT NULL, - name TEXT NOT NULL, - "owner" felt252 NOT NULL, - primary_def introspect.primary_def NOT NULL, - alive BOOLEAN NOT NULL DEFAULT TRUE, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - created_block uint64 NOT NULL, - updated_block uint64 NOT NULL, - created_tx felt252 NOT NULL, - updated_tx felt252 NOT NULL, - PRIMARY KEY ("schema", id) -); - -CREATE TABLE IF NOT EXISTS introspect.db_columns( - "schema" TEXT NOT NULL, - "table" felt252 NOT NULL, - id felt252 NOT NULL, - name TEXT NOT NULL, - type_def JSONB NOT NULL, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - created_block uint64 NOT NULL, - updated_block uint64 NOT NULL, - created_tx felt252 NOT NULL, - updated_tx felt252 NOT NULL, - PRIMARY KEY ("schema", "table", id), - FOREIGN KEY ("schema", "table") REFERENCES introspect.db_tables("schema", id) -); - -CREATE TABLE IF NOT EXISTS introspect.db_dead_fields ( - "schema" TEXT NOT NULL, - "table" felt252, - id uint128, - name TEXT, - type_def JSONB, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - created_block uint64 NOT NULL, - updated_block uint64 NOT NULL, - created_tx felt252 NOT NULL, - updated_tx felt252 NOT NULL, - PRIMARY KEY ("schema", "table", id), - FOREIGN KEY ("schema", "table") REFERENCES introspect.db_tables("schema", id) -); \ No newline at end of file diff --git a/crates/introspect-postgres-sink/src/backend.rs b/crates/introspect-postgres-sink/src/backend.rs deleted file mode 100644 index 7c3cabcd..00000000 --- a/crates/introspect-postgres-sink/src/backend.rs +++ /dev/null @@ -1,145 +0,0 @@ -use crate::insert::insert_record_queries; -use crate::query::{insert_columns_query, insert_table_query, CreatePgTable}; -use crate::upgrade::PgTableUpgrade; -use async_trait::async_trait; -use introspect_types::schema::{Names, TypeDefs}; -use introspect_types::{ColumnDef, FeltIds, PrimaryDef}; -use starknet_types_core::felt::Felt; -use torii_introspect::tables::RecordSchema; -use torii_introspect::Record; -use torii_introspect_sql_sink::processor::IntrospectDb; -use torii_introspect_sql_sink::{ - IntrospectQueryMaker, IntrospectSqlSink, RecordResult, Table, TableError, TableResult, -}; -use torii_sql::{DbConnection, PgPool, PgQuery, Postgres}; - -pub type IntrospectPgDb = IntrospectDb>; - -pub struct PostgresBackend>(T); - -impl> From for PostgresBackend { - fn from(value: T) -> Self { - PostgresBackend(value) - } -} - -impl> DbConnection for PostgresBackend { - fn pool(&self) -> &PgPool { - self.0.pool() - } -} - -#[async_trait] -impl + Send + Sync> IntrospectQueryMaker for PostgresBackend { - type DB = Postgres; - - fn create_table_queries( - namespace: &str, - id: &Felt, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> TableResult<()> { - let ns = namespace.into(); - CreatePgTable::new(&ns, id, name, primary, columns)?.make_queries(queries); - store_table_queries( - namespace, - id, - name, - primary, - columns, - from_address, - block_number, - transaction_hash, - queries, - ) - } - fn update_table_queries( - table: &mut Table, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> TableResult<()> { - let upgrades = table.upgrade_table(name, primary, columns)?; - upgrades.to_queries(block_number, transaction_hash, queries)?; - let columns = table.columns_with_ids(&upgrades.columns_upgraded)?; - store_table_queries( - &table.namespace, - &table.id, - name, - primary, - columns, - from_address, - block_number, - transaction_hash, - queries, - ) - } - fn insert_record_queries( - namespace: &str, - table_name: &str, - schema: &RecordSchema<'_>, - records: &[Record], - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> RecordResult<()> { - insert_record_queries( - namespace, - table_name, - schema, - records, - from_address, - block_number, - transaction_hash, - queries, - ) - } -} - -fn store_table_queries( - schema: &str, - id: &Felt, - name: &str, - primary: &PrimaryDef, - columns: CS, - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, -) -> TableResult<()> -where - CS: Names + FeltIds + TypeDefs, -{ - queries.push( - insert_table_query( - &schema, - &id, - &name, - &primary, - from_address, - block_number, - transaction_hash, - ) - .map_err(TableError::Encode)?, - ); - - queries.push( - insert_columns_query(&schema, &id, columns, block_number, transaction_hash) - .map_err(TableError::Encode)?, - ); - Ok(()) -} - -impl> IntrospectSqlSink for PostgresBackend { - const NAME: &'static str = "Introspect Postgres"; -} diff --git a/crates/introspect-postgres-sink/src/create.rs b/crates/introspect-postgres-sink/src/create.rs deleted file mode 100644 index 86d6a7b1..00000000 --- a/crates/introspect-postgres-sink/src/create.rs +++ /dev/null @@ -1,323 +0,0 @@ -use crate::{ - query::{make_schema_query, CreatePgTable, CreatesType}, - utils::{AsBytes, HasherExt}, - PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, -}; -use introspect_types::{ - ArrayDef, ColumnDef, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, PrimaryTypeDef, - StructDef, TupleDef, TypeDef, VariantDef, -}; -use itertools::Itertools; -use starknet_types_core::felt::Felt; -use std::rc::Rc; -use torii_introspect_sql_sink::{TypeError, TypeResult}; -use torii_sql::{postgres::PgQuery, Queries}; -use xxhash_rust::xxh3::Xxh3; - -pub trait PostgresTypeExtractor { - fn extract_type( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult; -} - -pub trait PostgresFieldExtractor { - type Id: AsBytes; - fn name(&self) -> &str; - fn type_def(&self) -> &TypeDef; - fn id(&self) -> &Self::Id; - fn branch(&self, branch: &Xxh3) -> Xxh3 { - branch.branch(self.id()) - } - fn extract_field( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult { - Ok(PostgresField::new( - self.name().to_string(), - self.type_def() - .extract_type(schema, &self.branch(branch), creates)?, - )) - } -} - -impl PostgresField { - pub fn new(name: impl Into, pg_type: PostgresType) -> Self { - Self { - name: name.into(), - pg_type, - } - } - - pub fn new_composite(name: S, schema: &Rc, type_name: T) -> Self - where - S: Into, - T: Into, - { - Self { - name: name.into(), - pg_type: PostgresType::composite(schema, type_name), - } - } -} - -impl PostgresFieldExtractor for ColumnDef { - type Id = Felt; - fn name(&self) -> &str { - &self.name - } - - fn type_def(&self) -> &TypeDef { - &self.type_def - } - fn id(&self) -> &Self::Id { - &self.id - } -} - -impl PostgresFieldExtractor for MemberDef { - type Id = String; - fn name(&self) -> &str { - &self.name - } - - fn type_def(&self) -> &TypeDef { - &self.type_def - } - fn id(&self) -> &Self::Id { - &self.name - } -} - -impl PostgresFieldExtractor for (&Felt, &VariantDef) { - type Id = Felt; - fn name(&self) -> &str { - &self.1.name - } - - fn type_def(&self) -> &TypeDef { - &self.1.type_def - } - fn id(&self) -> &Self::Id { - self.0 - } -} - -impl PostgresTypeExtractor for TypeDef { - fn extract_type( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult { - match self { - TypeDef::None => Ok(PostgresScalar::None.into()), - TypeDef::Bool => Ok(PostgresScalar::Boolean.into()), - TypeDef::I8 | TypeDef::I16 => Ok(PostgresScalar::SmallInt.into()), - TypeDef::I32 => Ok(PostgresScalar::Int.into()), - TypeDef::I64 => Ok(PostgresScalar::BigInt.into()), - TypeDef::U8 => Ok(PostgresScalar::Uint8.into()), - TypeDef::U16 => Ok(PostgresScalar::Uint16.into()), - TypeDef::U32 => Ok(PostgresScalar::Uint32.into()), - TypeDef::U64 => Ok(PostgresScalar::Uint64.into()), - TypeDef::U128 => Ok(PostgresScalar::Uint128.into()), - TypeDef::I128 => Ok(PostgresScalar::Int128.into()), - TypeDef::U256 => Ok(PostgresScalar::Uint256.into()), - TypeDef::U512 => Ok(PostgresScalar::Uint512.into()), - TypeDef::Felt252 => Ok(PostgresScalar::Felt252.into()), - TypeDef::ContractAddress - | TypeDef::ClassHash - | TypeDef::StorageAddress - | TypeDef::StorageBaseAddress => Ok(PostgresScalar::StarknetHash.into()), - TypeDef::EthAddress => Ok(PostgresScalar::EthAddress.into()), - TypeDef::Utf8String => Ok(PostgresScalar::Text.into()), - TypeDef::ShortUtf8 => Ok(PostgresScalar::Char31.into()), - TypeDef::ByteArray | TypeDef::ByteArrayEncoded(_) => Ok(PostgresScalar::Bytea.into()), - TypeDef::Bytes31 | TypeDef::Bytes31Encoded(_) => Ok(PostgresScalar::Bytes31.into()), - TypeDef::Tuple(type_defs) => type_defs.extract_type(schema, branch, creates), - TypeDef::Enum(enum_def) => enum_def.extract_type(schema, branch, creates), - TypeDef::Array(array_def) => array_def.extract_type(schema, branch, creates), - TypeDef::FixedArray(fixed_array_def) => { - fixed_array_def.extract_type(schema, branch, creates) - } - TypeDef::Struct(struct_def) => struct_def.extract_type(schema, branch, creates), - TypeDef::Option(def) => def.type_def.extract_type(schema, branch, creates), - TypeDef::Nullable(def) => def.type_def.extract_type(schema, branch, creates), - TypeDef::Felt252Dict(_) | TypeDef::Result(_) | TypeDef::Ref(_) | TypeDef::Custom(_) => { - Err(TypeError::UnsupportedType(format!("{self:?}"))) - } - } - } -} - -impl From<&PrimaryDef> for PrimaryKey { - fn from(primary: &PrimaryDef) -> Self { - let pg_type = match primary.type_def { - PrimaryTypeDef::Bool => PostgresScalar::Boolean, - PrimaryTypeDef::I8 | PrimaryTypeDef::I16 => PostgresScalar::SmallInt, - PrimaryTypeDef::I32 => PostgresScalar::Int, - PrimaryTypeDef::I64 => PostgresScalar::BigInt, - PrimaryTypeDef::U8 => PostgresScalar::Uint8, - PrimaryTypeDef::U16 => PostgresScalar::Uint16, - PrimaryTypeDef::U32 => PostgresScalar::Uint32, - PrimaryTypeDef::U64 => PostgresScalar::Uint64, - PrimaryTypeDef::U128 => PostgresScalar::Uint128, - PrimaryTypeDef::I128 => PostgresScalar::Int128, - PrimaryTypeDef::Felt252 => PostgresScalar::Felt252, - PrimaryTypeDef::ContractAddress - | PrimaryTypeDef::ClassHash - | PrimaryTypeDef::StorageAddress - | PrimaryTypeDef::StorageBaseAddress => PostgresScalar::StarknetHash, - PrimaryTypeDef::EthAddress => PostgresScalar::EthAddress, - PrimaryTypeDef::ShortUtf8 => PostgresScalar::Char31, - PrimaryTypeDef::Bytes31 | PrimaryTypeDef::Bytes31Encoded(_) => PostgresScalar::Bytes31, - }; - PrimaryKey { - name: primary.name.clone(), - pg_type, - } - } -} - -impl PostgresTypeExtractor for ArrayDef { - fn extract_type( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult { - self.type_def - .extract_type(schema, branch, creates)? - .to_array(None) - } -} - -impl PostgresTypeExtractor for FixedArrayDef { - fn extract_type( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult { - self.type_def - .extract_type(schema, branch, creates)? - .to_array(Some(self.size)) - } -} - -impl PostgresTypeExtractor for StructDef { - fn extract_type( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult { - let members = self - .members - .iter() - .map(|f| f.extract_field(schema, branch, creates)) - .collect::>>()?; - let name = branch.type_name(&self.name); - creates.push(CreatesType::new_struct(schema, &name, members).into()); - Ok(PostgresType::composite(schema, name)) - } -} - -impl PostgresTypeExtractor for EnumDef { - fn extract_type( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult { - let name = branch.type_name(&self.name); - let variants_type = branch.type_name(&format!("v_{}", self.name)); - let variant_names = self.variants.values().map(|v| v.name.clone()).collect_vec(); - creates.push(CreatesType::new_enum(schema, &variants_type, variant_names).into()); - let mut fields = Vec::with_capacity(self.variants.len() + 1); - fields.push(PostgresField::new_composite( - "_variant", - schema, - variants_type, - )); - for variant in &self.variants { - match variant.1.type_def { - TypeDef::None => {} - _ => fields.push(variant.extract_field(schema, branch, creates)?), - } - } - creates.push(CreatesType::new_struct(schema, &name, fields).into()); - Ok(PostgresType::composite(schema, name)) - } -} - -impl PostgresTypeExtractor for TupleDef { - fn extract_type( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult { - let mut variants = Vec::with_capacity(self.elements.len()); - for (i, element) in self.elements.iter().enumerate() { - variants.push( - element - .extract_type(schema, &branch.branch(&(i as u32)), creates)? - .to_field(format!("_{}", i)), - ); - } - let name = branch.type_name("tuple"); - creates.push(CreatesType::new_struct(schema, &name, variants).into()); - Ok(PostgresType::composite(schema, name)) - } -} - -impl PostgresTypeExtractor for OptionDef { - fn extract_type( - &self, - schema: &Rc, - branch: &Xxh3, - creates: &mut Vec>, - ) -> TypeResult { - self.type_def.extract_type(schema, branch, creates) - } -} - -impl CreatePgTable { - pub fn new( - schema: &Rc, - id: &Felt, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], - ) -> TypeResult { - let mut creates: Vec = Vec::new(); - let branch = Xxh3::new_based(id); - let primary = primary.into(); - let columns = columns - .iter() - .map(|col| col.extract_field(schema, &branch, &mut creates)) - .collect::>>()?; - Ok(Self { - name: SchemaName::new(schema, name), - primary, - columns, - pg_types: creates, - }) - } - pub fn make_queries(&self, queries: &mut Vec) { - queries.add(make_schema_query(&self.name.0)); - for pg_type in &self.pg_types { - queries.add(pg_type.to_string()); - } - queries.add(self.to_string()); - queries.add(format!( - r#"CREATE TRIGGER set_timestamps BEFORE INSERT ON {} FOR EACH ROW EXECUTE FUNCTION introspect.set_default_timestamps();"#, - self.name - )); - } -} diff --git a/crates/introspect-postgres-sink/src/handler.rs b/crates/introspect-postgres-sink/src/handler.rs deleted file mode 100644 index 48c5e53d..00000000 --- a/crates/introspect-postgres-sink/src/handler.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::query::{fetch_columns, fetch_dead_fields, fetch_tables}; -use crate::PostgresBackend; -use async_trait::async_trait; -use introspect_types::ResultInto; -use torii_introspect_sql_sink::backend::IntrospectInitialize; -use torii_introspect_sql_sink::{DbColumn, DbDeadField, DbResult, DbTable}; -use torii_sql::{DbConnection, Postgres}; - -pub const INTROSPECT_PG_SINK_MIGRATIONS: sqlx::migrate::Migrator = sqlx::migrate!("./migrations"); - -#[async_trait] -impl + Send + Sync> IntrospectInitialize for PostgresBackend { - async fn load_tables(&self, schemas: &Option>) -> DbResult> { - fetch_tables(self.pool(), schemas).await.err_into() - } - async fn load_columns(&self, schemas: &Option>) -> DbResult> { - fetch_columns(self.pool(), schemas).await.err_into() - } - async fn load_dead_fields(&self, schemas: &Option>) -> DbResult> { - fetch_dead_fields(self.pool(), schemas).await.err_into() - } - async fn initialize(&self) -> DbResult<()> { - self.migrate(Some("introspect"), INTROSPECT_PG_SINK_MIGRATIONS) - .await - .err_into() - } -} diff --git a/crates/introspect-postgres-sink/src/insert.rs b/crates/introspect-postgres-sink/src/insert.rs deleted file mode 100644 index c750480d..00000000 --- a/crates/introspect-postgres-sink/src/insert.rs +++ /dev/null @@ -1,90 +0,0 @@ -use crate::json::PostgresJsonSerializer; -use introspect_types::ColumnInfo; -use serde::ser::SerializeMap; -use serde_json::Serializer as JsonSerializer; -use starknet_types_core::felt::Felt; -use std::io::Write; -use torii_introspect::{ - tables::{RecordSchema, SerializeEntries}, - Record, -}; -use torii_introspect_sql_sink::RecordResult; -use torii_sql::{postgres::PgQuery, Queries}; - -pub const METADATA_CONFLICTS: &str = "__updated_at = NOW(), __updated_block = EXCLUDED.__updated_block, __updated_tx = EXCLUDED.__updated_tx"; - -pub struct MetaData<'a> { - pub block_number: u64, - pub transaction_hash: &'a Felt, -} - -impl<'a> MetaData<'a> { - pub fn new(block_number: u64, transaction_hash: &'a Felt) -> Self { - Self { - block_number, - transaction_hash, - } - } -} - -pub fn pg_json_felt252(value: &Felt) -> String { - format!("\\x{}", hex::encode(value.to_bytes_be())) -} - -impl SerializeEntries for MetaData<'_> { - fn entry_count(&self) -> usize { - 4 - } - fn serialize_entries( - &self, - map: &mut ::SerializeMap, - ) -> Result<(), S::Error> { - let tx_hash = pg_json_felt252(&self.transaction_hash); - map.serialize_entry("__created_block", &self.block_number)?; - map.serialize_entry("__updated_block", &self.block_number)?; - map.serialize_entry("__created_tx", &tx_hash)?; - map.serialize_entry("__updated_tx", &tx_hash) - } -} - -pub fn insert_record_queries( - namespace: &str, - table_name: &str, - schema: &RecordSchema<'_>, - records: &[Record], - _from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, -) -> RecordResult<()> { - let mut writer = Vec::new(); - let metadata = MetaData::new(block_number, transaction_hash); - write!( - writer, - r#"INSERT INTO "{namespace}"."{table_name}" SELECT * FROM jsonb_populate_recordset(NULL::"{namespace}"."{table_name}", $$"# - ) - .unwrap(); - schema.parse_records_with_metadata( - records, - &metadata, - &mut JsonSerializer::new(&mut writer), - &PostgresJsonSerializer, - )?; - write!( - writer, - r#"$$) ON CONFLICT ("{}") DO UPDATE SET {METADATA_CONFLICTS}"#, - schema.primary().name - ) - .unwrap(); - for ColumnInfo { name, .. } in schema.columns() { - write!( - writer, - r#", "{name}" = COALESCE(EXCLUDED."{name}", "{table_name}"."{name}")"#, - name = name - ) - .unwrap(); - } - let string = unsafe { String::from_utf8_unchecked(writer) }; - queries.add(string); - Ok(()) -} diff --git a/crates/introspect-postgres-sink/src/json.rs b/crates/introspect-postgres-sink/src/json.rs deleted file mode 100644 index 7e8cc911..00000000 --- a/crates/introspect-postgres-sink/src/json.rs +++ /dev/null @@ -1,89 +0,0 @@ -use introspect_types::serialize::ToCairoDeSeFrom; -use introspect_types::serialize_def::CairoTypeSerialization; -use introspect_types::{CairoDeserializer, ResultDef, TupleDef, TypeDef}; -use serde::ser::SerializeMap; -use serde::Serializer; - -pub struct PostgresJsonSerializer; - -impl CairoTypeSerialization for PostgresJsonSerializer { - fn serialize_byte_array( - &self, - serializer: S, - value: &[u8], - ) -> Result { - serializer.serialize_str(&format!("\\x{}", hex::encode(value))) - } - fn serialize_string( - &self, - serializer: S, - value: &str, - ) -> Result { - serializer.serialize_str(&value.replace('\0', "\u{FFFD}")) - } - fn serialize_felt( - &self, - serializer: S, - value: &[u8; 32], - ) -> Result { - self.serialize_byte_array(serializer, value) - } - fn serialize_eth_address( - &self, - serializer: S, - value: &[u8; 20], - ) -> Result { - self.serialize_byte_array(serializer, value) - } - fn serialize_tuple<'a, S: Serializer>( - &'a self, - data: &mut impl CairoDeserializer, - serializer: S, - tuple: &'a TupleDef, - ) -> Result { - let mut seq = serializer.serialize_map(Some(tuple.elements.len()))?; - for (i, element) in tuple.elements.iter().enumerate() { - seq.serialize_entry(&format!("_{i}"), &element.to_de_se(data, self))?; - } - seq.end() - } - - fn serialize_variant<'a, S: Serializer>( - &'a self, - data: &mut impl CairoDeserializer, - serializer: S, - name: &str, - type_def: &'a TypeDef, - ) -> Result { - match type_def { - TypeDef::None => { - let mut map = serializer.serialize_map(Some(1))?; - map.serialize_entry("_variant", name)?; - map - } - _ => { - let mut map = serializer.serialize_map(Some(2))?; - map.serialize_entry("_variant", name)?; - map.serialize_entry(name, &type_def.to_de_se(data, self))?; - map - } - } - .end() - } - - fn serialize_result<'a, S: Serializer>( - &'a self, - data: &mut impl CairoDeserializer, - serializer: S, - result: &'a ResultDef, - is_ok: bool, - ) -> Result { - let mut map = serializer.serialize_map(Some(1))?; - map.serialize_entry("is_ok", &is_ok)?; - match is_ok { - true => map.serialize_entry("Ok", &result.ok.to_de_se(data, self))?, - false => map.serialize_entry("Err", &result.err.to_de_se(data, self))?, - } - map.end() - } -} diff --git a/crates/introspect-postgres-sink/src/lib.rs b/crates/introspect-postgres-sink/src/lib.rs deleted file mode 100644 index bb7c4684..00000000 --- a/crates/introspect-postgres-sink/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -pub mod backend; -pub mod create; -pub mod handler; -pub mod insert; -pub mod json; -pub mod query; -pub mod types; -pub mod upgrade; -pub mod utils; - -pub use backend::{IntrospectPgDb, PostgresBackend}; -pub use types::{ - PostgresArray, PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, -}; -pub use utils::{truncate, HasherExt}; diff --git a/crates/introspect-postgres-sink/src/query.rs b/crates/introspect-postgres-sink/src/query.rs deleted file mode 100644 index 0f409c9c..00000000 --- a/crates/introspect-postgres-sink/src/query.rs +++ /dev/null @@ -1,692 +0,0 @@ -use crate::{PostgresField, PostgresType, PrimaryKey, SchemaName}; -use introspect_types::schema::{Names, TypeDefs}; -use introspect_types::{ColumnDef, FeltIds, MemberDef, PrimaryDef, TypeDef}; -use itertools::Itertools; -use sqlx::error::BoxDynError; -use sqlx::postgres::PgRow; -use sqlx::prelude::FromRow; -use sqlx::query::QueryAs; -use sqlx::{postgres::PgArguments, types::Json}; -use sqlx::{Arguments, Executor, Postgres}; -use starknet_types_core::felt::Felt; -use std::{ - fmt::{Display, Formatter, Result as FmtResult, Write}, - rc::Rc, -}; -use torii_introspect::postgres::types::{PgPrimary, Uint128}; -use torii_introspect::postgres::PgFelt; -use torii_introspect_sql_sink::processor::{DbColumn, DbDeadField, DbTable}; -use torii_introspect_sql_sink::table::DeadFieldDef; -use torii_introspect_sql_sink::{TableError, TableResult}; -use torii_sql::postgres::PgQuery; -use torii_sql::{Queries, SqlxResult}; - -pub const COMMIT_CMD: &str = "--COMMIT"; - -const CREATE_METADATA_COLUMNS: &str = "__created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __created_block public.uint64 NOT NULL, __updated_block public.uint64 NOT NULL, __created_tx public.felt252 NOT NULL, __updated_tx public.felt252 NOT NULL);"; -const INSERT_DEAD_MEMBER_QUERY: &str = r#"INSERT INTO introspect.db_dead_fields - ("schema", "table", id, name, type_def, updated_at, created_block, updated_block, created_tx, updated_tx) - SELECT $1, $2, unnest($3::bigint[]), unnest($4::text[]), unnest($5::jsonb[]), NOW(), $6::uint64, $6::uint64, $7, $7 - ON CONFLICT ("schema", "table", id) DO UPDATE SET - name = EXCLUDED.name, type_def = EXCLUDED.type_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; -const INSERT_TABLE_QUERY: &str = r#"INSERT INTO introspect.db_tables - ("schema", id, owner, name, primary_def, updated_at, created_block, updated_block, created_tx, updated_tx) - VALUES ($1, $2, $3, $4, $5, NOW(), $6::uint64, $6::uint64, $7, $7) - ON CONFLICT ("schema", id) DO UPDATE SET - name = EXCLUDED.name, primary_def = EXCLUDED.primary_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; -const INSERT_COLUMN_QUERY: &str = r#"INSERT INTO introspect.db_columns - ("schema", "table", id, name, type_def, updated_at, created_block, updated_block, created_tx, updated_tx) - SELECT $1, $2, unnest($3::felt252[]), unnest($4::text[]), unnest($5::jsonb[]), NOW(), $6::uint64, $6::uint64, $7, $7 - ON CONFLICT ("schema", "table", id) DO UPDATE SET - name = EXCLUDED.name, type_def = EXCLUDED.type_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; - -const FETCH_TABLES_QUERY: &str = r#"SELECT "schema", id, name, primary_def, owner FROM introspect.db_tables WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; -const FETCH_COLUMNS_QUERY: &str = r#"SELECT "schema", "table", id, name, type_def FROM introspect.db_columns WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; -const FETCH_DEAD_FIELDS_QUERY: &str = r#"SELECT "schema", "table", id, name, type_def FROM introspect.db_dead_fields WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; - -#[derive(FromRow)] -pub struct TableRow { - pub schema: String, - pub id: PgFelt, - pub name: String, - pub primary_def: PgPrimary, - pub owner: PgFelt, -} - -#[derive(FromRow)] -pub struct ColumnRow { - pub schema: String, - pub table: PgFelt, - pub id: PgFelt, - pub name: String, - pub type_def: Json, -} - -#[derive(FromRow)] -pub struct DeadFieldRow { - pub schema: String, - pub table: PgFelt, - pub id: Uint128, - pub name: String, - pub type_def: Json, -} - -#[derive(Debug)] -pub struct CreatePgTable { - pub name: SchemaName, - pub primary: PrimaryKey, - pub columns: Vec, - pub pg_types: Vec, -} - -#[derive(Debug)] -pub struct TableUpgrade { - pub schema: Rc, - pub id: Felt, - pub name: String, - pub old_name: Option, - pub atomic: Vec, - pub alters: Vec, - pub columns: Vec, - pub columns_upgraded: Vec, - pub dead: Vec, - pub col_alters: Vec, -} - -#[derive(Debug)] -pub struct ColumnUpgrade { - pub atomic: Vec, - pub alters: Vec, - pub dead: Vec, - pub altered: bool, - pub upgraded: bool, -} - -#[derive(Debug)] -pub struct CreateStruct { - pub name: SchemaName, - pub fields: Vec, -} - -#[derive(Debug)] -pub struct CreateEnum { - pub name: SchemaName, - pub variants: Vec, -} - -#[derive(Debug)] -pub enum StructMod { - Add(PostgresField), - Rename(String, String), -} - -#[derive(Debug)] -pub enum TypeMod { - Struct(StructUpgrade), - Enum(EnumUpgrade), - Create(CreatesType), -} - -#[derive(Debug)] -pub enum ColumnMod { - Add(PostgresField), - Rename(String, String), - Alter(PostgresField), -} - -#[derive(Debug)] -pub struct StructUpgrade { - name: SchemaName, - mods: Vec, -} - -#[derive(Debug)] -pub struct StructAlter { - name: SchemaName, - field: String, - pg_type: PostgresType, -} - -#[derive(Debug)] -pub struct EnumUpgrade { - name: SchemaName, - rename: Vec<(String, String)>, - add: Vec, -} - -#[derive(Debug)] -pub enum CreatesType { - Struct(CreateStruct), - Enum(CreateEnum), -} - -impl Display for CreatePgTable { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - r#"CREATE TABLE IF NOT EXISTS {} ({}, "#, - self.name, self.primary - )?; - for column in &self.columns { - write!(f, "{column}, ")?; - } - CREATE_METADATA_COLUMNS.fmt(f) - } -} - -impl Display for CreateStruct { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "CREATE TYPE {} AS (", self.name)?; - if let Some((last, batch)) = self.fields.split_last() { - for field in batch { - write!(f, "{field}, ")?; - } - last.fmt(f)?; - } - write!(f, ");") - } -} - -impl Display for CreateEnum { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "CREATE TYPE {} AS ENUM (", self.name)?; - if let Some((last, batch)) = self.variants.split_last() { - for field in batch { - write!(f, "'{field}', ")?; - } - write!(f, "'{last}'")?; - } - write!(f, ");") - } -} - -impl Display for CreatesType { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - match self { - CreatesType::Struct(s) => s.fmt(f), - CreatesType::Enum(e) => e.fmt(f), - } - } -} - -impl CreatesType { - pub fn new_struct>( - schema: &Rc, - name: S, - fields: Vec, - ) -> Self { - Self::Struct(CreateStruct { - name: SchemaName::new(schema, name), - fields, - }) - } - - pub fn new_enum>(schema: &Rc, name: S, variants: Vec) -> Self { - Self::Enum(CreateEnum { - name: SchemaName::new(schema, name), - variants, - }) - } -} - -impl TableUpgrade { - pub fn new>(schema: &Rc, id: Felt, name: S) -> Self { - Self { - schema: schema.clone(), - id, - name: name.into(), - old_name: None, - columns: Vec::new(), - columns_upgraded: Vec::new(), - alters: Vec::new(), - atomic: Vec::new(), - dead: Vec::new(), - col_alters: Vec::new(), - } - } - pub fn rename_column(&mut self, old: &mut String, new: &str) -> bool { - let renamed = old != new; - if renamed { - let old = std::mem::replace(old, new.to_string()); - self.columns.push(ColumnMod::Rename(old, new.to_string())); - } - renamed - } - pub fn rename_table(&mut self, new: &str) { - if self.name != new { - self.old_name = Some(std::mem::replace(&mut self.name, new.into())); - } - } - pub fn retype_primary(&mut self, name: &str, pg_type: Option) { - if let Some(pg_type) = pg_type { - self.columns.push(ColumnMod::Alter(pg_type.to_field(name))); - } - } - pub fn retype_column( - &mut self, - column: &ColumnDef, - pg_type: Option, - upgrade: ColumnUpgrade, - field: PostgresType, - ) { - if let Some(pg_type) = pg_type { - self.columns - .push(ColumnMod::Alter(pg_type.to_field(&column.name))); - } - if upgrade.altered { - self.col_alters.push(field.to_field(&column.name)); - } - if upgrade.upgraded { - self.columns_upgraded.push(column.id); - } - self.atomic = upgrade.atomic; - self.alters = upgrade.alters; - self.dead = upgrade.dead; - } - - pub fn add_column(&mut self, id: Felt, name: &str, pg_type: PostgresType) { - self.columns.push(ColumnMod::Add(PostgresField::new( - name.to_string(), - pg_type, - ))); - self.columns_upgraded.push(id); - } - - pub fn column_upgrade(&mut self, upgraded: bool) -> ColumnUpgrade { - ColumnUpgrade { - atomic: std::mem::take(&mut self.atomic), - alters: std::mem::take(&mut self.alters), - dead: std::mem::take(&mut self.dead), - altered: false, - upgraded, - } - } - - pub fn to_queries( - &self, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec, - ) -> TableResult<()> { - let schema = &self.schema; - let name = &self.name; - queries.add( - insert_dead_member_query( - &self.schema, - &self.id, - &self.dead, - block_number, - transaction_hash, - ) - .map_err(TableError::Encode)?, - ); - if let Some(old_name) = &self.old_name { - queries.add(format!( - r#"ALTER TABLE "{schema}"."{old_name}" RENAME TO "{name}";"# - )); - } - self.atomic.iter().for_each(|m| m.to_queries(queries)); - if let Some((last, columns)) = self.columns.split_last() { - let mut alterations = format!(r#"ALTER TABLE "{schema}"."{name}" "#); - columns - .iter() - .for_each(|m| write!(alterations, "{m}, ").unwrap()); - write!(alterations, "{last};").unwrap(); - queries.add(alterations); - } - self.alter_queries(queries); - Ok(()) - } - - fn alter_queries(&self, queries: &mut Vec) { - if let Some((last, others)) = self.col_alters.split_last() { - let (schema, name) = (&self.schema, &self.name); - let mut forward = format!(r#"ALTER TABLE "{schema}"."{name}" "#); - let mut reverse = forward.clone(); - for PostgresField { name: col, pg_type } in others { - write!( - forward, - r#"ALTER COLUMN "{col}" TYPE jsonb USING to_jsonb("{col}"),"# - ) - .unwrap(); - write!( - reverse, - r#"ALTER COLUMN "{col}" TYPE {pg_type} USING jsonb_populate_record(null::{pg_type}, "{col}"),"# - ) - .unwrap(); - } - let PostgresField { name: col, pg_type } = last; - write!( - forward, - r#"ALTER COLUMN "{col}" TYPE jsonb USING to_jsonb("{col}");"# - ) - .unwrap(); - write!( - reverse, - r#"ALTER COLUMN "{col}" TYPE {pg_type} USING jsonb_populate_record(null::{pg_type}, "{col}");"# - ) - .unwrap(); - queries.add(forward); - self.alters.iter().for_each(|a| queries.add(a.to_string())); - queries.add(reverse); - } - } -} - -impl Display for ColumnMod { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - match self { - ColumnMod::Add(field) => write!(f, r#"ADD COLUMN {field}"#), - ColumnMod::Alter(PostgresField { name, pg_type }) => { - write!(f, r#"ALTER COLUMN "{name}" TYPE {pg_type}"#,) - } - ColumnMod::Rename(old, new) => write!(f, r#"RENAME COLUMN "{old}" TO "{new}""#), - } - } -} - -impl StructUpgrade { - fn to_queries(&self, queries: &mut Vec) { - let name = &self.name; - self.mods - .iter() - .for_each(|m| queries.add(format!("ALTER TYPE {name} {m};"))); - } -} - -impl Display for StructMod { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - match self { - StructMod::Add(field) => write!(f, "ADD ATTRIBUTE {field}"), - StructMod::Rename(old, new) => write!(f, r#"RENAME ATTRIBUTE "{old}" TO "{new}""#), - } - } -} - -impl Display for StructAlter { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!( - f, - r#"ALTER TYPE {} ALTER ATTRIBUTE "{}" TYPE {};"#, - self.name, self.field, self.pg_type - ) - } -} - -impl EnumUpgrade { - fn to_queries(&self, queries: &mut Vec) { - let name = &self.name; - for (old, new) in &self.rename { - queries.add(format!( - r#"ALTER TYPE {name} RENAME VALUE '{old}' TO '{new}';"# - )); - } - for variant in &self.add { - queries.add(format!(r#"ALTER TYPE {name} ADD VALUE '{variant}';"#)); - } - queries.add(COMMIT_CMD); - } -} - -impl TypeMod { - fn to_queries(&self, queries: &mut Vec) { - match self { - TypeMod::Struct(upgrade) => upgrade.to_queries(queries), - TypeMod::Enum(upgrade) => upgrade.to_queries(queries), - TypeMod::Create(create) => queries.add(create.to_string()), - } - } -} - -impl StructMod { - pub fn add>(name: S, pg_type: PostgresType) -> Self { - StructMod::Add(PostgresField::new(name.into(), pg_type)) - } - - pub fn add_field(field: PostgresField) -> Self { - StructMod::Add(field) - } -} - -pub trait TypeMods { - fn add_mod(&mut self, type_mod: TypeMod); -} - -impl TypeMods for Vec { - fn add_mod(&mut self, type_mod: TypeMod) { - self.push(type_mod); - } -} - -impl ColumnUpgrade { - pub fn maybe_alter( - &mut self, - schema: &Rc, - name: &str, - field: &str, - pg_type: Option, - ) { - if let Some(pg_type) = pg_type { - self.alters.push(StructAlter { - name: SchemaName::new(schema, name), - field: field.to_string(), - pg_type, - }); - self.upgraded = true; - } - } - - pub fn add_struct_mod>( - &mut self, - schema: &Rc, - name: S, - mods: Vec, - ) { - if !mods.is_empty() { - self.upgraded = true; - self.atomic.push(TypeMod::Struct(StructUpgrade { - name: SchemaName::new(schema, name), - mods, - })) - } - } - pub fn add_enum_mod>( - &mut self, - schema: &Rc, - name: S, - rename: Vec<(String, String)>, - add: Vec, - ) { - if !rename.is_empty() || !add.is_empty() { - self.upgraded = true; - - self.atomic.push(TypeMod::Enum(EnumUpgrade { - name: SchemaName::new(schema, name), - rename, - add, - })) - } - } - pub fn add_dead_member(&mut self, id: u128, member: &MemberDef) { - self.upgraded = true; - self.dead.push(DeadFieldDef { - id, - name: member.name.clone(), - type_def: member.type_def.clone(), - }); - } -} - -pub trait StructMods { - fn add_mod(&mut self, struct_mod: StructMod); - fn add>(&mut self, name: S, pg_type: PostgresType) { - self.add_mod(StructMod::add(name, pg_type)); - } - fn add_field(&mut self, field: PostgresField) { - self.add_mod(StructMod::add_field(field)); - } - fn rename, S: Into>(&mut self, old: T, new: S) { - self.add_mod(StructMod::Rename(old.into(), new.into())); - } -} - -impl StructMods for Vec { - fn add_mod(&mut self, struct_mod: StructMod) { - self.push(struct_mod); - } -} - -impl From for TypeMod { - fn from(value: CreatesType) -> Self { - TypeMod::Create(value) - } -} - -impl From for DbColumn { - fn from(value: ColumnRow) -> Self { - DbColumn { - namespace: value.schema, - table: value.table.into(), - id: value.id.into(), - name: value.name, - type_def: value.type_def.0, - } - } -} - -impl From for DbDeadField { - fn from(value: DeadFieldRow) -> Self { - DbDeadField { - namespace: value.schema, - table: value.table.into(), - id: value.id.into(), - name: value.name, - type_def: value.type_def.0, - } - } -} - -impl From for DbTable { - fn from(value: TableRow) -> Self { - DbTable { - namespace: value.schema, - id: value.id.into(), - owner: value.owner.into(), - name: value.name, - primary: value.primary_def.into(), - columns: Vec::new(), - dead: Vec::new(), - alive: true, - } - } -} - -fn insert_dead_member_query( - schema: &str, - table: &Felt, - fields: &[DeadFieldDef], - block_number: u64, - transaction_hash: &Felt, -) -> Result { - let mut args = PgArguments::default(); - args.add(schema.to_string())?; - args.add(PgFelt::from(*table))?; - args.add(fields.iter().map(|f| f.id.to_string()).collect::>())?; - args.add(fields.iter().map(|f| f.name.clone()).collect::>())?; - args.add(fields.iter().map(|f| Json(&f.type_def)).collect::>())?; - args.add(block_number.to_string())?; - args.add(PgFelt::from(*transaction_hash))?; - - Ok(PgQuery::new(INSERT_DEAD_MEMBER_QUERY, args)) -} - -pub fn insert_columns_query( - schema: &str, - table: &Felt, - columns: CS, - block_number: u64, - transaction_hash: &Felt, -) -> Result -where - CS: Names + FeltIds + TypeDefs, -{ - let mut args = PgArguments::default(); - args.add(schema.to_string())?; - args.add(PgFelt::from(*table))?; - args.add(columns.ids().iter().map_into::().collect_vec())?; - args.add(columns.names())?; - args.add(columns.type_defs().into_iter().map(Json).collect_vec())?; - args.add(block_number.to_string())?; - args.add(PgFelt::from(*transaction_hash))?; - - Ok(PgQuery::new(INSERT_COLUMN_QUERY, args)) -} - -pub fn insert_table_query( - schema: &str, - id: &Felt, - name: &str, - primary_def: &PrimaryDef, - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, -) -> Result { - let mut args = PgArguments::default(); - args.add(schema.to_string())?; - args.add(PgFelt::from(*id))?; - args.add(PgFelt::from(*from_address))?; - args.add(name.to_owned())?; - args.add(PgPrimary::from(primary_def))?; - args.add(block_number.to_string())?; - args.add(PgFelt::from(*transaction_hash))?; - - Ok(PgQuery::new(INSERT_TABLE_QUERY, args)) -} - -pub fn schema_query<'a, R>( - query: &'a str, - schemas: &'a Option>, -) -> QueryAs<'a, Postgres, R, PgArguments> -where - R: for<'r> FromRow<'r, PgRow>, -{ - let query = sqlx::query_as::<_, R>(query); - match schemas { - Some(schemas) => query.bind(schemas), - None => query.bind("{}".to_string()), - } -} - -pub async fn fetch_tables<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( - conn: E, - schemas: &Option>, -) -> SqlxResult> { - schema_query::(FETCH_TABLES_QUERY, schemas) - .fetch_all(conn) - .await - .map(|rows| rows.into_iter().map_into().collect()) -} - -pub async fn fetch_columns<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( - conn: E, - schemas: &Option>, -) -> SqlxResult> { - schema_query::(FETCH_COLUMNS_QUERY, schemas) - .fetch_all(conn) - .await - .map(|rows| rows.into_iter().map_into().collect()) -} - -pub async fn fetch_dead_fields<'e, 'c, E: 'e + Executor<'c, Database = Postgres>>( - conn: E, - schemas: &Option>, -) -> SqlxResult> { - schema_query::(FETCH_DEAD_FIELDS_QUERY, schemas) - .fetch_all(conn) - .await - .map(|rows| rows.into_iter().map_into().collect()) -} - -pub fn make_schema_query(schema: &str) -> String { - format!(r#"CREATE SCHEMA IF NOT EXISTS "{schema}""#) -} diff --git a/crates/introspect-postgres-sink/src/types.rs b/crates/introspect-postgres-sink/src/types.rs deleted file mode 100644 index cf3ebfbd..00000000 --- a/crates/introspect-postgres-sink/src/types.rs +++ /dev/null @@ -1,187 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::{ - collections::VecDeque, - fmt::{Display, Formatter, Result as FmtResult}, - rc::Rc, -}; -use torii_introspect_sql_sink::{TypeError, TypeResult}; - -#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] -pub struct SchemaName(pub Rc, pub String); - -#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] -pub enum PostgresScalar { - None, - Boolean, - SmallInt, // i16 - Int, // i32 - BigInt, // i64 - Int128, - Uint8, - Uint16, - Uint32, - Uint64, - Uint128, - Uint256, - Uint512, - Felt252, - StarknetHash, - EthAddress, - Text, - Char31, - Bytes31, - Bytea, - Composite(SchemaName), -} - -#[derive(Debug)] -pub struct PrimaryKey { - pub name: String, - pub pg_type: PostgresScalar, -} - -#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] -pub struct PostgresType { - pub scalar: PostgresScalar, - pub array: PostgresArray, -} - -#[derive(Deserialize, Serialize, Debug)] -pub struct PostgresField { - pub name: String, - pub pg_type: PostgresType, -} - -#[derive(Clone, Deserialize, Serialize, PartialEq, Debug)] -pub enum PostgresArray { - None, - Dynamic, - Fixed(VecDeque), -} - -impl From for PostgresType { - fn from(value: PostgresScalar) -> Self { - PostgresType { - scalar: value, - array: PostgresArray::None, - } - } -} - -impl Display for SchemaName { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, r#""{}"."{}""#, self.0, self.1) - } -} - -impl Display for PostgresScalar { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - match self { - PostgresScalar::None => f.write_str("VOID"), - PostgresScalar::Boolean => f.write_str("BOOLEAN"), - PostgresScalar::SmallInt => f.write_str("SMALLINT"), - PostgresScalar::Int => f.write_str("INTEGER"), - PostgresScalar::BigInt => f.write_str("BIGINT"), - PostgresScalar::Int128 => f.write_str("public.int128"), - PostgresScalar::Uint8 => f.write_str("public.uint8"), - PostgresScalar::Uint16 => f.write_str("public.uint16"), - PostgresScalar::Uint32 => f.write_str("public.uint32"), - PostgresScalar::Uint64 => f.write_str("public.uint64"), - PostgresScalar::Uint128 => f.write_str("public.uint128"), - PostgresScalar::Uint256 => f.write_str("public.uint256"), - PostgresScalar::Uint512 => f.write_str("public.uint512"), - PostgresScalar::Felt252 => f.write_str("public.felt252"), - PostgresScalar::Char31 => f.write_str("public.char31"), - PostgresScalar::Bytes31 => f.write_str("public.byte31"), - PostgresScalar::StarknetHash => f.write_str("public.starknet_hash"), - PostgresScalar::EthAddress => f.write_str("public.eth_address"), - PostgresScalar::Text => f.write_str("TEXT"), - PostgresScalar::Bytea => f.write_str("BYTEA"), - PostgresScalar::Composite(name) => name.fmt(f), - } - } -} - -impl Display for PostgresArray { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - match self { - PostgresArray::None => Ok(()), - PostgresArray::Dynamic => write!(f, "[]"), - PostgresArray::Fixed(sizes) => sizes.iter().try_for_each(|size| write!(f, "[{size}]")), - } - } -} - -impl Display for PostgresType { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "{}{}", self.scalar, self.array) - } -} - -impl Display for PrimaryKey { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, r#""{}" {} PRIMARY KEY"#, self.name, self.pg_type) - } -} - -impl Display for PostgresField { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, r#""{}" {}"#, self.name, self.pg_type) - } -} - -impl From for PostgresType { - fn from(value: SchemaName) -> Self { - PostgresType { - scalar: PostgresScalar::Composite(value), - array: PostgresArray::None, - } - } -} - -impl SchemaName { - pub fn new>(schema: &Rc, name: T) -> Self { - Self(schema.clone(), name.into()) - } - pub fn replace>(&mut self, name: S) -> String { - std::mem::replace(&mut self.1, name.into()) - } -} - -impl PostgresType { - pub fn is_composite(&self) -> bool { - matches!(self.scalar, PostgresScalar::Composite(_)) - } - pub fn to_array(self, size: Option) -> TypeResult { - let arr = match (self.array, size) { - (PostgresArray::None, None) => PostgresArray::Dynamic, - (PostgresArray::None, Some(size)) => PostgresArray::Fixed(VecDeque::from([size])), - (PostgresArray::Fixed(mut sizes), Some(size)) => { - sizes.push_back(size); - PostgresArray::Fixed(sizes) - } - _ => return Err(TypeError::NestedArrays), - }; - Ok(Self { - scalar: self.scalar, - array: arr, - }) - } - - pub fn composite>(schema: &Rc, name: S) -> Self { - Self { - scalar: PostgresScalar::Composite(SchemaName::new(schema, name)), - array: PostgresArray::None, - } - } - - pub fn to_field(self, name: impl Into) -> PostgresField { - PostgresField::new(name, self) - } -} - -impl From for (String, PostgresType) { - fn from(val: PostgresField) -> Self { - (val.name, val.pg_type) - } -} diff --git a/crates/introspect-postgres-sink/src/upgrade.rs b/crates/introspect-postgres-sink/src/upgrade.rs deleted file mode 100644 index f34dcbdb..00000000 --- a/crates/introspect-postgres-sink/src/upgrade.rs +++ /dev/null @@ -1,575 +0,0 @@ -use crate::create::PostgresTypeExtractor; -use crate::query::{ColumnUpgrade, StructMod, StructMods, TableUpgrade}; -use crate::{HasherExt, PostgresScalar, PostgresType}; -use introspect_types::{ - ArrayDef, ColumnDef, EnumDef, FixedArrayDef, MemberDef, OptionDef, PrimaryDef, PrimaryTypeDef, - ResultInto, StructDef, TupleDef, TypeDef, VariantDef, -}; -use std::collections::HashMap; -use std::rc::Rc; -use torii_introspect_sql_sink::table::Table; -use torii_introspect_sql_sink::{ - DeadField, TableResult, TypeError, TypeResult, UpgradeError, UpgradeResult, UpgradeResultExt, -}; -use xxhash_rust::xxh3::Xxh3; - -pub trait PgTableUpgrade { - fn upgrade_table( - &mut self, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], - ) -> TableResult; - fn retype_primary(&mut self, new: &PrimaryTypeDef) -> UpgradeResult>; -} - -impl PgTableUpgrade for Table { - fn upgrade_table( - &mut self, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], - ) -> TableResult { - let branch = Xxh3::new_based(&self.id); - let schema: Rc = self.namespace(); - let mut table_mod = TableUpgrade::new(&schema, self.id, self.name.clone()); - table_mod.rename_table(name); - table_mod.rename_column(&mut self.primary.name, &primary.name); - let pg_type = self - .retype_primary(&primary.type_def) - .to_table_result(&self.name, &self.primary.name)?; - table_mod.retype_primary(&self.primary.name, pg_type); - for column in columns { - let branch = branch.branch(&column.id); - if let Some(current) = self.columns.get_mut(&column.id) { - let upgraded = table_mod.rename_column(&mut current.name, &column.name); - let mut column_upgrade = table_mod.column_upgrade(upgraded); - let pg_type = current - .type_def - .compare_type( - &schema, - &branch, - &column.type_def, - &mut self.dead, - &mut column_upgrade, - ) - .to_table_result(&self.name, ¤t.name)?; - let type_name = current.type_def.get_pg_type(&schema, &branch)?; - table_mod.retype_column(column, pg_type, column_upgrade, type_name); - } else { - let (column_id, info) = column.clone().into(); - self.columns.insert(column_id, info); - let pg_type = - column - .type_def - .extract_type(&schema, &branch, &mut table_mod.atomic)?; - table_mod.add_column(column_id, &column.name, pg_type); - } - } - Ok(table_mod) - } - fn retype_primary(&mut self, new: &PrimaryTypeDef) -> UpgradeResult> { - use crate::PostgresScalar::{ - BigInt, Felt252 as PgFelt252, Int, Int128, SmallInt, Uint128, Uint16, Uint32, Uint64, - Uint8, - }; - use introspect_types::PrimaryTypeDef::{ - Bool, Bytes31, Bytes31Encoded, ClassHash, ContractAddress, EthAddress, Felt252, - ShortUtf8, StorageAddress, StorageBaseAddress, I128, I16, I32, I64, I8, U128, U16, U32, - U64, U8, - }; - match (&self.primary.type_def, new) { - (Bool, Bool) - | (U8, U8) - | (U16, U16) - | (U32, U32) - | (U64, U64) - | (U128, U128) - | (I8, I8) - | (I16, I16) - | (I32, I32) - | (I64, I64) - | (I128, I128) - | (ShortUtf8, ShortUtf8) - | (EthAddress, EthAddress) - | (ClassHash, ClassHash) - | (ContractAddress, ContractAddress) - | (StorageAddress, StorageAddress) - | (StorageBaseAddress, StorageBaseAddress) - | (Bytes31, Bytes31) - | (Bytes31Encoded(_), Bytes31Encoded(_)) - | (Felt252, Felt252) => Ok(None), - (Bool, U8) => self.primary.type_def.update_as(U8, Uint8), - (Bool | U8, U16) => self.primary.type_def.update_as(U16, Uint16), - (Bool | U8 | U16, U32) => self.primary.type_def.update_as(U32, Uint32), - (Bool | U8 | U16 | U32, U64) => self.primary.type_def.update_as(U64, Uint64), - (Bool | U8 | U16 | U32 | U64, U128) => self.primary.type_def.update_as(U128, Uint128), - (Bool | U8, I8) => self.primary.type_def.update_as(I8, SmallInt), - (Bool | U8 | I8, I16) => self.primary.type_def.update_as(I16, SmallInt), - (Bool | U8 | U16 | I8 | I16, I32) => self.primary.type_def.update_as(I32, Int), - (Bool | U8 | U16 | U32 | I8 | I16 | I32, I64) => { - self.primary.type_def.update_as(I64, BigInt) - } - (Bool | U8 | U16 | U32 | U64 | I8 | I16 | I32 | I64, I128) => { - self.primary.type_def.update_as(I128, Int128) - } - ( - EthAddress, - ClassHash | ContractAddress | StorageAddress | StorageBaseAddress | Felt252, - ) => self.primary.type_def.update_to(new, PgFelt252), - ( - ClassHash | ContractAddress | StorageAddress | StorageBaseAddress | Felt252, - ClassHash | ContractAddress | StorageAddress | StorageBaseAddress | Felt252, - ) => self.primary.type_def.update_no_change(new), - _ => UpgradeError::primary_upgrade_err(&self.primary.type_def, new), - } - } -} - -pub trait ExtractItem { - fn as_struct(&mut self) -> UpgradeResult<&mut StructDef>; - fn as_enum(&mut self) -> UpgradeResult<&mut EnumDef>; - fn as_fixed_array(&mut self) -> UpgradeResult<&mut FixedArrayDef>; - fn as_array(&mut self) -> UpgradeResult<&mut TypeDef>; - fn as_tuple(&mut self) -> UpgradeResult<&mut TupleDef>; - fn update_as_array( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &ArrayDef, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult>; - fn update_as_option( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &TypeDef, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult>; - fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> TypeResult; -} - -impl ExtractItem for TypeDef { - fn as_struct(&mut self) -> UpgradeResult<&mut StructDef> { - match self { - TypeDef::Struct(def) => Ok(def), - item => UpgradeError::type_upgrade_to_err(item, "Struct"), - } - } - fn as_enum(&mut self) -> UpgradeResult<&mut EnumDef> { - match self { - TypeDef::Enum(def) => Ok(def), - item => UpgradeError::type_upgrade_to_err(item, "Enum"), - } - } - fn as_fixed_array(&mut self) -> UpgradeResult<&mut FixedArrayDef> { - match self { - TypeDef::FixedArray(def) => Ok(def), - item => UpgradeError::type_upgrade_to_err(item, "FixedArray"), - } - } - fn as_array(&mut self) -> UpgradeResult<&mut TypeDef> { - match self { - TypeDef::Array(def) => Ok(&mut def.type_def), - TypeDef::FixedArray(def) => Ok(&mut def.type_def), - item => UpgradeError::type_upgrade_to_err(item, "Array"), - } - } - fn as_tuple(&mut self) -> UpgradeResult<&mut TupleDef> { - match self { - TypeDef::Tuple(def) => Ok(def), - item => UpgradeError::type_upgrade_to_err(item, "Tuple"), - } - } - - fn update_as_array( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &ArrayDef, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult> { - self.as_array()? - .compare_type(schema, branch, new, dead, queries)? - .map(|a| a.to_array(None)) - .transpose() - .err_into() - } - fn update_as_option( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &TypeDef, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult> { - match self { - TypeDef::Option(def) => def.compare_type(schema, branch, new, dead, queries), - _ => { - let pg_type = self.compare_type(schema, branch, new, dead, queries); - *self = OptionDef::new_type_def(std::mem::take(self)); - pg_type - } - } - } - fn get_pg_type(&self, schema: &Rc, branch: &Xxh3) -> TypeResult { - match self { - TypeDef::None => Ok(PostgresScalar::None.into()), - TypeDef::Bool => Ok(PostgresScalar::Boolean.into()), - TypeDef::I8 | TypeDef::I16 => Ok(PostgresScalar::SmallInt.into()), - TypeDef::I32 => Ok(PostgresScalar::Int.into()), - TypeDef::I64 => Ok(PostgresScalar::BigInt.into()), - TypeDef::U8 => Ok(PostgresScalar::Uint8.into()), - TypeDef::U16 => Ok(PostgresScalar::Uint16.into()), - TypeDef::U32 => Ok(PostgresScalar::Uint32.into()), - TypeDef::U64 => Ok(PostgresScalar::Uint64.into()), - TypeDef::U128 => Ok(PostgresScalar::Uint128.into()), - TypeDef::I128 => Ok(PostgresScalar::Int128.into()), - TypeDef::U256 => Ok(PostgresScalar::Uint256.into()), - TypeDef::U512 => Ok(PostgresScalar::Uint512.into()), - TypeDef::Felt252 => Ok(PostgresScalar::Felt252.into()), - TypeDef::ContractAddress - | TypeDef::ClassHash - | TypeDef::StorageAddress - | TypeDef::StorageBaseAddress => Ok(PostgresScalar::StarknetHash.into()), - TypeDef::EthAddress => Ok(PostgresScalar::EthAddress.into()), - TypeDef::Utf8String => Ok(PostgresScalar::Text.into()), - TypeDef::ShortUtf8 => Ok(PostgresScalar::Char31.into()), - TypeDef::ByteArray | TypeDef::ByteArrayEncoded(_) => Ok(PostgresScalar::Bytea.into()), - TypeDef::Bytes31 | TypeDef::Bytes31Encoded(_) => Ok(PostgresScalar::Bytes31.into()), - TypeDef::Tuple(_) => Ok(PostgresType::composite(schema, branch.tuple_name())), - TypeDef::Enum(def) => Ok(PostgresType::composite(schema, branch.type_name(&def.name))), - TypeDef::Array(def) => def.get_pg_type(schema, branch)?.to_array(None), - TypeDef::FixedArray(def) => def - .type_def - .get_pg_type(schema, branch)? - .to_array(Some(def.size)), - TypeDef::Struct(def) => { - Ok(PostgresType::composite(schema, branch.type_name(&def.name))) - } - TypeDef::Option(def) => def.get_pg_type(schema, branch), - TypeDef::Nullable(def) => def.get_pg_type(schema, branch), - TypeDef::Felt252Dict(_) | TypeDef::Result(_) | TypeDef::Ref(_) | TypeDef::Custom(_) => { - Err(TypeError::UnsupportedType(format!("{self:?}"))) - } - } - } -} - -pub trait CompareType { - fn compare_type( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &Self, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult>; -} - -pub trait UpdateType: Clone { - fn update_no_change(&mut self, new: &Self) -> UpgradeResult> { - *self = new.clone(); - Ok(None) - } - fn update_to( - &mut self, - def: &Self, - pg: impl Into, - ) -> UpgradeResult> { - *self = def.clone(); - Ok(Some(pg.into())) - } - fn update_as( - &mut self, - def: Self, - pg: impl Into, - ) -> UpgradeResult> { - *self = def; - Ok(Some(pg.into())) - } -} - -impl UpdateType for TypeDef {} -impl UpdateType for PrimaryTypeDef {} - -pub trait UpgradeField { - fn type_def(&self) -> &TypeDef; - fn type_def_mut(&mut self) -> &mut TypeDef; - fn name(&self) -> &str; - fn upgrade_field( - &mut self, - schema: &Rc, - name: &str, - branch: &Xxh3, - new: &Self, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult<()> { - let pg_type = - self.type_def_mut() - .compare_type(schema, branch, new.type_def(), dead, queries)?; - queries.maybe_alter(schema, name, self.name(), pg_type); - Ok(()) - } - fn add_field( - &self, - schema: &Rc, - branch: &Xxh3, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult { - let pg_type = self - .type_def() - .extract_type(schema, branch, &mut queries.atomic)?; - Ok(StructMod::add(self.name(), pg_type)) - } -} - -impl UpgradeField for MemberDef { - fn type_def(&self) -> &TypeDef { - &self.type_def - } - fn type_def_mut(&mut self) -> &mut TypeDef { - &mut self.type_def - } - fn name(&self) -> &str { - &self.name - } -} - -impl UpgradeField for VariantDef { - fn type_def(&self) -> &TypeDef { - &self.type_def - } - fn type_def_mut(&mut self) -> &mut TypeDef { - &mut self.type_def - } - fn name(&self) -> &str { - &self.name - } -} - -impl CompareType for TypeDef { - fn compare_type( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &TypeDef, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult> { - use introspect_types::TypeDef::{ - Array, Bool, ByteArray, ByteArrayEncoded, Bytes31, Bytes31Encoded, ClassHash, - ContractAddress, Enum, EthAddress, Felt252, FixedArray, None as TDNone, ShortUtf8, - StorageAddress, StorageBaseAddress, Struct, Tuple, Utf8String, I128, I16, I32, I64, I8, - U128, U16, U256, U32, U512, U64, U8, - }; - use PostgresScalar::{ - BigInt, Felt252 as PgFelt252, Int, Int128, SmallInt, Uint128, Uint16, Uint256, Uint32, - Uint512, Uint64, Uint8, - }; - match (&*self, new) { - (TDNone, TDNone) - | (Utf8String, Utf8String) - | (ShortUtf8, ShortUtf8) - | (Bool, Bool) - | (U8, U8) - | (U16, U16) - | (U32, U32) - | (U64, U64) - | (U128, U128) - | (U256, U256) - | (U512, U512) - | (I8, I8) - | (I16, I16) - | (I32, I32) - | (I64, I64) - | (I128, I128) - | (Felt252, Felt252) - | (EthAddress, EthAddress) - | (ClassHash, ClassHash) - | (ContractAddress, ContractAddress) - | (StorageAddress, StorageAddress) - | (StorageBaseAddress, StorageBaseAddress) - | (Bytes31, Bytes31) - | (ByteArray, ByteArray) => Ok(None), - (I8, I16) - | (Bytes31, Bytes31Encoded(_)) - | (ByteArray, ByteArrayEncoded(_)) - | ( - ClassHash | ContractAddress | StorageAddress | StorageBaseAddress, - ClassHash | ContractAddress | StorageAddress | StorageBaseAddress, - ) => self.update_no_change(new), - (Bool, U8) => self.update_as(U8, Uint8), - (Bool | U8, U16) => self.update_as(U16, Uint16), - (Bool | U8 | U16, U32) => self.update_as(U32, Uint32), - (Bool | U8 | U16 | U32, U64) => self.update_as(U64, Uint64), - (Bool | U8 | U16 | U32 | U64, U128) => self.update_as(U128, Uint128), - (Bool | U8 | U16 | U32 | U64 | U128, U256) => self.update_as(U256, Uint256), - (Bool | U8 | U16 | U32 | U64 | U128 | U256, U512) => self.update_as(U512, Uint512), - (Bool | U8, I8) => self.update_as(I8, SmallInt), - (Bool | U8, I16) => self.update_as(I16, SmallInt), - (Bool | U8 | U16 | I8 | I16, I32) => self.update_as(I32, Int), - (Bool | U8 | U16 | U32 | I8 | I16 | I32, I64) => self.update_as(I64, BigInt), - (Bool | U8 | U16 | U32 | U64 | I8 | I16 | I32 | I64, I128) => { - self.update_as(I128, Int128) - } - (ClassHash | ContractAddress | StorageAddress | StorageBaseAddress, Felt252) => { - self.update_as(Felt252, PgFelt252) - } - (_, Struct(new_def)) => self - .as_struct()? - .compare_type(schema, branch, new_def, dead, queries), - (_, Enum(new_def)) => self - .as_enum()? - .compare_type(schema, branch, new_def, dead, queries), - (_, FixedArray(new_def)) => self - .as_fixed_array()? - .compare_type(schema, branch, new_def, dead, queries), - (_, Array(new_def)) => self.update_as_array(schema, branch, new_def, dead, queries), - (_, Tuple(new_def)) => self - .as_tuple()? - .compare_type(schema, branch, new_def, dead, queries), - (_, TypeDef::Option(new_def)) => { - self.update_as_option(schema, branch, new_def, dead, queries) - } - _ => UpgradeError::type_upgrade_err(self, new), - } - } -} - -impl CompareType for StructDef { - fn compare_type( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &StructDef, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult> { - let mut mods: Vec = Vec::new(); - let mut current_map: HashMap = std::mem::take(&mut self.members) - .into_iter() - .map(|m| (m.name.clone(), m)) - .collect(); - let struct_name = branch.type_name(&self.name); - for member in &new.members { - let branch = branch.branch(&member.name); - if let Some(mut current) = current_map - .remove(&member.name) - .or_else(|| dead.remove(&branch.digest128()).map(Into::into)) - { - current.upgrade_field(schema, &struct_name, &branch, member, dead, queries)?; - self.members.push(current); - } else { - mods.push(member.add_field(schema, &branch, queries)?); - self.members.push(member.clone()); - } - } - for (_, dead_member) in current_map.drain() { - let id = branch.branch(&dead_member.name).digest128(); - queries.add_dead_member(id, &dead_member); - dead.insert(id, dead_member.into()); - } - queries.add_struct_mod(schema, struct_name, mods); - Ok(None) - } -} - -impl CompareType for EnumDef { - fn compare_type( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &EnumDef, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult> { - let mut rename = Vec::new(); - let mut add = Vec::new(); - let mut mods = Vec::new(); - let enum_name = branch.type_name(&self.name); - for (id, variant) in &new.variants { - let branch = branch.branch(id); - if let Some(current) = self.variants.get_mut(id) { - if current.name != variant.name { - rename.push((current.name.clone(), variant.name.clone())); - mods.rename(¤t.name, &variant.name); - current.name = variant.name.clone(); - } - current.upgrade_field(schema, &enum_name, &branch, variant, dead, queries)?; - } else { - add.push(variant.name.clone()); - variant.add_field(schema, &branch, queries)?; - self.variants.insert(*id, variant.clone()); - self.order.push(*id); - } - } - queries.add_enum_mod( - schema, - branch.type_name(&format!("v_{}", self.name)), - rename, - add, - ); - queries.add_struct_mod(schema, enum_name, mods); - Ok(None) - } -} - -impl CompareType for FixedArrayDef { - fn compare_type( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &Self, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult> { - let pg_type = self - .type_def - .compare_type(schema, branch, &new.type_def, dead, queries)?; - if self.size > new.size { - return UpgradeError::array_shorten_err(self.size, new.size); - } - self.size = new.size; - pg_type - .map(|pg_type| pg_type.to_array(Some(self.size))) - .transpose() - .err_into() - } -} - -impl CompareType for TupleDef { - fn compare_type( - &mut self, - schema: &Rc, - branch: &Xxh3, - new: &Self, - dead: &mut HashMap, - queries: &mut ColumnUpgrade, - ) -> UpgradeResult> { - let mut mods = Vec::new(); - let name = branch.tuple_name(); - if self.elements.len() > new.elements.len() { - return Err(UpgradeError::TupleReductionError); - } - for (n, ty) in new.elements.iter().enumerate() { - let branch = branch.branch(&(n as u32)); - if let Some(current) = self.elements.get_mut(n) { - let pg_type = current.compare_type(schema, &branch, ty, dead, queries)?; - queries.maybe_alter(schema, &name, &format!("_{}", n), pg_type); - } else { - self.elements.push(ty.clone()); - mods.add( - format!("_{}", n), - ty.extract_type(schema, &branch, &mut queries.atomic)?, - ); - } - } - queries.add_struct_mod(schema, name, mods); - Ok(None) - } -} diff --git a/crates/introspect-postgres-sink/src/utils.rs b/crates/introspect-postgres-sink/src/utils.rs deleted file mode 100644 index a006d44e..00000000 --- a/crates/introspect-postgres-sink/src/utils.rs +++ /dev/null @@ -1,95 +0,0 @@ -use starknet_types_core::felt::Felt; -use xxhash_rust::xxh3::Xxh3; - -pub fn truncate(s: &str, max_chars: usize) -> &str { - match s.char_indices().nth(max_chars) { - None => s, - Some((idx, _)) => &s[..idx], - } -} - -const ALLOWED_TYPE_NAME_CHARS: &str = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; - -fn parse_type_name(type_name: &str) -> String { - fn parse_char(c: char) -> char { - if ALLOWED_TYPE_NAME_CHARS.contains(c) { - c - } else { - '_' - } - } - type_name - .chars() - .take(31) - .map(parse_char) - .collect::() - .to_lowercase() -} - -pub trait HasherExt { - fn new_based(base: &T) -> Self; - fn type_name(&self, name: &str) -> String; - fn tuple_name(&self) -> String; - fn branch(&self, name: &T) -> Self; - fn branch_to_type_name(&self, leaf: &T, name: &str) -> String; -} - -impl HasherExt for Xxh3 { - fn new_based(base: &T) -> Self { - let mut hash = Xxh3::new(); - let bytes = base.as_bytes(); - hash.update(&(bytes.len() as u32).to_le_bytes()); - hash.update(&bytes); - hash - } - - fn type_name(&self, name: &str) -> String { - let hash = &format!("{:032x}", self.digest128())[..31]; - format!("{}_{}", parse_type_name(name), hash) - } - - fn tuple_name(&self) -> String { - self.type_name("tuple") - } - - fn branch(&self, name: &T) -> Xxh3 { - let mut hasher = self.clone(); - let bytes = name.as_bytes(); - hasher.update(&(bytes.len() as u32).to_le_bytes()); - hasher.update(&bytes); - hasher - } - - fn branch_to_type_name(&self, leaf: &T, name: &str) -> String { - self.branch(leaf).type_name(name) - } -} - -pub trait AsBytes { - fn as_bytes(&self) -> Vec; -} - -impl AsBytes for Felt { - fn as_bytes(&self) -> Vec { - self.to_bytes_be().to_vec() - } -} - -impl AsBytes for str { - fn as_bytes(&self) -> Vec { - str::as_bytes(self).to_vec() - } -} - -impl AsBytes for String { - fn as_bytes(&self) -> Vec { - self.as_bytes().to_vec() - } -} - -impl AsBytes for u32 { - fn as_bytes(&self) -> Vec { - self.to_le_bytes().to_vec() - } -} diff --git a/crates/introspect-sql-sink/src/backend.rs b/crates/introspect-sql-sink/src/backend.rs index 7017741b..1435753c 100644 --- a/crates/introspect-sql-sink/src/backend.rs +++ b/crates/introspect-sql-sink/src/backend.rs @@ -9,7 +9,7 @@ use starknet_types_core::felt::Felt; use torii_introspect::events::IntrospectBody; use torii_introspect::tables::RecordSchema; use torii_introspect::Record; -use torii_sql::{DbConnection, Executable, FlexQuery}; +use torii_sql::{DbPool, Executable, FlexQuery}; #[async_trait] pub trait IntrospectProcessor { @@ -32,7 +32,7 @@ pub trait IntrospectInitialize { ) -> DbResult>; } -pub trait IntrospectQueryMaker: DbConnection { +pub trait IntrospectQueryMaker: DbPool { type DB: Database; fn create_table_queries( namespace: &str, diff --git a/crates/introspect-sql-sink/src/lib.rs b/crates/introspect-sql-sink/src/lib.rs index 3605664c..1553b8de 100644 --- a/crates/introspect-sql-sink/src/lib.rs +++ b/crates/introspect-sql-sink/src/lib.rs @@ -18,9 +18,14 @@ pub use table::{DeadField, DeadFieldDef, Table}; #[cfg(feature = "postgres")] pub mod postgres; +#[cfg(feature = "postgres")] +pub use postgres::{IntrospectPgDb, PostgresBackend}; #[cfg(feature = "sqlite")] pub mod sqlite; +#[cfg(feature = "sqlite")] +pub use sqlite::{IntrospectSqliteDb, SqliteBackend}; #[cfg(feature = "postgres")] +#[cfg(feature = "sqlite")] pub mod runtime; diff --git a/crates/introspect-sql-sink/src/postgres/backend.rs b/crates/introspect-sql-sink/src/postgres/backend.rs index 8fe705ab..3fb9d4b7 100644 --- a/crates/introspect-sql-sink/src/postgres/backend.rs +++ b/crates/introspect-sql-sink/src/postgres/backend.rs @@ -11,26 +11,26 @@ use introspect_types::{ColumnDef, FeltIds, PrimaryDef}; use starknet_types_core::felt::Felt; use torii_introspect::tables::RecordSchema; use torii_introspect::Record; -use torii_sql::{DbConnection, PgPool, PgQuery, Postgres}; +use torii_sql::{DbPool, PgPool, PgQuery, Postgres}; -pub type IntrospectPgDb = IntrospectDb>; +pub type IntrospectPgDb = IntrospectDb; -pub struct PostgresBackend>(T); +pub struct PostgresBackend(PgPool); -impl> From for PostgresBackend { - fn from(value: T) -> Self { +impl From for PostgresBackend { + fn from(value: PgPool) -> Self { PostgresBackend(value) } } -impl> DbConnection for PostgresBackend { +impl DbPool for PostgresBackend { fn pool(&self) -> &PgPool { - self.0.pool() + &self.0 } } #[async_trait] -impl + Send + Sync> IntrospectQueryMaker for PostgresBackend { +impl IntrospectQueryMaker for PostgresBackend { type DB = Postgres; fn create_table_queries( @@ -140,6 +140,6 @@ where Ok(()) } -impl> IntrospectSqlSink for PostgresBackend { +impl IntrospectSqlSink for PostgresBackend { const NAME: &'static str = "Introspect Postgres"; } diff --git a/crates/introspect-sql-sink/src/postgres/handler.rs b/crates/introspect-sql-sink/src/postgres/handler.rs index d511a12f..e4733efd 100644 --- a/crates/introspect-sql-sink/src/postgres/handler.rs +++ b/crates/introspect-sql-sink/src/postgres/handler.rs @@ -4,13 +4,13 @@ use crate::backend::IntrospectInitialize; use crate::{DbColumn, DbDeadField, DbResult, DbTable}; use async_trait::async_trait; use introspect_types::ResultInto; -use torii_sql::{DbConnection, Postgres}; +use torii_sql::DbPool; pub const INTROSPECT_PG_SINK_MIGRATIONS: sqlx::migrate::Migrator = sqlx::migrate!("./migrations/postgres"); #[async_trait] -impl + Send + Sync> IntrospectInitialize for PostgresBackend { +impl IntrospectInitialize for PostgresBackend { async fn load_tables(&self, schemas: &Option>) -> DbResult> { fetch_tables(self.pool(), schemas).await.err_into() } diff --git a/crates/introspect-sql-sink/src/processor.rs b/crates/introspect-sql-sink/src/processor.rs index 52b2d384..ae2d2da3 100644 --- a/crates/introspect-sql-sink/src/processor.rs +++ b/crates/introspect-sql-sink/src/processor.rs @@ -12,7 +12,7 @@ use sqlx::Pool; use starknet_types_core::felt::Felt; use std::collections::HashMap; use torii_introspect::events::IntrospectBody; -use torii_sql::{DbConnection, Executable, FlexQuery}; +use torii_sql::{DbPool, Executable, FlexQuery}; pub const COMMIT_CMD: &str = "--COMMIT"; @@ -49,7 +49,7 @@ pub struct DbDeadField { pub type_def: TypeDef, } -impl DbConnection for IntrospectDb { +impl DbPool for IntrospectDb { fn pool(&self) -> &Pool { self.db.pool() } @@ -84,7 +84,7 @@ where } } -impl IntrospectDb { +impl IntrospectDb { pub fn new(pool: impl Into, namespaces: impl Into) -> Self { Self { tables: Tables::default(), @@ -92,7 +92,8 @@ impl IntrospectDb db: pool.into(), } } - +} +impl IntrospectDb { pub async fn initialize_introspect_sql_sink(&self) -> DbResult> { self.db.initialize().await?; self.load_store_data().await diff --git a/crates/introspect-sql-sink/src/runtime.rs b/crates/introspect-sql-sink/src/runtime.rs index 4d6b7460..273c20d0 100644 --- a/crates/introspect-sql-sink/src/runtime.rs +++ b/crates/introspect-sql-sink/src/runtime.rs @@ -6,19 +6,15 @@ use crate::{ NamespaceMode, }; use async_trait::async_trait; -use sqlx::{Postgres, Sqlite}; use torii_introspect::events::IntrospectBody; -use torii_sql::DbConnection; -pub enum RuntimeBackend { - Postgres(Pg), - Sqlite(Site), +pub enum RuntimeBackend { + Postgres(PostgresBackend), + Sqlite(SqliteBackend), } #[async_trait] -impl - IntrospectInitialize for RuntimeBackend -{ +impl IntrospectInitialize for RuntimeBackend { async fn initialize(&self) -> DbResult<()> { match self { RuntimeBackend::Postgres(pg) => pg.initialize().await, @@ -49,9 +45,7 @@ impl - IntrospectProcessor for RuntimeBackend -{ +impl IntrospectProcessor for RuntimeBackend { async fn process_msgs( &self, tables: &Tables, @@ -65,18 +59,14 @@ impl, Site> From> - for RuntimeBackend, Site> -{ - fn from(pg: PostgresBackend) -> Self { +impl From for RuntimeBackend { + fn from(pg: PostgresBackend) -> Self { RuntimeBackend::Postgres(pg) } } -impl, Pg> From> - for RuntimeBackend> -{ - fn from(site: SqliteBackend) -> Self { +impl From for RuntimeBackend { + fn from(site: SqliteBackend) -> Self { RuntimeBackend::Sqlite(site) } } diff --git a/crates/introspect-sql-sink/src/sqlite/backend.rs b/crates/introspect-sql-sink/src/sqlite/backend.rs index c10576b8..7613ce03 100644 --- a/crates/introspect-sql-sink/src/sqlite/backend.rs +++ b/crates/introspect-sql-sink/src/sqlite/backend.rs @@ -9,28 +9,36 @@ use sqlx::prelude::FromRow; use sqlx::types::Json; use starknet_types_core::felt::{Felt, FromStrError}; use std::collections::HashMap; +use std::ops::Deref; use torii_introspect::tables::RecordSchema; use torii_introspect::Record; -use torii_sql::{DbConnection, Queries, Sqlite, SqlitePool, SqliteQuery}; +use torii_sql::{DbPool, Queries, Sqlite, SqlitePool, SqliteQuery}; use super::query::create_table_query; pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: sqlx::migrate::Migrator = sqlx::migrate!("./migrations/sqlite"); -pub type IntrospectSqliteDb = IntrospectDb>; +pub type IntrospectSqliteDb = IntrospectDb; -pub struct SqliteBackend>(T); +pub struct SqliteBackend(SqlitePool); -impl> From for SqliteBackend { - fn from(value: T) -> Self { +impl Deref for SqliteBackend { + type Target = SqlitePool; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for SqliteBackend { + fn from(value: SqlitePool) -> Self { SqliteBackend(value) } } -impl> DbConnection for SqliteBackend { +impl DbPool for SqliteBackend { fn pool(&self) -> &SqlitePool { - self.0.pool() + &self.0 } } @@ -63,7 +71,7 @@ impl TryFrom for DbTable { } #[async_trait] -impl + Send + Sync> IntrospectQueryMaker for SqliteBackend { +impl IntrospectQueryMaker for SqliteBackend { type DB = Sqlite; fn create_table_queries( namespace: &str, @@ -105,12 +113,12 @@ impl + Send + Sync> IntrospectQueryMaker for SqliteBacke } } -impl> IntrospectSqlSink for SqliteBackend { +impl IntrospectSqlSink for SqliteBackend { const NAME: &'static str = "Introspect Sqlite"; } #[async_trait] -impl + Send + Sync> IntrospectInitialize for SqliteBackend { +impl IntrospectInitialize for SqliteBackend { async fn load_tables(&self, _schemas: &Option>) -> DbResult> { let rows: Vec = sqlx::query_as( r" diff --git a/crates/introspect-sql-sink/src/sqlite/mod.rs b/crates/introspect-sql-sink/src/sqlite/mod.rs index 265fc5e1..a121c7cb 100644 --- a/crates/introspect-sql-sink/src/sqlite/mod.rs +++ b/crates/introspect-sql-sink/src/sqlite/mod.rs @@ -3,4 +3,6 @@ pub mod json; pub mod query; use sqlx::migrate::Migrator; -pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: Migrator = sqlx::migrate!("./migrations"); +pub use backend::{IntrospectSqliteDb, SqliteBackend}; + +pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: Migrator = sqlx::migrate!("./migrations/sqlite"); diff --git a/crates/introspect-sqlite-sink/Cargo.toml b/crates/introspect-sqlite-sink/Cargo.toml deleted file mode 100644 index 508e8364..00000000 --- a/crates/introspect-sqlite-sink/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "torii-introspect-sqlite-sink" -version = "0.1.0" -edition = "2021" -description = "SQLite sink implementation for Torii runtime" -authors = ["Torii Runtime "] -license = "Apache-2.0" - -[dependencies] -sqlx = { workspace = true, features = [ - "sqlite", - "runtime-tokio-rustls", - "macros", - "migrate", -] } -anyhow.workspace = true -async-trait.workspace = true -metrics.workspace = true -hex.workspace = true -serde.workspace = true -serde_json.workspace = true -starknet.workspace = true -tokio.workspace = true -torii.workspace = true -tracing.workspace = true -starknet-types-core.workspace = true -thiserror.workspace = true -introspect-types.workspace = true -itertools.workspace = true - -torii-introspect.workspace = true -torii-sql = { workspace = true, features = ["sqlite"] } -torii-introspect-sql-sink.workspace = true - -[lints] -workspace = true diff --git a/crates/introspect-sqlite-sink/migrations/001_init.sql b/crates/introspect-sqlite-sink/migrations/001_init.sql deleted file mode 100644 index 1f3f65bb..00000000 --- a/crates/introspect-sqlite-sink/migrations/001_init.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE IF NOT EXISTS introspect_sink_metadata ( - id INTEGER PRIMARY KEY CHECK (id = 1), - initialized_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP -); diff --git a/crates/introspect-sqlite-sink/migrations/002_schema_state.sql b/crates/introspect-sqlite-sink/migrations/002_schema_state.sql deleted file mode 100644 index 6355d19d..00000000 --- a/crates/introspect-sqlite-sink/migrations/002_schema_state.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE IF NOT EXISTS introspect_sink_schema_state ( - namespace TEXT NOT NULL, - id TEXT NOT NULL, - owner TEXT NOT NULL, - "primary" TEXT NOT NULL, - columns TEXT NOT NULL, - dead TEXT NOT NULL, - alive INTEGER NOT NULL DEFAULT 1, - updated_at INTEGER NOT NULL DEFAULT (unixepoch()), - PRIMARY KEY (namespace, id) -); diff --git a/crates/introspect-sqlite-sink/src/backend.rs b/crates/introspect-sqlite-sink/src/backend.rs deleted file mode 100644 index feb0f8c3..00000000 --- a/crates/introspect-sqlite-sink/src/backend.rs +++ /dev/null @@ -1,139 +0,0 @@ -use async_trait::async_trait; -use introspect_types::{ColumnDef, ColumnInfo, PrimaryDef, ResultInto}; -use itertools::Itertools; -use sqlx::prelude::FromRow; -use sqlx::types::Json; -use starknet_types_core::felt::{Felt, FromStrError}; -use std::collections::HashMap; -use torii_introspect::tables::RecordSchema; -use torii_introspect::Record; -use torii_introspect_sql_sink::processor::IntrospectDb; -use torii_introspect_sql_sink::{ - DbColumn, DbDeadField, DbResult, DbTable, DeadField, IntrospectBackend, IntrospectSqlSink, - RecordResult, Table, TableResult, -}; -use torii_sql::{DbConnection, Queries, Sqlite, SqlitePool, SqliteQuery}; - -use crate::query::create_table_query; - -pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: sqlx::migrate::Migrator = - sqlx::migrate!("./migrations"); - -pub type IntrospectSqliteDb = IntrospectDb>; - -pub struct SqliteBackend>(T); - -impl> From for SqliteBackend { - fn from(value: T) -> Self { - SqliteBackend(value) - } -} - -impl> DbConnection for SqliteBackend { - fn pool(&self) -> &SqlitePool { - self.0.pool() - } -} - -#[derive(FromRow)] -pub struct SqliteTableRow { - namespace: String, - id: String, - owner: String, - name: String, - primary: Json, - columns: Json>, - dead: Json>, - alive: bool, -} - -impl TryFrom for DbTable { - type Error = FromStrError; - fn try_from(value: SqliteTableRow) -> Result { - Ok(DbTable { - namespace: value.namespace, - id: Felt::from_hex(&value.id)?, - owner: Felt::from_hex(&value.owner)?, - name: value.name, - primary: value.primary.0, - columns: value.columns.0.into_iter().map_into().collect(), - dead: value.dead.0.into_iter().map_into().collect(), - alive: value.alive, - }) - } -} - -#[async_trait] -impl + Send + Sync> IntrospectBackend for SqliteBackend { - type DB = Sqlite; - async fn load_tables(&self, _schemas: &Option>) -> DbResult> { - let rows: Vec = sqlx::query_as( - r" - SELECT namespace, id, owner, name, primary, columns, dead, alive - FROM introspect_sink_schema_state - ORDER BY updated_at ASC - ", - ) - .fetch_all(self.pool()) - .await?; - - let tables: Vec = rows - .into_iter() - .map(|row| row.try_into()) - .collect::>()?; - Ok(tables) - } - async fn load_columns(&self, _schemas: &Option>) -> DbResult> { - Ok(Vec::new()) - } - async fn load_dead_fields(&self, _schemas: &Option>) -> DbResult> { - Ok(Vec::new()) - } - async fn initialize(&self) -> DbResult<()> { - self.migrate(Some("introspect"), INTROSPECT_SQLITE_SINK_MIGRATIONS) - .await - .err_into() - } - fn create_table_queries( - namespace: &str, - _id: &Felt, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], - _from_address: &Felt, - _block_number: u64, - _transaction_hash: &Felt, - queries: &mut Vec, - ) -> TableResult<()> { - queries.add(create_table_query(namespace, name, primary, columns)); - Ok(()) - } - fn update_table_queries( - _table: &mut Table, - _name: &str, - _primary: &PrimaryDef, - _columns: &[ColumnDef], - _from_address: &Felt, - _block_number: u64, - _transaction_hash: &Felt, - _queries: &mut Vec, - ) -> TableResult<()> { - Ok(()) - } - fn insert_record_queries( - _namespace: &str, - _table_name: &str, - _schema: &RecordSchema<'_>, - _records: &[Record], - _from_address: &Felt, - _block_number: u64, - _transaction_hash: &Felt, - _queries: &mut Vec, - ) -> RecordResult<()> { - Ok(()) - } -} - -impl> IntrospectSqlSink for SqliteBackend { - const NAME: &'static str = "Introspect Sqlite"; -} diff --git a/crates/introspect-sqlite-sink/src/json.rs b/crates/introspect-sqlite-sink/src/json.rs deleted file mode 100644 index 64c4668e..00000000 --- a/crates/introspect-sqlite-sink/src/json.rs +++ /dev/null @@ -1,83 +0,0 @@ -use introspect_types::serialize::ToCairoDeSeFrom; -use introspect_types::serialize_def::CairoTypeSerialization; -use introspect_types::{CairoDeserializer, ResultDef, TupleDef, TypeDef}; -use serde::ser::SerializeMap; -use serde::Serializer; - -pub struct SqliteJsonSerializer; - -impl CairoTypeSerialization for SqliteJsonSerializer { - fn serialize_byte_array( - &self, - serializer: S, - value: &[u8], - ) -> Result { - serializer.serialize_str(&format!("0x{}", hex::encode(value))) - } - - fn serialize_felt( - &self, - serializer: S, - value: &[u8; 32], - ) -> Result { - self.serialize_byte_array(serializer, value) - } - - fn serialize_eth_address( - &self, - serializer: S, - value: &[u8; 20], - ) -> Result { - self.serialize_byte_array(serializer, value) - } - - fn serialize_tuple<'a, S: Serializer>( - &'a self, - data: &mut impl CairoDeserializer, - serializer: S, - tuple: &'a TupleDef, - ) -> Result { - let mut seq = serializer.serialize_map(Some(tuple.elements.len()))?; - for (index, element) in tuple.elements.iter().enumerate() { - seq.serialize_entry(&format!("_{index}"), &element.to_de_se(data, self))?; - } - seq.end() - } - - fn serialize_variant<'a, S: Serializer>( - &'a self, - data: &mut impl CairoDeserializer, - serializer: S, - name: &str, - type_def: &'a TypeDef, - ) -> Result { - if type_def == &TypeDef::None { - let mut map = serializer.serialize_map(Some(1))?; - map.serialize_entry("variant", name)?; - map - } else { - let mut map = serializer.serialize_map(Some(2))?; - map.serialize_entry("variant", name)?; - map.serialize_entry(&format!("_{name}"), &type_def.to_de_se(data, self))?; - map - } - .end() - } - - fn serialize_result<'a, S: Serializer>( - &'a self, - data: &mut impl CairoDeserializer, - serializer: S, - result: &'a ResultDef, - is_ok: bool, - ) -> Result { - let mut map = serializer.serialize_map(Some(1))?; - map.serialize_entry("is_ok", &is_ok)?; - if is_ok { - map.serialize_entry("Ok", &result.ok.to_de_se(data, self))?; - } else { - map.serialize_entry("Err", &result.err.to_de_se(data, self))?; - } - map.end() - } -} diff --git a/crates/introspect-sqlite-sink/src/lib.rs b/crates/introspect-sqlite-sink/src/lib.rs deleted file mode 100644 index 265fc5e1..00000000 --- a/crates/introspect-sqlite-sink/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod backend; -pub mod json; -pub mod query; -use sqlx::migrate::Migrator; - -pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: Migrator = sqlx::migrate!("./migrations"); diff --git a/crates/introspect-sqlite-sink/src/processor.rs b/crates/introspect-sqlite-sink/src/processor.rs deleted file mode 100644 index f655e432..00000000 --- a/crates/introspect-sqlite-sink/src/processor.rs +++ /dev/null @@ -1,396 +0,0 @@ -use crate::json::SqliteJsonSerializer; -use crate::table::{SqliteTable, SqliteTableError}; -use crate::INTROSPECT_SQLITE_SINK_MIGRATIONS; -use introspect_types::{ColumnDef, PrimaryDef}; -use serde_json::{Serializer as JsonSerializer, Value}; -use sqlx::{Error as SqlxError, Row, Sqlite}; -use starknet_types_core::felt::Felt; -use std::collections::HashMap; -use std::fmt::Display; -use std::ops::Deref; -use std::sync::{PoisonError, RwLock}; -use torii::etl::envelope::MetaData; -use torii_introspect::events::{IntrospectBody, IntrospectMsg}; -use torii_introspect::schema::TableSchema; -use torii_introspect::InsertsFields; -use torii_introspect_sql_sink::{table, Table}; -use torii_sql::DbConnection; - -#[derive(Debug, thiserror::Error)] -pub enum SqliteDbError { - #[error(transparent)] - DatabaseError(#[from] SqlxError), - #[error(transparent)] - JsonError(#[from] serde_json::Error), - #[error(transparent)] - TableError(#[from] SqliteTableError), - #[error("record frame must serialize to an object")] - InvalidRecordFrame, - #[error("Table with id: {0} already exists, incoming name: {1}, existing name: {2}")] - TableAlreadyExists(Felt, String, String), - #[error("Table not found with id: {0}")] - TableNotFound(Felt), - #[error("Table poison error: {0}")] - PoisonError(String), -} - -type SqliteDbResult = std::result::Result; - -impl From> for SqliteDbError { - fn from(err: PoisonError) -> Self { - Self::PoisonError(err.to_string()) - } -} - -#[derive(Debug, Default)] -pub struct SqliteTables(pub RwLock>); - -impl Deref for SqliteTables { - type Target = RwLock>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[derive(Debug, Clone, Default)] -pub enum SqliteNamespace { - #[default] - None, - Custom(String), -} - -impl SqliteNamespace { - pub fn prefix(&self) -> &str { - match self { - Self::None => "", - Self::Custom(prefix) => prefix, - } - } -} - -impl From<()> for SqliteNamespace { - fn from((): ()) -> Self { - Self::None - } -} - -impl From for SqliteNamespace { - fn from(value: String) -> Self { - if value.is_empty() { - Self::None - } else { - Self::Custom(value) - } - } -} - -impl From<&str> for SqliteNamespace { - fn from(value: &str) -> Self { - if value.is_empty() { - Self::None - } else { - Self::Custom(value.to_string()) - } - } -} - -impl Display for SqliteNamespace { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::None => f.write_str("main"), - Self::Custom(prefix) => f.write_str(prefix), - } - } -} - -impl SqliteTables { - pub fn assert_table_not_exists(&self, id: &Felt, name: &str) -> SqliteDbResult<()> { - match self.read()?.get(id) { - Some(existing) => Err(SqliteDbError::TableAlreadyExists( - *id, - name.to_string(), - existing.name.clone(), - )), - None => Ok(()), - } - } - - pub fn create_table( - &self, - namespace: &SqliteNamespace, - to_table: impl Into, - ) -> SqliteDbResult<(Felt, String)> { - let table = to_table.into(); - self.assert_table_not_exists(&table.id, &table.name)?; - let (id, sqlite_table) = SqliteTable::new_from_table(namespace.prefix(), table); - let create_query = create_table_query(&sqlite_table); - self.write()?.insert(id, sqlite_table); - Ok((id, create_query)) - } - - pub fn set_table_dead(&self, id: &Felt) -> SqliteDbResult<()> { - if let Some(table) = self.write()?.get_mut(id) { - table.alive = false; - return Ok(()); - } - Err(SqliteDbError::TableNotFound(*id)) - } -} - -fn create_table_query( - namespace: &str, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], -) -> String { - let mut columns_sql = Vec::with_capacity(columns.len() + 1); - columns_sql.push(format!(r#""{}" TEXT PRIMARY KEY"#, primary.name)); - for column in columns { - columns_sql.push(format!(r#""{}" TEXT"#, column.name)); - } - format!( - r#"CREATE TABLE IF NOT EXISTS "{}" ({});"#, - table_name(&namespace, name), - columns_sql.join(", ") - ) -} - -fn serialize_sqlite_value(value: &Value) -> Option { - match value { - Value::Null => None, - Value::String(value) => Some(value.clone()), - _ => Some(value.to_string()), - } -} - -pub struct IntrospectSqliteDb { - tables: SqliteTables, - namespace: SqliteNamespace, - pool: T, -} - -impl> DbConnection for IntrospectSqliteDb { - fn pool(&self) -> &sqlx::SqlitePool { - self.pool.pool() - } -} - -impl + Send + Sync> IntrospectSqliteDb { - pub fn new(pool: T, namespace: impl Into) -> Self { - Self { - tables: SqliteTables::default(), - namespace: namespace.into(), - pool, - } - } - - pub async fn initialize_introspect_sqlite_sink(&self) -> SqliteDbResult<()> { - self.migrate(Some("introspect"), INTROSPECT_SQLITE_SINK_MIGRATIONS) - .await?; - self.load_persisted_state().await?; - Ok(()) - } - - async fn load_persisted_state(&self) -> SqliteDbResult<()> { - let rows = sqlx::query( - r" - SELECT table_schema_json, alive - FROM introspect_sink_schema_state - ORDER BY updated_at ASC - ", - ) - .fetch_all(self.pool()) - .await?; - - let mut tables = self.tables.write()?; - for row in rows { - let schema_json: String = row.try_get("table_schema_json")?; - let alive: i64 = row.try_get("alive")?; - let table_schema: TableSchema = serde_json::from_str(&schema_json)?; - let (id, mut table) = - SqliteTable::new_from_table(self.namespace.prefix(), table_schema); - table.alive = alive != 0; - tables.insert(id, table); - } - - Ok(()) - } - - async fn persist_table_state(&self, table: &TableSchema, alive: bool) -> SqliteDbResult<()> { - let schema_json = serde_json::to_string(table)?; - let alive = i64::from(alive); - sqlx::query( - r" - INSERT INTO introspect_sink_schema_state (table_id, table_schema_json, alive, updated_at) - VALUES (?1, ?2, ?3, unixepoch()) - ON CONFLICT (table_id) - DO UPDATE SET - table_schema_json = excluded.table_schema_json, - alive = excluded.alive, - updated_at = unixepoch() - ", - ) - .bind(format!("{:#x}", table.id)) - .bind(schema_json) - .bind(alive) - .execute(self.pool()) - .await?; - Ok(()) - } - - async fn persist_alive_state(&self, table_id: Felt, alive: bool) -> SqliteDbResult<()> { - let alive = i64::from(alive); - sqlx::query( - r" - UPDATE introspect_sink_schema_state - SET alive = ?1, updated_at = unixepoch() - WHERE table_id = ?2 - ", - ) - .bind(alive) - .bind(format!("{table_id:#x}")) - .execute(self.pool()) - .await?; - Ok(()) - } - - pub fn load_tables_no_commit(&self, table_schemas: Vec) -> SqliteDbResult<()> { - let mut tables = self.tables.write()?; - for table in table_schemas { - let (id, sqlite_table) = SqliteTable::new_from_table(self.namespace.prefix(), table); - tables.insert(id, sqlite_table); - } - Ok(()) - } - - pub async fn process_message( - &self, - msg: &IntrospectMsg, - metadata: &MetaData, - ) -> SqliteDbResult<()> { - match msg { - IntrospectMsg::CreateTable(event) => { - let (_, query) = self.tables.create_table(&self.namespace, event.clone())?; - self.execute_queries(&[query]).await?; - self.persist_table_state(&event.clone().into(), true) - .await?; - Ok(()) - } - IntrospectMsg::UpdateTable(event) => { - self.tables.set_table_dead(&event.id)?; - self.persist_alive_state(event.id, false).await - } - IntrospectMsg::AddColumns(event) => { - self.tables.set_table_dead(&event.table)?; - self.persist_alive_state(event.table, false).await - } - IntrospectMsg::DropColumns(event) => { - self.tables.set_table_dead(&event.table)?; - self.persist_alive_state(event.table, false).await - } - IntrospectMsg::RetypeColumns(event) => { - self.tables.set_table_dead(&event.table)?; - self.persist_alive_state(event.table, false).await - } - IntrospectMsg::RetypePrimary(event) => { - self.tables.set_table_dead(&event.table)?; - self.persist_alive_state(event.table, false).await - } - IntrospectMsg::RenameTable(_) - | IntrospectMsg::DropTable(_) - | IntrospectMsg::RenameColumns(_) - | IntrospectMsg::RenamePrimary(_) - | IntrospectMsg::DeleteRecords(_) - | IntrospectMsg::DeletesFields(_) => Ok(()), - IntrospectMsg::InsertsFields(event) => self.insert_fields(event, metadata).await, - } - } - - pub async fn process_messages( - &self, - msgs: Vec<&IntrospectBody>, - ) -> SqliteDbResult>> { - let mut results = Vec::with_capacity(msgs.len()); - for body in msgs { - let (msg, metadata) = body.into(); - results.push(self.process_message(msg, metadata).await); - } - Ok(results) - } - - async fn insert_fields( - &self, - event: &InsertsFields, - _metadata: &MetaData, - ) -> SqliteDbResult<()> { - let table = self - .tables - .read()? - .get(&event.table) - .ok_or(SqliteDbError::TableNotFound(event.table))? - .clone(); - if !table.alive { - return Ok(()); - } - - let record_schema = table.get_schema(&event.columns)?; - let column_names = std::iter::once(table.primary.name.as_str()) - .chain( - event - .columns - .iter() - .map(|id| table.columns[id].name.as_str()), - ) - .collect::>(); - - let update_columns = column_names - .iter() - .skip(1) - .map(|name| { - format!( - r#""{name}" = COALESCE(excluded."{name}", "{table_name}"."{name}")"#, - table_name = table.storage_name - ) - }) - .collect::>() - .join(", "); - - let sql = format!( - r#"INSERT INTO "{}" ({}) VALUES ({}) ON CONFLICT("{}") DO UPDATE SET {}"#, - table.storage_name, - column_names - .iter() - .map(|name| format!(r#""{name}""#)) - .collect::>() - .join(", "), - vec!["?"; column_names.len()].join(", "), - table.primary.name, - update_columns - ); - - let mut bytes = Vec::new(); - let mut serializer = JsonSerializer::new(&mut bytes); - record_schema.parse_records_with_metadata( - &event.records, - &(), - &mut serializer, - &SqliteJsonSerializer, - )?; - let rows = serde_json::from_slice::>(&bytes)?; - - let mut tx = self.begin().await?; - for value in rows { - let object = value.as_object().ok_or(SqliteDbError::InvalidRecordFrame)?; - - let mut query = sqlx::query(&sql); - for column_name in &column_names { - let value = object.get(*column_name).and_then(serialize_sqlite_value); - query = query.bind(value); - } - query.execute(&mut *tx).await?; - } - tx.commit().await?; - Ok(()) - } -} diff --git a/crates/introspect-sqlite-sink/src/query.rs b/crates/introspect-sqlite-sink/src/query.rs deleted file mode 100644 index 49a6a000..00000000 --- a/crates/introspect-sqlite-sink/src/query.rs +++ /dev/null @@ -1,23 +0,0 @@ -use introspect_types::{ColumnDef, PrimaryDef}; - -pub fn create_table_query( - namespace: &str, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], -) -> String { - let mut columns_sql = Vec::with_capacity(columns.len() + 1); - columns_sql.push(format!(r#""{}" TEXT PRIMARY KEY"#, primary.name)); - for column in columns { - columns_sql.push(format!(r#""{}" TEXT"#, column.name)); - } - format!( - r#"CREATE TABLE IF NOT EXISTS "{}" ({});"#, - table_name(&namespace, name), - columns_sql.join(", ") - ) -} - -pub fn table_name(namespace: &str, name: &str) -> String { - format!("{namespace}__{name}") -} diff --git a/crates/introspect-sqlite-sink/src/sink.rs b/crates/introspect-sqlite-sink/src/sink.rs deleted file mode 100644 index fc0b2717..00000000 --- a/crates/introspect-sqlite-sink/src/sink.rs +++ /dev/null @@ -1,102 +0,0 @@ -use crate::processor::IntrospectSqliteDb; -use anyhow::Result; -use async_trait::async_trait; -use sqlx::Sqlite; -use std::sync::Arc; -use torii::axum::Router; -use torii::etl::envelope::{Envelope, TypeId}; -use torii::etl::extractor::ExtractionBatch; -use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; -use torii_introspect::events::{IntrospectBody, IntrospectMsg}; -use torii_sql::DbConnection; - -pub const LOGGING_TARGET: &str = "torii::sinks::introspect::sqlite"; -const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); - -#[async_trait] -impl> Sink for IntrospectSqliteDb { - fn name(&self) -> &'static str { - "introspect-sqlite" - } - - fn interested_types(&self) -> Vec { - vec![TypeId::new("introspect")] - } - - async fn process(&self, envelopes: &[Envelope], _batch: &ExtractionBatch) -> Result<()> { - let mut processed = 0usize; - let mut create_tables = 0usize; - let mut update_tables = 0usize; - let mut inserts_fields = 0usize; - let mut inserted_records = 0usize; - let mut delete_records = 0usize; - let mut msgs = Vec::with_capacity(envelopes.len()); - for envelope in envelopes { - if envelope.type_id == INTROSPECT_TYPE { - if let Some(body) = envelope.downcast_ref::() { - match &body.msg { - IntrospectMsg::CreateTable(_) => create_tables += 1, - IntrospectMsg::UpdateTable(_) => update_tables += 1, - IntrospectMsg::InsertsFields(event) => { - inserts_fields += 1; - inserted_records += event.records.len(); - } - IntrospectMsg::DeleteRecords(event) => { - delete_records += event.rows.len(); - } - _ => {} - } - processed += 1; - msgs.push(body); - } - } - } - self.process_messages(msgs).await?; - - if processed > 0 { - tracing::info!( - target: LOGGING_TARGET, - processed, - create_tables, - update_tables, - inserts_fields, - inserted_records, - delete_records, - "Processed introspect envelopes" - ); - ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "create_table") - .increment(create_tables as u64); - ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "update_table") - .increment(update_tables as u64); - ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "inserts_fields") - .increment(inserts_fields as u64); - ::metrics::counter!("torii_introspect_sink_records_total", "message" => "inserts_fields") - .increment(inserted_records as u64); - ::metrics::counter!("torii_introspect_sink_records_total", "message" => "delete_records") - .increment(delete_records as u64); - } - - Ok(()) - } - - fn topics(&self) -> Vec { - Vec::new() - } - - fn build_routes(&self) -> Router { - Router::new() - } - - async fn initialize( - &mut self, - _event_bus: Arc, - _context: &SinkContext, - ) -> Result<()> { - self.initialize_introspect_sqlite_sink().await?; - tracing::info!( - target: LOGGING_TARGET, - "Initialized introspect SQLite sink" - ); - Ok(()) - } -} diff --git a/crates/introspect-sqlite-sink/src/table.rs b/crates/introspect-sqlite-sink/src/table.rs deleted file mode 100644 index 14b7a559..00000000 --- a/crates/introspect-sqlite-sink/src/table.rs +++ /dev/null @@ -1,70 +0,0 @@ -use introspect_types::{ColumnDef, ColumnInfo, FeltIds, PrimaryDef}; -use itertools::Itertools; -use starknet_types_core::felt::Felt; -use std::collections::HashMap; -use thiserror::Error; -use torii_introspect::schema::TableSchema; -use torii_introspect::tables::RecordSchema; - -#[derive(Debug, Error)] -pub enum SqliteTableError { - #[error("Column with id: {0} not found in table {1}")] - ColumnNotFound(Felt, String), -} - -pub type TableResult = std::result::Result; - -#[derive(Debug, Clone)] -pub struct SqliteTable { - pub name: String, - pub storage_name: String, - pub primary: PrimaryDef, - pub columns: HashMap, - pub order: Vec, - pub alive: bool, -} - -impl SqliteTable { - pub fn new( - storage_name: String, - name: String, - primary: PrimaryDef, - columns: Vec, - ) -> Self { - Self { - name, - storage_name, - primary, - order: columns.ids(), - columns: columns.into_iter().map_into().collect(), - alive: true, - } - } - - pub fn new_from_table(namespace: &str, table: impl Into) -> (Felt, Self) { - let table = table.into(); - let storage_name = if namespace.is_empty() { - table.name.clone() - } else { - format!("{namespace}__{}", table.name) - }; - ( - table.id, - Self::new(storage_name, table.name, table.primary, table.columns), - ) - } - - pub fn get_column(&self, selector: &Felt) -> TableResult<&ColumnInfo> { - self.columns - .get(selector) - .ok_or_else(|| SqliteTableError::ColumnNotFound(*selector, self.name.clone())) - } - - pub fn get_schema(&self, column_ids: &[Felt]) -> TableResult> { - let columns = column_ids - .iter() - .map(|selector| self.get_column(selector)) - .collect::, _>>()?; - Ok(RecordSchema::new(&self.primary, columns)) - } -} diff --git a/crates/sql/src/connection.rs b/crates/sql/src/connection.rs index db0628d9..57769ac4 100644 --- a/crates/sql/src/connection.rs +++ b/crates/sql/src/connection.rs @@ -1,13 +1,11 @@ -use crate::{query::Executable, AcquiredSchema, SqlxResult}; +use crate::query::Executable; +use crate::{AcquiredSchema, SqlxResult}; use async_trait::async_trait; -use sqlx::{ - migrate::{Migrate, Migrator}, - Database, Pool, Transaction, -}; -use std::ops::Deref; +use sqlx::migrate::{Migrate, Migrator}; +use sqlx::{Database, Pool, Transaction}; #[async_trait] -pub trait DbConnection { +pub trait DbPool { fn pool(&self) -> &Pool; async fn begin(&self) -> SqlxResult> { Ok(self.pool().begin().await?) @@ -21,7 +19,7 @@ pub trait DbConnection { Some(schema) => { let mut conn = AcquiredSchema { connection: self.pool().acquire().await?.detach(), - schema: schema, + schema, }; migrator.run_direct(&mut conn).await } @@ -29,17 +27,21 @@ pub trait DbConnection { }; Ok(result?) } - async fn execute_queries(&self, queries: impl Executable + Send) -> SqlxResult<()> { + async fn execute_queries + Send>(&self, queries: E) -> SqlxResult<()> { let mut transaction: Transaction<'_, DB> = self.begin().await?; queries.execute(&mut transaction).await?; transaction.commit().await } } -#[allow(clippy::explicit_auto_deref)] #[async_trait] -impl> + Send + Sync + 'static> DbConnection for T { +impl DbPool for Pool { fn pool(&self) -> &Pool { - &**self + self } } + +pub enum DbConn { + Postgres, + Sqlite, +} diff --git a/crates/sql/src/lib.rs b/crates/sql/src/lib.rs index 24dbf605..f586a529 100644 --- a/crates/sql/src/lib.rs +++ b/crates/sql/src/lib.rs @@ -3,7 +3,7 @@ pub mod migrate; pub mod query; pub mod types; -pub use connection::DbConnection; +pub use connection::DbPool; pub use migrate::{AcquiredSchema, SchemaMigrator}; pub use query::{Executable, FlexQuery, Queries}; diff --git a/crates/sql/src/postgres.rs b/crates/sql/src/postgres/migrate.rs similarity index 84% rename from crates/sql/src/postgres.rs rename to crates/sql/src/postgres/migrate.rs index 0af5f39d..9b5fc616 100644 --- a/crates/sql/src/postgres.rs +++ b/crates/sql/src/postgres/migrate.rs @@ -1,23 +1,9 @@ -use crate::types::SqlFelt; -use crate::{AcquiredSchema, DbConnection, FlexQuery}; +use crate::AcquiredSchema; use futures::future::BoxFuture; -use sqlx::encode::IsNull; -use sqlx::error::BoxDynError; use sqlx::migrate::{AppliedMigration, Migrate, MigrateError, Migration}; -use sqlx::postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef}; -use sqlx::{ - query, query_as, query_scalar, Connection, Decode, Encode, Executor, PgConnection, Type, -}; +use sqlx::{query, query_as, query_scalar, Connection, Executor, PgConnection, Postgres}; use std::time::{Duration, Instant}; -pub use sqlx::postgres::PgArguments; -pub use sqlx::{PgPool, Postgres}; - -pub type PgQuery = FlexQuery; - -pub trait PgDbConnection: DbConnection {} -impl PgDbConnection for T {} - impl Migrate for AcquiredSchema { fn ensure_migrations_table(&mut self) -> BoxFuture<'_, Result<(), MigrateError>> { Box::pin(async move { @@ -250,35 +236,3 @@ async fn revert_migration( Ok(()) } - -impl Type for SqlFelt { - fn type_info() -> PgTypeInfo { - PgTypeInfo::with_name("felt252") - } - - fn compatible(ty: &PgTypeInfo) -> bool { - *ty == PgTypeInfo::with_name("felt252") || <[u8] as Type>::compatible(ty) - } -} - -impl PgHasArrayType for SqlFelt { - fn array_type_info() -> PgTypeInfo { - PgTypeInfo::with_name("_felt252") - } -} - -impl Encode<'_, Postgres> for SqlFelt { - fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result { - <&[u8] as Encode>::encode(self.0.as_slice(), buf) - } -} - -impl Decode<'_, Postgres> for SqlFelt { - fn decode(value: PgValueRef<'_>) -> Result { - let bytes = <&[u8] as Decode>::decode(value)?; - let arr: [u8; 32] = bytes - .try_into() - .map_err(|_| format!("expected 32 bytes for felt252, got {}", bytes.len()))?; - Ok(SqlFelt(arr)) - } -} diff --git a/crates/sql/src/postgres/mod.rs b/crates/sql/src/postgres/mod.rs new file mode 100644 index 00000000..8224e523 --- /dev/null +++ b/crates/sql/src/postgres/mod.rs @@ -0,0 +1,10 @@ +pub mod migrate; +pub mod types; + +pub use sqlx::postgres::PgArguments; +pub use sqlx::{PgPool, Postgres}; + +pub type PgQuery = crate::FlexQuery; + +pub trait PgDbConnection: crate::DbPool {} +impl crate::PgDbConnection for T {} diff --git a/crates/sql/src/postgres/types.rs b/crates/sql/src/postgres/types.rs new file mode 100644 index 00000000..3ed6d57e --- /dev/null +++ b/crates/sql/src/postgres/types.rs @@ -0,0 +1,38 @@ +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; +use sqlx::postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef}; +use sqlx::{Decode, Encode, Postgres, Type}; + +use crate::types::SqlFelt; + +impl Type for SqlFelt { + fn type_info() -> PgTypeInfo { + PgTypeInfo::with_name("felt252") + } + + fn compatible(ty: &PgTypeInfo) -> bool { + *ty == PgTypeInfo::with_name("felt252") || <[u8] as Type>::compatible(ty) + } +} + +impl PgHasArrayType for SqlFelt { + fn array_type_info() -> PgTypeInfo { + PgTypeInfo::with_name("_felt252") + } +} + +impl Encode<'_, Postgres> for SqlFelt { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result { + <&[u8] as Encode>::encode(self.0.as_slice(), buf) + } +} + +impl Decode<'_, Postgres> for SqlFelt { + fn decode(value: PgValueRef<'_>) -> Result { + let bytes = <&[u8] as Decode>::decode(value)?; + let arr: [u8; 32] = bytes + .try_into() + .map_err(|_| format!("expected 32 bytes for felt252, got {}", bytes.len()))?; + Ok(SqlFelt(arr)) + } +} diff --git a/crates/sql/src/query.rs b/crates/sql/src/query.rs index 6571095a..cf5815bb 100644 --- a/crates/sql/src/query.rs +++ b/crates/sql/src/query.rs @@ -1,86 +1,73 @@ -use async_trait::async_trait; +use futures::future::BoxFuture; use itertools::Itertools; use sqlx::{Database, Executor, Transaction}; -use std::borrow::Cow; use std::sync::Arc; use crate::SqlxResult; -#[async_trait] pub trait Executable { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()>; + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't; } -#[async_trait] impl Executable for &str where for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - transaction.execute(self).await?; - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + transaction.execute(self).await?; + Ok(()) + }) } } -#[async_trait] impl Executable for &String where for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - transaction.execute(self.as_str()).await?; - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + transaction.execute(self.as_str()).await?; + Ok(()) + }) } } -#[async_trait] impl Executable for String where for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - transaction.execute(self.as_str()).await?; - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + transaction.execute(self.as_str()).await?; + Ok(()) + }) } } -#[async_trait] -impl Executable for Cow<'_, str> -where - for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, -{ - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - transaction.execute(self.as_ref()).await?; - Ok(()) - } -} - -pub struct QueryLike, DB: Database> { - sql: S, - args: Option<::Arguments<'static>>, -} - -impl, DB: Database> QueryLike { - pub fn new(sql: impl Into, args: ::Arguments<'static>) -> Self { - Self { - sql: sql.into(), - args: Some(args), - } - } - - pub fn from_sql(sql: S) -> Self { - Self { sql, args: None } - } -} - -#[async_trait] impl Executable for FlexStr where for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - transaction.execute(self.as_ref()).await?; - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + transaction.execute(self.as_ref()).await?; + Ok(()) + }) } } @@ -90,25 +77,58 @@ pub enum FlexStr { Shared(Arc), } -impl AsRef for FlexStr { - fn as_ref(&self) -> &str { +impl FlexStr { + pub fn as_str(&self) -> &str { match self { FlexStr::Owned(s) => s.as_str(), - FlexStr::Static(s) => s, FlexStr::Shared(s) => s, + FlexStr::Static(s) => s, } } } +impl AsRef for FlexStr { + fn as_ref(&self) -> &str { + self.as_str() + } +} + impl PartialEq for FlexStr { fn eq(&self, other: &str) -> bool { self.as_ref() == other } } -impl, DB: Database> PartialEq for QueryLike { +/// A query with optional bind arguments. +/// +/// SQL can be any `FlexStr` (String, Arc, &'static str). +/// When bind arguments are present, the SQL is stored separately as `&'static str` +/// because SQLite's `Arguments<'q>` requires the SQL lifetime to match exactly. +/// Dynamic SQL (DDL, schema operations) never has bind parameters. +pub enum FlexQuery { + Sql(FlexStr), + Bound { + sql: &'static str, + args: ::Arguments<'static>, + }, +} + +impl FlexQuery { + pub fn new(sql: &'static str, args: ::Arguments<'static>) -> Self { + FlexQuery::Bound { sql, args } + } + + pub fn from_sql(sql: impl Into) -> Self { + FlexQuery::Sql(sql.into()) + } +} + +impl PartialEq for FlexQuery { fn eq(&self, other: &str) -> bool { - self.sql.as_ref() == other + match self { + FlexQuery::Sql(s) => s.as_ref() == other, + FlexQuery::Bound { sql, .. } => *sql == other, + } } } @@ -130,107 +150,130 @@ impl From> for FlexStr { } } -impl From for QueryLike { +impl From for FlexQuery { fn from(sql: FlexStr) -> Self { - QueryLike::from_sql(sql) + FlexQuery::from_sql(sql) } } -impl From<&'static str> for QueryLike { +impl From<&'static str> for FlexQuery { fn from(sql: &'static str) -> Self { - QueryLike::from_sql(sql.into()) + FlexQuery::from_sql(sql) } } -impl From for QueryLike { +impl From for FlexQuery { fn from(sql: String) -> Self { - QueryLike::from_sql(sql.into()) + FlexQuery::from_sql(sql) } } -impl From> for QueryLike { +impl From> for FlexQuery { fn from(sql: Arc) -> Self { - QueryLike::from_sql(sql.into()) + FlexQuery::from_sql(sql) } } pub trait Queries { - fn add(&mut self, query: impl Into>); - fn adds(&mut self, queries: impl IntoIterator>>); + fn add(&mut self, query: impl Into>); + fn adds(&mut self, queries: impl IntoIterator>>); } -impl Queries for Vec> { - fn add(&mut self, query: impl Into>) { +impl Queries for Vec> { + fn add(&mut self, query: impl Into>) { self.push(query.into()); } - fn adds(&mut self, queries: impl IntoIterator>>) { + fn adds(&mut self, queries: impl IntoIterator>>) { self.extend(queries.into_iter().map_into()); } } -#[async_trait] impl Executable for &[String; N] where for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - for query in self { - transaction.execute(query.as_str()).await?; - } - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + for query in self { + transaction.execute(query.as_str()).await?; + } + Ok(()) + }) } } -#[async_trait] impl + Send> Executable for Vec { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - for item in self { - item.execute(transaction).await?; - } - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + for item in self { + item.execute(transaction).await?; + } + Ok(()) + }) } } -#[async_trait] impl<'a, DB: Database, T> Executable for &'a Vec where &'a T: Executable + Send, T: Send + Sync, { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - for item in self { - item.execute(transaction).await?; - } - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + for item in self { + item.execute(transaction).await?; + } + Ok(()) + }) } } -#[async_trait] impl<'a, DB: Database, T> Executable for &'a [T] where &'a T: Executable + Send, T: Send + Sync, { - async fn execute(self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - for item in self { - item.execute(transaction).await?; - } - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + for item in self { + item.execute(transaction).await?; + } + Ok(()) + }) } } -#[async_trait] -impl + Send, DB: Database> Executable for QueryLike +impl Executable for FlexQuery where for<'c> &'c mut ::Connection: Executor<'c, Database = DB>, - for<'q> ::Arguments<'static>: sqlx::IntoArguments<'q, DB>, + ::Arguments<'static>: sqlx::IntoArguments<'static, DB>, { - async fn execute(mut self, transaction: &mut Transaction<'_, DB>) -> SqlxResult<()> { - let sql = self.sql.as_ref(); - let args = self.args.take().unwrap_or_default(); - transaction.execute(sqlx::query_with(sql, args)).await?; - Ok(()) + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + match self { + FlexQuery::Bound { sql, args } => { + transaction.execute(sqlx::query_with(sql, args)).await?; + } + FlexQuery::Sql(sql) => { + transaction.execute(sql.as_ref()).await?; + } + } + Ok(()) + }) } } - -pub type FlexQuery = QueryLike; diff --git a/crates/sql/src/sqlite.rs b/crates/sql/src/sqlite/migrate.rs similarity index 63% rename from crates/sql/src/sqlite.rs rename to crates/sql/src/sqlite/migrate.rs index 0599574f..11c1ca22 100644 --- a/crates/sql/src/sqlite.rs +++ b/crates/sql/src/sqlite/migrate.rs @@ -1,22 +1,10 @@ -use crate::types::SqlFelt; -use crate::{AcquiredSchema, DbConnection, FlexQuery}; +use crate::AcquiredSchema; use futures::future::BoxFuture; -use sqlx::encode::IsNull; -use sqlx::error::BoxDynError; use sqlx::migrate::{AppliedMigration, Migrate, MigrateError, Migration}; -use sqlx::sqlite::SqliteConnectOptions; -use sqlx::{query, query_as, Acquire, Decode, Encode, Executor, SqliteConnection, Type}; +use sqlx::{query, query_as, Acquire, Executor, Sqlite, SqliteConnection}; use std::borrow::Cow; -use std::str::FromStr; use std::time::{Duration, Instant}; -pub use sqlx::sqlite::SqliteArguments; -pub use sqlx::{Sqlite, SqlitePool}; - -pub type SqliteQuery = FlexQuery; -pub trait SqliteDbConnection: DbConnection {} -impl> SqliteDbConnection for T {} - impl AcquiredSchema { fn table_name(&self) -> Cow<'static, str> { Cow::Owned(format!("_sqlx_migrations_{}", self.schema)) @@ -170,75 +158,3 @@ WHERE version = ?2 }) } } - -pub fn is_sqlite_memory_path(path: &str) -> bool { - path == ":memory:" - || path == "sqlite::memory:" - || path == "sqlite://:memory:" - || path.contains("mode=memory") -} - -pub fn sqlite_connect_options(path: &str) -> Result { - if path == ":memory:" || path == "sqlite::memory:" { - return SqliteConnectOptions::from_str("sqlite::memory:"); - } - - let options = if path.starts_with("sqlite:") { - SqliteConnectOptions::from_str(path)? - } else { - SqliteConnectOptions::new().filename(path) - }; - - if path.starts_with("sqlite:") && path.contains("mode=") { - Ok(options) - } else { - Ok(options.create_if_missing(true)) - } -} - -impl Type for SqlFelt { - fn type_info() -> ::TypeInfo { - >::type_info() - } -} - -impl<'q> Encode<'q, Sqlite> for SqlFelt { - fn encode_by_ref( - &self, - buf: &mut ::ArgumentBuffer<'q>, - ) -> Result { - let mut hex = String::with_capacity(66); - hex.push_str("0x"); - for byte in &self.0 { - use std::fmt::Write; - write!(hex, "{byte:02x}").unwrap(); - } - Encode::::encode(hex, buf) - } -} - -impl Decode<'_, Sqlite> for SqlFelt { - fn decode(value: ::ValueRef<'_>) -> Result { - let s = >::decode(value)?; - let s = s.strip_prefix("0x").unwrap_or(&s); - if s.len() != 64 { - return Err(format!("expected 64 hex chars for felt252, got {}", s.len()).into()); - } - let mut arr = [0u8; 32]; - for (i, chunk) in s.as_bytes().chunks(2).enumerate() { - let hi = hex_nibble(chunk[0])?; - let lo = hex_nibble(chunk[1])?; - arr[i] = (hi << 4) | lo; - } - Ok(SqlFelt(arr)) - } -} - -fn hex_nibble(c: u8) -> Result { - match c { - b'0'..=b'9' => Ok(c - b'0'), - b'a'..=b'f' => Ok(c - b'a' + 10), - b'A'..=b'F' => Ok(c - b'A' + 10), - _ => Err(format!("invalid hex char: {}", c as char).into()), - } -} diff --git a/crates/sql/src/sqlite/mod.rs b/crates/sql/src/sqlite/mod.rs new file mode 100644 index 00000000..dcaf6b9e --- /dev/null +++ b/crates/sql/src/sqlite/mod.rs @@ -0,0 +1,38 @@ +pub mod migrate; +pub mod types; + +pub use sqlx::sqlite::SqliteArguments; +pub use sqlx::{Sqlite, SqlitePool}; + +use sqlx::sqlite::SqliteConnectOptions; +use std::str::FromStr; + +pub type SqliteQuery = super::FlexQuery; + +pub trait SqliteDbConnection: super::DbPool {} +impl> SqliteDbConnection for T {} + +pub fn is_sqlite_memory_path(path: &str) -> bool { + path == ":memory:" + || path == "sqlite::memory:" + || path == "sqlite://:memory:" + || path.contains("mode=memory") +} + +pub fn sqlite_connect_options(path: &str) -> Result { + if path == ":memory:" || path == "sqlite::memory:" { + return SqliteConnectOptions::from_str("sqlite::memory:"); + } + + let options = if path.starts_with("sqlite:") { + SqliteConnectOptions::from_str(path)? + } else { + SqliteConnectOptions::new().filename(path) + }; + + if path.starts_with("sqlite:") && path.contains("mode=") { + Ok(options) + } else { + Ok(options.create_if_missing(true)) + } +} diff --git a/crates/sql/src/sqlite/types.rs b/crates/sql/src/sqlite/types.rs new file mode 100644 index 00000000..8d3ad9ab --- /dev/null +++ b/crates/sql/src/sqlite/types.rs @@ -0,0 +1,51 @@ +use crate::types::SqlFelt; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; +use sqlx::{Decode, Encode, Sqlite, Type}; + +impl Type for SqlFelt { + fn type_info() -> ::TypeInfo { + >::type_info() + } +} + +impl<'q> Encode<'q, Sqlite> for SqlFelt { + fn encode_by_ref( + &self, + buf: &mut ::ArgumentBuffer<'q>, + ) -> Result { + let mut hex = String::with_capacity(66); + hex.push_str("0x"); + for byte in &self.0 { + use std::fmt::Write; + write!(hex, "{byte:02x}").unwrap(); + } + Encode::::encode(hex, buf) + } +} + +impl Decode<'_, Sqlite> for SqlFelt { + fn decode(value: ::ValueRef<'_>) -> Result { + let s = >::decode(value)?; + let s = s.strip_prefix("0x").unwrap_or(&s); + if s.len() != 64 { + return Err(format!("expected 64 hex chars for felt252, got {}", s.len()).into()); + } + let mut arr = [0u8; 32]; + for (i, chunk) in s.as_bytes().chunks(2).enumerate() { + let hi = hex_nibble(chunk[0])?; + let lo = hex_nibble(chunk[1])?; + arr[i] = (hi << 4) | lo; + } + Ok(SqlFelt(arr)) + } +} + +fn hex_nibble(c: u8) -> Result { + match c { + b'0'..=b'9' => Ok(c - b'0'), + b'a'..=b'f' => Ok(c - b'a' + 10), + b'A'..=b'F' => Ok(c - b'A' + 10), + _ => Err(format!("invalid hex char: {}", c as char).into()), + } +} diff --git a/crates/torii-common/Cargo.toml b/crates/torii-common/Cargo.toml index 9112e39f..a10b65f1 100644 --- a/crates/torii-common/Cargo.toml +++ b/crates/torii-common/Cargo.toml @@ -15,13 +15,6 @@ urlencoding = "2" async-trait = "0.1" serde.workspace = true serde_json.workspace = true -sqlx = { workspace = true, features = [ - "postgres", - "runtime-tokio-rustls", - "mysql", - "sqlite", -] } -itertools.workspace = true [lints] workspace = true diff --git a/crates/torii-ecs-sink/Cargo.toml b/crates/torii-ecs-sink/Cargo.toml index 0d402e5f..244cab70 100644 --- a/crates/torii-ecs-sink/Cargo.toml +++ b/crates/torii-ecs-sink/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] torii = { path = "../.." } -torii-dojo = { path = "../dojo" } +torii-dojo = { workspace = true, features = ["postgres", "sqlite"] } torii-introspect = { path = "../introspect" } dojo-introspect.workspace = true introspect-types.workspace = true @@ -19,7 +19,12 @@ prost.workspace = true prost-types.workspace = true serde.workspace = true serde_json.workspace = true -sqlx = { workspace = true, features = ["runtime-tokio", "sqlite", "postgres", "any"] } +sqlx = { workspace = true, features = [ + "runtime-tokio", + "sqlite", + "postgres", + "any", +] } starknet.workspace = true tokio.workspace = true tokio-stream.workspace = true diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index 59014e16..aa53ff11 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -14,10 +14,10 @@ use introspect_types::{ use serde::ser::SerializeMap; use serde::Serializer; use serde_json::{Map, Serializer as JsonSerializer, Value}; -use sqlx::{ - any::AnyPoolOptions, postgres::PgPoolOptions, sqlite::SqliteConnectOptions, - sqlite::SqlitePoolOptions, Any, ConnectOptions, Pool, QueryBuilder, Row, -}; +use sqlx::any::AnyPoolOptions; +use sqlx::postgres::PgPoolOptions; +use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; +use sqlx::{Any, ConnectOptions, Pool, QueryBuilder, Row}; use starknet::core::types::Felt; use tokio::sync::mpsc::error::TrySendError; use tokio::sync::{mpsc, Mutex}; @@ -30,12 +30,14 @@ use torii_dojo::DojoTable; use torii_introspect::events::{CreateTable, Record, UpdateTable}; use torii_introspect::schema::TableSchema; +use crate::proto::types::clause::ClauseType; +use crate::proto::types::member_value::ValueType; use crate::proto::types::{ - self, clause::ClauseType, member_value::ValueType, ComparisonOperator, ContractType, - LogicalOperator, PaginationDirection, PatternMatching, + self, ComparisonOperator, ContractType, LogicalOperator, PaginationDirection, PatternMatching, }; +use crate::proto::world::world_server::World; use crate::proto::world::{ - world_server::World, RetrieveEntitiesRequest, RetrieveEntitiesResponse, RetrieveEventsRequest, + RetrieveEntitiesRequest, RetrieveEntitiesResponse, RetrieveEventsRequest, RetrieveEventsResponse, SubscribeContractsRequest, SubscribeContractsResponse, SubscribeEntitiesRequest, SubscribeEntityResponse, SubscribeEventsRequest, SubscribeEventsResponse, UpdateEntitiesSubscriptionRequest, WorldsRequest, WorldsResponse, @@ -1000,7 +1002,7 @@ impl EcsService { .max_connections(1) .connect_with(SqliteConnectOptions::from_str(&self.state.database_url)?) .await?; - let store = SqliteStore(Arc::new(pool)); + let store = SqliteStore(pool); Ok(store.read_tables(&[]).await?) } DbBackend::Postgres => { @@ -1008,7 +1010,7 @@ impl EcsService { .max_connections(1) .connect(&self.state.database_url) .await?; - let store = PgStore(Arc::new(pool)); + let store = PgStore(pool); Ok(store.read_tables(&[]).await?) } } diff --git a/examples/introspect/restart.rs b/examples/introspect/restart.rs index 0b0e7157..33de70c8 100644 --- a/examples/introspect/restart.rs +++ b/examples/introspect/restart.rs @@ -2,11 +2,10 @@ use itertools::Itertools; use sqlx::postgres::PgPoolOptions; use sqlx::PgPool; use starknet::core::types::Felt; -use std::sync::Arc; use torii_dojo::decoder::DojoDecoder; use torii_dojo::store::postgres::PgStore; use torii_dojo::DojoToriiError; -use torii_introspect_postgres_sink::IntrospectPgDb; +use torii_introspect_sql_sink::IntrospectPgDb; use torii_test_utils::{resolve_path_like, FakeProvider, MultiContractEventIterator}; const DB_URL: &str = "postgres://torii:torii@localhost:5432/torii"; @@ -28,7 +27,7 @@ const ADDRESSES: [Felt; 2] = [PISTOLS_ADDRESS, BLOB_ARENA_ADDRESS]; async fn run_events( events: &mut MultiContractEventIterator, provider: FakeProvider, - pool: Arc, + pool: PgPool, end: Option, event_n: &mut u32, success: &mut u32, @@ -93,7 +92,7 @@ async fn main() { let event_paths = EVENT_PATHS.map(resolve_path_like).to_vec(); let provider = FakeProvider::new(resolve_path_like(MODEL_CONTRACTS_PATH)); let mut event_iterator = MultiContractEventIterator::new(event_paths); - let pool = Arc::new(PgPoolOptions::new().connect(DB_URL).await.unwrap()); + let pool = PgPoolOptions::new().connect(DB_URL).await.unwrap(); let mut event_n = 0; let mut success = 0; while run_events( diff --git a/examples/introspect/simple.rs b/examples/introspect/simple.rs index 0ed581ea..025371fc 100644 --- a/examples/introspect/simple.rs +++ b/examples/introspect/simple.rs @@ -1,10 +1,9 @@ use itertools::Itertools; use sqlx::postgres::PgPoolOptions; -use std::sync::Arc; use torii_dojo::decoder::DojoDecoder; use torii_dojo::store::postgres::PgStore; use torii_dojo::DojoToriiError; -use torii_introspect_postgres_sink::IntrospectPgDb; +use torii_introspect_sql_sink::IntrospectPgDb; use torii_test_utils::{resolve_path_like, EventIterator, FakeProvider}; const DB_URL: &str = "postgres://torii:torii@localhost:5432/torii"; @@ -22,7 +21,7 @@ async fn main() { let provider = FakeProvider::new(contracts_path); let mut event_iterator = EventIterator::new(events_path); - let pool = Arc::new(PgPoolOptions::new().connect(DB_URL).await.unwrap()); + let pool = PgPoolOptions::new().connect(DB_URL).await.unwrap(); let decoder = DojoDecoder::, _>::new(pool.clone(), provider); let db = IntrospectPgDb::new(pool.clone(), SCHEMA_NAME); decoder.store.initialize().await.unwrap(); From 8221c66b10676fe10b3f7a90012887486480ff64 Mon Sep 17 00:00:00 2001 From: MartianGreed Date: Thu, 26 Mar 2026 09:07:10 +0100 Subject: [PATCH 10/21] fix(ecs): fix query --- bins/torii-arcade/src/config.rs | 27 ++ bins/torii-arcade/src/main.rs | 116 ++++- bins/torii-introspect-bin/src/config.rs | 20 +- bins/torii-introspect-bin/src/main.rs | 3 + crates/dojo/src/external_contract.rs | 30 +- crates/torii-ecs-sink/src/grpc_service.rs | 488 ++++++++++++++++------ crates/torii-ecs-sink/src/sink.rs | 4 + 7 files changed, 543 insertions(+), 145 deletions(-) diff --git a/bins/torii-arcade/src/config.rs b/bins/torii-arcade/src/config.rs index b490d903..0c5d83ca 100644 --- a/bins/torii-arcade/src/config.rs +++ b/bins/torii-arcade/src/config.rs @@ -160,6 +160,18 @@ pub struct Config { #[arg(long)] pub ignore_saved_state: bool, + /// Enable runtime indexing for Dojo `ExternalContractRegistered` events. + /// + /// Enabled by default. Pass `--index-external-contracts=false` to disable. + #[arg( + long, + default_value_t = true, + action = clap::ArgAction::Set, + num_args = 0..=1, + default_missing_value = "true" + )] + pub index_external_contracts: bool, + #[arg(long)] pub allow_unsafe_latest_schema_bootstrap: bool, @@ -452,6 +464,21 @@ mod tests { assert_eq!(cfg.rpc_parallelism, 6); } + #[test] + fn external_contract_indexing_defaults_to_enabled() { + let cfg = Config::parse_from(["torii-arcade"]); + assert!(cfg.index_external_contracts); + } + + #[test] + fn external_contract_indexing_flag_can_disable_runtime_registration() { + let cfg = Config::parse_from([ + "torii-arcade", + "--index-external-contracts=false", + ]); + assert!(!cfg.index_external_contracts); + } + #[test] fn historical_models_parse_as_exact_names() { let cfg = Config::parse_from([ diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index c6f5bb09..ac321148 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -17,6 +17,7 @@ use torii::etl::decoder::DecoderId; use torii::etl::extractor::{ ContractEventConfig, EventExtractor, EventExtractorConfig, Extractor, RetryPolicy, }; +use torii::etl::EngineDb; use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; use torii::etl::TypeId; use torii::EtlConcurrencyConfig; @@ -25,7 +26,10 @@ use torii_arcade_sink::{ArcadeSink, FILE_DESCRIPTOR_SET as ARCADE_DESCRIPTOR_SET use torii_common::{MetadataFetcher, TokenUriService}; use torii_config_common::apply_observability_env; use torii_dojo::decoder::DojoDecoder; -use torii_dojo::external_contract::RegisteredContractType; +use torii_dojo::external_contract::{ + contract_type_from_decoder_ids, RegisterExternalContractCommandHandler, + RegisteredContractType, SharedContractTypeRegistry, SharedDecoderRegistry, +}; use torii_dojo::store::postgres::PgStore; use torii_dojo::store::sqlite::SqliteStore; use torii_ecs_sink::proto::world::world_server::WorldServer; @@ -64,7 +68,7 @@ fn build_contract_type_registry( erc20_addresses: &[Felt], erc721_addresses: &[Felt], erc1155_addresses: &[Felt], -) -> Arc>> { +) -> SharedContractTypeRegistry { let mut contract_types = HashMap::new(); for &contract in dojo_event_contracts { contract_types.insert(contract, RegisteredContractType::World); @@ -81,6 +85,48 @@ fn build_contract_type_registry( Arc::new(RwLock::new(contract_types)) } +async fn load_persisted_contract_registries( + engine_db: &EngineDb, + decoder_registry: &SharedDecoderRegistry, + contract_type_registry: &SharedContractTypeRegistry, +) -> Result<()> { + let mappings = engine_db.get_all_contract_decoders().await?; + let mut decoders = decoder_registry.write().await; + let mut contract_types = contract_type_registry.write().await; + + for (contract, decoder_ids, _) in mappings { + decoders.insert(contract, decoder_ids.clone()); + if let Some(contract_type) = contract_type_from_decoder_ids(&decoder_ids) { + contract_types.insert(contract, contract_type); + } + } + + Ok(()) +} + +fn installed_external_decoder_ids( + enabled: bool, + install_erc20: bool, + install_erc721: bool, + install_erc1155: bool, +) -> HashSet { + if !enabled { + return HashSet::new(); + } + + let mut installed = HashSet::from([DecoderId::new("dojo-introspect")]); + if install_erc20 { + installed.insert(DecoderId::new("erc20")); + } + if install_erc721 { + installed.insert(DecoderId::new("erc721")); + } + if install_erc1155 { + installed.insert(DecoderId::new("erc1155")); + } + installed +} + struct ArcadeProjectionPipeline { sinks: Vec>, } @@ -266,6 +312,14 @@ async fn run_indexer(config: Config) -> Result<()> { "disabled" } ); + tracing::info!( + "External contract indexing: {}", + if config.index_external_contracts { + "enabled" + } else { + "disabled" + } + ); tracing::info!("Historical models tracked: {}", historical_models.len()); let excluded_dojo_contracts: Vec = dojo_event_contracts @@ -274,6 +328,36 @@ async fn run_indexer(config: Config) -> Result<()> { .filter(|contract| !introspect_contracts.contains(contract)) .collect(); + let registry_engine_db = Arc::new( + EngineDb::new(torii::etl::engine_db::EngineDbConfig { + path: engine_database_url.clone(), + }) + .await?, + ); + let decoder_registry: SharedDecoderRegistry = Arc::new(RwLock::new(HashMap::new())); + let contract_type_registry = build_contract_type_registry( + &dojo_event_contracts, + &erc20_addresses, + &erc721_addresses, + &erc1155_addresses, + ); + load_persisted_contract_registries( + registry_engine_db.as_ref(), + &decoder_registry, + &contract_type_registry, + ) + .await?; + + let install_erc20 = config.index_external_contracts || !erc20_addresses.is_empty(); + let install_erc721 = config.index_external_contracts || !erc721_addresses.is_empty(); + let install_erc1155 = config.index_external_contracts || !erc1155_addresses.is_empty(); + let installed_external_decoders = installed_external_decoder_ids( + config.index_external_contracts, + install_erc20, + install_erc721, + install_erc1155, + ); + let extractor = build_extractor( provider.clone(), &dojo_event_contracts, @@ -347,14 +431,10 @@ async fn run_indexer(config: Config) -> Result<()> { Some(erc20_db_url.as_str()), Some(erc721_db_url.as_str()), Some(erc1155_db_url.as_str()), - build_contract_type_registry( - &dojo_event_contracts, - &erc20_addresses, - &erc721_addresses, - &erc1155_addresses, - ), - false, - HashSet::new(), + contract_type_registry.clone(), + config.from_block, + config.index_external_contracts, + installed_external_decoders.clone(), ) .await?; let ecs_grpc_service = ecs_sink.get_grpc_service_impl(); @@ -399,6 +479,16 @@ async fn run_indexer(config: Config) -> Result<()> { .add_sink_boxed(Box::new(ecs_sink)) .add_sink_boxed(Box::new(arcade_projection_pipeline)); + if config.index_external_contracts { + torii_config = torii_config + .with_registry_cache(decoder_registry.clone()) + .with_command_handler(Box::new(RegisterExternalContractCommandHandler::new( + registry_engine_db.clone(), + decoder_registry.clone(), + contract_type_registry.clone(), + ))); + } + if !excluded_dojo_contracts.is_empty() { torii_config = torii_config.blacklist_contracts(excluded_dojo_contracts.clone()); } @@ -421,7 +511,7 @@ async fn run_indexer(config: Config) -> Result<()> { let mut erc1155_grpc_service: Option = None; let mut token_uri_services = Vec::new(); - if !erc20_addresses.is_empty() { + if install_erc20 { let storage = Arc::new(Erc20Storage::new(&erc20_db_url).await?); let grpc_service = Erc20Service::new(storage.clone()); let sink = Box::new( @@ -451,7 +541,7 @@ async fn run_indexer(config: Config) -> Result<()> { erc20_grpc_service = Some(grpc_service); } - if !erc721_addresses.is_empty() { + if install_erc721 { let storage = Arc::new(Erc721Storage::new(&erc721_db_url).await?); let grpc_service = Erc721Service::new(storage.clone()); let mut sink = Erc721Sink::new(storage.clone()).with_grpc_service(grpc_service.clone()); @@ -486,7 +576,7 @@ async fn run_indexer(config: Config) -> Result<()> { erc721_grpc_service = Some(grpc_service); } - if !erc1155_addresses.is_empty() { + if install_erc1155 { let storage = Arc::new(Erc1155Storage::new(&erc1155_db_url).await?); let grpc_service = Erc1155Service::new(storage.clone()); let mut sink = Erc1155Sink::new(storage.clone()) diff --git a/bins/torii-introspect-bin/src/config.rs b/bins/torii-introspect-bin/src/config.rs index 6fb58b41..47a0d818 100644 --- a/bins/torii-introspect-bin/src/config.rs +++ b/bins/torii-introspect-bin/src/config.rs @@ -121,7 +121,15 @@ pub struct Config { pub ignore_saved_state: bool, /// Enable runtime indexing for Dojo `ExternalContractRegistered` events. - #[arg(long)] + /// + /// Enabled by default. Pass `--index-external-contracts=false` to disable. + #[arg( + long, + default_value_t = true, + action = clap::ArgAction::Set, + num_args = 0..=1, + default_missing_value = "true" + )] pub index_external_contracts: bool, /// Exact Dojo model names to mirror into append-only `_historical` tables. @@ -298,20 +306,20 @@ mod tests { } #[test] - fn external_contract_indexing_defaults_to_disabled() { + fn external_contract_indexing_defaults_to_enabled() { let cfg = Config::parse_from(["torii-server", "--contract", "0x1"]); - assert!(!cfg.index_external_contracts); + assert!(cfg.index_external_contracts); } #[test] - fn external_contract_indexing_flag_enables_runtime_registration() { + fn external_contract_indexing_flag_can_disable_runtime_registration() { let cfg = Config::parse_from([ "torii-server", "--contract", "0x1", - "--index-external-contracts", + "--index-external-contracts=false", ]); - assert!(cfg.index_external_contracts); + assert!(!cfg.index_external_contracts); } #[test] diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index e9c561d7..0c2bc8ce 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -217,6 +217,7 @@ fn installed_external_decoder_ids(enabled: bool) -> HashSet { } HashSet::from([ + DecoderId::new("dojo-introspect"), DecoderId::new("erc20"), DecoderId::new("erc721"), DecoderId::new("erc1155"), @@ -694,6 +695,7 @@ async fn run_with_postgres( erc721_url, erc1155_url, contract_type_registry.clone(), + config.from_block, config.index_external_contracts, installed_external_decoders.clone(), ) @@ -901,6 +903,7 @@ async fn run_with_sqlite( erc721_url, erc1155_url, contract_type_registry.clone(), + config.from_block, config.index_external_contracts, installed_external_decoders.clone(), ) diff --git a/crates/dojo/src/external_contract.rs b/crates/dojo/src/external_contract.rs index 70f8aaaa..dad58a12 100644 --- a/crates/dojo/src/external_contract.rs +++ b/crates/dojo/src/external_contract.rs @@ -122,6 +122,10 @@ pub fn resolve_external_contract(contract_name: &str) -> Option() .to_ascii_uppercase(); + if normalized.is_empty() { + return None; + } + match normalized.as_str() { "ERC20" => Some(ResolvedExternalContract { contract_type: RegisteredContractType::Erc20, @@ -135,7 +139,10 @@ pub fn resolve_external_contract(contract_name: &str) -> Option None, + _ => Some(ResolvedExternalContract { + contract_type: RegisteredContractType::World, + decoder_ids: vec![DecoderId::new("dojo-introspect")], + }), } } @@ -163,6 +170,7 @@ pub struct RegisterExternalContractCommand { pub contract_name: String, pub namespace: String, pub instance_name: String, + pub from_block: u64, pub registration_block: u64, pub contract_type: RegisteredContractType, pub decoder_ids: Vec, @@ -228,7 +236,7 @@ impl CommandHandler for RegisterExternalContractCommandHandler { .set_extractor_state( EVENT_EXTRACTOR_TYPE, &state_key, - &format!("block:{}", command.registration_block), + &format!("block:{}", command.from_block), ) .await .with_context(|| { @@ -262,6 +270,7 @@ impl CommandHandler for RegisterExternalContractCommandHandler { namespace = command.namespace, contract_name = command.contract_name, instance_name = command.instance_name, + from_block = command.from_block, registration_block = command.registration_block, "Registered external contract for runtime indexing" ); @@ -287,7 +296,11 @@ mod tests { let erc1155 = resolve_external_contract("Erc-1155").unwrap(); assert_eq!(erc1155.contract_type, RegisteredContractType::Erc1155); - assert!(resolve_external_contract("udc").is_none()); + let dojo = resolve_external_contract("Actions").unwrap(); + assert_eq!(dojo.contract_type, RegisteredContractType::World); + assert_eq!(dojo.decoder_ids, vec![DecoderId::new("dojo-introspect")]); + + assert!(resolve_external_contract("---").is_none()); } #[tokio::test] @@ -315,6 +328,7 @@ mod tests { contract_name: "ERC20".to_string(), namespace: "tokens".to_string(), instance_name: "eth".to_string(), + from_block: 12, registration_block: 77, contract_type: RegisteredContractType::Erc20, decoder_ids: vec![DecoderId::new("erc20")], @@ -322,6 +336,15 @@ mod tests { .await .unwrap(); + assert_eq!( + engine_db + .get_extractor_state(EVENT_EXTRACTOR_TYPE, &format!("{contract_address:#x}")) + .await + .unwrap() + .as_deref(), + Some("block:12") + ); + engine_db .set_extractor_state( EVENT_EXTRACTOR_TYPE, @@ -338,6 +361,7 @@ mod tests { contract_name: "ERC20".to_string(), namespace: "tokens".to_string(), instance_name: "eth".to_string(), + from_block: 12, registration_block: 77, contract_type: RegisteredContractType::Erc20, decoder_ids: vec![DecoderId::new("erc20")], diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index a391b0f1..37dabccd 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -2828,90 +2828,114 @@ impl EcsService { .as_ref() .map_or(String::new(), |pagination| pagination.cursor.clone()); - let keys_start = Instant::now(); - let mut candidate_keys = self - .load_entity_page_keys( - kind, - &world_filters, - table_id_filter, - member_pushdown.as_ref(), - &cursor, - direction, - target_limit.saturating_add(1), - ) - .await?; - ::metrics::histogram!("torii_ecs_load_entity_page_meta_seconds") - .record(keys_start.elapsed().as_secs_f64()); + let mut items = Vec::new(); + let mut next_cursor = String::new(); + let mut candidate_cursor = cursor; - let has_more = target_limit != usize::MAX && candidate_keys.len() > target_limit; - if has_more { - candidate_keys.truncate(target_limit); - } + loop { + let keys_start = Instant::now(); + let mut candidate_keys = self + .load_entity_page_keys( + kind, + &world_filters, + table_id_filter, + member_pushdown.as_ref(), + &candidate_cursor, + direction, + target_limit.saturating_add(1), + ) + .await?; + ::metrics::histogram!("torii_ecs_load_entity_page_meta_seconds") + .record(keys_start.elapsed().as_secs_f64()); - let meta_start = Instant::now(); - let candidate_meta = self - .load_entity_meta_for_keys(kind, None, candidate_keys.as_slice()) - .await?; - ::metrics::histogram!("torii_ecs_load_entity_page_meta_rows_seconds") - .record(meta_start.elapsed().as_secs_f64()); - ::metrics::gauge!("torii_ecs_load_entity_page_candidates").set(candidate_keys.len() as f64); + if candidate_keys.is_empty() { + next_cursor.clear(); + break; + } - let mut items = Vec::new(); - for chunk in candidate_keys.chunks(256) { - let rows_start = Instant::now(); - let rows = self - .load_entity_page_rows(kind, &world_filters, None, chunk) + let has_more_candidates = candidate_keys.len() > target_limit; + if has_more_candidates { + candidate_keys.truncate(target_limit); + } + ::metrics::gauge!("torii_ecs_load_entity_page_candidates") + .set(candidate_keys.len() as f64); + + let batch_cursor = candidate_keys + .last() + .map(|(_, entity_id)| entity_id.trim_start_matches("0x").to_string()) + .unwrap_or_default(); + + let meta_start = Instant::now(); + let candidate_meta = self + .load_entity_meta_for_keys(kind, None, candidate_keys.as_slice()) .await?; - ::metrics::histogram!("torii_ecs_load_entity_page_rows_seconds") - .record(rows_start.elapsed().as_secs_f64()); - ::metrics::counter!("torii_ecs_load_entity_page_rows_total") - .increment(rows.len() as u64); - let row_map = rows.into_iter().fold( - HashMap::<(String, String), Vec<(String, String)>>::new(), - |mut acc, row| { - acc.entry((row.world_address, row.entity_id)) - .or_default() - .push((row.table_id, row.row_json)); - acc - }, - ); + ::metrics::histogram!("torii_ecs_load_entity_page_meta_rows_seconds") + .record(meta_start.elapsed().as_secs_f64()); - for key in chunk { - let Some(meta) = candidate_meta.get(key) else { - continue; - }; - let Some(entity) = - build_entity_from_snapshot(key, meta, row_map.get(key), &all_model_map)? - else { - continue; - }; - let entity = entity.into_proto(); - if query - .clause - .as_ref() - .is_some_and(|clause| !entity_matches_clause(&entity, clause)) - { - continue; + for chunk in candidate_keys.chunks(256) { + let rows_start = Instant::now(); + let rows = self + .load_entity_page_rows(kind, &world_filters, None, chunk) + .await?; + ::metrics::histogram!("torii_ecs_load_entity_page_rows_seconds") + .record(rows_start.elapsed().as_secs_f64()); + ::metrics::counter!("torii_ecs_load_entity_page_rows_total") + .increment(rows.len() as u64); + let row_map = rows.into_iter().fold( + HashMap::<(String, String), Vec<(String, String)>>::new(), + |mut acc, row| { + acc.entry((row.world_address, row.entity_id)) + .or_default() + .push((row.table_id, row.row_json)); + acc + }, + ); + + for key in chunk { + let Some(meta) = candidate_meta.get(key) else { + continue; + }; + let Some(entity) = + build_entity_from_snapshot(key, meta, row_map.get(key), &all_model_map)? + else { + continue; + }; + let entity = entity.into_proto(); + if query + .clause + .as_ref() + .is_some_and(|clause| !entity_matches_clause(&entity, clause)) + { + continue; + } + items.push(entity); + if items.len() >= target_limit { + break; + } } - items.push(entity); + if items.len() >= target_limit { break; } } if items.len() >= target_limit { + next_cursor = if has_more_candidates { + batch_cursor + } else { + String::new() + }; break; } - } - let next_cursor = if has_more { - candidate_keys - .last() - .map(|(_, entity_id)| entity_id.trim_start_matches("0x").to_string()) - .unwrap_or_default() - } else { - String::new() - }; + if !has_more_candidates { + next_cursor.clear(); + break; + } + + candidate_cursor = batch_cursor; + next_cursor = candidate_cursor.clone(); + } if query.no_hashed_keys { for entity in &mut items { @@ -5301,27 +5325,7 @@ fn entity_matches_clause(entity: &types::Entity, clause: &types::Clause) -> bool Some(ClauseType::HashedKeys(hashed)) => { hashed.hashed_keys.is_empty() || hashed.hashed_keys.contains(&entity.hashed_keys) } - Some(ClauseType::Keys(keys)) => { - if !keys.models.is_empty() - && !entity - .models - .iter() - .any(|model| keys.models.contains(&model.name)) - { - return false; - } - let entity_keys = entity_key_values(entity); - if keys.pattern_matching == PatternMatching::FixedLen as i32 - && entity_keys.len() != keys.keys.len() - { - return false; - } - entity_keys.iter().enumerate().all(|(index, key)| { - keys.keys - .get(index) - .is_none_or(|expected| expected.is_empty() || expected == key) - }) - } + Some(ClauseType::Keys(keys)) => entity_matches_keys_clause(entity, keys), Some(ClauseType::Member(member)) => entity.models.iter().any(|model| { model.name == member.model && model_member_matches( @@ -5347,19 +5351,37 @@ fn entity_matches_clause(entity: &types::Entity, clause: &types::Clause) -> bool fn match_keys(keys: &[Vec], clauses: &[types::KeysClause]) -> bool { clauses.is_empty() - || clauses.iter().any(|clause| { - if clause.pattern_matching == PatternMatching::FixedLen as i32 - && keys.len() != clause.keys.len() - { - return false; - } - keys.iter().enumerate().all(|(index, key)| { - clause - .keys - .get(index) - .is_none_or(|expected| expected.is_empty() || expected == key) - }) - }) + || clauses + .iter() + .any(|clause| keys_clause_matches_entity_keys(keys, clause)) +} + +fn entity_matches_keys_clause(entity: &types::Entity, clause: &types::KeysClause) -> bool { + if clause.models.is_empty() { + return keys_clause_matches_entity_keys(&entity_key_values(entity), clause); + } + + entity + .models + .iter() + .filter(|model| clause.models.contains(&model.name)) + .filter_map(model_key_values) + .any(|keys| keys_clause_matches_entity_keys(&keys, clause)) +} + +fn keys_clause_matches_entity_keys(entity_keys: &[Vec], clause: &types::KeysClause) -> bool { + if clause.pattern_matching == PatternMatching::FixedLen as i32 + && entity_keys.len() != clause.keys.len() + { + return false; + } + + entity_keys.iter().enumerate().all(|(index, key)| { + clause + .keys + .get(index) + .is_none_or(|expected| expected.is_empty() || expected == key) + }) } fn model_member_matches( @@ -5499,26 +5521,28 @@ fn entity_key_values(entity: &types::Entity) -> Vec> { entity .models .iter() - .find_map(|model| { - let keys = model - .children - .iter() - .filter(|member| member.key) - .filter_map(|member| { - scalar_from_ty(member.ty.as_ref()?).map(|value| match value { - ScalarValue::Bool(value) => vec![u8::from(value)], - ScalarValue::Signed(value) => value.to_be_bytes().to_vec(), - ScalarValue::Unsigned(value) => value.to_be_bytes().to_vec(), - ScalarValue::Text(value) => value.into_bytes(), - ScalarValue::Bytes(value) => value, - }) - }) - .collect::>(); - (!keys.is_empty()).then_some(keys) - }) + .find_map(model_key_values) .unwrap_or_default() } +fn model_key_values(model: &types::Struct) -> Option>> { + let keys = model + .children + .iter() + .filter(|member| member.key) + .filter_map(|member| { + scalar_from_ty(member.ty.as_ref()?).map(|value| match value { + ScalarValue::Bool(value) => vec![u8::from(value)], + ScalarValue::Signed(value) => value.to_be_bytes().to_vec(), + ScalarValue::Unsigned(value) => value.to_be_bytes().to_vec(), + ScalarValue::Text(value) => value.into_bytes(), + ScalarValue::Bytes(value) => value, + }) + }) + .collect::>(); + (!keys.is_empty()).then_some(keys) +} + fn contract_matches_query(contract: &types::Contract, query: &types::ContractQuery) -> bool { (query.contract_addresses.is_empty() || query @@ -5545,7 +5569,7 @@ mod tests { use std::collections::BTreeMap; use super::*; - use introspect_types::{ColumnDef, PrimaryDef, PrimaryTypeDef, TypeDef}; + use introspect_types::{Attribute, ColumnDef, PrimaryDef, PrimaryTypeDef, TypeDef}; use tokio::time::{timeout, Duration}; use tokio_stream::StreamExt; @@ -5737,7 +5761,11 @@ mod tests { .await .expect("upsert entity meta"); - let row_json = serde_json::json!({ "open": open }).to_string(); + let row_json = serde_json::json!({ + "entity_id": felt_hex(entity_id), + "open": open + }) + .to_string(); sqlx::query( "INSERT INTO torii_ecs_entity_models ( kind, world_address, table_id, entity_id, row_json, updated_at @@ -5828,7 +5856,120 @@ mod tests { .await .expect("upsert entity meta"); - let row_json = serde_json::json!({ field_name: field_value }).to_string(); + let row_json = serde_json::json!({ + "entity_id": felt_hex(entity_id), + field_name: field_value + }) + .to_string(); + sqlx::query( + "INSERT INTO torii_ecs_entity_models ( + kind, world_address, table_id, entity_id, row_json, updated_at + ) VALUES (?1, ?2, ?3, ?4, ?5, ?6) + ON CONFLICT(kind, world_address, table_id, entity_id) DO UPDATE SET + row_json = excluded.row_json, + updated_at = excluded.updated_at", + ) + .bind(kind.as_str()) + .bind(felt_hex(world_address)) + .bind(felt_hex(table_id)) + .bind(felt_hex(entity_id)) + .bind(row_json) + .bind(1_i64) + .execute(&service.state.pool) + .await + .expect("insert entity model"); + } + + fn keyed_member(name: &str, value: Felt) -> types::Member { + types::Member { + name: name.to_string(), + key: true, + ty: Some(types::Ty { + ty_type: Some(types::ty::TyType::Primitive(types::Primitive { + primitive_type: Some(types::primitive::PrimitiveType::Felt252( + value.to_bytes_be().to_vec(), + )), + })), + }), + } + } + + async fn seed_entity_with_custom_keys( + service: &EcsService, + kind: TableKind, + world_address: Felt, + table_id: Felt, + table_name: &str, + entity_id: Felt, + key_field_name: &str, + key_value: Felt, + ) { + sqlx::query( + "CREATE TABLE IF NOT EXISTS dojo_tables ( + owner BLOB NOT NULL, + id BLOB NOT NULL, + name TEXT NOT NULL, + attributes TEXT NOT NULL, + keys_json TEXT NOT NULL, + values_json TEXT NOT NULL, + legacy INTEGER NOT NULL, + created_at INTEGER, + updated_at INTEGER, + created_block INTEGER, + updated_block INTEGER, + created_tx BLOB, + updated_tx BLOB, + PRIMARY KEY(owner, id) + )", + ) + .execute(&service.state.pool) + .await + .expect("create dojo_tables"); + sqlx::query( + "CREATE TABLE IF NOT EXISTS dojo_columns ( + owner BLOB NOT NULL, + table_id BLOB NOT NULL, + id BLOB NOT NULL, + payload TEXT NOT NULL, + PRIMARY KEY(owner, table_id, id) + )", + ) + .execute(&service.state.pool) + .await + .expect("create dojo_columns"); + + let table = CreateTable { + id: table_id, + name: table_name.to_string(), + attributes: vec![], + primary: PrimaryDef { + name: "entity_id".to_string(), + attributes: vec![], + type_def: PrimaryTypeDef::Felt252, + }, + columns: vec![ColumnDef { + id: Felt::from(1_u64), + name: key_field_name.to_string(), + attributes: vec![Attribute::new_empty("key".to_string())], + type_def: TypeDef::Felt252, + }], + }; + + service.cache_created_table(world_address, &table).await; + service + .record_table_kind(world_address, table_id, kind) + .await + .expect("record table kind"); + service + .upsert_entity_meta(kind, world_address, table_id, entity_id, 1, false) + .await + .expect("upsert entity meta"); + + let row_json = serde_json::json!({ + "entity_id": felt_hex(entity_id), + key_field_name: felt_hex(key_value) + }) + .to_string(); sqlx::query( "INSERT INTO torii_ecs_entity_models ( kind, world_address, table_id, entity_id, row_json, updated_at @@ -6093,6 +6234,36 @@ mod tests { assert_eq!(contract.contract_type, ContractType::World as i32); } + #[test] + fn entity_keys_clause_scopes_key_extraction_to_requested_models() { + let entity = types::Entity { + hashed_keys: vec![], + models: vec![ + types::Struct { + name: "NUMS-Other".to_string(), + children: vec![keyed_member("other_id", Felt::from(0x111_u64))], + }, + types::Struct { + name: "NUMS-Config".to_string(), + children: vec![keyed_member("config_id", Felt::from(0x222_u64))], + }, + ], + created_at: 0, + updated_at: 0, + executed_at: 0, + world_address: vec![], + }; + let clause = types::Clause { + clause_type: Some(ClauseType::Keys(types::KeysClause { + models: vec!["NUMS-Config".to_string()], + pattern_matching: PatternMatching::VariableLen as i32, + keys: vec![Felt::from(0x222_u64).to_bytes_be().to_vec()], + })), + }; + + assert!(entity_matches_clause(&entity, &clause)); + } + #[tokio::test] async fn retrieve_entities_without_filters_uses_bounded_query() { let db_path = test_db_path("retrieve-entities"); @@ -6209,6 +6380,77 @@ mod tests { assert!(model_names.contains("NUMS-QuestAssociation")); } + #[tokio::test] + async fn retrieve_entities_keys_clause_fills_first_page_with_matches() { + let db_path = test_db_path("retrieve-entities-keys-page"); + let service = EcsService::new(&db_path, Some(1), None, None, None) + .await + .expect("service init"); + let world = Felt::from(920_u64); + let matching_key = Felt::from(0xdead_u64); + + for index in 0..100_u64 { + let entity_id = Felt::from(index + 1); + seed_entity_with_custom_keys( + &service, + TableKind::Entity, + world, + Felt::from(index + 1_000), + "NUMS-Config", + entity_id, + "config_id", + Felt::from(0x100_u64 + index), + ) + .await; + } + + let matching_entity = Felt::from(10_000_u64); + seed_entity_with_custom_keys( + &service, + TableKind::Entity, + world, + Felt::from(9_999_u64), + "NUMS-Config", + matching_entity, + "config_id", + matching_key, + ) + .await; + + let response = service + .retrieve_entities(Request::new(RetrieveEntitiesRequest { + query: Some(types::Query { + pagination: Some(types::Pagination { + cursor: String::new(), + limit: 100, + direction: PaginationDirection::Forward as i32, + order_by: vec![], + }), + world_addresses: vec![world.to_bytes_be().to_vec()], + models: vec![], + clause: Some(types::Clause { + clause_type: Some(ClauseType::Keys(types::KeysClause { + models: vec!["NUMS-Config".to_string()], + pattern_matching: PatternMatching::VariableLen as i32, + keys: vec![matching_key.to_bytes_be().to_vec()], + })), + }), + no_hashed_keys: false, + historical: false, + }), + })) + .await + .expect("retrieve entities") + .into_inner(); + + assert_eq!(response.entities.len(), 1); + assert_eq!( + response.entities[0].hashed_keys, + matching_entity.to_bytes_be().to_vec() + ); + assert!(response.next_cursor.is_empty()); + } + #[tokio::test] async fn execute_sql_exposes_legacy_compat_views() { let db_path = test_db_path("sql-compat"); diff --git a/crates/torii-ecs-sink/src/sink.rs b/crates/torii-ecs-sink/src/sink.rs index 8802c374..2e0680d2 100644 --- a/crates/torii-ecs-sink/src/sink.rs +++ b/crates/torii-ecs-sink/src/sink.rs @@ -27,6 +27,7 @@ use crate::grpc_service::{EcsService, TableKind}; pub struct EcsSink { service: Arc, contract_types: SharedContractTypeRegistry, + external_contract_from_block: u64, external_contract_indexing: bool, installed_external_decoders: HashSet, command_bus: RwLock>, @@ -40,6 +41,7 @@ impl EcsSink { erc721_url: Option<&str>, erc1155_url: Option<&str>, contract_types: SharedContractTypeRegistry, + external_contract_from_block: u64, external_contract_indexing: bool, installed_external_decoders: HashSet, ) -> Result { @@ -55,6 +57,7 @@ impl EcsSink { .await?, ), contract_types, + external_contract_from_block, external_contract_indexing, installed_external_decoders, command_bus: RwLock::new(None), @@ -142,6 +145,7 @@ impl EcsSink { contract_name: body.msg.contract_name.clone(), namespace: body.msg.namespace.clone(), instance_name: body.msg.instance_name.clone(), + from_block: self.external_contract_from_block, registration_block: body.msg.registration_block, contract_type: resolved.contract_type, decoder_ids: resolved.decoder_ids, From 3d6992cfd22934c531bc95aa9fec9d833e63317a Mon Sep 17 00:00:00 2001 From: Bengineer Date: Mon, 30 Mar 2026 11:39:47 +0100 Subject: [PATCH 11/21] feat(sqlite): refactor schema and queries for introspect_db_tables; enhance table management and state persistence --- .../migrations/sqlite/002_schema_state.sql | 4 +- crates/introspect-sql-sink/src/error.rs | 8 +- .../introspect-sql-sink/src/postgres/query.rs | 5 +- crates/introspect-sql-sink/src/processor.rs | 12 +- .../introspect-sql-sink/src/sqlite/backend.rs | 100 +++++--- crates/introspect-sql-sink/src/sqlite/mod.rs | 2 +- .../introspect-sql-sink/src/sqlite/query.rs | 23 -- .../introspect-sql-sink/src/sqlite/table.rs | 240 ++++++++++++++---- .../introspect-sql-sink/src/sqlite/types.rs | 49 +++- crates/introspect-sql-sink/src/table.rs | 8 + 10 files changed, 319 insertions(+), 132 deletions(-) delete mode 100644 crates/introspect-sql-sink/src/sqlite/query.rs diff --git a/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql b/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql index 6355d19d..43ec73bc 100644 --- a/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql +++ b/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql @@ -1,10 +1,10 @@ -CREATE TABLE IF NOT EXISTS introspect_sink_schema_state ( +CREATE TABLE IF NOT EXISTS introspect_db_tables ( namespace TEXT NOT NULL, id TEXT NOT NULL, owner TEXT NOT NULL, + name TEXT NOT NULL, "primary" TEXT NOT NULL, columns TEXT NOT NULL, - dead TEXT NOT NULL, alive INTEGER NOT NULL DEFAULT 1, updated_at INTEGER NOT NULL DEFAULT (unixepoch()), PRIMARY KEY (namespace, id) diff --git a/crates/introspect-sql-sink/src/error.rs b/crates/introspect-sql-sink/src/error.rs index d52c32d6..eee542e9 100644 --- a/crates/introspect-sql-sink/src/error.rs +++ b/crates/introspect-sql-sink/src/error.rs @@ -30,11 +30,13 @@ pub enum TableError { column: String, reason: UpgradeError, }, + #[error(transparent)] + JsonError(#[from] serde_json::Error), #[error("error occurred while encoding a value: {0}")] - Encode(#[source] BoxDynError), + Encode(#[from] BoxDynError), } -pub type TableResult = std::result::Result; +pub type TableResult = std::result::Result; #[derive(Debug, thiserror::Error)] pub enum UpgradeError { @@ -56,7 +58,7 @@ pub enum UpgradeError { TupleReductionError, } -pub type UpgradeResult = Result; +pub type UpgradeResult = Result; impl UpgradeError { pub fn type_upgrade_err(old: &TypeDef, new: &TypeDef) -> UpgradeResult { diff --git a/crates/introspect-sql-sink/src/postgres/query.rs b/crates/introspect-sql-sink/src/postgres/query.rs index 50342b12..514a5a74 100644 --- a/crates/introspect-sql-sink/src/postgres/query.rs +++ b/crates/introspect-sql-sink/src/postgres/query.rs @@ -10,6 +10,7 @@ use sqlx::query::QueryAs; use sqlx::types::Json; use sqlx::{Arguments, Executor, Postgres}; use starknet_types_core::felt::Felt; +use std::collections::HashMap; use std::fmt::{Display, Formatter, Result as FmtResult, Write}; use std::rc::Rc; use torii_introspect::postgres::types::{PgPrimary, Uint128}; @@ -571,8 +572,8 @@ impl From for DbTable { owner: value.owner.into(), name: value.name, primary: value.primary_def.into(), - columns: Vec::new(), - dead: Vec::new(), + columns: HashMap::new(), + dead: HashMap::new(), alive: true, } } diff --git a/crates/introspect-sql-sink/src/processor.rs b/crates/introspect-sql-sink/src/processor.rs index 0caa87f9..907eaf0f 100644 --- a/crates/introspect-sql-sink/src/processor.rs +++ b/crates/introspect-sql-sink/src/processor.rs @@ -2,11 +2,11 @@ use crate::backend::{ IntrospectExecutor, IntrospectInitialize, IntrospectProcessor, IntrospectQueryMaker, }; use crate::error::TableLoadError; -use crate::table::{DeadField, DeadFieldDef, Table}; +use crate::table::{DeadField, Table}; use crate::tables::Tables; use crate::{DbResult, NamespaceMode}; use async_trait::async_trait; -use introspect_types::{ColumnDef, ColumnInfo, PrimaryDef, TypeDef}; +use introspect_types::{ColumnInfo, PrimaryDef, TypeDef}; use itertools::Itertools; use sqlx::Pool; use starknet_types_core::felt::Felt; @@ -28,8 +28,8 @@ pub struct DbTable { pub owner: Felt, pub name: String, pub primary: PrimaryDef, - pub columns: Vec, - pub dead: Vec, + pub columns: HashMap, + pub dead: HashMap, pub alive: bool, } @@ -159,8 +159,8 @@ impl From for ((String, Felt), Table) { name: value.name, owner: value.owner, primary: value.primary.into(), - columns: value.columns.into_hash_map(), - dead: value.dead.into_hash_map(), + columns: value.columns, + dead: value.dead, alive: value.alive, }, ) diff --git a/crates/introspect-sql-sink/src/sqlite/backend.rs b/crates/introspect-sql-sink/src/sqlite/backend.rs index 7984cbd2..24e00e70 100644 --- a/crates/introspect-sql-sink/src/sqlite/backend.rs +++ b/crates/introspect-sql-sink/src/sqlite/backend.rs @@ -1,9 +1,13 @@ -use super::query::create_table_query; use crate::sqlite::record::{coalesce_sql, SqliteDeserializer}; +use crate::sqlite::table::{ + create_table_query, persist_table_state_query, qualified_table_name, update_column, + update_column_query, ColumnInfoRef, FETCH_TABLES_QUERY, +}; use crate::sqlite::types::SqliteColumn; use crate::{ - DbColumn, DbDeadField, DbResult, DbTable, DeadField, IntrospectDb, IntrospectInitialize, + DbColumn, DbDeadField, DbResult, DbTable, IntrospectDb, IntrospectInitialize, IntrospectQueryMaker, IntrospectSqlSink, RecordResult, Table, TableResult, TypeResult, + UpgradeResultExt, }; use async_trait::async_trait; use introspect_types::bytes::IntoByteSource; @@ -56,7 +60,6 @@ pub struct SqliteTableRow { name: String, primary: Json, columns: Json>, - dead: Json>, alive: bool, } @@ -70,7 +73,7 @@ impl TryFrom for DbTable { name: value.name, primary: value.primary.0, columns: value.columns.0.into_iter().map_into().collect(), - dead: value.dead.0.into_iter().map_into().collect(), + dead: HashMap::new(), alive: value.alive, }) } @@ -81,28 +84,60 @@ impl IntrospectQueryMaker for SqliteBackend { type DB = Sqlite; fn create_table_queries( namespace: &str, - _id: &Felt, + id: &Felt, name: &str, primary: &PrimaryDef, columns: &[ColumnDef], - _from_address: &Felt, - _block_number: u64, - _transaction_hash: &Felt, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, queries: &mut Vec, ) -> TableResult<()> { - queries.add(create_table_query(namespace, name, primary, columns)); - Ok(()) + queries.add(create_table_query(namespace, name, primary, columns)?); + persist_table_state_query( + namespace, + id, + name, + primary, + columns.iter().map(ColumnInfoRef::from_def).collect(), + from_address, + block_number, + transaction_hash, + queries, + ) } fn update_table_queries( - _table: &mut Table, - _name: &str, - _primary: &PrimaryDef, - _columns: &[ColumnDef], - _from_address: &Felt, - _block_number: u64, - _transaction_hash: &Felt, - _queries: &mut Vec, + table: &mut Table, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, ) -> TableResult<()> { + let table_name = qualified_table_name(&table.namespace, name); + if table.name != name { + queries.add(format!( + r#"ALTER TABLE "{}" RENAME TO "{table_name}""#, + qualified_table_name(&table.namespace, &table.name), + )); + table.name = name.to_string(); + } + update_column( + &table_name, + &mut table.primary, + &primary.name, + &((&primary.type_def).into()), + queries, + ) + .to_table_result(&table_name, "primary"); + // let mut all_columns = table.columns.iter().map(ColumnInfoRef::from_info).collect(); + // for column in columns{ + // match all_columns.get_mut(&column.id){ + // Some(mut existing) + // } + // } Ok(()) } fn insert_record_queries( @@ -115,7 +150,7 @@ impl IntrospectQueryMaker for SqliteBackend { _transaction_hash: &Felt, queries: &mut Vec, ) -> RecordResult<()> { - let qualified_table_name = qualified_table_name(namespace, table_name); + let table_name = qualified_table_name(namespace, table_name); let all_columns = schema.all_columns(); let sql_columns = all_columns .iter() @@ -125,10 +160,10 @@ impl IntrospectQueryMaker for SqliteBackend { let placeholders = sql_columns.iter().map(SqliteColumn::placeholder).join(", "); let coalesce = sql_columns[1..] .iter() - .map(|col| coalesce_sql(&qualified_table_name, col)) + .map(|col| coalesce_sql(&table_name, col)) .join(", "); let sql: Arc = format!( - r#"INSERT INTO "{qualified_table_name}" ({}) VALUES ({}) ON CONFLICT("{}") DO UPDATE SET {}"#, + r#"INSERT INTO "{table_name}" ({}) VALUES ({}) ON CONFLICT("{}") DO UPDATE SET {}"#, column_names .iter() .map(|name| format!(r#""{name}""#)) @@ -137,7 +172,8 @@ impl IntrospectQueryMaker for SqliteBackend { placeholders, schema.primary_name(), coalesce - ).into(); + ) + .into(); for record in records { let mut arguments: SqliteArguments<'static> = SqliteArguments::default(); @@ -168,15 +204,9 @@ impl IntrospectSqlSink for SqliteBackend { #[async_trait] impl IntrospectInitialize for SqliteBackend { async fn load_tables(&self, _schemas: &Option>) -> DbResult> { - let rows: Vec = sqlx::query_as( - r" - SELECT namespace, id, owner, name, primary, columns, dead, alive - FROM introspect_sink_schema_state - ORDER BY updated_at ASC - ", - ) - .fetch_all(self.pool()) - .await?; + let rows: Vec = sqlx::query_as(FETCH_TABLES_QUERY) + .fetch_all(self.pool()) + .await?; let tables: Vec = rows .into_iter() @@ -196,11 +226,3 @@ impl IntrospectInitialize for SqliteBackend { .err_into() } } - -pub fn qualified_table_name(namespace: &str, table_name: &str) -> String { - if namespace.is_empty() { - table_name.to_string() - } else { - format!("{}_{}", namespace, table_name) - } -} diff --git a/crates/introspect-sql-sink/src/sqlite/mod.rs b/crates/introspect-sql-sink/src/sqlite/mod.rs index 58e9fc63..acbee860 100644 --- a/crates/introspect-sql-sink/src/sqlite/mod.rs +++ b/crates/introspect-sql-sink/src/sqlite/mod.rs @@ -1,7 +1,7 @@ pub mod backend; pub mod json; -pub mod query; pub mod record; +pub mod table; pub mod types; use sqlx::migrate::Migrator; diff --git a/crates/introspect-sql-sink/src/sqlite/query.rs b/crates/introspect-sql-sink/src/sqlite/query.rs deleted file mode 100644 index 49a6a000..00000000 --- a/crates/introspect-sql-sink/src/sqlite/query.rs +++ /dev/null @@ -1,23 +0,0 @@ -use introspect_types::{ColumnDef, PrimaryDef}; - -pub fn create_table_query( - namespace: &str, - name: &str, - primary: &PrimaryDef, - columns: &[ColumnDef], -) -> String { - let mut columns_sql = Vec::with_capacity(columns.len() + 1); - columns_sql.push(format!(r#""{}" TEXT PRIMARY KEY"#, primary.name)); - for column in columns { - columns_sql.push(format!(r#""{}" TEXT"#, column.name)); - } - format!( - r#"CREATE TABLE IF NOT EXISTS "{}" ({});"#, - table_name(&namespace, name), - columns_sql.join(", ") - ) -} - -pub fn table_name(namespace: &str, name: &str) -> String { - format!("{namespace}__{name}") -} diff --git a/crates/introspect-sql-sink/src/sqlite/table.rs b/crates/introspect-sql-sink/src/sqlite/table.rs index 14b7a559..af4f4a58 100644 --- a/crates/introspect-sql-sink/src/sqlite/table.rs +++ b/crates/introspect-sql-sink/src/sqlite/table.rs @@ -1,70 +1,200 @@ -use introspect_types::{ColumnDef, ColumnInfo, FeltIds, PrimaryDef}; -use itertools::Itertools; +use crate::sqlite::types::SqliteType; +use crate::{TableResult, UpgradeError, UpgradeResult}; +use introspect_types::{Attribute, ColumnDef, ColumnInfo, PrimaryDef, TypeDef}; +use serde::ser::SerializeMap; +use serde::{Serialize, Serializer}; +use serde_json::{Result as JsonResult, Serializer as JsonSerializer}; +use sqlx::Arguments; use starknet_types_core::felt::Felt; use std::collections::HashMap; -use thiserror::Error; -use torii_introspect::schema::TableSchema; -use torii_introspect::tables::RecordSchema; +use std::fmt::{Display, Write}; +use torii_sql::types::SqlFelt; +use torii_sql::{Queries, SqliteArguments, SqliteQuery}; -#[derive(Debug, Error)] -pub enum SqliteTableError { - #[error("Column with id: {0} not found in table {1}")] - ColumnNotFound(Felt, String), -} +pub const FETCH_TABLES_QUERY: &str = r#" + SELECT namespace, id, owner, name, "primary", columns, alive + FROM introspect_db_tables + ORDER BY updated_at ASC +"#; -pub type TableResult = std::result::Result; +const INSERT_TABLE_QUERY: &str = r#" INSERT INTO introspect_db_tables + (namespace, id, owner, name, "primary", columns, updated_at) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, unixepoch()) + ON CONFLICT (namespace, id) DO UPDATE SET + owner = excluded.owner, name = excluded.name, "primary" = excluded."primary", columns = excluded.columns, dead = excluded.dead, alive = excluded.alive, updated_at = unixepoch() +"#; -#[derive(Debug, Clone)] -pub struct SqliteTable { - pub name: String, - pub storage_name: String, - pub primary: PrimaryDef, - pub columns: HashMap, - pub order: Vec, - pub alive: bool, -} +struct TableName<'a>(&'a str, &'a str); -impl SqliteTable { - pub fn new( - storage_name: String, - name: String, - primary: PrimaryDef, - columns: Vec, - ) -> Self { - Self { - name, - storage_name, - primary, - order: columns.ids(), - columns: columns.into_iter().map_into().collect(), - alive: true, +impl Display for TableName<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if !self.0.is_empty() { + write!(f, "{}__", self.0)?; } + self.1.fmt(f) } +} - pub fn new_from_table(namespace: &str, table: impl Into) -> (Felt, Self) { - let table = table.into(); - let storage_name = if namespace.is_empty() { - table.name.clone() - } else { - format!("{namespace}__{}", table.name) - }; - ( - table.id, - Self::new(storage_name, table.name, table.primary, table.columns), - ) +pub fn qualified_table_name(namespace: &str, table_name: &str) -> String { + if namespace.is_empty() { + table_name.to_string() + } else { + format!("{}__{}", namespace, table_name) } +} - pub fn get_column(&self, selector: &Felt) -> TableResult<&ColumnInfo> { - self.columns - .get(selector) - .ok_or_else(|| SqliteTableError::ColumnNotFound(*selector, self.name.clone())) +pub fn serialize_columns<'a>(columns: Vec>>) -> JsonResult { + let mut data = Vec::new(); + let mut serializer = JsonSerializer::new(&mut data); + let mut array = serializer.serialize_map(Some(columns.len()))?; + for column in columns { + let column_ref: ColumnDefRef = column.into(); + array.serialize_entry(column_ref.id, &column_ref)?; } + array.end()?; + Ok(unsafe { String::from_utf8_unchecked(data) }) +} + +pub fn persist_table_state_query<'a>( + namespace: &str, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[impl Into>], + from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + queries: &mut Vec, +) -> TableResult<()> { + let mut args = SqliteArguments::default(); + args.add(namespace.to_string())?; + args.add(Into::::into(*id))?; + args.add(Into::::into(*from_address))?; + args.add(name.to_string())?; + args.add(serde_json::to_string(primary)?)?; + args.add(serialize_columns(columns)?)?; + queries.add((INSERT_TABLE_QUERY, args)); + Ok(()) +} - pub fn get_schema(&self, column_ids: &[Felt]) -> TableResult> { - let columns = column_ids - .iter() - .map(|selector| self.get_column(selector)) - .collect::, _>>()?; - Ok(RecordSchema::new(&self.primary, columns)) +pub fn create_table_query( + namespace: &str, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], +) -> TableResult { + let table_name = TableName(namespace, name); + let mut query = format!( + r#"CREATE TABLE IF NOT EXISTS "{table_name}" ("{}" {} PRIMARY KEY "#, + primary.name, + TryInto::::try_into(primary)? + ); + for column in columns { + let sql_type: SqliteType = column.try_into()?; + write!(query, r#", "{}" {sql_type}"#, column.name).unwrap(); } + query.push_str(");"); + Ok(query) +} + +pub fn update_columns( + columns: &mut HashMap, + table_name: &str, + new: &[ColumnDef], + queries: &mut Vec, +) -> TableResult<()> { + for column in new { + match columns.get_mut(&column.id) { + Some(existing) => { + update_column( + table_name, + existing, + &column.name, + &column.type_def, + queries, + )?; + } + None => { + queries.add(create_column_query(table_name, column)?); + columns.insert( + column.id, + ColumnInfo { + name: column.name.clone(), + type_def: column.type_def.clone(), + attributes: column.attributes.clone(), + }, + ); + } + } + } + Ok(()) +} + +pub fn update_column( + table_name: &str, + column: &mut ColumnInfo, + new_name: &str, + new_type: &TypeDef, + queries: &mut Vec, +) -> UpgradeResult { + use introspect_types::TypeDef::{ + Array, Bool, ByteArray, ByteArrayEncoded, Bytes31, Bytes31Encoded, ClassHash, + ContractAddress, Custom, Enum, EthAddress, Felt252, FixedArray, Nullable, + Option as TDOption, Result as TDResult, ShortUtf8, StorageAddress, StorageBaseAddress, + Struct, Tuple, Utf8String, I128, I16, I32, I64, I8, U128, U16, U256, U32, U512, U64, U8, + }; + if column.name != new_name { + queries.add(format!( + r#"ALTER TABLE "{table_name}" RENAME COLUMN "{}" TO "{new_name}";"#, + column.name + )); + column.name = new_name.to_string(); + } + let cast = match (&column.type_def, &new_type) { + (Bool | U8 | U16 | U32, Bool | U8 | U16 | U32 | I8 | I16 | I32 | I64) + | (I8 | I16 | I32 | I64, I8 | I16 | I32 | I64) + | (U64 | U128 | U256 | U512, U64 | U128 | U256 | U512 | I128) + | (I128, I128) + | ( + Felt252 | ClassHash | ContractAddress | EthAddress | StorageAddress + | StorageBaseAddress, + Felt252 | ClassHash | ContractAddress | EthAddress | StorageAddress + | StorageBaseAddress, + ) + | (ShortUtf8 | Utf8String, ShortUtf8 | Utf8String) + | ( + Bytes31 | Bytes31Encoded(_) | ByteArray | ByteArrayEncoded(_) | Custom(_), + Bytes31 | Bytes31Encoded(_) | ByteArray | ByteArrayEncoded(_) | Custom(_), + ) + | ( + Tuple(_) | Array(_) | FixedArray(_) | Struct(_) | Enum(_) | TDOption(_) | TDResult(_) + | Nullable(_), + Tuple(_) | Array(_) | FixedArray(_) | Struct(_) | Enum(_) | TDOption(_) | TDResult(_) + | Nullable(_), + ) => None, + (Bool | U8 | U16 | U32, U64 | U128 | U256 | U512 | I128) | (I8 | I16 | I32 | I64, I128) => { + Some(format!(r#"CAST("{new_name}" AS TEXT)"#)) + } + ( + Bool | U8 | U16 | U32, + Felt252 | ClassHash | ContractAddress | EthAddress | StorageAddress + | StorageBaseAddress, + ) => Some(format!(r#"printf('0x%064x', "{new_name}")"#)), + _ => return UpgradeError::type_upgrade_err(&column.type_def, &new_type), + }; + column.type_def = new_type.clone(); + if let Some(cast) = cast { + queries.add(format!( + r#"UPDATE "{table_name}" SET "{new_name}" = {cast};"# + )); + } + Ok(()) +} + +pub fn create_column_query(table_name: &str, column: &ColumnDef) -> TableResult { + let sql_type: SqliteType = column.try_into()?; + Ok(format!( + r#"ALTER TABLE "{table_name}" ADD COLUMN "{}" {sql_type};"#, + column.name + )) } diff --git a/crates/introspect-sql-sink/src/sqlite/types.rs b/crates/introspect-sql-sink/src/sqlite/types.rs index 97781f3b..a7b3e904 100644 --- a/crates/introspect-sql-sink/src/sqlite/types.rs +++ b/crates/introspect-sql-sink/src/sqlite/types.rs @@ -1,4 +1,6 @@ -use introspect_types::{ColumnInfo, TypeDef}; +use std::fmt::Display; + +use introspect_types::{ColumnDef, ColumnInfo, PrimaryDef, PrimaryTypeDef, TypeDef}; use crate::{TypeError, TypeResult}; @@ -11,6 +13,19 @@ pub enum SqliteType { Json, } +impl Display for SqliteType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SqliteType::Null => write!(f, "NULL"), + SqliteType::Text => write!(f, "TEXT"), + SqliteType::Integer => write!(f, "INTEGER"), + SqliteType::Real => write!(f, "REAL"), + SqliteType::Blob => write!(f, "BLOB"), + SqliteType::Json => write!(f, "TEXT"), + } + } +} + pub struct SqliteColumn<'a> { pub name: &'a str, pub sql_type: SqliteType, @@ -58,6 +73,38 @@ impl TryFrom<&TypeDef> for SqliteType { } } +impl TryFrom<&ColumnDef> for SqliteType { + type Error = TypeError; + + fn try_from(value: &ColumnDef) -> Result { + (&value.type_def).try_into() + } +} + +impl TryFrom<&ColumnInfo> for SqliteType { + type Error = TypeError; + + fn try_from(value: &ColumnInfo) -> Result { + (&value.type_def).try_into() + } +} + +impl TryFrom<&PrimaryTypeDef> for SqliteType { + type Error = TypeError; + + fn try_from(value: &PrimaryTypeDef) -> Result { + (&Into::::into(value)).try_into() + } +} + +impl TryFrom<&PrimaryDef> for SqliteType { + type Error = TypeError; + + fn try_from(value: &PrimaryDef) -> Result { + (&value.type_def).try_into() + } +} + impl<'a> TryFrom<&'a ColumnInfo> for SqliteColumn<'a> { type Error = TypeError; diff --git a/crates/introspect-sql-sink/src/table.rs b/crates/introspect-sql-sink/src/table.rs index 7c76a26e..61a29853 100644 --- a/crates/introspect-sql-sink/src/table.rs +++ b/crates/introspect-sql-sink/src/table.rs @@ -91,6 +91,10 @@ impl Table { .collect::>>() } + pub fn all_columns(&self) -> Vec<&ColumnInfo> { + self.columns.values().collect() + } + pub fn columns_with_ids<'a>( &'a self, ids: &'a [Felt], @@ -100,6 +104,10 @@ impl Table { .collect::>>() } + pub fn all_columns_with_ids(&self) -> Vec<(&Felt, &ColumnInfo)> { + self.columns.iter().collect() + } + pub fn new( id: Felt, namespace: String, From e6be17d3e61554d48cbad8b624e9f4fb6e3e8f89 Mon Sep 17 00:00:00 2001 From: Bengineer Date: Mon, 30 Mar 2026 19:41:20 +0100 Subject: [PATCH 12/21] Refactor database connection handling and improve SQL sink functionality - Introduced `DbPoolOptions` and `PoolConfig` for better database connection management. - Updated `DbPool` to support both PostgreSQL and SQLite connections. - Refactored `create_table`, `update_table`, and `insert_fields` methods to use the new connection structure. - Enhanced error handling and logging in database operations. - Updated event processing logic in the introspect example to utilize the new database connection methods. - Removed deprecated code and improved type safety with `DbType` enum. - Added tests to ensure compatibility with both PostgreSQL and SQLite backends. --- Cargo.lock | 6 +- Cargo.toml | 9 +- bins/torii-arcade/src/main.rs | 93 ++---- bins/torii-introspect-bin/src/main.rs | 11 +- bins/torii-introspect-synth/Cargo.toml | 7 +- bins/torii-introspect-synth/src/main.rs | 6 +- .../{ => postgres}/001_dojo_store.sql | 0 crates/dojo/src/decoder.rs | 39 +-- crates/dojo/src/error.rs | 20 +- crates/dojo/src/store/json.rs | 20 +- crates/dojo/src/store/mod.rs | 19 +- crates/dojo/src/store/postgres.rs | 54 +-- crates/dojo/src/store/sql.rs | 35 ++ crates/dojo/src/store/sqlite.rs | 51 +-- crates/dojo/src/table.rs | 4 +- crates/introspect-sql-sink/src/backend.rs | 31 +- crates/introspect-sql-sink/src/error.rs | 2 +- crates/introspect-sql-sink/src/lib.rs | 4 +- .../src/postgres/backend.rs | 33 +- .../src/postgres/handler.rs | 6 +- .../introspect-sql-sink/src/postgres/mod.rs | 2 +- crates/introspect-sql-sink/src/processor.rs | 24 +- crates/introspect-sql-sink/src/runtime.rs | 48 +-- .../introspect-sql-sink/src/sqlite/backend.rs | 58 ++-- crates/introspect-sql-sink/src/sqlite/json.rs | 8 +- crates/introspect-sql-sink/src/sqlite/mod.rs | 2 +- .../introspect-sql-sink/src/sqlite/record.rs | 8 +- crates/introspect-sql-sink/src/sqlite/sink.rs | 111 ------- .../introspect-sql-sink/src/sqlite/table.rs | 44 +-- crates/introspect-sql-sink/src/tables.rs | 28 +- crates/sql/Cargo.toml | 1 + crates/sql/src/connection.rs | 313 +++++++++++++++++- crates/sql/src/lib.rs | 13 +- crates/sql/src/postgres/mod.rs | 2 +- crates/sql/src/query.rs | 50 +++ crates/sql/src/runtime.rs | 43 +++ crates/sql/src/sqlite/mod.rs | 4 +- crates/torii-ecs-sink/src/grpc_service.rs | 4 +- crates/torii-runtime-common/Cargo.toml | 1 + crates/torii-runtime-common/src/database.rs | 112 +++---- examples/introspect/restart copy.rs | 109 ++++++ examples/introspect/restart.rs | 26 +- sqlite-data.db-journal | Bin 0 -> 1646216 bytes 43 files changed, 906 insertions(+), 555 deletions(-) rename crates/dojo/migrations/{ => postgres}/001_dojo_store.sql (100%) create mode 100644 crates/dojo/src/store/sql.rs delete mode 100644 crates/introspect-sql-sink/src/sqlite/sink.rs create mode 100644 crates/sql/src/runtime.rs create mode 100644 examples/introspect/restart copy.rs create mode 100644 sqlite-data.db-journal diff --git a/Cargo.lock b/Cargo.lock index 53d41466..4a1076bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,7 +916,6 @@ dependencies = [ [[package]] name = "dojo-introspect" version = "0.1.0" -source = "git+https://github.com/dojoengine/dojo-introspect?rev=3f4c646#3f4c646e59cfa68d9dbea46a46e724129bb2bc19" dependencies = [ "async-trait", "introspect-rust-macros", @@ -1863,7 +1862,6 @@ dependencies = [ [[package]] name = "introspect-events" version = "0.1.2" -source = "git+https://github.com/cartridge-gg/introspect?rev=49bf186#49bf18652205d88d57bc0e0a601457793bb711b5" dependencies = [ "cainome-cairo-serde", "introspect-types", @@ -1875,7 +1873,6 @@ dependencies = [ [[package]] name = "introspect-rust-macros" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/introspect?rev=49bf186#49bf18652205d88d57bc0e0a601457793bb711b5" dependencies = [ "paste", "proc-macro2", @@ -1887,7 +1884,6 @@ dependencies = [ [[package]] name = "introspect-types" version = "0.1.2" -source = "git+https://github.com/cartridge-gg/introspect?rev=49bf186#49bf18652205d88d57bc0e0a601457793bb711b5" dependencies = [ "blake3", "convert_case", @@ -5048,6 +5044,7 @@ dependencies = [ "tokio", "tokio-postgres", "torii", + "torii-sql", "tracing", ] @@ -5059,6 +5056,7 @@ dependencies = [ "crc", "futures", "itertools 0.14.0", + "log", "sqlx", "starknet-types-core", ] diff --git a/Cargo.toml b/Cargo.toml index b71e8ab6..a05b0023 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,6 +68,7 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } metrics = "0.24" metrics-exporter-prometheus = "0.17" +log = "0.4.29" # CLI clap = { version = "4.5", features = ["derive"] } @@ -106,10 +107,10 @@ bigdecimal = "0.4.10" tonic-build = "0.12" # Introspect -introspect-events = { git = "https://github.com/cartridge-gg/introspect", rev = "49bf186" } -introspect-types = { git = "https://github.com/cartridge-gg/introspect", rev = "49bf186" } -introspect-rust-macros = { git = "https://github.com/cartridge-gg/introspect", rev = "49bf186" } -dojo-introspect = { git = "https://github.com/dojoengine/dojo-introspect", rev = "3f4c646" } +introspect-events = { git = "https://github.com/cartridge-gg/introspect", rev = "b89ee9e" } +introspect-types = { git = "https://github.com/cartridge-gg/introspect", rev = "b89ee9e" } +introspect-rust-macros = { git = "https://github.com/cartridge-gg/introspect", rev = "b89ee9e" } +dojo-introspect = { git = "https://github.com/dojoengine/dojo-introspect", rev = "fd99a0a" } # Utils diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index f792cf83..189c89df 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -3,8 +3,6 @@ mod config; use anyhow::Result; use clap::Parser; use config::{Config, MetadataMode}; -use sqlx::postgres::PgPoolOptions; -use sqlx::sqlite::SqlitePoolOptions; use starknet::core::types::Felt; use std::collections::{HashMap, HashSet}; use std::path::Path; @@ -17,9 +15,8 @@ use torii::etl::decoder::DecoderId; use torii::etl::extractor::{ ContractEventConfig, EventExtractor, EventExtractorConfig, Extractor, RetryPolicy, }; -use torii::etl::EngineDb; use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; -use torii::etl::TypeId; +use torii::etl::{EngineDb, TypeId}; use torii::EtlConcurrencyConfig; use torii_arcade_sink::proto::arcade::arcade_server::ArcadeServer; use torii_arcade_sink::{ArcadeSink, FILE_DESCRIPTOR_SET as ARCADE_DESCRIPTOR_SET}; @@ -27,11 +24,10 @@ use torii_common::{MetadataFetcher, TokenUriService}; use torii_config_common::apply_observability_env; use torii_dojo::decoder::DojoDecoder; use torii_dojo::external_contract::{ - contract_type_from_decoder_ids, RegisterExternalContractCommandHandler, - RegisteredContractType, SharedContractTypeRegistry, SharedDecoderRegistry, + contract_type_from_decoder_ids, RegisterExternalContractCommandHandler, RegisteredContractType, + SharedContractTypeRegistry, SharedDecoderRegistry, }; -use torii_dojo::store::postgres::PgStore; -use torii_dojo::store::sqlite::SqliteStore; +use torii_dojo::store::DojoStoreTrait; use torii_ecs_sink::proto::world::world_server::WorldServer; use torii_ecs_sink::{EcsSink, FILE_DESCRIPTOR_SET as ECS_DESCRIPTOR_SET}; use torii_entities_historical_sink::EntitiesHistoricalSink; @@ -50,9 +46,9 @@ use torii_erc721::{ Erc721Decoder, Erc721MetadataCommandHandler, Erc721Service, Erc721Sink, Erc721Storage, FILE_DESCRIPTOR_SET as ERC721_DESCRIPTOR_SET, }; -use torii_introspect_sql_sink::{IntrospectPgDb, IntrospectSqliteDb, NamespaceMode}; -use torii_runtime_common::database::{validate_uniform_backends, DatabaseBackend}; -use torii_sql::sqlite::{is_sqlite_memory_path, sqlite_connect_options}; +use torii_introspect_sql_sink::{IntrospectDb, NamespaceMode}; +use torii_runtime_common::database::validate_uniform_backends; +use torii_sql::{DbPool, DbPoolOptions, PoolExt}; type StarknetProvider = starknet::providers::jsonrpc::JsonRpcClient; @@ -237,7 +233,7 @@ async fn run_indexer(config: Config) -> Result<()> { ("erc1155", &erc1155_db_url), ], "torii-arcade does not support mixed storage backends in one runtime; configure all databases as either SQLite or PostgreSQL", - )?; + ).map_err(|err| anyhow::anyhow!(err))?; let provider = starknet::providers::jsonrpc::JsonRpcClient::new( starknet::providers::jsonrpc::HttpTransport::new( @@ -365,61 +361,22 @@ async fn run_indexer(config: Config) -> Result<()> { &erc1155_addresses, &config, ); + let pool_options = DbPoolOptions::new().max_connections(config.max_db_connections.unwrap_or(5)); + let pool = pool_options.connect_any(&engine_database_url).await?; + if let DbPool::Sqlite(pool) = &pool { + pool.execute_queries([ + "PRAGMA journal_mode=WAL", + "PRAGMA synchronous=NORMAL", + "PRAGMA foreign_keys=ON", + ]) + .await?; + } + let dojo_decoder = DojoDecoder::new(pool.clone(), provider.clone()); + let introspect_sink = IntrospectDb::new(pool, NamespaceMode::Address); - let (dojo_decoder, introspect_sink): ( - Arc, - Box, - ) = match backend { - DatabaseBackend::Postgres => { - let max_db_connections = config.max_db_connections.unwrap_or(5); - let pool = PgPoolOptions::new() - .max_connections(max_db_connections) - .connect(&storage_database_url) - .await?; - - let decoder = DojoDecoder::, _>::new(pool.clone(), (*provider).clone()); - let sink = IntrospectPgDb::new(pool.clone(), NamespaceMode::Address); - decoder.store.initialize().await?; - decoder.load_tables(&[]).await?; - - ( - Arc::new(decoder) as Arc, - Box::new(sink), - ) - } - DatabaseBackend::Sqlite => { - let options = sqlite_connect_options(&storage_database_url)?; - let max_db_connections = match config.max_db_connections { - Some(limit) => limit.max(1), - None if is_sqlite_memory_path(&storage_database_url) => 1, - None => 1, - }; - let pool = SqlitePoolOptions::new() - .max_connections(max_db_connections) - .connect_with(options) - .await?; - - sqlx::query("PRAGMA journal_mode=WAL") - .execute(&pool) - .await?; - sqlx::query("PRAGMA synchronous=NORMAL") - .execute(&pool) - .await?; - sqlx::query("PRAGMA foreign_keys=ON").execute(&pool).await?; - - let decoder = DojoDecoder::, _>::new(pool.clone(), (*provider).clone()); - decoder.store.initialize().await?; - decoder.load_tables(&[]).await?; - - ( - Arc::new(decoder) as Arc, - Box::new(IntrospectSqliteDb::new( - pool.clone(), - NamespaceMode::Address, - )), - ) - } - }; + dojo_decoder.initialize().await?; + dojo_decoder.load_tables(&[]).await?; + introspect_sink.initialize_introspect_sql_sink().await?; let ecs_sink = EcsSink::new( &storage_database_url, @@ -457,7 +414,7 @@ async fn run_indexer(config: Config) -> Result<()> { .await?, ); let arcade_projection_pipeline = ArcadeProjectionPipeline::new(vec![ - introspect_sink, + Box::new(introspect_sink), historical_sink, Box::new(arcade_sink), ]); @@ -471,7 +428,7 @@ async fn run_indexer(config: Config) -> Result<()> { }) .engine_database_url(engine_database_url) .with_extractor(extractor) - .add_decoder(dojo_decoder) + .add_decoder(Arc::new(dojo_decoder)) .add_sink_boxed(Box::new(ecs_sink)) .add_sink_boxed(Box::new(arcade_projection_pipeline)); diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index e01f131e..edcf05a7 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -27,8 +27,7 @@ use torii_dojo::external_contract::{ contract_type_from_decoder_ids, RegisterExternalContractCommandHandler, RegisteredContractType, SharedContractTypeRegistry, SharedDecoderRegistry, }; -use torii_dojo::store::postgres::PgStore; -use torii_dojo::store::sqlite::SqliteStore; +use torii_dojo::store::DojoStoreTrait; use torii_ecs_sink::proto::world::world_server::WorldServer; use torii_ecs_sink::{EcsSink, FILE_DESCRIPTOR_SET as ECS_DESCRIPTOR_SET}; use torii_entities_historical_sink::EntitiesHistoricalSink; @@ -666,9 +665,9 @@ async fn run_with_postgres( .connect(storage_database_url) .await?; - let decoder = DojoDecoder::, _>::new(pool.clone(), provider); + let decoder = DojoDecoder::new(pool.clone(), provider); let introspect_sink = IntrospectPgDb::new(pool.clone(), NamespaceMode::Address); - decoder.store.initialize().await?; + decoder.initialize().await?; introspect_sink.initialize_introspect_sql_sink().await?; decoder.load_tables(&[]).await?; @@ -872,8 +871,8 @@ async fn run_with_sqlite( .await?; sqlx::query("PRAGMA foreign_keys=ON").execute(&pool).await?; - let decoder = DojoDecoder::, _>::new(pool.clone(), provider); - decoder.store.initialize().await?; + let decoder = DojoDecoder::new(pool.clone(), provider); + decoder.initialize().await?; decoder.load_tables(&[]).await?; let decoder: Arc = Arc::new(decoder); diff --git a/bins/torii-introspect-synth/Cargo.toml b/bins/torii-introspect-synth/Cargo.toml index ee1da853..d6204edf 100644 --- a/bins/torii-introspect-synth/Cargo.toml +++ b/bins/torii-introspect-synth/Cargo.toml @@ -9,11 +9,8 @@ path = "src/main.rs" [dependencies] torii.workspace = true -torii-dojo.workspace = true -torii-introspect-sql-sink = { workspace = true, features = [ - "postgres", - "sqlite", -] } +torii-dojo = { workspace = true, features = ["postgres"] } +torii-introspect-sql-sink = { workspace = true, features = ["postgres"] } tokio = { version = "1", features = ["full"] } tracing = "0.1" diff --git a/bins/torii-introspect-synth/src/main.rs b/bins/torii-introspect-synth/src/main.rs index 4970a0b5..494d4e0d 100644 --- a/bins/torii-introspect-synth/src/main.rs +++ b/bins/torii-introspect-synth/src/main.rs @@ -26,7 +26,7 @@ use torii::etl::sink::{EventBus, Sink, SinkContext}; use torii::etl::Decoder; use torii::grpc::SubscriptionManager; use torii_dojo::decoder::DojoDecoder; -use torii_dojo::store::postgres::PgStore; +use torii_dojo::store::DojoStoreTrait; use torii_introspect_sql_sink::IntrospectPgDb; const EXTRACTOR_TYPE: &str = "synthetic_introspect"; @@ -441,8 +441,8 @@ async fn main() -> Result<()> { .await?, ); - let decoder = DojoDecoder::, _>::new(pool.clone(), NeverFetchSchema); - decoder.store.initialize().await?; + let decoder = DojoDecoder::new(pool.clone(), NeverFetchSchema); + decoder.initialize().await?; decoder.load_tables(&[]).await?; let decoder: Arc = Arc::new(decoder); let decoder_context = diff --git a/crates/dojo/migrations/001_dojo_store.sql b/crates/dojo/migrations/postgres/001_dojo_store.sql similarity index 100% rename from crates/dojo/migrations/001_dojo_store.sql rename to crates/dojo/migrations/postgres/001_dojo_store.sql diff --git a/crates/dojo/src/decoder.rs b/crates/dojo/src/decoder.rs index 1b95122d..3d91f92b 100644 --- a/crates/dojo/src/decoder.rs +++ b/crates/dojo/src/decoder.rs @@ -65,12 +65,12 @@ pub trait DojoRecordEvent: Sized + CairoEventInfo + Debug { #[async_trait] impl DojoStoreTrait for DojoDecoder where - Store: DojoStoreTrait + Send + Sync, - Store::Error: ToString, - F: Send + Sync + 'static, + Store: DojoStoreTrait + Sync, + F: Sync, { - type Error = DojoToriiError; - + async fn initialize(&self) -> DojoToriiResult<()> { + self.store.initialize().await + } async fn save_table( &self, owner: &Felt, @@ -81,14 +81,10 @@ where self.store .save_table(owner, table, tx_hash, block_number) .await - .map_err(DojoToriiError::store_error) } async fn read_tables(&self, owners: &[Felt]) -> DojoToriiResult> { - self.store - .read_tables(owners) - .await - .map_err(DojoToriiError::store_error) + self.store.read_tables(owners).await } } @@ -116,11 +112,10 @@ impl DojoDecoder { impl DojoDecoder where - Store: DojoStoreTrait + Sync, + Store: DojoStoreTrait + Sync + Send, F: DojoSchemaFetcher + Send + Sync + 'static, { - pub fn new>(store: S, fetcher: F) -> Self { - let store = store.into(); + pub fn new(store: Store, fetcher: F) -> Self { Self { tables: Default::default(), store, @@ -347,15 +342,10 @@ mod tests { use crate::ExternalContractRegisteredBody; use async_trait::async_trait; use dojo_introspect::DojoIntrospectError; - use introspect_types::{ - utils::string_to_cairo_serialize_byte_array, Attribute, ColumnDef, TypeDef, - }; + use introspect_types::utils::string_to_cairo_serialize_byte_array; + use introspect_types::{Attribute, ColumnDef, TypeDef}; use std::sync::Mutex; - #[derive(Debug, thiserror::Error)] - #[error("{0}")] - struct FakeStoreError(String); - #[derive(Default)] struct FakeStore { saved_blocks: Mutex>, @@ -363,20 +353,21 @@ mod tests { #[async_trait] impl DojoStoreTrait for FakeStore { - type Error = FakeStoreError; - + async fn initialize(&self) -> DojoToriiResult { + Ok(()) + } async fn save_table( &self, _owner: &Felt, _table: &DojoTable, _tx_hash: &Felt, block_number: u64, - ) -> Result<(), Self::Error> { + ) -> DojoToriiResult { self.saved_blocks.lock().unwrap().push(block_number); Ok(()) } - async fn read_tables(&self, _owners: &[Felt]) -> Result, Self::Error> { + async fn read_tables(&self, _owners: &[Felt]) -> DojoToriiResult> { Ok(Vec::new()) } } diff --git a/crates/dojo/src/error.rs b/crates/dojo/src/error.rs index 911f7550..e9d4cc78 100644 --- a/crates/dojo/src/error.rs +++ b/crates/dojo/src/error.rs @@ -1,10 +1,10 @@ -use std::sync::PoisonError; - use dojo_introspect::DojoIntrospectError; use introspect_types::transcode::TranscodeError; use introspect_types::DecodeError; use starknet::core::utils::NonAsciiNameError; use starknet_types_core::felt::Felt; +use std::error::Error as StdError; +use std::sync::PoisonError; #[derive(Debug, thiserror::Error)] pub enum DojoToriiError { @@ -12,8 +12,8 @@ pub enum DojoToriiError { UnknownDojoEventSelector(Felt), #[error("Missing event selector")] MissingEventSelector, - #[error("Column {0:#066x} not found in table {1}")] - ColumnNotFound(Felt, String), + #[error("Column {1:#066x} not found in table {0}")] + ColumnNotFound(String, Felt), #[error("Failed to parse field {0:#066x} in table {1}")] FieldParseError(Felt, String), #[error("Too many values provided for field {0:#066x}")] @@ -26,8 +26,6 @@ pub enum DojoToriiError { TableNotFoundById(Felt), #[error("Failed to acquire lock: {0}")] LockError(String), - #[error("Store error: {0}")] - StoreError(String), #[error("Starknet selector error: {0}")] StarknetSelectorError(#[from] NonAsciiNameError), #[error("Lock poisoned: {0}")] @@ -40,9 +38,13 @@ pub enum DojoToriiError { DojoIntrospectError(#[from] DojoIntrospectError), #[error("Transcode error: {0:?}")] TranscodeError(TranscodeError), + #[error("Store error: {0}")] + StoreError(#[source] Box), + #[error(transparent)] + JsonError(#[from] serde_json::Error), } -pub type DojoToriiResult = std::result::Result; +pub type DojoToriiResult = std::result::Result; impl From> for DojoToriiError { fn from(err: TranscodeError) -> Self { @@ -51,8 +53,8 @@ impl From> for DojoToriiError { } impl DojoToriiError { - pub fn store_error(err: T) -> Self { - Self::StoreError(err.to_string()) + pub fn store_error(err: T) -> Self { + Self::StoreError(Box::new(err)) } } diff --git a/crates/dojo/src/store/json.rs b/crates/dojo/src/store/json.rs index a3349671..d3988b1d 100644 --- a/crates/dojo/src/store/json.rs +++ b/crates/dojo/src/store/json.rs @@ -1,6 +1,7 @@ use super::DojoStoreTrait; -use crate::DojoTable; +use crate::{DojoTable, DojoToriiResult}; use async_trait::async_trait; +use introspect_types::ResultInto; use serde_json::Error as JsonError; use starknet_types_core::felt::Felt; use std::fs; @@ -68,19 +69,24 @@ impl JsonStore { #[async_trait] impl DojoStoreTrait for JsonStore { - type Error = JsonError; - + async fn initialize(&self) -> DojoToriiResult { + // No initialization needed for JSON store, but we can check if the path is accessible. + if !self.path.exists() { + std::fs::create_dir_all(&self.path).map_err(JsonError::io)?; + } + Ok(()) + } async fn save_table( &self, _owner: &Felt, table: &DojoTable, _tx_hash: &Felt, _block_number: u64, - ) -> Result<(), Self::Error> { - self.dump_table(table) + ) -> DojoToriiResult { + self.dump_table(table).err_into() } - async fn read_tables(&self, _owners: &[Felt]) -> Result, Self::Error> { - self.load_all_tables() + async fn read_tables(&self, _owners: &[Felt]) -> DojoToriiResult> { + self.load_all_tables().err_into() } } diff --git a/crates/dojo/src/store/mod.rs b/crates/dojo/src/store/mod.rs index 1a4ab6da..946ffc60 100644 --- a/crates/dojo/src/store/mod.rs +++ b/crates/dojo/src/store/mod.rs @@ -5,30 +5,31 @@ pub mod postgres; #[cfg(feature = "sqlite")] pub mod sqlite; +#[cfg(feature = "postgres")] +#[cfg(feature = "sqlite")] +pub mod sql; + use crate::table::DojoTableInfo; -use crate::DojoTable; +use crate::{DojoTable, DojoToriiResult}; use async_trait::async_trait; use starknet_types_core::felt::Felt; use std::collections::HashMap; #[async_trait] -pub trait DojoStoreTrait -where - Self: Send + Sync + 'static + Sized, -{ - type Error: std::error::Error; +pub trait DojoStoreTrait { + async fn initialize(&self) -> DojoToriiResult; async fn save_table( &self, owner: &Felt, table: &DojoTable, tx_hash: &Felt, block_number: u64, - ) -> Result<(), Self::Error>; - async fn read_tables(&self, owners: &[Felt]) -> Result, Self::Error>; + ) -> DojoToriiResult; + async fn read_tables(&self, owners: &[Felt]) -> DojoToriiResult>; async fn read_table_map( &self, owners: &[Felt], - ) -> Result, Self::Error> { + ) -> DojoToriiResult> { Ok(self .read_tables(owners) .await? diff --git a/crates/dojo/src/store/postgres.rs b/crates/dojo/src/store/postgres.rs index 6fbe009b..a4e0594c 100644 --- a/crates/dojo/src/store/postgres.rs +++ b/crates/dojo/src/store/postgres.rs @@ -1,9 +1,9 @@ use super::DojoStoreTrait; use crate::decoder::primary_field_def; use crate::table::DojoTableInfo; -use crate::DojoTable; +use crate::{DojoTable, DojoToriiError, DojoToriiResult}; use async_trait::async_trait; -use introspect_types::{Attribute, ColumnInfo, ResultInto, TypeDef}; +use introspect_types::{Attribute, ColumnInfo, TypeDef}; use itertools::Itertools; use sqlx::migrate::Migrator; use sqlx::query::Query; @@ -14,7 +14,7 @@ use std::collections::HashMap; use torii_introspect::postgres::owned::PgTypeDef; use torii_introspect::postgres::PgFelt; use torii_introspect::schema::ColumnKeyTrait; -use torii_sql::{DbPool, PgArguments, PgPool, Postgres, SqlxResult}; +use torii_sql::{PgArguments, PgPool, PoolExt, Postgres, SqlxResult}; pub const FETCH_TABLES_QUERY: &str = r#" SELECT DISTINCT ON (owner, id) @@ -84,7 +84,7 @@ pub const INSERT_COLUMN_QUERY: &str = r#" updated_at = NOW(), updated_tx = EXCLUDED.updated_tx"#; -pub const DOJO_STORE_MIGRATIONS: Migrator = sqlx::migrate!(); +pub const DOJO_STORE_MIGRATIONS: Migrator = sqlx::migrate!("./migrations/postgres"); #[derive(Debug, thiserror::Error)] pub enum DojoPgStoreError { @@ -98,8 +98,6 @@ pub enum DojoPgStoreError { table_id: Felt, column_id: Felt, }, - #[error("Duplicate tables found for owner {owner:?} and table id {table_id}")] - DuplicateTables { owner: Felt, table_id: Felt }, } impl DojoPgStoreError { @@ -281,40 +279,44 @@ impl DojoTable { pub struct PgStore(pub T); -impl> DbPool for PgStore { +impl> PoolExt for PgStore { fn pool(&self) -> &PgPool { &self.0.pool() } } -impl + Send + Sync> PgStore { +impl + Send + Sync> PgStore { pub async fn initialize(&self) -> SqlxResult<()> { self.migrate(Some("dojo"), DOJO_STORE_MIGRATIONS).await } } -impl> From for PgStore { +impl> From for PgStore { fn from(pool: T) -> Self { PgStore(pool) } } #[async_trait] -impl + Send + Sync + 'static> DojoStoreTrait for PgStore { - type Error = DojoPgStoreError; - +impl DojoStoreTrait for PgPool { + async fn initialize(&self) -> DojoToriiResult { + self.migrate(Some("dojo"), DOJO_STORE_MIGRATIONS) + .await + .map_err(DojoToriiError::store_error) + } async fn save_table( &self, owner: &Felt, table: &DojoTable, tx_hash: &Felt, block_number: u64, - ) -> Result<(), Self::Error> { - let mut transaction = self.begin().await?; + ) -> DojoToriiResult { + let mut transaction = self.begin().await.map_err(DojoToriiError::store_error)?; table .insert_query(owner, tx_hash, block_number) .execute(&mut *transaction) - .await?; + .await + .map_err(DojoToriiError::store_error)?; for (id, info) in &table.columns { column_info_insert_query( INSERT_COLUMN_QUERY, @@ -326,27 +328,33 @@ impl + Send + Sync + 'static> DojoStoreTrait for PgStore tx_hash, ) .execute(&mut *transaction) - .await?; + .await + .map_err(DojoToriiError::store_error)?; } - transaction.commit().await.err_into() + transaction + .commit() + .await + .map_err(DojoToriiError::store_error) } - async fn read_tables(&self, owners: &[Felt]) -> Result, Self::Error> { + async fn read_tables(&self, owners: &[Felt]) -> DojoToriiResult> { let mut tables = PgTypeDef::get_rows::(self.pool(), FETCH_TABLES_QUERY, owners) - .await? + .await + .map_err(DojoToriiError::store_error)? .into_iter() .map(|row: ((), DojoTable)| row.1) .collect_vec(); let mut columns: HashMap<(Felt, Felt), _> = ColumnInfo::get_hash_map::(self.pool(), FETCH_COLUMNS_QUERY, owners) - .await?; + .await + .map_err(DojoToriiError::store_error)?; for table in &mut tables { for key in table.key_fields.iter().chain(table.value_fields.iter()) { - let column = columns.remove(&(table.id, *key)).ok_or_else(|| { - DojoPgStoreError::column_not_found(table.name.clone(), &(table.id, *key)) - })?; + let column = columns + .remove(&(table.id, *key)) + .ok_or_else(|| DojoToriiError::ColumnNotFound(table.name.clone(), *key))?; table.columns.insert(*key, column); } } diff --git a/crates/dojo/src/store/sql.rs b/crates/dojo/src/store/sql.rs new file mode 100644 index 00000000..14cb676b --- /dev/null +++ b/crates/dojo/src/store/sql.rs @@ -0,0 +1,35 @@ +use crate::store::DojoStoreTrait; +use crate::{DojoTable, DojoToriiResult}; +use async_trait::async_trait; +use starknet_types_core::felt::Felt; +use torii_sql::DbPool; + +#[async_trait] +impl DojoStoreTrait for DbPool { + async fn initialize(&self) -> DojoToriiResult { + match self { + DbPool::Postgres(pool) => pool.initialize().await, + DbPool::Sqlite(pool) => pool.initialize().await, + } + } + + async fn save_table( + &self, + owner: &Felt, + table: &DojoTable, + tx_hash: &Felt, + block_number: u64, + ) -> DojoToriiResult { + match self { + DbPool::Postgres(pool) => pool.save_table(owner, table, tx_hash, block_number).await, + DbPool::Sqlite(pool) => pool.save_table(owner, table, tx_hash, block_number).await, + } + } + + async fn read_tables(&self, owners: &[Felt]) -> DojoToriiResult> { + match self { + DbPool::Postgres(pool) => pool.read_tables(owners).await, + DbPool::Sqlite(pool) => pool.read_tables(owners).await, + } + } +} diff --git a/crates/dojo/src/store/sqlite.rs b/crates/dojo/src/store/sqlite.rs index e585e90a..4bd41068 100644 --- a/crates/dojo/src/store/sqlite.rs +++ b/crates/dojo/src/store/sqlite.rs @@ -1,13 +1,12 @@ use super::DojoStoreTrait; use crate::decoder::primary_field_def; -use crate::DojoTable; +use crate::{DojoTable, DojoToriiError, DojoToriiResult}; use async_trait::async_trait; use introspect_types::ColumnInfo; use serde::{Deserialize, Serialize}; use sqlx::migrate::Migrator; use sqlx::sqlite::SqliteArguments; -use sqlx::Arguments; -use sqlx::{FromRow, Sqlite}; +use sqlx::{Arguments, FromRow, Sqlite, SqlitePool}; use starknet_types_core::felt::Felt; use std::collections::HashMap; use std::io; @@ -15,7 +14,7 @@ use std::ops::Deref; use torii_common::{blob_to_felt, felt_to_blob}; use torii_introspect::schema::ColumnKeyTrait; use torii_sql::sqlite::SqliteDbConnection; -use torii_sql::SqlxResult; +use torii_sql::{PoolExt, SqlxResult}; pub const DOJO_SQLITE_STORE_MIGRATIONS: Migrator = sqlx::migrate!("./migrations/sqlite"); @@ -176,17 +175,20 @@ impl From for SqliteStore { } #[async_trait] -impl DojoStoreTrait for SqliteStore { - type Error = DojoSqliteStoreError; - +impl DojoStoreTrait for SqlitePool { + async fn initialize(&self) -> DojoToriiResult { + self.migrate(Some("dojo"), DOJO_SQLITE_STORE_MIGRATIONS) + .await + .map_err(DojoToriiError::store_error) + } async fn save_table( &self, owner: &Felt, table: &DojoTable, tx_hash: &Felt, block_number: u64, - ) -> Result<(), Self::Error> { - let mut transaction = self.begin().await?; + ) -> DojoToriiResult { + let mut transaction = self.begin().await.map_err(DojoToriiError::store_error)?; sqlx::query( r" @@ -227,7 +229,8 @@ impl DojoStoreTrait for SqliteSto .bind(felt_to_blob(*tx_hash)) .bind(felt_to_blob(*tx_hash)) .execute(&mut *transaction) - .await?; + .await + .map_err(DojoToriiError::store_error)?; for (id, info) in &table.columns { let payload = StoredColumnInfo { @@ -248,37 +251,45 @@ impl DojoStoreTrait for SqliteSto .bind(felt_to_blob(*id)) .bind(serde_json::to_string(&payload)?) .execute(&mut *transaction) - .await?; + .await + .map_err(DojoToriiError::store_error)?; } - transaction.commit().await?; + transaction + .commit() + .await + .map_err(DojoToriiError::store_error)?; Ok(()) } - async fn read_tables(&self, owners: &[Felt]) -> Result, Self::Error> { + async fn read_tables(&self, owners: &[Felt]) -> DojoToriiResult> { let (table_query, table_args) = select_table_query(owners); let rows = sqlx::query_as_with::(&table_query, table_args) .fetch_all(self.pool()) - .await?; + .await + .map_err(DojoToriiError::store_error)?; let mut tables = rows .into_iter() .map(table_row_into_table) - .collect::, _>>()?; + .collect::, _>>() + .map_err(DojoToriiError::store_error)?; let (column_query, column_args) = select_column_query(owners); let mut columns: HashMap<(Felt, Felt), ColumnInfo> = sqlx::query_as_with::(&column_query, column_args) .fetch_all(self.pool()) - .await? + .await + .map_err(DojoToriiError::store_error)? .into_iter() .map(column_row_into_entry::<(Felt, Felt)>) - .collect::, _>>()?; + .collect::, _>>() + .map_err(DojoToriiError::store_error)?; for table in &mut tables { for key in table.key_fields.iter().chain(table.value_fields.iter()) { - let column = columns.remove(&(table.id, *key)).ok_or_else(|| { - DojoSqliteStoreError::column_not_found(table.name.clone(), &(table.id, *key)) - })?; + let column = columns + .remove(&(table.id, *key)) + .ok_or_else(|| DojoToriiError::ColumnNotFound(table.name.clone(), *key))?; table.columns.insert(*key, column); } } diff --git a/crates/dojo/src/table.rs b/crates/dojo/src/table.rs index 05048a88..674f4808 100644 --- a/crates/dojo/src/table.rs +++ b/crates/dojo/src/table.rs @@ -178,7 +178,7 @@ impl DojoTable { pub fn get_column(&self, selector: &Felt) -> DojoToriiResult<&ColumnInfo> { self.columns .get(selector) - .ok_or_else(|| DojoToriiError::ColumnNotFound(*selector, self.name.clone())) + .ok_or_else(|| DojoToriiError::ColumnNotFound(self.name.clone(), *selector)) } pub fn selectors(&self) -> impl Iterator + '_ { @@ -270,7 +270,7 @@ impl DojoTableInfo { pub fn get_column(&self, selector: &Felt) -> DojoToriiResult<&ColumnInfo> { self.columns .get(selector) - .ok_or_else(|| DojoToriiError::ColumnNotFound(*selector, self.name.clone())) + .ok_or_else(|| DojoToriiError::ColumnNotFound(self.name.clone(), *selector)) } pub fn selectors(&self) -> impl Iterator + '_ { diff --git a/crates/introspect-sql-sink/src/backend.rs b/crates/introspect-sql-sink/src/backend.rs index 1435753c..1d49e1e3 100644 --- a/crates/introspect-sql-sink/src/backend.rs +++ b/crates/introspect-sql-sink/src/backend.rs @@ -4,12 +4,12 @@ use crate::tables::Tables; use crate::{DbResult, NamespaceMode, RecordResult, TableResult}; use async_trait::async_trait; use introspect_types::{ColumnDef, PrimaryDef}; -use sqlx::Database; +use sqlx::{Database, Pool}; use starknet_types_core::felt::Felt; use torii_introspect::events::IntrospectBody; use torii_introspect::tables::RecordSchema; use torii_introspect::Record; -use torii_sql::{DbPool, Executable, FlexQuery}; +use torii_sql::{Executable, FlexQuery, PoolExt}; #[async_trait] pub trait IntrospectProcessor { @@ -32,8 +32,7 @@ pub trait IntrospectInitialize { ) -> DbResult>; } -pub trait IntrospectQueryMaker: DbPool { - type DB: Database; +pub trait IntrospectQueryMaker: Database { fn create_table_queries( namespace: &str, id: &Felt, @@ -43,7 +42,7 @@ pub trait IntrospectQueryMaker: DbPool { from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> TableResult<()>; fn update_table_queries( table: &mut Table, @@ -53,7 +52,7 @@ pub trait IntrospectQueryMaker: DbPool { from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> TableResult<()>; fn insert_record_queries( namespace: &str, @@ -63,18 +62,18 @@ pub trait IntrospectQueryMaker: DbPool { from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> RecordResult<()>; - fn msgs_to_queries( + fn msgs_to_queries( tables: &Tables, namespaces: &NamespaceMode, msgs: Vec<&IntrospectBody>, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult>> { let mut results = Vec::with_capacity(msgs.len()); for body in msgs { let (msg, metadata) = body.into(); - results.push(tables.handle_message::( + results.push(tables.handle_message::( namespaces.to_namespace(&metadata.from_address)?, msg, &metadata.from_address, @@ -88,8 +87,8 @@ pub trait IntrospectQueryMaker: DbPool { } #[async_trait] -pub trait IntrospectExecutor: IntrospectQueryMaker + Sized { - async fn process_queries(&self, queries: Vec>) -> DbResult<()>; +pub trait IntrospectPool { + async fn process_queries(&self, queries: Vec>) -> DbResult<()>; async fn execute_msgs( &self, tables: &Tables, @@ -97,18 +96,18 @@ pub trait IntrospectExecutor: IntrospectQueryMaker + Sized { msgs: Vec<&IntrospectBody>, ) -> DbResult>> { let mut queries = Vec::new(); - let results = Self::msgs_to_queries::(tables, namespaces, msgs, &mut queries)?; + let results = DB::msgs_to_queries(tables, namespaces, msgs, &mut queries)?; self.process_queries(queries).await?; Ok(results) } } #[async_trait] -impl IntrospectExecutor for Backend +impl IntrospectPool for Pool where - Vec>: Executable, + Vec>: Executable, { - async fn process_queries(&self, queries: Vec>) -> DbResult<()> { + async fn process_queries(&self, queries: Vec>) -> DbResult<()> { let mut batch = Vec::new(); for query in queries { if query == *COMMIT_CMD { diff --git a/crates/introspect-sql-sink/src/error.rs b/crates/introspect-sql-sink/src/error.rs index eee542e9..f4e98f05 100644 --- a/crates/introspect-sql-sink/src/error.rs +++ b/crates/introspect-sql-sink/src/error.rs @@ -162,7 +162,7 @@ pub enum DbError { FeltFromStrError(#[from] FromStrError), } -pub type DbResult = std::result::Result; +pub type DbResult = std::result::Result; impl From> for DbError { fn from(err: PoisonError) -> Self { diff --git a/crates/introspect-sql-sink/src/lib.rs b/crates/introspect-sql-sink/src/lib.rs index 1553b8de..249898a0 100644 --- a/crates/introspect-sql-sink/src/lib.rs +++ b/crates/introspect-sql-sink/src/lib.rs @@ -19,12 +19,12 @@ pub use table::{DeadField, DeadFieldDef, Table}; #[cfg(feature = "postgres")] pub mod postgres; #[cfg(feature = "postgres")] -pub use postgres::{IntrospectPgDb, PostgresBackend}; +pub use postgres::IntrospectPgDb; #[cfg(feature = "sqlite")] pub mod sqlite; #[cfg(feature = "sqlite")] -pub use sqlite::{IntrospectSqliteDb, SqliteBackend}; +pub use sqlite::IntrospectSqliteDb; #[cfg(feature = "postgres")] #[cfg(feature = "sqlite")] diff --git a/crates/introspect-sql-sink/src/postgres/backend.rs b/crates/introspect-sql-sink/src/postgres/backend.rs index 3fb9d4b7..2016ef4f 100644 --- a/crates/introspect-sql-sink/src/postgres/backend.rs +++ b/crates/introspect-sql-sink/src/postgres/backend.rs @@ -11,28 +11,27 @@ use introspect_types::{ColumnDef, FeltIds, PrimaryDef}; use starknet_types_core::felt::Felt; use torii_introspect::tables::RecordSchema; use torii_introspect::Record; -use torii_sql::{DbPool, PgPool, PgQuery, Postgres}; +use torii_sql::{PgPool, PgQuery, Postgres}; -pub type IntrospectPgDb = IntrospectDb; +pub type IntrospectPgDb = IntrospectDb; -pub struct PostgresBackend(PgPool); +// #[derive(Clone)] +// pub struct PostgresBackend(PgPool); -impl From for PostgresBackend { - fn from(value: PgPool) -> Self { - PostgresBackend(value) - } -} +// impl From for PostgresBackend { +// fn from(value: PgPool) -> Self { +// PostgresBackend(value) +// } +// } -impl DbPool for PostgresBackend { - fn pool(&self) -> &PgPool { - &self.0 - } -} +// impl DbConnection for PostgresBackend { +// fn pool(&self) -> &PgPool { +// &self.0 +// } +// } #[async_trait] -impl IntrospectQueryMaker for PostgresBackend { - type DB = Postgres; - +impl IntrospectQueryMaker for Postgres { fn create_table_queries( namespace: &str, id: &Felt, @@ -140,6 +139,6 @@ where Ok(()) } -impl IntrospectSqlSink for PostgresBackend { +impl IntrospectSqlSink for PgPool { const NAME: &'static str = "Introspect Postgres"; } diff --git a/crates/introspect-sql-sink/src/postgres/handler.rs b/crates/introspect-sql-sink/src/postgres/handler.rs index e4733efd..c445a50c 100644 --- a/crates/introspect-sql-sink/src/postgres/handler.rs +++ b/crates/introspect-sql-sink/src/postgres/handler.rs @@ -1,16 +1,16 @@ use super::query::{fetch_columns, fetch_dead_fields, fetch_tables}; -use super::PostgresBackend; use crate::backend::IntrospectInitialize; use crate::{DbColumn, DbDeadField, DbResult, DbTable}; use async_trait::async_trait; use introspect_types::ResultInto; -use torii_sql::DbPool; +use sqlx::PgPool; +use torii_sql::PoolExt; pub const INTROSPECT_PG_SINK_MIGRATIONS: sqlx::migrate::Migrator = sqlx::migrate!("./migrations/postgres"); #[async_trait] -impl IntrospectInitialize for PostgresBackend { +impl IntrospectInitialize for PgPool { async fn load_tables(&self, schemas: &Option>) -> DbResult> { fetch_tables(self.pool(), schemas).await.err_into() } diff --git a/crates/introspect-sql-sink/src/postgres/mod.rs b/crates/introspect-sql-sink/src/postgres/mod.rs index bb7c4684..d9d75201 100644 --- a/crates/introspect-sql-sink/src/postgres/mod.rs +++ b/crates/introspect-sql-sink/src/postgres/mod.rs @@ -8,7 +8,7 @@ pub mod types; pub mod upgrade; pub mod utils; -pub use backend::{IntrospectPgDb, PostgresBackend}; +pub use backend::IntrospectPgDb; pub use types::{ PostgresArray, PostgresField, PostgresScalar, PostgresType, PrimaryKey, SchemaName, }; diff --git a/crates/introspect-sql-sink/src/processor.rs b/crates/introspect-sql-sink/src/processor.rs index 907eaf0f..e644a2a3 100644 --- a/crates/introspect-sql-sink/src/processor.rs +++ b/crates/introspect-sql-sink/src/processor.rs @@ -1,18 +1,16 @@ -use crate::backend::{ - IntrospectExecutor, IntrospectInitialize, IntrospectProcessor, IntrospectQueryMaker, -}; +use crate::backend::{IntrospectInitialize, IntrospectPool, IntrospectProcessor}; use crate::error::TableLoadError; use crate::table::{DeadField, Table}; use crate::tables::Tables; -use crate::{DbResult, NamespaceMode}; +use crate::{DbResult, IntrospectQueryMaker, NamespaceMode}; use async_trait::async_trait; use introspect_types::{ColumnInfo, PrimaryDef, TypeDef}; use itertools::Itertools; -use sqlx::Pool; +use sqlx::{Database, Pool}; use starknet_types_core::felt::Felt; use std::collections::HashMap; use torii_introspect::events::IntrospectBody; -use torii_sql::{DbPool, Executable, FlexQuery}; +use torii_sql::{Executable, FlexQuery, PoolExt}; pub const COMMIT_CMD: &str = "--COMMIT"; @@ -49,9 +47,9 @@ pub struct DbDeadField { pub type_def: TypeDef, } -impl DbPool for IntrospectDb { - fn pool(&self) -> &Pool { - self.db.pool() +impl PoolExt for IntrospectDb> { + fn pool(&self) -> &Pool { + &self.db } } @@ -70,9 +68,9 @@ where } #[async_trait] -impl IntrospectProcessor for Backend +impl IntrospectProcessor for Pool where - Vec>: Executable, + Vec>: Executable, { async fn process_msgs( &self, @@ -85,11 +83,11 @@ where } impl IntrospectDb { - pub fn new(pool: impl Into, namespaces: impl Into) -> Self { + pub fn new(pool: Backend, namespaces: impl Into) -> Self { Self { tables: Tables::default(), namespaces: namespaces.into(), - db: pool.into(), + db: pool, } } } diff --git a/crates/introspect-sql-sink/src/runtime.rs b/crates/introspect-sql-sink/src/runtime.rs index 273c20d0..cc1979b1 100644 --- a/crates/introspect-sql-sink/src/runtime.rs +++ b/crates/introspect-sql-sink/src/runtime.rs @@ -1,36 +1,34 @@ -use crate::postgres::PostgresBackend; -use crate::sqlite::backend::SqliteBackend; use crate::tables::Tables; use crate::{ DbColumn, DbDeadField, DbResult, DbTable, IntrospectInitialize, IntrospectProcessor, - NamespaceMode, + IntrospectSqlSink, NamespaceMode, }; use async_trait::async_trait; use torii_introspect::events::IntrospectBody; +use torii_sql::DbPool; -pub enum RuntimeBackend { - Postgres(PostgresBackend), - Sqlite(SqliteBackend), +impl IntrospectSqlSink for DbPool { + const NAME: &'static str = "introspect-sql"; } #[async_trait] -impl IntrospectInitialize for RuntimeBackend { - async fn initialize(&self) -> DbResult<()> { +impl IntrospectInitialize for DbPool { + async fn initialize(&self) -> DbResult { match self { - RuntimeBackend::Postgres(pg) => pg.initialize().await, - RuntimeBackend::Sqlite(site) => site.initialize().await, + DbPool::Postgres(pg) => pg.initialize().await, + DbPool::Sqlite(site) => site.initialize().await, } } async fn load_tables(&self, namespaces: &Option>) -> DbResult> { match self { - RuntimeBackend::Postgres(pg) => pg.load_tables(namespaces).await, - RuntimeBackend::Sqlite(site) => site.load_tables(namespaces).await, + DbPool::Postgres(pg) => pg.load_tables(namespaces).await, + DbPool::Sqlite(site) => site.load_tables(namespaces).await, } } async fn load_columns(&self, namespaces: &Option>) -> DbResult> { match self { - RuntimeBackend::Postgres(pg) => pg.load_columns(namespaces).await, - RuntimeBackend::Sqlite(site) => site.load_columns(namespaces).await, + DbPool::Postgres(pg) => pg.load_columns(namespaces).await, + DbPool::Sqlite(site) => site.load_columns(namespaces).await, } } async fn load_dead_fields( @@ -38,14 +36,14 @@ impl IntrospectInitialize for RuntimeBackend { namespaces: &Option>, ) -> DbResult> { match self { - RuntimeBackend::Postgres(pg) => pg.load_dead_fields(namespaces).await, - RuntimeBackend::Sqlite(site) => site.load_dead_fields(namespaces).await, + DbPool::Postgres(pg) => pg.load_dead_fields(namespaces).await, + DbPool::Sqlite(site) => site.load_dead_fields(namespaces).await, } } } #[async_trait] -impl IntrospectProcessor for RuntimeBackend { +impl IntrospectProcessor for DbPool { async fn process_msgs( &self, tables: &Tables, @@ -53,20 +51,8 @@ impl IntrospectProcessor for RuntimeBackend { msgs: Vec<&IntrospectBody>, ) -> DbResult>> { match self { - RuntimeBackend::Postgres(pg) => pg.process_msgs(tables, namespaces, msgs).await, - RuntimeBackend::Sqlite(site) => site.process_msgs(tables, namespaces, msgs).await, + DbPool::Postgres(pg) => pg.process_msgs(tables, namespaces, msgs).await, + DbPool::Sqlite(site) => site.process_msgs(tables, namespaces, msgs).await, } } } - -impl From for RuntimeBackend { - fn from(pg: PostgresBackend) -> Self { - RuntimeBackend::Postgres(pg) - } -} - -impl From for RuntimeBackend { - fn from(site: SqliteBackend) -> Self { - RuntimeBackend::Sqlite(site) - } -} diff --git a/crates/introspect-sql-sink/src/sqlite/backend.rs b/crates/introspect-sql-sink/src/sqlite/backend.rs index 24e00e70..14d29ce8 100644 --- a/crates/introspect-sql-sink/src/sqlite/backend.rs +++ b/crates/introspect-sql-sink/src/sqlite/backend.rs @@ -1,7 +1,7 @@ use crate::sqlite::record::{coalesce_sql, SqliteDeserializer}; use crate::sqlite::table::{ create_table_query, persist_table_state_query, qualified_table_name, update_column, - update_column_query, ColumnInfoRef, FETCH_TABLES_QUERY, + update_columns, FETCH_TABLES_QUERY, }; use crate::sqlite::types::SqliteColumn; use crate::{ @@ -20,37 +20,15 @@ use sqlx::Arguments; use sqlx::Error::Encode as EncodeError; use starknet_types_core::felt::{Felt, FromStrError}; use std::collections::HashMap; -use std::ops::Deref; use std::sync::Arc; use torii_introspect::tables::RecordSchema; use torii_introspect::Record; -use torii_sql::{DbPool, Queries, Sqlite, SqliteArguments, SqlitePool, SqliteQuery}; +use torii_sql::{PoolExt, Queries, Sqlite, SqliteArguments, SqlitePool, SqliteQuery}; pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: sqlx::migrate::Migrator = sqlx::migrate!("./migrations/sqlite"); -pub type IntrospectSqliteDb = IntrospectDb; - -pub struct SqliteBackend(SqlitePool); - -impl Deref for SqliteBackend { - type Target = SqlitePool; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl From for SqliteBackend { - fn from(value: SqlitePool) -> Self { - SqliteBackend(value) - } -} - -impl DbPool for SqliteBackend { - fn pool(&self) -> &SqlitePool { - &self.0 - } -} +pub type IntrospectSqliteDb = IntrospectDb; #[derive(FromRow)] pub struct SqliteTableRow { @@ -80,8 +58,7 @@ impl TryFrom for DbTable { } #[async_trait] -impl IntrospectQueryMaker for SqliteBackend { - type DB = Sqlite; +impl IntrospectQueryMaker for Sqlite { fn create_table_queries( namespace: &str, id: &Felt, @@ -99,7 +76,7 @@ impl IntrospectQueryMaker for SqliteBackend { id, name, primary, - columns.iter().map(ColumnInfoRef::from_def).collect(), + columns, from_address, block_number, transaction_hash, @@ -131,14 +108,19 @@ impl IntrospectQueryMaker for SqliteBackend { &((&primary.type_def).into()), queries, ) - .to_table_result(&table_name, "primary"); - // let mut all_columns = table.columns.iter().map(ColumnInfoRef::from_info).collect(); - // for column in columns{ - // match all_columns.get_mut(&column.id){ - // Some(mut existing) - // } - // } - Ok(()) + .to_table_result(&table_name, "primary")?; + update_columns(&mut table.columns, &table_name, columns, queries)?; + persist_table_state_query( + &table.namespace, + &table.id, + &table.name, + primary, + &table.columns.iter().collect_vec(), + from_address, + block_number, + transaction_hash, + queries, + ) } fn insert_record_queries( namespace: &str, @@ -197,12 +179,12 @@ impl IntrospectQueryMaker for SqliteBackend { } } -impl IntrospectSqlSink for SqliteBackend { +impl IntrospectSqlSink for SqlitePool { const NAME: &'static str = "Introspect Sqlite"; } #[async_trait] -impl IntrospectInitialize for SqliteBackend { +impl IntrospectInitialize for SqlitePool { async fn load_tables(&self, _schemas: &Option>) -> DbResult> { let rows: Vec = sqlx::query_as(FETCH_TABLES_QUERY) .fetch_all(self.pool()) diff --git a/crates/introspect-sql-sink/src/sqlite/json.rs b/crates/introspect-sql-sink/src/sqlite/json.rs index 3b7c28d8..7cf2f75b 100644 --- a/crates/introspect-sql-sink/src/sqlite/json.rs +++ b/crates/introspect-sql-sink/src/sqlite/json.rs @@ -2,7 +2,7 @@ use introspect_types::serialize::ToCairoDeSeFrom; use introspect_types::serialize_def::CairoTypeSerialization; use introspect_types::{CairoDeserializer, ResultDef, TupleDef, TypeDef}; use primitive_types::{U256, U512}; -use serde::ser::SerializeMap; +use serde::ser::{SerializeMap, SerializeTuple}; use serde::Serializer; pub struct SqliteJsonSerializer; @@ -54,9 +54,9 @@ impl CairoTypeSerialization for SqliteJsonSerializer { serializer: S, tuple: &'a TupleDef, ) -> Result { - let mut seq = serializer.serialize_map(Some(tuple.elements.len()))?; - for (index, element) in tuple.elements.iter().enumerate() { - seq.serialize_entry(&format!("_{index}"), &element.to_de_se(data, self))?; + let mut seq = serializer.serialize_tuple(tuple.elements.len())?; + for element in tuple.elements.iter() { + seq.serialize_element(&element.to_de_se(data, self))?; } seq.end() } diff --git a/crates/introspect-sql-sink/src/sqlite/mod.rs b/crates/introspect-sql-sink/src/sqlite/mod.rs index acbee860..036ed176 100644 --- a/crates/introspect-sql-sink/src/sqlite/mod.rs +++ b/crates/introspect-sql-sink/src/sqlite/mod.rs @@ -6,6 +6,6 @@ pub mod types; use sqlx::migrate::Migrator; -pub use backend::{IntrospectSqliteDb, SqliteBackend}; +pub use backend::IntrospectSqliteDb; pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: Migrator = sqlx::migrate!("./migrations/sqlite"); diff --git a/crates/introspect-sql-sink/src/sqlite/record.rs b/crates/introspect-sql-sink/src/sqlite/record.rs index 8e9ffe7b..d530e3c6 100644 --- a/crates/introspect-sql-sink/src/sqlite/record.rs +++ b/crates/introspect-sql-sink/src/sqlite/record.rs @@ -13,9 +13,13 @@ pub fn coalesce_sql<'a>(table_name: &str, column: &SqliteColumn<'a>) -> String { let column_name = column.name; match column.sql_type { SqliteType::Json => { - format!(r#"COALESCE(jsonb(excluded."{column_name}"), "{table_name}"."{column_name}")"#) + format!( + r#""{column_name}" = COALESCE(jsonb(excluded."{column_name}"), "{table_name}"."{column_name}")"# + ) } - _ => format!(r#"COALESCE(excluded."{column_name}", "{table_name}"."{column_name}")"#), + _ => format!( + r#""{column_name}" = COALESCE(excluded."{column_name}", "{table_name}"."{column_name}")"# + ), } } diff --git a/crates/introspect-sql-sink/src/sqlite/sink.rs b/crates/introspect-sql-sink/src/sqlite/sink.rs deleted file mode 100644 index 04202874..00000000 --- a/crates/introspect-sql-sink/src/sqlite/sink.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::processor::IntrospectSqliteDb; -use anyhow::Result; -use async_trait::async_trait; -use sqlx::Sqlite; -use std::sync::Arc; -use torii::axum::Router; -use torii::etl::envelope::{Envelope, TypeId}; -use torii::etl::extractor::ExtractionBatch; -use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; -use torii_introspect::events::{IntrospectBody, IntrospectMsg}; -use torii_sql::DbConnection; - -pub const LOGGING_TARGET: &str = "torii::sinks::introspect::sqlite"; -const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); - -#[async_trait] -impl> Sink for IntrospectSqliteDb { - fn name(&self) -> &'static str { - "introspect-sqlite" - } - - fn interested_types(&self) -> Vec { - vec![TypeId::new("introspect")] - } - - async fn process(&self, envelopes: &[Envelope], _batch: &ExtractionBatch) -> Result<()> { - let mut processed = 0usize; - let mut create_tables = 0usize; - let mut update_tables = 0usize; - let mut inserts_fields = 0usize; - let mut inserted_records = 0usize; - let mut delete_records = 0usize; - let mut msgs = Vec::with_capacity(envelopes.len()); - for envelope in envelopes { - if envelope.type_id == INTROSPECT_TYPE { - if let Some(body) = envelope.downcast_ref::() { - match &body.msg { - IntrospectMsg::CreateTable(_) => create_tables += 1, - IntrospectMsg::UpdateTable(_) => update_tables += 1, - IntrospectMsg::InsertsFields(event) => { - inserts_fields += 1; - inserted_records += event.records.len(); - } - IntrospectMsg::DeleteRecords(event) => { - delete_records += event.rows.len(); - } - _ => {} - } - processed += 1; - msgs.push(body); - } - } - } - let results = self.process_messages(msgs).await?; - let failed = results.iter().filter(|r| r.is_err()).count(); - if failed > 0 { - tracing::error!( - target: LOGGING_TARGET, - failed, - total = results.len(), - "Introspect messages failed — data may be missing from SQL tables" - ); - } - - if processed > 0 { - tracing::info!( - target: LOGGING_TARGET, - processed, - create_tables, - update_tables, - inserts_fields, - inserted_records, - delete_records, - "Processed introspect envelopes" - ); - ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "create_table") - .increment(create_tables as u64); - ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "update_table") - .increment(update_tables as u64); - ::metrics::counter!("torii_introspect_sink_messages_total", "message" => "inserts_fields") - .increment(inserts_fields as u64); - ::metrics::counter!("torii_introspect_sink_records_total", "message" => "inserts_fields") - .increment(inserted_records as u64); - ::metrics::counter!("torii_introspect_sink_records_total", "message" => "delete_records") - .increment(delete_records as u64); - } - - Ok(()) - } - - fn topics(&self) -> Vec { - Vec::new() - } - - fn build_routes(&self) -> Router { - Router::new() - } - - async fn initialize( - &mut self, - _event_bus: Arc, - _context: &SinkContext, - ) -> Result<()> { - self.initialize_introspect_sqlite_sink().await?; - tracing::info!( - target: LOGGING_TARGET, - "Initialized introspect SQLite sink" - ); - Ok(()) - } -} diff --git a/crates/introspect-sql-sink/src/sqlite/table.rs b/crates/introspect-sql-sink/src/sqlite/table.rs index af4f4a58..aad3262f 100644 --- a/crates/introspect-sql-sink/src/sqlite/table.rs +++ b/crates/introspect-sql-sink/src/sqlite/table.rs @@ -1,8 +1,9 @@ use crate::sqlite::types::SqliteType; -use crate::{TableResult, UpgradeError, UpgradeResult}; -use introspect_types::{Attribute, ColumnDef, ColumnInfo, PrimaryDef, TypeDef}; +use crate::{TableResult, UpgradeError, UpgradeResult, UpgradeResultExt}; +use introspect_types::schema::AsColumnRef; +use introspect_types::{ColumnDef, ColumnInfo, PrimaryDef, TypeDef}; use serde::ser::SerializeMap; -use serde::{Serialize, Serializer}; +use serde::Serializer; use serde_json::{Result as JsonResult, Serializer as JsonSerializer}; use sqlx::Arguments; use starknet_types_core::felt::Felt; @@ -19,9 +20,9 @@ pub const FETCH_TABLES_QUERY: &str = r#" const INSERT_TABLE_QUERY: &str = r#" INSERT INTO introspect_db_tables (namespace, id, owner, name, "primary", columns, updated_at) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, unixepoch()) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, unixepoch()) ON CONFLICT (namespace, id) DO UPDATE SET - owner = excluded.owner, name = excluded.name, "primary" = excluded."primary", columns = excluded.columns, dead = excluded.dead, alive = excluded.alive, updated_at = unixepoch() + owner = excluded.owner, name = excluded.name, "primary" = excluded."primary", columns = excluded.columns, updated_at = unixepoch() "#; struct TableName<'a>(&'a str, &'a str); @@ -43,13 +44,13 @@ pub fn qualified_table_name(namespace: &str, table_name: &str) -> String { } } -pub fn serialize_columns<'a>(columns: Vec>>) -> JsonResult { +pub fn serialize_columns<'a>(columns: &'a [impl AsColumnRef<'a>]) -> JsonResult { let mut data = Vec::new(); let mut serializer = JsonSerializer::new(&mut data); let mut array = serializer.serialize_map(Some(columns.len()))?; for column in columns { - let column_ref: ColumnDefRef = column.into(); - array.serialize_entry(column_ref.id, &column_ref)?; + let (id, info) = column.as_entry(); + array.serialize_entry(id, &info)?; } array.end()?; Ok(unsafe { String::from_utf8_unchecked(data) }) @@ -60,7 +61,7 @@ pub fn persist_table_state_query<'a>( id: &Felt, name: &str, primary: &PrimaryDef, - columns: &[impl Into>], + columns: &'a [impl AsColumnRef<'a>], from_address: &Felt, _block_number: u64, _transaction_hash: &Felt, @@ -104,18 +105,15 @@ pub fn update_columns( queries: &mut Vec, ) -> TableResult<()> { for column in new { - match columns.get_mut(&column.id) { - Some(existing) => { - update_column( - table_name, - existing, - &column.name, - &column.type_def, - queries, - )?; - } + let result = match columns.get_mut(&column.id) { + Some(existing) => update_column( + table_name, + existing, + &column.name, + &column.type_def, + queries, + ), None => { - queries.add(create_column_query(table_name, column)?); columns.insert( column.id, ColumnInfo { @@ -124,8 +122,10 @@ pub fn update_columns( attributes: column.attributes.clone(), }, ); + create_column_query(table_name, column).map(|query| queries.add(query)) } - } + }; + result.to_table_result(table_name, &column.name)?; } Ok(()) } @@ -191,7 +191,7 @@ pub fn update_column( Ok(()) } -pub fn create_column_query(table_name: &str, column: &ColumnDef) -> TableResult { +pub fn create_column_query(table_name: &str, column: &ColumnDef) -> UpgradeResult { let sql_type: SqliteType = column.try_into()?; Ok(format!( r#"ALTER TABLE "{table_name}" ADD COLUMN "{}" {sql_type};"#, diff --git a/crates/introspect-sql-sink/src/tables.rs b/crates/introspect-sql-sink/src/tables.rs index b25f157e..71a5cac1 100644 --- a/crates/introspect-sql-sink/src/tables.rs +++ b/crates/introspect-sql-sink/src/tables.rs @@ -25,21 +25,21 @@ impl Deref for Tables { } impl Tables { - pub fn create_table( + pub fn create_table( &self, namespace_key: NamespaceKey, to_table: impl Into, from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult<()> { let (id, info) = Into::::into(to_table).into(); let namespace = namespace_key.to_string(); let key = TableKey::new(namespace_key, id); self.assert_table_not_exists(&key, &info.name)?; - Backend::create_table_queries( + DB::create_table_queries( &namespace, &id, &info.name, @@ -55,14 +55,14 @@ impl Tables { Ok(()) } - pub fn update_table( + pub fn update_table( &self, namespace_key: NamespaceKey, to_table: impl Into, from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult<()> { let (id, new) = Into::::into(to_table).into(); let mut tables = self.write()?; @@ -70,7 +70,7 @@ impl Tables { let table = tables .get_mut(&key) .ok_or_else(|| DbError::TableNotFound(key.clone()))?; - Backend::update_table_queries( + DB::update_table_queries( table, &new.name, &new.primary, @@ -106,14 +106,14 @@ impl Tables { } } - pub fn insert_fields( + pub fn insert_fields( &self, namespace: NamespaceKey, event: &InsertsFields, from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult<()> { let tables = self.read().unwrap(); let key = TableKey::new(namespace, event.table); @@ -125,7 +125,7 @@ impl Tables { return Ok(()); } let schema = table.get_record_schema(&event.columns)?; - Backend::insert_record_queries( + DB::insert_record_queries( &table.namespace, &table.name, &schema, @@ -138,17 +138,17 @@ impl Tables { .to_db_result(&table.name) } - pub fn handle_message( + pub fn handle_message( &self, namespace: NamespaceKey, msg: &IntrospectMsg, from_address: &Felt, block_number: u64, transaction_hash: &Felt, - queries: &mut Vec>, + queries: &mut Vec>, ) -> DbResult<()> { match msg { - IntrospectMsg::CreateTable(event) => self.create_table::( + IntrospectMsg::CreateTable(event) => self.create_table::( namespace, event.clone(), from_address, @@ -156,7 +156,7 @@ impl Tables { transaction_hash, queries, ), - IntrospectMsg::UpdateTable(event) => self.update_table::( + IntrospectMsg::UpdateTable(event) => self.update_table::( namespace, event.clone(), from_address, @@ -172,7 +172,7 @@ impl Tables { | IntrospectMsg::DropTable(_) | IntrospectMsg::RenameColumns(_) | IntrospectMsg::RenamePrimary(_) => Ok(()), - IntrospectMsg::InsertsFields(event) => self.insert_fields::( + IntrospectMsg::InsertsFields(event) => self.insert_fields::( namespace, event, from_address, diff --git a/crates/sql/Cargo.toml b/crates/sql/Cargo.toml index 2e5717ff..6197320b 100644 --- a/crates/sql/Cargo.toml +++ b/crates/sql/Cargo.toml @@ -11,6 +11,7 @@ itertools.workspace = true futures.workspace = true crc.workspace = true starknet-types-core.workspace = true +log.workspace = true [features] postgres = ["sqlx/postgres"] diff --git a/crates/sql/src/connection.rs b/crates/sql/src/connection.rs index ec494591..c5c2d292 100644 --- a/crates/sql/src/connection.rs +++ b/crates/sql/src/connection.rs @@ -1,11 +1,26 @@ use crate::query::Executable; use crate::{AcquiredSchema, SqlxResult}; use async_trait::async_trait; +use log::LevelFilter; use sqlx::migrate::{Migrate, Migrator}; +use sqlx::pool::PoolOptions; use sqlx::{Database, Pool, Transaction}; +use std::fmt::Display; +use std::time::Duration; + +const DEFAULT_TEST_BEFORE_ACQUIRE: bool = true; +const DEFAULT_MAX_CONNECTIONS: u32 = 10; +const DEFAULT_MIN_CONNECTIONS: u32 = 0; +const DEFAULT_ACQUIRE_TIME_LEVEL: LevelFilter = LevelFilter::Off; +const DEFAULT_ACQUIRE_SLOW_LEVEL: LevelFilter = LevelFilter::Warn; +const DEFAULT_ACQUIRE_SLOW_THRESHOLD: Duration = Duration::from_secs(2); +const DEFAULT_ACQUIRE_TIMEOUT: Duration = Duration::from_secs(30); +const DEFAULT_IDLE_TIMEOUT: Option = Some(Duration::from_secs(10 * 60)); +const DEFAULT_MAX_LIFETIME: Option = Some(Duration::from_secs(30 * 60)); +const DEFAULT_FAIR: bool = true; #[async_trait] -pub trait DbPool { +pub trait PoolExt { fn pool(&self) -> &Pool; async fn begin(&self) -> SqlxResult> { Ok(self.pool().begin().await?) @@ -34,28 +49,294 @@ pub trait DbPool { } } -#[async_trait] -impl DbPool for Pool { +impl PoolExt for Pool { fn pool(&self) -> &Pool { self } } -pub enum DbConn { +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DbType { Postgres, Sqlite, } -// #[async_trait] -// pub trait Committable { -// async fn commit(self, pool: &Pool) -> SqlxResult<()>; -// } +impl Display for DbType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + DbType::Postgres => write!(f, "PostgreSQL"), + DbType::Sqlite => write!(f, "SQLite"), + } + } +} + +impl DbType { + pub fn from_url(url: &str) -> Option { + if url.starts_with("postgres") || url.starts_with("postgresql") { + Some(DbType::Postgres) + } else if url.starts_with("sqlite") || url == ":memory:" || url == "memory" { + Some(DbType::Sqlite) + } else { + None + } + } +} + +impl TryFrom<&str> for DbType { + type Error = String; + + fn try_from(value: &str) -> Result { + DbType::from_url(value).ok_or_else(|| { + format!( + "Unsupported database type in connection string: {value}. Supported types are PostgreSQL and SQLite." + ) + }) + } +} + +impl TryFrom for DbType { + type Error = String; + + fn try_from(value: String) -> Result { + DbType::try_from(value.as_str()) + } +} + +#[derive(Debug, Clone, Copy)] +pub struct DbPoolOptions { + pub test_before_acquire: bool, + pub max_connections: u32, + pub acquire_time_level: LevelFilter, + pub acquire_slow_level: LevelFilter, + pub acquire_slow_threshold: Duration, + pub acquire_timeout: Duration, + pub min_connections: u32, + pub max_lifetime: Option, + pub idle_timeout: Option, + pub fair: bool, +} + +#[derive(Debug, Clone)] +pub struct PoolConfig { + pub url: String, + pub options: DbPoolOptions, +} + +impl PoolConfig { + pub fn new(url: String) -> Self { + Self { + url, + options: DbPoolOptions::new(), + } + } + pub async fn connect(&self) -> SqlxResult> { + self.options.connect(&self.url).await + } + pub fn options(&self) -> PoolOptions { + self.options.options() + } + pub fn max_connections(mut self, max: u32) -> Self { + self.options.max_connections = max; + self + } + + pub fn get_max_connections(&self) -> u32 { + self.options.max_connections + } + + pub fn min_connections(mut self, min: u32) -> Self { + self.options.min_connections = min; + self + } + + pub fn get_min_connections(&self) -> u32 { + self.options.min_connections + } + + pub fn acquire_time_level(mut self, level: LevelFilter) -> Self { + self.options.acquire_time_level = level; + self + } + + pub fn acquire_slow_level(mut self, level: LevelFilter) -> Self { + self.options.acquire_slow_level = level; + self + } + + pub fn acquire_slow_threshold(mut self, threshold: Duration) -> Self { + self.options.acquire_slow_threshold = threshold; + self + } + + pub fn get_acquire_slow_threshold(&self) -> Duration { + self.options.acquire_slow_threshold + } + + pub fn acquire_timeout(mut self, timeout: Duration) -> Self { + self.options.acquire_timeout = timeout; + self + } + + pub fn get_acquire_timeout(&self) -> Duration { + self.options.acquire_timeout + } + + pub fn max_lifetime(mut self, lifetime: impl Into>) -> Self { + self.options.max_lifetime = lifetime.into(); + self + } + + pub fn get_max_lifetime(&self) -> Option { + self.options.max_lifetime + } + + pub fn idle_timeout(mut self, timeout: impl Into>) -> Self { + self.options.idle_timeout = timeout.into(); + self + } + + pub fn get_idle_timeout(&self) -> Option { + self.options.idle_timeout + } + + pub fn test_before_acquire(mut self, test: bool) -> Self { + self.options.test_before_acquire = test; + self + } + + pub fn get_test_before_acquire(&self) -> bool { + self.options.test_before_acquire + } + + pub fn fair(mut self, fair: bool) -> Self { + self.options.fair = fair; + self + } + + pub fn get_fair(&self) -> bool { + self.options.fair + } +} + +impl Default for DbPoolOptions { + fn default() -> Self { + DbPoolOptions::new() + } +} + +impl DbPoolOptions { + pub fn new() -> Self { + Self { + test_before_acquire: DEFAULT_TEST_BEFORE_ACQUIRE, + max_connections: DEFAULT_MAX_CONNECTIONS, + acquire_time_level: DEFAULT_ACQUIRE_TIME_LEVEL, + acquire_slow_level: DEFAULT_ACQUIRE_SLOW_LEVEL, + acquire_slow_threshold: DEFAULT_ACQUIRE_SLOW_THRESHOLD, + acquire_timeout: DEFAULT_ACQUIRE_TIMEOUT, + min_connections: DEFAULT_MIN_CONNECTIONS, + max_lifetime: DEFAULT_MAX_LIFETIME, + idle_timeout: DEFAULT_IDLE_TIMEOUT, + fair: DEFAULT_FAIR, + } + } + + pub async fn connect(&self, url: &str) -> SqlxResult> { + Ok(self.options::().connect(url).await?) + } + + pub fn options(&self) -> PoolOptions { + PoolOptions::::new() + .test_before_acquire(self.test_before_acquire) + .max_connections(self.max_connections) + .acquire_time_level(self.acquire_time_level) + .acquire_slow_level(self.acquire_slow_level) + .acquire_slow_threshold(self.acquire_slow_threshold) + .acquire_timeout(self.acquire_timeout) + .min_connections(self.min_connections) + .max_lifetime(self.max_lifetime) + .idle_timeout(self.idle_timeout) + .__fair(self.fair) + } + + pub fn max_connections(mut self, max: u32) -> Self { + self.max_connections = max; + self + } + + pub fn get_max_connections(&self) -> u32 { + self.max_connections + } + + pub fn min_connections(mut self, min: u32) -> Self { + self.min_connections = min; + self + } + + pub fn get_min_connections(&self) -> u32 { + self.min_connections + } + + pub fn acquire_time_level(mut self, level: LevelFilter) -> Self { + self.acquire_time_level = level; + self + } + + pub fn acquire_slow_level(mut self, level: LevelFilter) -> Self { + self.acquire_slow_level = level; + self + } + + pub fn acquire_slow_threshold(mut self, threshold: Duration) -> Self { + self.acquire_slow_threshold = threshold; + self + } + + pub fn get_acquire_slow_threshold(&self) -> Duration { + self.acquire_slow_threshold + } + + pub fn acquire_timeout(mut self, timeout: Duration) -> Self { + self.acquire_timeout = timeout; + self + } + + pub fn get_acquire_timeout(&self) -> Duration { + self.acquire_timeout + } + + pub fn max_lifetime(mut self, lifetime: impl Into>) -> Self { + self.max_lifetime = lifetime.into(); + self + } + + pub fn get_max_lifetime(&self) -> Option { + self.max_lifetime + } -// #[async_trait]y -// impl + Send> Committable for E { -// async fn commit(self, pool: &Pool) -> SqlxResult<()> { -// let mut transaction: Transaction<'_, DB> = pool.begin().await?; -// self.execute(&mut transaction).await?; -// transaction.commit().await -// } -// } + pub fn idle_timeout(mut self, timeout: impl Into>) -> Self { + self.idle_timeout = timeout.into(); + self + } + + pub fn get_idle_timeout(&self) -> Option { + self.idle_timeout + } + + pub fn test_before_acquire(mut self, test: bool) -> Self { + self.test_before_acquire = test; + self + } + + pub fn get_test_before_acquire(&self) -> bool { + self.test_before_acquire + } + + pub fn fair(mut self, fair: bool) -> Self { + self.fair = fair; + self + } + + pub fn get_fair(&self) -> bool { + self.fair + } +} diff --git a/crates/sql/src/lib.rs b/crates/sql/src/lib.rs index f586a529..b492eab8 100644 --- a/crates/sql/src/lib.rs +++ b/crates/sql/src/lib.rs @@ -3,12 +3,12 @@ pub mod migrate; pub mod query; pub mod types; -pub use connection::DbPool; +pub use connection::{DbPoolOptions, PoolConfig, PoolExt}; pub use migrate::{AcquiredSchema, SchemaMigrator}; pub use query::{Executable, FlexQuery, Queries}; pub use sqlx::Error as SqlxError; -pub type SqlxResult = std::result::Result; +pub type SqlxResult = std::result::Result; #[cfg(feature = "postgres")] pub mod postgres; @@ -20,5 +20,10 @@ pub mod sqlite; #[cfg(feature = "sqlite")] pub use sqlite::{Sqlite, SqliteArguments, SqliteDbConnection, SqlitePool, SqliteQuery}; -// #[cfg(feature = "mysql")] -// pub mod mysql; +#[cfg(feature = "postgres")] +#[cfg(feature = "sqlite")] +pub mod runtime; + +#[cfg(feature = "postgres")] +#[cfg(feature = "sqlite")] +pub use runtime::DbPool; diff --git a/crates/sql/src/postgres/mod.rs b/crates/sql/src/postgres/mod.rs index be509b4d..379307b3 100644 --- a/crates/sql/src/postgres/mod.rs +++ b/crates/sql/src/postgres/mod.rs @@ -10,7 +10,7 @@ use sqlx::{Executor, PgTransaction}; pub type PgQuery = crate::FlexQuery; -pub trait PgDbConnection: crate::DbPool {} +pub trait PgDbConnection: crate::PoolExt {} impl crate::PgDbConnection for T {} impl Executable for FlexQuery { diff --git a/crates/sql/src/query.rs b/crates/sql/src/query.rs index baeb0cd4..cd136034 100644 --- a/crates/sql/src/query.rs +++ b/crates/sql/src/query.rs @@ -2,6 +2,7 @@ use crate::SqlxResult; use futures::future::BoxFuture; use itertools::Itertools; use sqlx::{Database, Executor, Transaction}; +use std::fmt::Display; use std::sync::Arc; pub trait Executable { @@ -70,12 +71,19 @@ where } } +#[derive(Debug, Clone)] pub enum FlexStr { Owned(String), Static(&'static str), Shared(Arc), } +impl Display for FlexStr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_ref().fmt(f) + } +} + impl FlexStr { pub fn as_str(&self) -> &str { match self { @@ -105,11 +113,36 @@ impl PartialEq for FlexStr { /// The per-database `Executable` impls handle the lifetime requirements: /// Postgres needs no special treatment; SQLite uses an unsafe lifetime extension /// that is sound because the `FlexStr` outlives the `.await` point. + pub struct FlexQuery { pub(crate) sql: FlexStr, pub(crate) args: Option<::Arguments<'static>>, } +impl Clone for FlexQuery +where + DB::Arguments<'static>: Clone, +{ + fn clone(&self) -> Self { + Self { + sql: self.sql.clone(), + args: self.args.clone(), + } + } +} + +impl std::fmt::Debug for FlexQuery +where + DB::Arguments<'static>: std::fmt::Debug, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("FlexQuery") + .field("sql", &self.sql) + .field("args", &self.args) + .finish() + } +} + impl FlexQuery { pub fn new(sql: impl Into, args: ::Arguments<'static>) -> Self { FlexQuery { @@ -264,3 +297,20 @@ where }) } } + +impl<'a, const N: usize, DB: Database, T> Executable for [T; N] +where + T: Executable + Send, +{ + fn execute<'t>(self, transaction: &'t mut Transaction<'_, DB>) -> BoxFuture<'t, SqlxResult<()>> + where + Self: 't, + { + Box::pin(async move { + for item in self { + item.execute(transaction).await?; + } + Ok(()) + }) + } +} diff --git a/crates/sql/src/runtime.rs b/crates/sql/src/runtime.rs new file mode 100644 index 00000000..5af8b69c --- /dev/null +++ b/crates/sql/src/runtime.rs @@ -0,0 +1,43 @@ +use crate::connection::DbType; +use crate::{DbPoolOptions, PoolConfig, SqlxError, SqlxResult}; +use sqlx::{Pool, Postgres, Sqlite}; + +#[derive(Clone)] +pub enum DbPool { + Postgres(Pool), + Sqlite(Pool), +} + +impl From<&str> for DbPool { + fn from(value: &str) -> Self { + match DbType::try_from(value) { + Ok(DbType::Postgres) => DbPool::Postgres( + Pool::::connect_lazy(value).expect("Failed to create Postgres pool"), + ), + Ok(DbType::Sqlite) => DbPool::Sqlite( + Pool::::connect_lazy(value).expect("Failed to create Sqlite pool"), + ), + Err(err) => panic!("Error parsing database connection string: {}", err), + } + } +} + +impl PoolConfig { + pub async fn connect_any(&self) -> SqlxResult { + match DbType::try_from(self.url.as_str()) { + Ok(DbType::Postgres) => self.connect::().await.map(DbPool::Postgres), + Ok(DbType::Sqlite) => self.connect::().await.map(DbPool::Sqlite), + Err(err) => Err(SqlxError::Configuration(err.into())), + } + } +} + +impl DbPoolOptions { + pub async fn connect_any(&self, url: &str) -> SqlxResult { + match DbType::try_from(url) { + Ok(DbType::Postgres) => self.connect::(url).await.map(DbPool::Postgres), + Ok(DbType::Sqlite) => self.connect::(url).await.map(DbPool::Sqlite), + Err(err) => Err(SqlxError::Configuration(err.into())), + } + } +} diff --git a/crates/sql/src/sqlite/mod.rs b/crates/sql/src/sqlite/mod.rs index ccf97c81..d797fb48 100644 --- a/crates/sql/src/sqlite/mod.rs +++ b/crates/sql/src/sqlite/mod.rs @@ -13,8 +13,8 @@ use crate::{Executable, SqlxResult}; pub type SqliteQuery = super::FlexQuery; -pub trait SqliteDbConnection: super::DbPool {} -impl> SqliteDbConnection for T {} +pub trait SqliteDbConnection: super::PoolExt {} +impl> SqliteDbConnection for T {} pub fn is_sqlite_memory_path(path: &str) -> bool { path == ":memory:" diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index 0656e148..670cbc2f 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -48,7 +48,6 @@ use tokio::sync::{mpsc, Mutex}; use tokio::time::{sleep, Duration}; use tokio_stream::wrappers::ReceiverStream; use tonic::{Request, Response, Status}; -use torii_dojo::store::postgres::PgStore; use torii_dojo::store::sqlite::SqliteStore; use torii_dojo::store::DojoStoreTrait; use torii_dojo::DojoTable; @@ -2740,8 +2739,7 @@ impl EcsService { .max_connections(1) .connect(&self.state.database_url) .await?; - let store = PgStore(pool); - Ok(store.read_tables(&[]).await?) + Ok(pool.read_tables(&[]).await?) } } } diff --git a/crates/torii-runtime-common/Cargo.toml b/crates/torii-runtime-common/Cargo.toml index 423d5e70..9cbc5ffd 100644 --- a/crates/torii-runtime-common/Cargo.toml +++ b/crates/torii-runtime-common/Cargo.toml @@ -10,6 +10,7 @@ tokio.workspace = true tokio-postgres = "0.7" tracing.workspace = true torii.workspace = true +torii-sql.workspace = true [lints] workspace = true diff --git a/crates/torii-runtime-common/src/database.rs b/crates/torii-runtime-common/src/database.rs index cc1df161..4af1f96c 100644 --- a/crates/torii-runtime-common/src/database.rs +++ b/crates/torii-runtime-common/src/database.rs @@ -1,41 +1,21 @@ -use anyhow::{bail, Result}; +use anyhow::{bail, Result as AnyhowResult}; use std::path::{Path, PathBuf}; - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum DatabaseBackend { - Postgres, - Sqlite, -} - -pub fn backend_from_url_or_path(value: &str) -> DatabaseBackend { - if value.starts_with("postgres://") || value.starts_with("postgresql://") { - DatabaseBackend::Postgres - } else { - DatabaseBackend::Sqlite - } -} +use torii_sql::connection::DbType; pub fn validate_uniform_backends( named_urls: &[(&str, &str)], - mixed_backend_message: &str, -) -> Result { - let Some((_, first_url)) = named_urls.first() else { - bail!("at least one database URL must be provided"); - }; - - let expected_backend = backend_from_url_or_path(first_url); - if named_urls - .iter() - .any(|(_, url)| backend_from_url_or_path(url) != expected_backend) - { - let summary = named_urls - .iter() - .map(|(name, url)| format!("{name}={:?}({url})", backend_from_url_or_path(url))) - .collect::>() - .join(", "); - bail!("{mixed_backend_message}. current: {summary}"); + _mixed_backend_message: &str, +) -> Result { + let ((_, first_url), rest) = named_urls + .split_first() + .ok_or_else(|| "at least one database URL must be provided".to_string())?; + let expected_backend: DbType = (*first_url).try_into()?; + for (name, url) in rest { + let backend: DbType = (*url).try_into()?; + if backend != expected_backend { + return Err(format!("{name}={backend}({url})")); + } } - Ok(expected_backend) } @@ -76,17 +56,17 @@ pub struct TokenDbSetup { pub erc20_url: String, pub erc721_url: String, pub erc1155_url: String, - pub engine_backend: DatabaseBackend, - pub erc20_backend: DatabaseBackend, - pub erc721_backend: DatabaseBackend, - pub erc1155_backend: DatabaseBackend, + pub engine_backend: DbType, + pub erc20_backend: DbType, + pub erc721_backend: DbType, + pub erc1155_backend: DbType, } pub fn resolve_token_db_setup( db_dir: &Path, engine_database_url: Option<&str>, storage_database_url: Option<&str>, -) -> Result { +) -> AnyhowResult { let engine_url = engine_database_url.map_or_else( || db_dir.join("engine.db").to_string_lossy().to_string(), ToOwned::to_owned, @@ -110,21 +90,37 @@ pub fn resolve_token_db_setup( "erc1155.db", ); - let engine_backend = backend_from_url_or_path(&engine_url); - let erc20_backend = backend_from_url_or_path(&erc20_url); - let erc721_backend = backend_from_url_or_path(&erc721_url); - let erc1155_backend = backend_from_url_or_path(&erc1155_url); - - if engine_database_url - .map(backend_from_url_or_path) - .is_some_and(|backend| backend == DatabaseBackend::Postgres) - && (erc20_backend != DatabaseBackend::Postgres - || erc721_backend != DatabaseBackend::Postgres - || erc1155_backend != DatabaseBackend::Postgres) - { - bail!( - "Engine is configured for Postgres but one or more token storages resolved to SQLite. Set --storage-database-url to the same Postgres URL." - ); + let engine_backend = DbType::from_url(&engine_url).ok_or_else(|| { + anyhow::anyhow!( + "Error parsing engine database URL '{engine_url}': Unsupported database type" + ) + })?; + let erc20_backend = DbType::from_url(&erc20_url).ok_or_else(|| { + anyhow::anyhow!("Error parsing ERC20 database URL '{erc20_url}': Unsupported database type") + })?; + + let erc721_backend = DbType::from_url(&erc721_url).ok_or_else(|| { + anyhow::anyhow!( + "Error parsing ERC721 database URL '{erc721_url}': Unsupported database type" + ) + })?; + let erc1155_backend = DbType::from_url(&erc1155_url).ok_or_else(|| { + anyhow::anyhow!( + "Error parsing ERC1155 database URL '{erc1155_url}': Unsupported database type" + ) + })?; + + if let Some(url) = storage_database_url { + let backend: DbType = DbType::from_url(url).ok_or_else(|| { + anyhow::anyhow!("Error parsing storage database URL '{url}': Unsupported database type") + })?; + if backend == DbType::Postgres + && (erc20_backend != DbType::Postgres + || erc721_backend != DbType::Postgres + || erc1155_backend != DbType::Postgres) + { + bail!("Engine is configured for Postgres but one or more token storages resolved to SQLite. Set --storage-database-url to the same Postgres URL."); + } } Ok(TokenDbSetup { @@ -159,8 +155,8 @@ mod tests { fn resolves_sqlite_defaults() { let db_dir = Path::new("./torii-data"); let setup = resolve_token_db_setup(db_dir, None, None).unwrap(); - assert_eq!(setup.engine_backend, DatabaseBackend::Sqlite); - assert_eq!(setup.erc20_backend, DatabaseBackend::Sqlite); + assert_eq!(setup.engine_backend, DbType::Sqlite); + assert_eq!(setup.erc20_backend, DbType::Sqlite); assert!(setup.engine_url.ends_with("engine.db")); assert!(setup.erc20_url.ends_with("erc20.db")); } @@ -188,8 +184,8 @@ mod tests { Some("postgres://localhost/torii"), ) .unwrap(); - assert_eq!(setup.engine_backend, DatabaseBackend::Postgres); - assert_eq!(setup.erc721_backend, DatabaseBackend::Postgres); + assert_eq!(setup.engine_backend, DbType::Postgres); + assert_eq!(setup.erc721_backend, DbType::Postgres); } #[test] @@ -202,7 +198,7 @@ mod tests { "mixed backends", ) .unwrap(); - assert_eq!(backend, DatabaseBackend::Postgres); + assert_eq!(backend, DbType::Postgres); } #[test] diff --git a/examples/introspect/restart copy.rs b/examples/introspect/restart copy.rs new file mode 100644 index 00000000..33de70c8 --- /dev/null +++ b/examples/introspect/restart copy.rs @@ -0,0 +1,109 @@ +use itertools::Itertools; +use sqlx::postgres::PgPoolOptions; +use sqlx::PgPool; +use starknet::core::types::Felt; +use torii_dojo::decoder::DojoDecoder; +use torii_dojo::store::postgres::PgStore; +use torii_dojo::DojoToriiError; +use torii_introspect_sql_sink::IntrospectPgDb; +use torii_test_utils::{resolve_path_like, FakeProvider, MultiContractEventIterator}; + +const DB_URL: &str = "postgres://torii:torii@localhost:5432/torii"; +const EVENT_PATHS: [&str; 2] = ["~/tc-tests/blob-arena/events", "~/tc-tests/pistols/events"]; +const MODEL_CONTRACTS_PATH: &str = "~/tc-tests/model-contracts"; +const BATCH_SIZE: usize = 10000; +const PISTOLS_ADDRESS: Felt = + Felt::from_hex_unchecked("08b4838140a3cbd36ebe64d4b5aaf56a30cc3753c928a79338bf56c53f506c5"); +const BLOB_ARENA_ADDRESS: Felt = + Felt::from_hex_unchecked("2d26295d6c541d64740e1ae56abc079b82b22c35ab83985ef8bd15dc0f9edfb"); + +// const SCHEMA_MAP: [(Felt, &str); 2] = [ +// (PISTOLS_ADDRESS, "pistols"), +// (BLOB_ARENA_ADDRESS, "blob_arena"), +// ]; + +const ADDRESSES: [Felt; 2] = [PISTOLS_ADDRESS, BLOB_ARENA_ADDRESS]; + +async fn run_events( + events: &mut MultiContractEventIterator, + provider: FakeProvider, + pool: PgPool, + end: Option, + event_n: &mut u32, + success: &mut u32, +) -> bool { + println!("Starting event processing run"); + let decoder = DojoDecoder::, _>::new(pool.clone(), provider); + let db = IntrospectPgDb::new(pool.clone(), ADDRESSES); + decoder.store.initialize().await.unwrap(); + decoder.load_tables(&[]).await.unwrap(); + let results = db.initialize_introspect_sql_sink().await.unwrap(); + if results.len() > 0 { + for err in results { + println!("Error loading table: {err}"); + } + panic!(""); + } + let mut running = true; + let mut this_run = 0; + while running { + let mut msgs = Vec::with_capacity(BATCH_SIZE); + for _ in 0..BATCH_SIZE { + let Some(event) = events.next() else { + running = false; + break; + }; + *event_n += 1; + this_run += 1; + match decoder.decode_raw_event(&event).await { + Ok(msg) => { + msgs.push(msg); + } + Err(DojoToriiError::UnknownDojoEventSelector(_)) => { + println!("Unknown event selector, skipping event"); + } + Err(err) => { + println!("Failed to decode event: {err:?}"); + } + }; + } + let msgs_ref = msgs.iter().collect_vec(); + for res in db.process_messages(msgs_ref).await.unwrap() { + match res { + Err(err) => println!("Failed to process message: {err:?}"), + Ok(()) => *success += 1, + } + } + println!( + "Processed batch of events, total events processed: {event_n}, successful: {success}" + ); + if let Some(end) = end { + if end <= this_run as u64 { + println!("Reached end of event range, stopping"); + return true; + } + } + } + false +} + +#[tokio::main] +async fn main() { + let event_paths = EVENT_PATHS.map(resolve_path_like).to_vec(); + let provider = FakeProvider::new(resolve_path_like(MODEL_CONTRACTS_PATH)); + let mut event_iterator = MultiContractEventIterator::new(event_paths); + let pool = PgPoolOptions::new().connect(DB_URL).await.unwrap(); + let mut event_n = 0; + let mut success = 0; + while run_events( + &mut event_iterator, + provider.clone(), + pool.clone(), + Some(20000), + &mut event_n, + &mut success, + ) + .await + {} + println!("Finished processing events"); +} diff --git a/examples/introspect/restart.rs b/examples/introspect/restart.rs index 33de70c8..8a1d5315 100644 --- a/examples/introspect/restart.rs +++ b/examples/introspect/restart.rs @@ -1,17 +1,17 @@ use itertools::Itertools; -use sqlx::postgres::PgPoolOptions; -use sqlx::PgPool; use starknet::core::types::Felt; use torii_dojo::decoder::DojoDecoder; -use torii_dojo::store::postgres::PgStore; +use torii_dojo::store::DojoStoreTrait; use torii_dojo::DojoToriiError; -use torii_introspect_sql_sink::IntrospectPgDb; +use torii_introspect_sql_sink::IntrospectDb; +use torii_sql::{DbPool, PoolConfig}; use torii_test_utils::{resolve_path_like, FakeProvider, MultiContractEventIterator}; -const DB_URL: &str = "postgres://torii:torii@localhost:5432/torii"; +// const DB_URL: &str = "postgres://torii:torii@localhost:5432/torii"; +const DB_URL: &str = "sqlite://sqlite-data.db?mode=rwc"; const EVENT_PATHS: [&str; 2] = ["~/tc-tests/blob-arena/events", "~/tc-tests/pistols/events"]; const MODEL_CONTRACTS_PATH: &str = "~/tc-tests/model-contracts"; -const BATCH_SIZE: usize = 10000; +const BATCH_SIZE: usize = 1000; const PISTOLS_ADDRESS: Felt = Felt::from_hex_unchecked("08b4838140a3cbd36ebe64d4b5aaf56a30cc3753c928a79338bf56c53f506c5"); const BLOB_ARENA_ADDRESS: Felt = @@ -27,15 +27,15 @@ const ADDRESSES: [Felt; 2] = [PISTOLS_ADDRESS, BLOB_ARENA_ADDRESS]; async fn run_events( events: &mut MultiContractEventIterator, provider: FakeProvider, - pool: PgPool, + pool: DbPool, end: Option, event_n: &mut u32, success: &mut u32, ) -> bool { println!("Starting event processing run"); - let decoder = DojoDecoder::, _>::new(pool.clone(), provider); - let db = IntrospectPgDb::new(pool.clone(), ADDRESSES); - decoder.store.initialize().await.unwrap(); + let decoder = DojoDecoder::new(pool.clone(), provider); + let db = IntrospectDb::new(pool, ADDRESSES); + decoder.initialize().await.unwrap(); decoder.load_tables(&[]).await.unwrap(); let results = db.initialize_introspect_sql_sink().await.unwrap(); if results.len() > 0 { @@ -92,7 +92,11 @@ async fn main() { let event_paths = EVENT_PATHS.map(resolve_path_like).to_vec(); let provider = FakeProvider::new(resolve_path_like(MODEL_CONTRACTS_PATH)); let mut event_iterator = MultiContractEventIterator::new(event_paths); - let pool = PgPoolOptions::new().connect(DB_URL).await.unwrap(); + let pool = PoolConfig::new(DB_URL.to_string()) + .max_connections(5) + .connect_any() + .await + .unwrap(); let mut event_n = 0; let mut success = 0; while run_events( diff --git a/sqlite-data.db-journal b/sqlite-data.db-journal new file mode 100644 index 0000000000000000000000000000000000000000..6673afd43024c4b3ba416929e340e595e4b58e85 GIT binary patch literal 1646216 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%0A>(Qr^@*xFQ6aJ7|>fmdz{?V`{TyQM&BC)Eu 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

gEvoV7GlvofzyXCj+SJsBoNW7r_XXqn?qMhL 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 B8JSA^OMOvM*a>_m&g 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

yB&_rH{3n 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

J=?qj7QiIOH6#Zw^xNJ_i*=9?T$JJnAkxHRy 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%0A3NVAj&)^G71JUDCp)V8LAmc8K^E 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 Date: Mon, 30 Mar 2026 19:50:44 +0100 Subject: [PATCH 13/21] refactor: remove From<&str> implementation for DbPool to streamline connection handling --- crates/sql/src/runtime.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/crates/sql/src/runtime.rs b/crates/sql/src/runtime.rs index 5af8b69c..f7dc7c2a 100644 --- a/crates/sql/src/runtime.rs +++ b/crates/sql/src/runtime.rs @@ -8,20 +8,6 @@ pub enum DbPool { Sqlite(Pool), } -impl From<&str> for DbPool { - fn from(value: &str) -> Self { - match DbType::try_from(value) { - Ok(DbType::Postgres) => DbPool::Postgres( - Pool::::connect_lazy(value).expect("Failed to create Postgres pool"), - ), - Ok(DbType::Sqlite) => DbPool::Sqlite( - Pool::::connect_lazy(value).expect("Failed to create Sqlite pool"), - ), - Err(err) => panic!("Error parsing database connection string: {}", err), - } - } -} - impl PoolConfig { pub async fn connect_any(&self) -> SqlxResult { match DbType::try_from(self.url.as_str()) { From 3e1ca93ab2ed689475bbb82bffa98bf0c116e77f Mon Sep 17 00:00:00 2001 From: Bengineer Date: Mon, 30 Mar 2026 21:25:36 +0100 Subject: [PATCH 14/21] feat: add torii-sql dependency and refactor database handling - Added `torii-sql` as a dependency in multiple Cargo.toml files. - Refactored database backend handling to use `DbType` and `DbUrl` enums for better clarity and type safety. - Updated various modules to accommodate the new database handling logic, including `EntitiesHistoricalSink`, `IntrospectQueryMaker`, and others. - Removed the `introspect_simple` example as it was deemed unnecessary. - Improved error handling and logging in database operations. - Adjusted SQL migration scripts for better compatibility with both Postgres and SQLite. --- Cargo.lock | 3 + Cargo.toml | 4 - bins/torii-arcade/src/main.rs | 1 + bins/torii-erc20/Cargo.toml | 8 +- bins/torii-erc20/src/main.rs | 10 +- bins/torii-introspect-bin/src/config.rs | 1 + bins/torii-tokens/Cargo.toml | 13 +- bins/torii-tokens/src/main.rs | 4 +- crates/dojo/src/external_contract.rs | 2 +- crates/dojo/src/store/postgres.rs | 2 +- crates/introspect-sql-sink/src/backend.rs | 1 + .../src/postgres/backend.rs | 11 +- .../src/postgres/insert.rs | 3 +- .../introspect-sql-sink/src/sqlite/table.rs | 3 +- crates/sql/src/connection.rs | 72 ++++++++- crates/sql/src/lib.rs | 2 +- crates/sql/src/postgres/migrate.rs | 37 ++--- crates/sql/src/query.rs | 3 +- crates/torii-ecs-sink/src/grpc_service.rs | 2 +- .../torii-entities-historical-sink/Cargo.toml | 8 +- .../torii-entities-historical-sink/src/lib.rs | 140 +++++++----------- crates/torii-runtime-common/src/database.rs | 6 +- examples/introspect/restart.rs | 2 +- examples/introspect/simple.rs | 64 -------- 24 files changed, 190 insertions(+), 212 deletions(-) delete mode 100644 examples/introspect/simple.rs diff --git a/Cargo.lock b/Cargo.lock index 4a1076bb..f1f90d6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4794,6 +4794,7 @@ dependencies = [ "tokio", "torii", "torii-introspect", + "torii-sql", "tracing", ] @@ -4864,6 +4865,7 @@ dependencies = [ "torii", "torii-erc20", "torii-runtime-common", + "torii-sql", "tracing", "tracing-subscriber", "url", @@ -5119,6 +5121,7 @@ dependencies = [ "torii-erc20", "torii-erc721", "torii-runtime-common", + "torii-sql", "tracing", "tracing-subscriber", "url", diff --git a/Cargo.toml b/Cargo.toml index a05b0023..6318da0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -163,10 +163,6 @@ path = "examples/http_only_sink/main.rs" name = "test_block_extractor" path = "examples/test_block_extractor/main.rs" -[[example]] -name = "introspect_simple" -path = "examples/introspect/simple.rs" - [[example]] name = "introspect_restart" path = "examples/introspect/restart.rs" diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index 189c89df..1be7f842 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -99,6 +99,7 @@ async fn load_persisted_contract_registries( Ok(()) } +#[allow(clippy::fn_params_excessive_bools)] fn installed_external_decoder_ids( enabled: bool, install_erc20: bool, diff --git a/bins/torii-erc20/Cargo.toml b/bins/torii-erc20/Cargo.toml index 9dd48af1..b69a7d7b 100644 --- a/bins/torii-erc20/Cargo.toml +++ b/bins/torii-erc20/Cargo.toml @@ -9,10 +9,12 @@ path = "src/main.rs" [dependencies] # Core dependencies -torii = { path = "../../" } -torii-erc20 = { path = "../../crates/torii-erc20" } +torii.workspace = true +torii-erc20.workspace = true torii-runtime-common.workspace = true +torii-sql = { workspace = true, optional = true } + # Async runtime tokio = { version = "1", features = ["full"] } @@ -41,7 +43,7 @@ features = ["flamegraph", "prost-codec"] optional = true [features] -profiling = ["pprof"] +profiling = ["pprof", "torii-sql"] [lints] workspace = true diff --git a/bins/torii-erc20/src/main.rs b/bins/torii-erc20/src/main.rs index 33b1272d..bced24c4 100644 --- a/bins/torii-erc20/src/main.rs +++ b/bins/torii-erc20/src/main.rs @@ -38,7 +38,7 @@ use torii::etl::decoder::DecoderId; use torii::etl::extractor::{BlockRangeConfig, BlockRangeExtractor}; use torii_runtime_common::database::resolve_single_db_setup; #[cfg(feature = "profiling")] -use torii_runtime_common::database::{backend_from_url_or_path, DatabaseBackend}; +use torii_sql::DbType; // Import from the library crate use torii_erc20::proto::erc20_server::Erc20Server; @@ -217,10 +217,10 @@ async fn main() -> Result<()> { .duration_since(UNIX_EPOCH) .map(|d| d.as_secs()) .unwrap_or(0); - let db_backend = match backend_from_url_or_path(&db_setup.storage_url) { - DatabaseBackend::Postgres => "postgres", - DatabaseBackend::Sqlite => "sqlite", - }; + let db_backend: DbType = db_setup + .storage_url + .try_into() + .map_err(|e: String| anyhow::anyhow!(e))?; let filename = format!("flamegraph-torii-erc20-block-range-{db_backend}-{ts}.svg"); let file = std::fs::File::create(&filename).unwrap(); report.flamegraph(file).unwrap(); diff --git a/bins/torii-introspect-bin/src/config.rs b/bins/torii-introspect-bin/src/config.rs index 47a0d818..851c360e 100644 --- a/bins/torii-introspect-bin/src/config.rs +++ b/bins/torii-introspect-bin/src/config.rs @@ -25,6 +25,7 @@ pub enum StorageBackend { .multiple(true) .required(true) ))] +#[allow(clippy::struct_excessive_bools)] pub struct Config { /// Starknet RPC URL. #[arg( diff --git a/bins/torii-tokens/Cargo.toml b/bins/torii-tokens/Cargo.toml index b6a98319..627c87f0 100644 --- a/bins/torii-tokens/Cargo.toml +++ b/bins/torii-tokens/Cargo.toml @@ -10,13 +10,14 @@ path = "src/main.rs" [dependencies] # Core dependencies -torii = { path = "../../" } -torii-common = { path = "../../crates/torii-common" } +torii.workspace = true +torii-common.workspace = true torii-config-common.workspace = true torii-runtime-common.workspace = true -torii-erc20 = { path = "../../crates/torii-erc20" } -torii-erc721 = { path = "../../crates/torii-erc721" } -torii-erc1155 = { path = "../../crates/torii-erc1155" } +torii-erc20.workspace = true +torii-erc721.workspace = true +torii-erc1155.workspace = true +torii-sql = { workspace = true, optional = true } # Async runtime tokio = { version = "1", features = ["full"] } @@ -47,7 +48,7 @@ features = ["flamegraph", "prost-codec"] optional = true [features] -profiling = ["pprof"] +profiling = ["pprof", "torii-sql"] [lints] workspace = true diff --git a/bins/torii-tokens/src/main.rs b/bins/torii-tokens/src/main.rs index f81d81ac..d06274dc 100644 --- a/bins/torii-tokens/src/main.rs +++ b/bins/torii-tokens/src/main.rs @@ -61,7 +61,7 @@ use torii_common::{MetadataFetcher, TokenUriService}; use torii_config_common::apply_observability_env; use torii_runtime_common::database::resolve_token_db_setup; #[cfg(feature = "profiling")] -use torii_runtime_common::database::DatabaseBackend; +use torii_sql::DbType; // Import from ERC20 library crate use torii_erc20::proto::erc20_server::Erc20Server; @@ -780,7 +780,7 @@ async fn run_indexer(config: Config) -> Result<()> { .duration_since(UNIX_EPOCH) .map(|d| d.as_secs()) .unwrap_or(0); - let db_backend = if db_setup.erc20_backend == DatabaseBackend::Postgres { + let db_backend = if db_setup.erc20_backend == DbType::Postgres { "postgres" } else { "sqlite" diff --git a/crates/dojo/src/external_contract.rs b/crates/dojo/src/external_contract.rs index dad58a12..5d2d158f 100644 --- a/crates/dojo/src/external_contract.rs +++ b/crates/dojo/src/external_contract.rs @@ -118,7 +118,7 @@ pub struct ResolvedExternalContract { pub fn resolve_external_contract(contract_name: &str) -> Option { let normalized = contract_name .chars() - .filter(|ch| ch.is_ascii_alphanumeric()) + .filter(char::is_ascii_alphanumeric) .collect::() .to_ascii_uppercase(); diff --git a/crates/dojo/src/store/postgres.rs b/crates/dojo/src/store/postgres.rs index a4e0594c..480e1743 100644 --- a/crates/dojo/src/store/postgres.rs +++ b/crates/dojo/src/store/postgres.rs @@ -281,7 +281,7 @@ pub struct PgStore(pub T); impl> PoolExt for PgStore { fn pool(&self) -> &PgPool { - &self.0.pool() + self.0.pool() } } diff --git a/crates/introspect-sql-sink/src/backend.rs b/crates/introspect-sql-sink/src/backend.rs index 1d49e1e3..3dcb7b01 100644 --- a/crates/introspect-sql-sink/src/backend.rs +++ b/crates/introspect-sql-sink/src/backend.rs @@ -32,6 +32,7 @@ pub trait IntrospectInitialize { ) -> DbResult>; } +#[allow(clippy::too_many_arguments)] pub trait IntrospectQueryMaker: Database { fn create_table_queries( namespace: &str, diff --git a/crates/introspect-sql-sink/src/postgres/backend.rs b/crates/introspect-sql-sink/src/postgres/backend.rs index 2016ef4f..b2855eff 100644 --- a/crates/introspect-sql-sink/src/postgres/backend.rs +++ b/crates/introspect-sql-sink/src/postgres/backend.rs @@ -105,6 +105,7 @@ impl IntrospectQueryMaker for Postgres { } } +#[allow(clippy::too_many_arguments)] fn store_table_queries( schema: &str, id: &Felt, @@ -121,10 +122,10 @@ where { queries.push( insert_table_query( - &schema, - &id, - &name, - &primary, + schema, + id, + name, + primary, from_address, block_number, transaction_hash, @@ -133,7 +134,7 @@ where ); queries.push( - insert_columns_query(&schema, &id, columns, block_number, transaction_hash) + insert_columns_query(schema, id, columns, block_number, transaction_hash) .map_err(TableError::Encode)?, ); Ok(()) diff --git a/crates/introspect-sql-sink/src/postgres/insert.rs b/crates/introspect-sql-sink/src/postgres/insert.rs index f1b5ebf8..c94ec895 100644 --- a/crates/introspect-sql-sink/src/postgres/insert.rs +++ b/crates/introspect-sql-sink/src/postgres/insert.rs @@ -38,7 +38,7 @@ impl SerializeEntries for MetaData<'_> { &self, map: &mut ::SerializeMap, ) -> Result<(), S::Error> { - let tx_hash = pg_json_felt252(&self.transaction_hash); + let tx_hash = pg_json_felt252(self.transaction_hash); map.serialize_entry("__created_block", &self.block_number)?; map.serialize_entry("__updated_block", &self.block_number)?; map.serialize_entry("__created_tx", &tx_hash)?; @@ -46,6 +46,7 @@ impl SerializeEntries for MetaData<'_> { } } +#[allow(clippy::too_many_arguments)] pub fn insert_record_queries( namespace: &str, table_name: &str, diff --git a/crates/introspect-sql-sink/src/sqlite/table.rs b/crates/introspect-sql-sink/src/sqlite/table.rs index aad3262f..24141628 100644 --- a/crates/introspect-sql-sink/src/sqlite/table.rs +++ b/crates/introspect-sql-sink/src/sqlite/table.rs @@ -56,6 +56,7 @@ pub fn serialize_columns<'a>(columns: &'a [impl AsColumnRef<'a>]) -> JsonResult< Ok(unsafe { String::from_utf8_unchecked(data) }) } +#[allow(clippy::too_many_arguments)] pub fn persist_table_state_query<'a>( namespace: &str, id: &Felt, @@ -180,7 +181,7 @@ pub fn update_column( Felt252 | ClassHash | ContractAddress | EthAddress | StorageAddress | StorageBaseAddress, ) => Some(format!(r#"printf('0x%064x', "{new_name}")"#)), - _ => return UpgradeError::type_upgrade_err(&column.type_def, &new_type), + _ => return UpgradeError::type_upgrade_err(&column.type_def, new_type), }; column.type_def = new_type.clone(); if let Some(cast) = cast { diff --git a/crates/sql/src/connection.rs b/crates/sql/src/connection.rs index c5c2d292..2a1ea8fd 100644 --- a/crates/sql/src/connection.rs +++ b/crates/sql/src/connection.rs @@ -6,6 +6,7 @@ use sqlx::migrate::{Migrate, Migrator}; use sqlx::pool::PoolOptions; use sqlx::{Database, Pool, Transaction}; use std::fmt::Display; +use std::str::FromStr; use std::time::Duration; const DEFAULT_TEST_BEFORE_ACQUIRE: bool = true; @@ -61,6 +62,75 @@ pub enum DbType { Sqlite, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum DbUrl { + Postgres(String), + Sqlite(String), +} + +pub struct DbOption { + postgres: T, + sqlite: T, +} + +impl DbOption { + pub fn new(postgres: T, sqlite: T) -> Self { + Self { postgres, sqlite } + } + + pub fn value(self, db_type: &DbType) -> T { + match db_type { + DbType::Postgres => self.postgres, + DbType::Sqlite => self.sqlite, + } + } +} + +impl FromStr for DbUrl { + type Err = String; + + fn from_str(s: &str) -> Result { + if s.starts_with("postgres") || s.starts_with("postgresql") { + Ok(DbUrl::Postgres(s.to_string())) + } else if s == ":memory:" || s == "memory" { + Ok(DbUrl::Sqlite("sqlite::memory:".to_string())) + } else if s.starts_with("sqlite") { + Ok(DbUrl::Sqlite(s.to_string())) + } else { + Err(format!("Unsupported database url: {s}")) + } + } +} + +impl DbUrl { + pub fn from_url(url: String) -> Option { + if url.starts_with("postgres") || url.starts_with("postgresql") { + Some(DbUrl::Postgres(url)) + } else if url == ":memory:" || url == "memory" { + Some(DbUrl::Sqlite("sqlite::memory:".to_string())) + } else if url.starts_with("sqlite") { + Some(DbUrl::Sqlite(url)) + } else { + None + } + } + pub fn as_type(&self) -> DbType { + match self { + DbUrl::Postgres(_) => DbType::Postgres, + DbUrl::Sqlite(_) => DbType::Sqlite, + } + } +} + +impl From for (DbType, String) { + fn from(value: DbUrl) -> Self { + match value { + DbUrl::Postgres(url) => (DbType::Postgres, url), + DbUrl::Sqlite(url) => (DbType::Sqlite, url), + } + } +} + impl Display for DbType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -241,7 +311,7 @@ impl DbPoolOptions { } pub async fn connect(&self, url: &str) -> SqlxResult> { - Ok(self.options::().connect(url).await?) + self.options::().connect(url).await } pub fn options(&self) -> PoolOptions { diff --git a/crates/sql/src/lib.rs b/crates/sql/src/lib.rs index b492eab8..18612eae 100644 --- a/crates/sql/src/lib.rs +++ b/crates/sql/src/lib.rs @@ -3,7 +3,7 @@ pub mod migrate; pub mod query; pub mod types; -pub use connection::{DbPoolOptions, PoolConfig, PoolExt}; +pub use connection::{DbPoolOptions, DbType, DbUrl, PoolConfig, PoolExt}; pub use migrate::{AcquiredSchema, SchemaMigrator}; pub use query::{Executable, FlexQuery, Queries}; diff --git a/crates/sql/src/postgres/migrate.rs b/crates/sql/src/postgres/migrate.rs index 9b5fc616..02982cc6 100644 --- a/crates/sql/src/postgres/migrate.rs +++ b/crates/sql/src/postgres/migrate.rs @@ -11,17 +11,15 @@ impl Migrate for AcquiredSchema { self.connection .execute( format!( - r#" -CREATE SCHEMA IF NOT EXISTS {schema}; -CREATE TABLE IF NOT EXISTS {schema}._sqlx_migrations ( - version BIGINT PRIMARY KEY, - description TEXT NOT NULL, - installed_on TIMESTAMPTZ NOT NULL DEFAULT now(), - success BOOLEAN NOT NULL, - checksum BYTEA NOT NULL, - execution_time BIGINT NOT NULL -); - "#, + "CREATE SCHEMA IF NOT EXISTS {schema}; + CREATE TABLE IF NOT EXISTS {schema}._sqlx_migrations ( + version BIGINT PRIMARY KEY, + description TEXT NOT NULL, + installed_on TIMESTAMPTZ NOT NULL DEFAULT now(), + success BOOLEAN NOT NULL, + checksum BYTEA NOT NULL, + execution_time BIGINT NOT NULL + );", schema = self.schema ) .as_str(), @@ -138,11 +136,7 @@ CREATE TABLE IF NOT EXISTS {schema}._sqlx_migrations ( // language=SQL #[allow(clippy::cast_possible_truncation)] let _ = query(&format!( - r#" - UPDATE {schema}._sqlx_migrations - SET execution_time = $1 - WHERE version = $2 - "#, + "UPDATE {schema}._sqlx_migrations SET execution_time = $1 WHERE version = $2", schema = self.schema )) .bind(elapsed.as_nanos() as i64) @@ -203,18 +197,14 @@ async fn execute_migration( .map_err(|e| MigrateError::ExecuteMigration(e, migration.version))?; // language=SQL - let _ = query( - format!(r#" - INSERT INTO {schema}._sqlx_migrations ( version, description, success, checksum, execution_time ) - VALUES ( $1, $2, TRUE, $3, -1 ) - "#).as_str() + query( + format!(r#"INSERT INTO "{schema}"._sqlx_migrations ( version, description, success, checksum, execution_time ) VALUES ( $1, $2, TRUE, $3, -1 )"#).as_str() ) .bind(migration.version) .bind(&*migration.description) .bind(&*migration.checksum) .execute(conn) .await?; - Ok(()) } @@ -228,8 +218,7 @@ async fn revert_migration( .await .map_err(|e| MigrateError::ExecuteMigration(e, migration.version))?; - // language=SQL - let _ = query(format!(r#"DELETE FROM {schema}._sqlx_migrations WHERE version = $1"#).as_str()) + query(format!(r#"DELETE FROM "{schema}"._sqlx_migrations WHERE version = $1"#).as_str()) .bind(migration.version) .execute(conn) .await?; diff --git a/crates/sql/src/query.rs b/crates/sql/src/query.rs index cd136034..fe916a37 100644 --- a/crates/sql/src/query.rs +++ b/crates/sql/src/query.rs @@ -113,7 +113,6 @@ impl PartialEq for FlexStr { /// The per-database `Executable` impls handle the lifetime requirements: /// Postgres needs no special treatment; SQLite uses an unsafe lifetime extension /// that is sound because the `FlexStr` outlives the `.await` point. - pub struct FlexQuery { pub(crate) sql: FlexStr, pub(crate) args: Option<::Arguments<'static>>, @@ -298,7 +297,7 @@ where } } -impl<'a, const N: usize, DB: Database, T> Executable for [T; N] +impl Executable for [T; N] where T: Executable + Send, { diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index 670cbc2f..fdc6b824 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -2932,7 +2932,7 @@ impl EcsService { } candidate_cursor = batch_cursor; - next_cursor = candidate_cursor.clone(); + next_cursor.clone_from(&candidate_cursor); } if query.no_hashed_keys { diff --git a/crates/torii-entities-historical-sink/Cargo.toml b/crates/torii-entities-historical-sink/Cargo.toml index 162195c2..20c36c04 100644 --- a/crates/torii-entities-historical-sink/Cargo.toml +++ b/crates/torii-entities-historical-sink/Cargo.toml @@ -11,7 +11,12 @@ anyhow.workspace = true async-trait.workspace = true serde.workspace = true serde_json.workspace = true -sqlx = { workspace = true, features = ["any", "postgres", "sqlite", "runtime-tokio-rustls"] } +sqlx = { workspace = true, features = [ + "any", + "postgres", + "sqlite", + "runtime-tokio-rustls", +] } starknet.workspace = true tokio.workspace = true torii.workspace = true @@ -19,6 +24,7 @@ tracing.workspace = true thiserror.workspace = true introspect-types.workspace = true +torii-sql.workspace = true torii-introspect.workspace = true [lints] diff --git a/crates/torii-entities-historical-sink/src/lib.rs b/crates/torii-entities-historical-sink/src/lib.rs index 79976dbf..27cc119b 100644 --- a/crates/torii-entities-historical-sink/src/lib.rs +++ b/crates/torii-entities-historical-sink/src/lib.rs @@ -1,4 +1,5 @@ use std::collections::{HashMap, HashSet}; +use std::str::FromStr; use std::sync::Arc; use anyhow::{anyhow, Context, Result}; @@ -13,28 +14,14 @@ use torii::etl::extractor::ExtractionBatch; use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; use torii_introspect::events::{CreateTable, IntrospectBody, IntrospectMsg, UpdateTable}; use torii_introspect::schema::TableSchema; +use torii_sql::connection::DbOption; +use torii_sql::{DbType, DbUrl}; const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); const SQLITE_SCHEMA_STATE_TABLE: &str = "introspect_sink_schema_state"; const PG_METADATA_SCHEMA: &str = "introspect"; const PG_METADATA_TABLES: &str = "db_tables"; -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -enum DbBackend { - Sqlite, - Postgres, -} - -impl DbBackend { - fn detect(database_url: &str) -> Self { - if database_url.starts_with("postgres://") || database_url.starts_with("postgresql://") { - Self::Postgres - } else { - Self::Sqlite - } - } -} - #[derive(Clone, Debug, Default)] pub enum HistoricalNamespace { #[default] @@ -59,7 +46,7 @@ impl HistoricalNamespace { } impl From<()> for HistoricalNamespace { - fn from(_: ()) -> Self { + fn from((): ()) -> Self { Self::Default } } @@ -101,7 +88,7 @@ struct TrackedTable { #[derive(Clone)] pub struct EntitiesHistoricalSink { pool: Pool, - backend: DbBackend, + backend: DbType, namespace: HistoricalNamespace, tracked_names: HashSet, tracked_tables: Arc>>, @@ -115,19 +102,11 @@ impl EntitiesHistoricalSink { tracked_models: Vec, ) -> Result { sqlx::any::install_default_drivers(); - - let backend = DbBackend::detect(database_url); - let database_url = match backend { - DbBackend::Postgres => database_url.to_string(), - DbBackend::Sqlite => sqlite_url(database_url)?, - }; + let db_url_type = DbUrl::from_str(database_url).map_err(|err| anyhow!(err))?; + let (backend, url) = db_url_type.into(); let pool = AnyPoolOptions::new() - .max_connections(max_connections.unwrap_or(if backend == DbBackend::Sqlite { - 1 - } else { - 5 - })) - .connect(&database_url) + .max_connections(max_connections.unwrap_or(DbOption::new(5, 1).value(&backend))) + .connect(&url) .await?; Ok(Self { @@ -147,7 +126,7 @@ impl EntitiesHistoricalSink { return Ok(()); } - if self.backend == DbBackend::Sqlite { + if self.backend == DbType::Sqlite { sqlx::query("PRAGMA journal_mode=WAL") .execute(&self.pool) .await @@ -155,7 +134,7 @@ impl EntitiesHistoricalSink { } match self.backend { - DbBackend::Sqlite => { + DbType::Sqlite => { let rows = sqlx::query(&format!( "SELECT table_schema_json FROM {SQLITE_SCHEMA_STATE_TABLE} WHERE alive != 0" )) @@ -169,7 +148,7 @@ impl EntitiesHistoricalSink { } } } - DbBackend::Postgres => { + DbType::Postgres => { let rows = sqlx::query(&format!( "SELECT id, name FROM {PG_METADATA_SCHEMA}.{PG_METADATA_TABLES} WHERE \"schema\" = $1" )) @@ -191,10 +170,11 @@ impl EntitiesHistoricalSink { } async fn resolve_tracked_table(&self, table_id: Felt) -> Result> { - if let Some(table) = self.tracked_tables.read().await.get(&table_id).cloned() { - return Ok(Some(table)); + { + if let Some(table) = self.tracked_tables.read().await.get(&table_id) { + return Ok(Some(table.clone())); + } } - let resolved = self.lookup_table_name(table_id).await?; let Some(table_name) = resolved else { return Ok(None); @@ -210,7 +190,7 @@ impl EntitiesHistoricalSink { async fn lookup_table_name(&self, table_id: Felt) -> Result> { let (canonical_table_id, compact_table_id) = felt_hex_variants(table_id); match self.backend { - DbBackend::Sqlite => { + DbType::Sqlite => { let row = sqlx::query(&format!( "SELECT table_schema_json FROM {SQLITE_SCHEMA_STATE_TABLE} \ WHERE table_id = ?1 OR table_id = ?2 LIMIT 1" @@ -226,7 +206,7 @@ impl EntitiesHistoricalSink { }) .transpose() } - DbBackend::Postgres => { + DbType::Postgres => { let row = sqlx::query(&format!( "SELECT name FROM {PG_METADATA_SCHEMA}.{PG_METADATA_TABLES} \ WHERE \"schema\" = $1 AND (id::text = $2 OR id::text = $3) LIMIT 1" @@ -244,15 +224,15 @@ impl EntitiesHistoricalSink { async fn sync_tracked_table(&self, table_id: Felt, logical_name: &str) -> Result { let base_name = match self.backend { - DbBackend::Sqlite => sqlite_storage_name(self.namespace.sqlite_prefix(), logical_name), - DbBackend::Postgres => logical_name.to_string(), + DbType::Sqlite => sqlite_storage_name(self.namespace.sqlite_prefix(), logical_name), + DbType::Postgres => logical_name.to_string(), }; let history_name = match self.backend { - DbBackend::Sqlite => sqlite_storage_name( + DbType::Sqlite => sqlite_storage_name( self.namespace.sqlite_prefix(), &format!("{logical_name}_historical"), ), - DbBackend::Postgres => format!("{logical_name}_historical"), + DbType::Postgres => format!("{logical_name}_historical"), }; let columns = self.load_source_columns(&base_name).await?; if !columns.iter().any(|column| column.name == "entity_id") { @@ -276,7 +256,7 @@ impl EntitiesHistoricalSink { async fn load_source_columns(&self, base_name: &str) -> Result> { match self.backend { - DbBackend::Sqlite => { + DbType::Sqlite => { let rows = sqlx::query(&format!( "PRAGMA table_info({})", quote_sqlite_identifier(base_name) @@ -291,7 +271,7 @@ impl EntitiesHistoricalSink { } Ok(columns) } - DbBackend::Postgres => { + DbType::Postgres => { let rows = sqlx::query( "SELECT a.attname AS column_name, pg_catalog.format_type(a.atttypid, a.atttypmod) AS column_type @@ -325,8 +305,8 @@ impl EntitiesHistoricalSink { async fn ensure_history_table(&self, tracked: &TrackedTable) -> Result<()> { let create_sql = match self.backend { - DbBackend::Sqlite => self.create_history_table_sqlite(tracked), - DbBackend::Postgres => self.create_history_table_postgres(tracked), + DbType::Sqlite => self.create_history_table_sqlite(tracked), + DbType::Postgres => self.create_history_table_postgres(tracked), }; sqlx::query(&create_sql).execute(&self.pool).await?; @@ -336,13 +316,13 @@ impl EntitiesHistoricalSink { continue; } let add_sql = match self.backend { - DbBackend::Sqlite => format!( + DbType::Sqlite => format!( "ALTER TABLE {} ADD COLUMN {} {}", quote_sqlite_identifier(&tracked.history_name), quote_ident(&column.name), column.type_sql ), - DbBackend::Postgres => format!( + DbType::Postgres => format!( "ALTER TABLE {} ADD COLUMN IF NOT EXISTS {} {}", quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name), quote_ident(&column.name), @@ -368,7 +348,7 @@ impl EntitiesHistoricalSink { tracked: &TrackedTable, ) -> Result> { let rows = match self.backend { - DbBackend::Sqlite => { + DbType::Sqlite => { sqlx::query(&format!( "PRAGMA table_info({})", quote_sqlite_identifier(&tracked.history_name) @@ -376,7 +356,7 @@ impl EntitiesHistoricalSink { .fetch_all(&self.pool) .await? } - DbBackend::Postgres => { + DbType::Postgres => { sqlx::query( "SELECT a.attname AS column_name FROM pg_catalog.pg_attribute a @@ -395,7 +375,7 @@ impl EntitiesHistoricalSink { }; let mut columns = HashSet::with_capacity(rows.len()); for row in rows { - let name = if self.backend == DbBackend::Sqlite { + let name = if self.backend == DbType::Sqlite { row.try_get("name")? } else { row.try_get("column_name")? @@ -459,7 +439,7 @@ impl EntitiesHistoricalSink { existing_columns: &HashSet, ) -> Vec { match self.backend { - DbBackend::Sqlite => { + DbType::Sqlite => { let mut sql = Vec::new(); let target = quote_sqlite_identifier(&tracked.history_name); if !existing_columns.contains("revision") { @@ -489,7 +469,7 @@ impl EntitiesHistoricalSink { } sql } - DbBackend::Postgres => vec![ + DbType::Postgres => vec![ format!( "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"revision\" BIGINT NOT NULL DEFAULT 0", quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) @@ -518,7 +498,7 @@ impl EntitiesHistoricalSink { let unique_index = format!("{}_entity_revision_idx", tracked.history_name); let entity_index = format!("{}_entity_idx", tracked.history_name); match self.backend { - DbBackend::Sqlite => vec![ + DbType::Sqlite => vec![ format!( "CREATE UNIQUE INDEX IF NOT EXISTS {} ON {} (\"entity_id\", \"revision\")", quote_ident(&unique_index), @@ -530,7 +510,7 @@ impl EntitiesHistoricalSink { quote_sqlite_identifier(&tracked.history_name) ), ], - DbBackend::Postgres => vec![ + DbType::Postgres => vec![ format!( "CREATE UNIQUE INDEX IF NOT EXISTS {} ON {} (\"entity_id\", \"revision\")", quote_ident(&unique_index), @@ -552,12 +532,12 @@ impl EntitiesHistoricalSink { compact_entity_id_hex: &str, ) -> Result { let sql = match self.backend { - DbBackend::Sqlite => format!( + DbType::Sqlite => format!( "SELECT COALESCE(MAX(\"revision\"), 0) + 1 AS next_revision \ FROM {} WHERE \"entity_id\" = ?1 OR \"entity_id\" = ?2", quote_sqlite_identifier(&tracked.history_name) ), - DbBackend::Postgres => format!( + DbType::Postgres => format!( "SELECT COALESCE(MAX(\"revision\"), 0) + 1 AS next_revision \ FROM {} WHERE \"entity_id\"::text = $1 OR \"entity_id\"::text = $2", quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) @@ -640,24 +620,24 @@ impl EntitiesHistoricalSink { \"historical_block_number\", \"historical_tx_hash\", \"historical_executed_at\"" ); let history_target = match self.backend { - DbBackend::Sqlite => quote_sqlite_identifier(&tracked.history_name), - DbBackend::Postgres => { + DbType::Sqlite => quote_sqlite_identifier(&tracked.history_name), + DbType::Postgres => { quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) } }; let source_target = match self.backend { - DbBackend::Sqlite => quote_sqlite_identifier(&tracked.base_name), - DbBackend::Postgres => { + DbType::Sqlite => quote_sqlite_identifier(&tracked.base_name), + DbType::Postgres => { quote_pg_qualified(self.namespace.postgres_schema(), &tracked.base_name) } }; let where_entity = match self.backend { - DbBackend::Sqlite => "(\"entity_id\" = ?6 OR \"entity_id\" = ?7)", - DbBackend::Postgres => "(\"entity_id\"::text = $6 OR \"entity_id\"::text = $7)", + DbType::Sqlite => "(\"entity_id\" = ?6 OR \"entity_id\" = ?7)", + DbType::Postgres => "(\"entity_id\"::text = $6 OR \"entity_id\"::text = $7)", }; let placeholder = match self.backend { - DbBackend::Sqlite => "?", - DbBackend::Postgres => "$", + DbType::Sqlite => "?", + DbType::Postgres => "$", }; let revision_ph = format!("{placeholder}1"); let deleted_ph = format!("{placeholder}2"); @@ -671,8 +651,8 @@ impl EntitiesHistoricalSink { ); let mut query = sqlx::query(&sql).bind(revision); query = match self.backend { - DbBackend::Sqlite => query.bind(i64::from(deleted)), - DbBackend::Postgres => query.bind(deleted), + DbType::Sqlite => query.bind(i64::from(deleted)), + DbType::Postgres => query.bind(deleted), }; let result = query .bind(block_number.map(|value| value as i64)) @@ -726,8 +706,8 @@ impl EntitiesHistoricalSink { values_sql.push(self.value_placeholder(bind_index)); let target = match self.backend { - DbBackend::Sqlite => quote_sqlite_identifier(&tracked.history_name), - DbBackend::Postgres => { + DbType::Sqlite => quote_sqlite_identifier(&tracked.history_name), + DbType::Postgres => { quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) } }; @@ -739,8 +719,8 @@ impl EntitiesHistoricalSink { let mut query = sqlx::query(&sql).bind(entity_id_hex).bind(revision); query = match self.backend { - DbBackend::Sqlite => query.bind(1_i64), - DbBackend::Postgres => query.bind(true), + DbType::Sqlite => query.bind(1_i64), + DbType::Postgres => query.bind(true), }; query .bind(block_number.map(|value| value as i64)) @@ -754,15 +734,15 @@ impl EntitiesHistoricalSink { fn value_placeholder(&self, index: usize) -> String { match self.backend { - DbBackend::Sqlite => "?".to_string(), - DbBackend::Postgres => format!("${index}"), + DbType::Sqlite => "?".to_string(), + DbType::Postgres => format!("${index}"), } } fn entity_cast_placeholder(&self, index: usize, type_sql: &str) -> String { match self.backend { - DbBackend::Sqlite => "?".to_string(), - DbBackend::Postgres => format!("CAST(${index} AS {type_sql})"), + DbType::Sqlite => "?".to_string(), + DbType::Postgres => format!("CAST(${index} AS {type_sql})"), } } @@ -892,16 +872,6 @@ fn sqlite_storage_name(prefix: &str, logical_name: &str) -> String { } } -fn sqlite_url(database_url: &str) -> Result { - if database_url == ":memory:" { - return Ok("sqlite::memory:".to_string()); - } - if database_url.starts_with("sqlite:") { - return Ok(database_url.to_string()); - } - Ok(format!("sqlite://{database_url}")) -} - fn quote_ident(identifier: &str) -> String { format!("\"{}\"", identifier.replace('"', "\"\"")) } diff --git a/crates/torii-runtime-common/src/database.rs b/crates/torii-runtime-common/src/database.rs index 4af1f96c..3bf18db8 100644 --- a/crates/torii-runtime-common/src/database.rs +++ b/crates/torii-runtime-common/src/database.rs @@ -211,8 +211,8 @@ mod tests { "mixed backends", ) .expect_err("expected mixed backend error"); - assert!(err.to_string().contains("mixed backends")); - assert!(err.to_string().contains("engine=Postgres")); - assert!(err.to_string().contains("storage=Sqlite")); + assert!(err.contains("mixed backends")); + assert!(err.contains("engine=Postgres")); + assert!(err.contains("storage=Sqlite")); } } diff --git a/examples/introspect/restart.rs b/examples/introspect/restart.rs index 8a1d5315..d3bb3407 100644 --- a/examples/introspect/restart.rs +++ b/examples/introspect/restart.rs @@ -38,7 +38,7 @@ async fn run_events( decoder.initialize().await.unwrap(); decoder.load_tables(&[]).await.unwrap(); let results = db.initialize_introspect_sql_sink().await.unwrap(); - if results.len() > 0 { + if results.is_empty() { for err in results { println!("Error loading table: {err}"); } diff --git a/examples/introspect/simple.rs b/examples/introspect/simple.rs deleted file mode 100644 index 025371fc..00000000 --- a/examples/introspect/simple.rs +++ /dev/null @@ -1,64 +0,0 @@ -use itertools::Itertools; -use sqlx::postgres::PgPoolOptions; -use torii_dojo::decoder::DojoDecoder; -use torii_dojo::store::postgres::PgStore; -use torii_dojo::DojoToriiError; -use torii_introspect_sql_sink::IntrospectPgDb; -use torii_test_utils::{resolve_path_like, EventIterator, FakeProvider}; - -const DB_URL: &str = "postgres://torii:torii@localhost:5432/torii"; -const CHAIN_DATA_PATH: &str = "~/tc-tests/pistols"; -const SCHEMA_NAME: &str = "pistols"; -// const CHAIN_DATA_PATH: &str = "~/tc-tests/blob-arena"; -// const SCHEMA_NAME: &str = "blob_arena"; -const BATCH_SIZE: usize = 1000; - -#[tokio::main] -async fn main() { - let chain_path = resolve_path_like(CHAIN_DATA_PATH); - let events_path = chain_path.join("events"); - let contracts_path = chain_path.join("model-contracts"); - let provider = FakeProvider::new(contracts_path); - let mut event_iterator = EventIterator::new(events_path); - - let pool = PgPoolOptions::new().connect(DB_URL).await.unwrap(); - let decoder = DojoDecoder::, _>::new(pool.clone(), provider); - let db = IntrospectPgDb::new(pool.clone(), SCHEMA_NAME); - decoder.store.initialize().await.unwrap(); - db.initialize_introspect_sql_sink().await.unwrap(); - - let mut event_n = 0; - let mut success = 0; - let mut running = true; - while running { - let mut msgs = Vec::with_capacity(BATCH_SIZE); - for _ in 0..BATCH_SIZE { - let Some(event) = event_iterator.next() else { - running = false; - break; - }; - event_n += 1; - match decoder.decode_raw_event(&event).await { - Ok(msg) => { - msgs.push(msg); - } - Err(DojoToriiError::UnknownDojoEventSelector(_)) => { - println!("Unknown event selector, skipping event"); - } - Err(err) => { - println!("Failed to decode event: {err:?}"); - } - }; - } - let msgs_ref = msgs.iter().collect_vec(); - for res in db.process_messages(msgs_ref).await.unwrap() { - match res { - Err(err) => println!("Failed to process message: {err:?}"), - Ok(()) => success += 1, - } - } - println!( - "Processed batch of events, total events processed: {event_n}, successful: {success}" - ); - } -} From 78cc10f8bc67bac015fffdeef1849e8066c6cb73 Mon Sep 17 00:00:00 2001 From: Bengineer Date: Tue, 31 Mar 2026 12:21:07 +0100 Subject: [PATCH 15/21] feat: update dependencies and refactor database handling for improved SQLite support --- Cargo.lock | 4 + Cargo.toml | 2 +- .../tests/sqlite_prepared_statements.rs | 2 +- .../torii-entities-historical-sink/src/lib.rs | 12 +- crates/torii-runtime-common/src/database.rs | 103 +++++++++--------- src/etl/engine_db.rs | 4 +- 6 files changed, 64 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f356f85e..7dbe17f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -987,6 +987,7 @@ dependencies = [ [[package]] name = "dojo-introspect" version = "0.1.0" +source = "git+https://github.com/dojoengine/dojo-introspect?rev=fd99a0a#fd99a0a3fe5698e1d26bbf06d8ff7d5fcc541a77" dependencies = [ "async-trait", "introspect-rust-macros", @@ -1958,6 +1959,7 @@ dependencies = [ [[package]] name = "introspect-events" version = "0.1.2" +source = "git+https://github.com/cartridge-gg/introspect?rev=b89ee9e#b89ee9ead02df170195bb4f67a48e4308edab855" dependencies = [ "cainome-cairo-serde", "introspect-types", @@ -1969,6 +1971,7 @@ dependencies = [ [[package]] name = "introspect-rust-macros" version = "0.1.0" +source = "git+https://github.com/cartridge-gg/introspect?rev=b89ee9e#b89ee9ead02df170195bb4f67a48e4308edab855" dependencies = [ "paste", "proc-macro2", @@ -1980,6 +1983,7 @@ dependencies = [ [[package]] name = "introspect-types" version = "0.1.2" +source = "git+https://github.com/cartridge-gg/introspect?rev=b89ee9e#b89ee9ead02df170195bb4f67a48e4308edab855" dependencies = [ "blake3", "convert_case", diff --git a/Cargo.toml b/Cargo.toml index f12d4bb1..57ffa5ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -184,7 +184,7 @@ prost-types.workspace = true rustls-pemfile = "2.0" serde_json.workspace = true serde.workspace = true -sqlx.workspace = true +sqlx = { workspace = true, features = ["sqlite"] } starknet.workspace = true tokio-stream.workspace = true tokio-rustls = { version = "0.26", default-features = false, features = [ diff --git a/crates/torii-ecs-sink/tests/sqlite_prepared_statements.rs b/crates/torii-ecs-sink/tests/sqlite_prepared_statements.rs index 58487346..bed8880b 100644 --- a/crates/torii-ecs-sink/tests/sqlite_prepared_statements.rs +++ b/crates/torii-ecs-sink/tests/sqlite_prepared_statements.rs @@ -24,7 +24,7 @@ fn runtime_sqlite_queries_avoid_uncached_prepare_and_inline_format_sql() { let files = [ "crates/torii-ecs-sink/src/grpc_service.rs", "crates/torii-entities-historical-sink/src/lib.rs", - "crates/introspect-sqlite-sink/src/processor.rs", + "crates/introspect-sql-sink/src/sqlite/table.rs", "crates/torii-erc20/src/storage.rs", "crates/torii-erc721/src/storage.rs", "crates/torii-erc1155/src/storage.rs", diff --git a/crates/torii-entities-historical-sink/src/lib.rs b/crates/torii-entities-historical-sink/src/lib.rs index 80f37c64..b5fa2bfc 100644 --- a/crates/torii-entities-historical-sink/src/lib.rs +++ b/crates/torii-entities-historical-sink/src/lib.rs @@ -18,7 +18,8 @@ use torii_sql::connection::DbOption; use torii_sql::DbBackend; const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); -const SQLITE_SCHEMA_STATE_TABLE: &str = "introspect_sink_schema_state"; +const SQLITE_FETCH_SCHEMA_STATE_QUERY: &str = + "SELECT table_schema_json FROM introspect_sink_schema_state WHERE alive != 0"; #[derive(Clone, Debug, Default)] pub enum HistoricalNamespace { @@ -140,11 +141,9 @@ impl EntitiesHistoricalSink { match self.backend { DbBackend::Sqlite => { - let rows = sqlx::query(&format!( - "SELECT table_schema_json FROM {SQLITE_SCHEMA_STATE_TABLE} WHERE alive != 0" - )) - .fetch_all(&self.pool) - .await?; + let rows = sqlx::query(SQLITE_FETCH_SCHEMA_STATE_QUERY) + .fetch_all(&self.pool) + .await?; for row in rows { let schema_json: String = row.try_get("table_schema_json")?; let schema: TableSchema = serde_json::from_str(&schema_json)?; @@ -275,6 +274,7 @@ impl EntitiesHistoricalSink { async fn load_source_columns(&self, base_name: &str) -> Result> { match self.backend { DbBackend::Sqlite => { + // sqlite-dynamic-ok let rows = sqlx::query(&format!( "PRAGMA table_info({})", quote_sqlite_identifier(base_name) diff --git a/crates/torii-runtime-common/src/database.rs b/crates/torii-runtime-common/src/database.rs index 9dc5f25c..ef409403 100644 --- a/crates/torii-runtime-common/src/database.rs +++ b/crates/torii-runtime-common/src/database.rs @@ -1,28 +1,38 @@ -use anyhow::{bail, Result as AnyhowResult}; +use anyhow::{bail, Result as AnyResult}; use std::path::{Path, PathBuf}; -use std::str::FromStr; use torii_sql::connection::DbBackend; pub const DEFAULT_SQLITE_MAX_CONNECTIONS: u32 = 500; +pub fn backend_from_url_or_path(value: &str) -> DbBackend { + if value.starts_with("postgres://") || value.starts_with("postgresql://") { + DbBackend::Postgres + } else { + DbBackend::Sqlite + } +} + pub fn validate_uniform_backends( named_urls: &[(&str, &str)], - _mixed_backend_message: &str, -) -> Result { - let ((_, first_url), rest) = named_urls - .split_first() - .ok_or_else(|| "at least one database URL must be provided".to_string())?; - let expected_backend = DbBackend::from_str(first_url).map_err(|_| { - format!("Error parsing database URL '{first_url}': Unsupported database type") - })?; - for (name, url) in rest { - let backend = DbBackend::from_str(url).map_err(|_| { - format!("Error validating database {name} URL '{url}': Unsupported database type") - })?; - if backend != expected_backend { - return Err(format!("{name}={backend}({url})")); - } + mixed_backend_message: &str, +) -> AnyResult { + let Some((_, first_url)) = named_urls.first() else { + bail!("at least one database URL must be provided"); + }; + + let expected_backend = backend_from_url_or_path(first_url); + if named_urls + .iter() + .any(|(_, url)| backend_from_url_or_path(url) != expected_backend) + { + let summary = named_urls + .iter() + .map(|(name, url)| format!("{name}={:?}({url})", backend_from_url_or_path(url))) + .collect::>() + .join(", "); + bail!("{mixed_backend_message}. current: {summary}"); } + Ok(expected_backend) } @@ -73,7 +83,7 @@ pub fn resolve_token_db_setup( db_dir: &Path, engine_database_url: Option<&str>, storage_database_url: Option<&str>, -) -> AnyhowResult { +) -> AnyResult { let engine_url = engine_database_url.map_or_else( || db_dir.join("engine.db").to_string_lossy().to_string(), ToOwned::to_owned, @@ -97,37 +107,21 @@ pub fn resolve_token_db_setup( "erc1155.db", ); - let engine_backend = DbBackend::from_str(&engine_url).map_err(|_| { - anyhow::anyhow!( - "Error parsing engine database URL '{engine_url}': Unsupported database type" - ) - })?; - let erc20_backend = DbBackend::from_str(&erc20_url).map_err(|_| { - anyhow::anyhow!("Error parsing ERC20 database URL '{erc20_url}': Unsupported database type") - })?; - - let erc721_backend = DbBackend::from_str(&erc721_url).map_err(|_| { - anyhow::anyhow!( - "Error parsing ERC721 database URL '{erc721_url}': Unsupported database type" - ) - })?; - let erc1155_backend = DbBackend::from_str(&erc1155_url).map_err(|_| { - anyhow::anyhow!( - "Error parsing ERC1155 database URL '{erc1155_url}': Unsupported database type" - ) - })?; - - if let Some(url) = storage_database_url { - let backend: DbBackend = DbBackend::from_str(url).map_err(|_| { - anyhow::anyhow!("Error parsing storage database URL '{url}': Unsupported database type") - })?; - if backend == DbBackend::Postgres - && (erc20_backend != DbBackend::Postgres - || erc721_backend != DbBackend::Postgres - || erc1155_backend != DbBackend::Postgres) - { - bail!("Engine is configured for Postgres but one or more token storages resolved to SQLite. Set --storage-database-url to the same Postgres URL."); - } + let engine_backend = backend_from_url_or_path(&engine_url); + let erc20_backend = backend_from_url_or_path(&erc20_url); + let erc721_backend = backend_from_url_or_path(&erc721_url); + let erc1155_backend = backend_from_url_or_path(&erc1155_url); + + if engine_database_url + .map(backend_from_url_or_path) + .is_some_and(|backend| backend == DbBackend::Postgres) + && (erc20_backend != DbBackend::Postgres + || erc721_backend != DbBackend::Postgres + || erc1155_backend != DbBackend::Postgres) + { + bail!( + "Engine is configured for Postgres but one or more token storages resolved to SQLite. Set --storage-database-url to the same Postgres URL." + ); } Ok(TokenDbSetup { @@ -175,8 +169,9 @@ mod tests { db_dir, Some("postgres://localhost/torii"), Some("./torii-data"), - ) - .expect_err("expected mixed backend validation error"); + ); + println!("{err:?}"); + let err = err.expect_err("expected mixed backend validation error"); assert!(err .to_string() .contains("Engine is configured for Postgres")); @@ -218,8 +213,8 @@ mod tests { "mixed backends", ) .expect_err("expected mixed backend error"); - assert!(err.contains("mixed backends")); - assert!(err.contains("engine=Postgres")); - assert!(err.contains("storage=Sqlite")); + assert!(err.to_string().contains("mixed backends")); + assert!(err.to_string().contains("engine=Postgres")); + assert!(err.to_string().contains("storage=Sqlite")); } } diff --git a/src/etl/engine_db.rs b/src/etl/engine_db.rs index 94215a7d..d3e9e93f 100644 --- a/src/etl/engine_db.rs +++ b/src/etl/engine_db.rs @@ -4,7 +4,9 @@ //! This will be enhanced with actual Torii features in the future. use anyhow::{Context, Result}; -use sqlx::{any::AnyPoolOptions, sqlite::SqliteConnectOptions, Any, ConnectOptions, Pool, Row}; +use sqlx::any::AnyPoolOptions; +use sqlx::sqlite::SqliteConnectOptions; +use sqlx::{Any, ConnectOptions, Pool, Row}; use starknet::core::types::Felt; use std::collections::HashMap; use std::str::FromStr; From 59dd33a4389ac073068b50de1f70ff0eb1093d07 Mon Sep 17 00:00:00 2001 From: Bengineer Date: Wed, 1 Apr 2026 09:49:28 +0100 Subject: [PATCH 16/21] refactor: replace StorageBackend enum with DbBackend for consistency in database handling --- bins/torii-introspect-bin/src/config.rs | 20 ++++----- bins/torii-introspect-bin/src/main.rs | 17 ++++---- crates/torii-ecs-sink/src/grpc_service.rs | 51 +++++++++++------------ 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/bins/torii-introspect-bin/src/config.rs b/bins/torii-introspect-bin/src/config.rs index 2af7c2bf..ae3c28fb 100644 --- a/bins/torii-introspect-bin/src/config.rs +++ b/bins/torii-introspect-bin/src/config.rs @@ -2,12 +2,7 @@ use anyhow::{bail, Result}; use clap::{ArgGroup, Parser}; use starknet::core::types::Felt; use std::path::{Path, PathBuf}; - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum StorageBackend { - Postgres, - Sqlite, -} +use torii_sql::DbBackend; /// Dojo introspect indexer backed by PostgreSQL or SQLite. /// @@ -187,11 +182,11 @@ impl Config { models } - pub fn storage_backend(&self) -> StorageBackend { + pub fn storage_backend(&self) -> DbBackend { if self.storage_database_url.is_some() { - StorageBackend::Postgres + DbBackend::Postgres } else { - StorageBackend::Sqlite + DbBackend::Sqlite } } @@ -210,7 +205,10 @@ impl Config { Ok(url.clone()) } Some(_) => bail!("--storage-database-url must be a PostgreSQL URL"), - None => Ok(db_dir.join("introspect.db").to_string_lossy().to_string()), + None => Ok(format!( + "sqlite://{}", + db_dir.join("introspect.db").to_string_lossy() + )), } } @@ -272,7 +270,7 @@ mod tests { fn sqlite_is_default_when_storage_database_url_is_omitted() { let cfg = Config::parse_from(["torii-server", "--contract", "0x1"]); - assert_eq!(cfg.storage_backend(), StorageBackend::Sqlite); + assert_eq!(cfg.storage_backend(), DbBackend::Sqlite); assert!(cfg .storage_database_url(Path::new("./torii-data")) .unwrap() diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index c1e4f2f1..b93b1332 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -4,12 +4,13 @@ mod config; use anyhow::Result; use clap::Parser; -use config::{Config, StorageBackend}; +use config::Config; use sqlx::postgres::PgPoolOptions; -use sqlx::sqlite::SqlitePoolOptions; +use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; use starknet::core::types::Felt; use std::collections::{HashMap, HashSet}; use std::path::Path; +use std::str::FromStr; use std::sync::Arc; use tokio::sync::RwLock; use tonic::codec::CompressionEncoding; @@ -51,7 +52,7 @@ use torii_runtime_common::database::{ resolve_token_db_setup, TokenDbSetup, DEFAULT_SQLITE_MAX_CONNECTIONS, }; use torii_runtime_common::token_support::{resolve_installed_token_support, InstalledTokenSupport}; -use torii_sql::sqlite::{is_sqlite_memory_path, sqlite_connect_options}; +use torii_sql::DbBackend; type StarknetProvider = starknet::providers::jsonrpc::JsonRpcClient; @@ -636,12 +637,12 @@ async fn run_indexer(config: Config) -> Result<()> { }, )); - if matches!(backend, StorageBackend::Sqlite) { + if matches!(backend, DbBackend::Sqlite) { tokio::fs::create_dir_all(db_dir).await?; } match backend { - StorageBackend::Postgres => { + DbBackend::Postgres => { run_with_postgres( &config, &storage_database_url, @@ -660,7 +661,7 @@ async fn run_indexer(config: Config) -> Result<()> { ) .await?; } - StorageBackend::Sqlite => { + DbBackend::Sqlite => { run_with_sqlite( &config, &storage_database_url, @@ -881,10 +882,10 @@ async fn run_with_sqlite( extractor: Box, ) -> Result<()> { let token_provider = Arc::new(provider.clone()); - let options = sqlite_connect_options(storage_database_url)?; + let options = SqliteConnectOptions::from_str(storage_database_url)?.create_if_missing(true); let max_db_connections = match config.max_db_connections { Some(limit) => limit.max(1), - None if is_sqlite_memory_path(storage_database_url) => 1, + None if options.is_in_memory() => 1, None => DEFAULT_SQLITE_MAX_CONNECTIONS, }; let pool = SqlitePoolOptions::new() diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index 363caf76..7fccb0fa 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -40,6 +40,7 @@ use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; use sqlx::{Any, AnyConnection, Column, ConnectOptions, Pool, QueryBuilder, Row}; use starknet::core::types::Felt; use std::collections::{HashMap, HashSet, VecDeque}; +use std::fs; use std::pin::Pin; use std::str::FromStr; use std::sync::Arc; @@ -887,15 +888,21 @@ impl EcsService { ("erc1155", &self.state.erc1155_url), ] { if let Some(url) = url { - let path = sqlite_db_path(url); - let file_exists = std::path::Path::new(&path).exists(); - tracing::info!( - schema, - path = %path, - file_exists, - "Attaching ERC database" - ); - attach_sqlite_database(&mut conn, schema, url).await?; + let options = SqliteConnectOptions::from_str(url)?; + match options.is_in_memory() { + true => tracing::info!(schema, "Attaching in-memory ERC database"), + false => { + let path = options.get_filename(); + let file_exists = path.exists(); + tracing::info!( + schema, + path = %path.display(), + file_exists, + "Attaching ERC database" + ) + } + }; + attach_sqlite_database(&mut conn, schema, &options).await?; match sqlx::query(sqlite_master_preview_sql(schema)) .fetch_all(&mut *conn) .await @@ -4896,7 +4903,8 @@ async fn attach_sqlite_databases( ("erc1155", erc1155_url), ] { if let Some(url) = url { - attach_sqlite_database(conn, schema, url).await?; + let options = SqliteConnectOptions::from_str(url)?; + attach_sqlite_database(conn, schema, &options).await?; } } Ok(()) @@ -4905,7 +4913,7 @@ async fn attach_sqlite_databases( async fn attach_sqlite_database( conn: &mut AnyConnection, schema: &str, - url: &str, + options: &SqliteConnectOptions, ) -> sqlx::Result<()> { let attached = sqlx::query_scalar::("SELECT 1 FROM pragma_database_list WHERE name = ? LIMIT 1") @@ -4916,9 +4924,14 @@ async fn attach_sqlite_database( if attached { return Ok(()); } + let path = options.get_filename(); - let path = sqlite_db_path(url).replace('\'', "''"); + if let Some(parent) = path.parent() { + fs::create_dir_all(parent)?; + } + fs::OpenOptions::new().create(true).write(true).open(path)?; // sqlite-dynamic-ok: ATTACH requires the database path and schema identifier in SQL text. + let path = path.to_string_lossy().replace('\'', "''"); sqlx::query(&format!("ATTACH DATABASE '{path}' AS {schema}")) .execute(&mut *conn) .await?; @@ -4934,20 +4947,6 @@ fn sqlite_master_preview_sql(schema: &str) -> &'static str { } } -fn sqlite_db_path(url: &str) -> String { - let path = url - .strip_prefix("sqlite://") - .or_else(|| url.strip_prefix("sqlite:")) - .unwrap_or(url); - let p = std::path::Path::new(path); - if let (Some(parent), Some(file_name)) = (p.parent(), p.file_name()) { - if let Ok(abs_parent) = parent.canonicalize() { - return abs_parent.join(file_name).to_string_lossy().into_owned(); - } - } - path.to_string() -} - fn get_db_backend(url: &str) -> DbBackend { if url.starts_with("postgres") { DbBackend::Postgres From ffabcc89144af5a1bda6a3abdb52d84600c38744 Mon Sep 17 00:00:00 2001 From: Bengineer Date: Wed, 1 Apr 2026 17:47:31 +0100 Subject: [PATCH 17/21] Refactor historical sink and event processing - Removed the `torii-entities-historical-sink` crate, consolidating its functionality into the main application. - Deleted the `restart copy.rs` example and updated the `restart.rs` example to improve event processing logic. - Enhanced the `run_events` function to handle `IntrospectBody` messages with `CreateTable` and set `append_only` to true. - Increased the batch size for event processing from 1000 to 2000 for improved performance. - Updated error handling during the initialization of the introspect SQL sink to ensure proper logging of errors. --- Cargo.lock | 26 +- Cargo.toml | 4 +- bins/torii-arcade/Cargo.toml | 1 - bins/torii-arcade/src/main.rs | 17 +- bins/torii-introspect-bin/Cargo.toml | 1 - bins/torii-introspect-bin/src/config.rs | 26 +- bins/torii-introspect-bin/src/main.rs | 48 +- crates/dojo/src/decoder.rs | 22 +- .../migrations/postgres/003_store.sql | 1 + .../migrations/sqlite/002_schema_state.sql | 1 + crates/introspect-sql-sink/src/backend.rs | 53 +- crates/introspect-sql-sink/src/error.rs | 56 +- .../src/postgres/append_only.rs | 106 ++ .../src/postgres/backend.rs | 64 +- .../src/postgres/create.rs | 12 +- .../src/postgres/insert.rs | 14 +- .../introspect-sql-sink/src/postgres/json.rs | 48 +- .../introspect-sql-sink/src/postgres/mod.rs | 1 + .../introspect-sql-sink/src/postgres/query.rs | 39 +- .../introspect-sql-sink/src/postgres/types.rs | 2 +- crates/introspect-sql-sink/src/processor.rs | 90 +- crates/introspect-sql-sink/src/runtime.rs | 6 +- .../src/sqlite/append_only.rs | 71 + .../introspect-sql-sink/src/sqlite/backend.rs | 96 +- crates/introspect-sql-sink/src/sqlite/mod.rs | 1 + .../introspect-sql-sink/src/sqlite/record.rs | 68 +- .../introspect-sql-sink/src/sqlite/table.rs | 27 +- .../introspect-sql-sink/src/sqlite/types.rs | 22 +- crates/introspect-sql-sink/src/table.rs | 45 +- crates/introspect-sql-sink/src/tables.rs | 104 +- crates/introspect/src/events.rs | 15 + crates/torii-ecs-sink/src/grpc_service.rs | 3 + .../tests/sqlite_prepared_statements.rs | 1 - .../torii-entities-historical-sink/Cargo.toml | 34 - .../torii-entities-historical-sink/src/lib.rs | 1165 ----------------- examples/introspect/restart copy.rs | 109 -- examples/introspect/restart.rs | 17 +- sqlite-data.db-journal | Bin 1646216 -> 1642112 bytes 38 files changed, 745 insertions(+), 1671 deletions(-) create mode 100644 crates/introspect-sql-sink/src/postgres/append_only.rs create mode 100644 crates/introspect-sql-sink/src/sqlite/append_only.rs delete mode 100644 crates/torii-entities-historical-sink/Cargo.toml delete mode 100644 crates/torii-entities-historical-sink/src/lib.rs delete mode 100644 examples/introspect/restart copy.rs diff --git a/Cargo.lock b/Cargo.lock index 7dbe17f6..adb5d43c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -987,7 +987,7 @@ dependencies = [ [[package]] name = "dojo-introspect" version = "0.1.0" -source = "git+https://github.com/dojoengine/dojo-introspect?rev=fd99a0a#fd99a0a3fe5698e1d26bbf06d8ff7d5fcc541a77" +source = "git+https://github.com/dojoengine/dojo-introspect?rev=c45d711#c45d711236c856bc60d567e43965b2043d5cb2b0" dependencies = [ "async-trait", "introspect-rust-macros", @@ -4803,7 +4803,6 @@ dependencies = [ "torii-config-common", "torii-dojo", "torii-ecs-sink", - "torii-entities-historical-sink", "torii-erc1155", "torii-erc20", "torii-erc721", @@ -4939,28 +4938,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "torii-entities-historical-sink" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "introspect-types", - "itertools 0.14.0", - "primitive-types 0.14.0", - "serde", - "serde_json", - "sqlx", - "starknet", - "thiserror 2.0.18", - "tokio", - "torii", - "torii-introspect", - "torii-runtime-common", - "torii-sql", - "tracing", -] - [[package]] name = "torii-erc1155" version = "0.1.0" @@ -5121,7 +5098,6 @@ dependencies = [ "torii-controllers-sink", "torii-dojo", "torii-ecs-sink", - "torii-entities-historical-sink", "torii-erc1155", "torii-erc20", "torii-erc721", diff --git a/Cargo.toml b/Cargo.toml index 57ffa5ce..c5fd7515 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ members = [ "crates/torii-controllers-sink", "crates/arcade-sink", "crates/torii-ecs-sink", - "crates/torii-entities-historical-sink", "crates/torii-erc20", "crates/torii-erc721", "crates/torii-erc1155", @@ -112,7 +111,7 @@ tonic-build = "0.12" introspect-events = { git = "https://github.com/cartridge-gg/introspect", rev = "b89ee9e" } introspect-types = { git = "https://github.com/cartridge-gg/introspect", rev = "b89ee9e" } introspect-rust-macros = { git = "https://github.com/cartridge-gg/introspect", rev = "b89ee9e" } -dojo-introspect = { git = "https://github.com/dojoengine/dojo-introspect", rev = "fd99a0a" } +dojo-introspect = { git = "https://github.com/dojoengine/dojo-introspect", rev = "c45d711" } # Utils @@ -132,7 +131,6 @@ torii-log-sink.path = "crates/torii-log-sink" torii-controllers-sink.path = "crates/torii-controllers-sink" torii-arcade-sink.path = "crates/arcade-sink" torii-ecs-sink.path = "crates/torii-ecs-sink" -torii-entities-historical-sink.path = "crates/torii-entities-historical-sink" torii-erc20.path = "crates/torii-erc20" torii-erc721.path = "crates/torii-erc721" torii-erc1155.path = "crates/torii-erc1155" diff --git a/bins/torii-arcade/Cargo.toml b/bins/torii-arcade/Cargo.toml index 926ce83c..38d0fd21 100644 --- a/bins/torii-arcade/Cargo.toml +++ b/bins/torii-arcade/Cargo.toml @@ -15,7 +15,6 @@ torii-config-common.workspace = true torii-arcade-sink.workspace = true torii-dojo.workspace = true torii-ecs-sink.workspace = true -torii-entities-historical-sink.workspace = true torii-erc20.workspace = true torii-erc721.workspace = true torii-erc1155.workspace = true diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index 208f90c5..e8d88ddb 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -31,7 +31,6 @@ use torii_dojo::external_contract::{ use torii_dojo::store::DojoStoreTrait; use torii_ecs_sink::proto::world::world_server::WorldServer; use torii_ecs_sink::{EcsSink, FILE_DESCRIPTOR_SET as ECS_DESCRIPTOR_SET}; -use torii_entities_historical_sink::EntitiesHistoricalSink; use torii_erc1155::proto::erc1155_server::Erc1155Server; use torii_erc1155::{ Erc1155Decoder, Erc1155MetadataCommandHandler, Erc1155Service, Erc1155Sink, Erc1155Storage, @@ -440,20 +439,8 @@ async fn run_indexer(config: Config) -> Result<()> { .register_encoded_file_descriptor_set(ECS_DESCRIPTOR_SET) .register_encoded_file_descriptor_set(ARCADE_DESCRIPTOR_SET); - let historical_sink = Box::new( - EntitiesHistoricalSink::new( - &storage_database_url, - config.max_db_connections, - (), - historical_models, - ) - .await?, - ); - let arcade_projection_pipeline = ArcadeProjectionPipeline::new(vec![ - Box::new(introspect_sink), - historical_sink, - Box::new(arcade_sink), - ]); + let arcade_projection_pipeline = + ArcadeProjectionPipeline::new(vec![Box::new(introspect_sink), Box::new(arcade_sink)]); let mut torii_config = torii::ToriiConfig::builder() .port(config.port) diff --git a/bins/torii-introspect-bin/Cargo.toml b/bins/torii-introspect-bin/Cargo.toml index 736ceb8f..68aecc28 100644 --- a/bins/torii-introspect-bin/Cargo.toml +++ b/bins/torii-introspect-bin/Cargo.toml @@ -18,7 +18,6 @@ torii-erc20.workspace = true torii-erc721.workspace = true torii-erc1155.workspace = true torii-ecs-sink.workspace = true -torii-entities-historical-sink.workspace = true torii-introspect-sql-sink = { workspace = true, features = [ "postgres", "sqlite", diff --git a/bins/torii-introspect-bin/src/config.rs b/bins/torii-introspect-bin/src/config.rs index ae3c28fb..58bda6c3 100644 --- a/bins/torii-introspect-bin/src/config.rs +++ b/bins/torii-introspect-bin/src/config.rs @@ -1,6 +1,7 @@ use anyhow::{bail, Result}; use clap::{ArgGroup, Parser}; use starknet::core::types::Felt; +use std::collections::HashSet; use std::path::{Path, PathBuf}; use torii_sql::DbBackend; @@ -172,14 +173,8 @@ impl Config { Self::parse_addresses("ERC1155", &self.erc1155) } - pub fn historical_models(&self) -> Vec { - let mut models = Vec::with_capacity(self.historical.len()); - for model in &self.historical { - if !model.is_empty() && !models.contains(model) { - models.push(model.clone()); - } - } - models + pub fn historical_models(&self) -> &[String] { + &self.historical } pub fn storage_backend(&self) -> DbBackend { @@ -223,6 +218,21 @@ impl Config { } } +pub fn parse_historical_models( + historical: &[String], + contracts: &[Felt], +) -> Result> { + let mut models = HashSet::with_capacity(historical.len()); + for model in historical { + let parts: Vec<&str> = model.splitn(2, ':').collect(); + match parts.len() { + 1 => contracts.iter().for_each(|&addr| {models.insert((addr, parts[0].to_string()));}), + 2 => {models.insert((Felt::from_hex(parts[0])?, parts[1].to_string()));}, + _ => bail!("Invalid historical model format: {model}. Expected format is either `ModelName` or `0xContractAddress:ModelName`"), + } + } + Ok(models) +} #[cfg(test)] mod tests { use super::*; diff --git a/bins/torii-introspect-bin/src/main.rs b/bins/torii-introspect-bin/src/main.rs index b93b1332..ef788d29 100644 --- a/bins/torii-introspect-bin/src/main.rs +++ b/bins/torii-introspect-bin/src/main.rs @@ -31,7 +31,6 @@ use torii_dojo::external_contract::{ use torii_dojo::store::DojoStoreTrait; use torii_ecs_sink::proto::world::world_server::WorldServer; use torii_ecs_sink::{EcsSink, FILE_DESCRIPTOR_SET as ECS_DESCRIPTOR_SET}; -use torii_entities_historical_sink::EntitiesHistoricalSink; use torii_erc1155::proto::erc1155_server::Erc1155Server; use torii_erc1155::{ Erc1155Decoder, Erc1155MetadataCommandHandler, Erc1155Service, Erc1155Sink, Erc1155Storage, @@ -54,6 +53,8 @@ use torii_runtime_common::database::{ use torii_runtime_common::token_support::{resolve_installed_token_support, InstalledTokenSupport}; use torii_sql::DbBackend; +use crate::config::parse_historical_models; + type StarknetProvider = starknet::providers::jsonrpc::JsonRpcClient; type ReflectionBuilder = tonic_reflection::server::Builder<'static>; @@ -491,7 +492,7 @@ async fn run_indexer(config: Config) -> Result<()> { erc1155: !token_targets.erc1155.is_empty(), }, ); - let historical_models = config.historical_models(); + let historical_models = parse_historical_models(config.historical_models(), &contracts)?; let token_db_setup = if installed_token_support.any() { Some(resolve_token_db_setup( db_dir, @@ -655,7 +656,7 @@ async fn run_indexer(config: Config) -> Result<()> { decoder_registry.clone(), contract_type_registry.clone(), installed_external_decoders.clone(), - historical_models.clone(), + historical_models, provider, extractor, ) @@ -674,7 +675,7 @@ async fn run_indexer(config: Config) -> Result<()> { decoder_registry.clone(), contract_type_registry.clone(), installed_external_decoders.clone(), - historical_models.clone(), + historical_models, provider, extractor, ) @@ -698,7 +699,7 @@ async fn run_with_postgres( decoder_registry: SharedDecoderRegistry, contract_type_registry: SharedContractTypeRegistry, installed_external_decoders: HashSet, - historical_models: Vec, + historical_models: HashSet<(Felt, String)>, provider: StarknetProvider, extractor: Box, ) -> Result<()> { @@ -709,8 +710,10 @@ async fn run_with_postgres( .connect(storage_database_url) .await?; - let decoder = DojoDecoder::new(pool.clone(), provider); + let mut decoder = DojoDecoder::new(pool.clone(), provider); let introspect_sink = IntrospectPgDb::new(pool.clone(), NamespaceMode::Address); + + decoder.append_historical(historical_models); decoder.initialize().await?; introspect_sink.initialize_introspect_sql_sink().await?; decoder.load_tables(&[]).await?; @@ -751,16 +754,7 @@ async fn run_with_postgres( .add_sink_boxed(Box::new(ecs_sink)) .add_sink_boxed(Box::new( OrderedSinkPipeline::new("introspect-projection-pipeline") - .push(Box::new(introspect_sink)) - .push(Box::new( - EntitiesHistoricalSink::new( - storage_database_url, - config.max_db_connections, - (), - historical_models, - ) - .await?, - )), + .push(Box::new(introspect_sink)), )); if let Some(tls) = config.tls_config()? { torii_config = torii_config.with_tls(tls); @@ -877,7 +871,7 @@ async fn run_with_sqlite( decoder_registry: SharedDecoderRegistry, contract_type_registry: SharedContractTypeRegistry, installed_external_decoders: HashSet, - historical_models: Vec, + historical_models: HashSet<(Felt, String)>, provider: StarknetProvider, extractor: Box, ) -> Result<()> { @@ -901,7 +895,8 @@ async fn run_with_sqlite( .await?; sqlx::query("PRAGMA foreign_keys=ON").execute(&pool).await?; - let decoder = DojoDecoder::new(pool.clone(), provider); + let mut decoder = DojoDecoder::new(pool.clone(), provider); + decoder.append_historical(historical_models); decoder.initialize().await?; decoder.load_tables(&[]).await?; @@ -940,20 +935,9 @@ async fn run_with_sqlite( .add_decoder(decoder) .add_sink_boxed(Box::new(ecs_sink)) .add_sink_boxed(Box::new( - OrderedSinkPipeline::new("introspect-projection-pipeline") - .push(Box::new(IntrospectSqliteDb::new( - pool.clone(), - NamespaceMode::Address, - ))) - .push(Box::new( - EntitiesHistoricalSink::new( - storage_database_url, - config.max_db_connections, - (), - historical_models, - ) - .await?, - )), + OrderedSinkPipeline::new("introspect-projection-pipeline").push(Box::new( + IntrospectSqliteDb::new(pool.clone(), NamespaceMode::Address), + )), )); if let Some(tls) = config.tls_config()? { torii_config = torii_config.with_tls(tls); diff --git a/crates/dojo/src/decoder.rs b/crates/dojo/src/decoder.rs index 3d91f92b..af140dbd 100644 --- a/crates/dojo/src/decoder.rs +++ b/crates/dojo/src/decoder.rs @@ -9,6 +9,7 @@ use dojo_introspect::events::{ ModelWithSchemaRegistered, StoreDelRecord, StoreSetRecord, StoreUpdateMember, StoreUpdateRecord, }; +use dojo_introspect::selector::compute_selector_from_dojo_tag; use dojo_introspect::serde::dojo_primary_def; use dojo_introspect::{DojoSchema, DojoSchemaFetcher}; use introspect_types::{ @@ -18,14 +19,14 @@ use introspect_types::{ use itertools::Itertools; use starknet::core::types::EmittedEvent; use starknet_types_core::felt::Felt; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::fmt::Debug; use std::sync::RwLock; use torii::etl::event::EmittedEventExt; use torii::etl::{Decoder, Envelope, EventMsg}; use torii_introspect::events::{IntrospectBody, IntrospectMsg}; use torii_introspect::schema::{TableMetadata, TableSchema}; -use torii_introspect::EventId; +use torii_introspect::{CreateTable, EventId}; pub const DOJO_ID_FIELD_NAME: &str = "entity_id"; @@ -33,6 +34,7 @@ pub struct DojoDecoder { pub tables: RwLock>, pub store: Store, pub fetcher: F, + pub append_only: HashSet<(Felt, Felt)>, } fn deserialize_data<'a, T>(keys: &[Felt], data: &'a [Felt]) -> DojoToriiResult @@ -120,9 +122,15 @@ where tables: Default::default(), store, fetcher, + append_only: HashSet::new(), + } + } + pub fn append_historical(&mut self, models: HashSet<(Felt, String)>) { + for (address, name) in models { + let table_id = compute_selector_from_dojo_tag(&name).unwrap(); + self.append_only.insert((address, table_id)); } } - pub async fn load_tables(&self, owners: &[Felt]) -> DojoToriiResult<()> { let new = self.read_tables(owners).await?; let mut tables = self.tables.write()?; @@ -150,6 +158,7 @@ where tables: RwLock::new(tables), store, fetcher, + append_only: HashSet::new(), } } @@ -160,7 +169,7 @@ where name: &str, schema: DojoSchema, metadata: &impl TableMetadata, - ) -> DojoToriiResult { + ) -> DojoToriiResult { let full_table = DojoTable::from_schema(schema, namespace, name, dojo_primary_def()); self.save_table( owner, @@ -180,7 +189,10 @@ where } } self.tables.write()?.insert(id, table); - Ok(full_table.into()) + Ok(CreateTable::from_schema( + full_table.into(), + self.append_only.contains(&(owner.clone(), id)), + )) } pub async fn update_table( diff --git a/crates/introspect-sql-sink/migrations/postgres/003_store.sql b/crates/introspect-sql-sink/migrations/postgres/003_store.sql index f5a83a78..461fd11f 100644 --- a/crates/introspect-sql-sink/migrations/postgres/003_store.sql +++ b/crates/introspect-sql-sink/migrations/postgres/003_store.sql @@ -24,6 +24,7 @@ CREATE TABLE IF NOT EXISTS introspect.db_tables ( name TEXT NOT NULL, "owner" felt252 NOT NULL, primary_def introspect.primary_def NOT NULL, + append_only BOOLEAN NOT NULL DEFAULT FALSE, alive BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), diff --git a/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql b/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql index 43ec73bc..1c345fb2 100644 --- a/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql +++ b/crates/introspect-sql-sink/migrations/sqlite/002_schema_state.sql @@ -5,6 +5,7 @@ CREATE TABLE IF NOT EXISTS introspect_db_tables ( name TEXT NOT NULL, "primary" TEXT NOT NULL, columns TEXT NOT NULL, + append_only INTEGER NOT NULL DEFAULT 0, alive INTEGER NOT NULL DEFAULT 1, updated_at INTEGER NOT NULL DEFAULT (unixepoch()), PRIMARY KEY (namespace, id) diff --git a/crates/introspect-sql-sink/src/backend.rs b/crates/introspect-sql-sink/src/backend.rs index 3dcb7b01..563e2e5e 100644 --- a/crates/introspect-sql-sink/src/backend.rs +++ b/crates/introspect-sql-sink/src/backend.rs @@ -1,4 +1,4 @@ -use crate::processor::{DbColumn, DbDeadField, DbTable, COMMIT_CMD}; +use crate::processor::{messages_to_queries, DbColumn, DbDeadField, DbTable, COMMIT_CMD}; use crate::table::Table; use crate::tables::Tables; use crate::{DbResult, NamespaceMode, RecordResult, TableResult}; @@ -6,8 +6,8 @@ use async_trait::async_trait; use introspect_types::{ColumnDef, PrimaryDef}; use sqlx::{Database, Pool}; use starknet_types_core::felt::Felt; +use std::fmt::Debug; use torii_introspect::events::IntrospectBody; -use torii_introspect::tables::RecordSchema; use torii_introspect::Record; use torii_sql::{Executable, FlexQuery, PoolExt}; @@ -15,8 +15,8 @@ use torii_sql::{Executable, FlexQuery, PoolExt}; pub trait IntrospectProcessor { async fn process_msgs( &self, - tables: &Tables, namespaces: &NamespaceMode, + tables: &Tables, msgs: Vec<&IntrospectBody>, ) -> DbResult>>; } @@ -40,6 +40,7 @@ pub trait IntrospectQueryMaker: Database { name: &str, primary: &PrimaryDef, columns: &[ColumnDef], + append_only: bool, from_address: &Felt, block_number: u64, transaction_hash: &Felt, @@ -56,49 +57,28 @@ pub trait IntrospectQueryMaker: Database { queries: &mut Vec>, ) -> TableResult<()>; fn insert_record_queries( - namespace: &str, - table_name: &str, - schema: &RecordSchema<'_>, + table: &Table, + columns: &[Felt], records: &[Record], from_address: &Felt, block_number: u64, transaction_hash: &Felt, queries: &mut Vec>, ) -> RecordResult<()>; - fn msgs_to_queries( - tables: &Tables, - namespaces: &NamespaceMode, - msgs: Vec<&IntrospectBody>, - queries: &mut Vec>, - ) -> DbResult>> { - let mut results = Vec::with_capacity(msgs.len()); - for body in msgs { - let (msg, metadata) = body.into(); - results.push(tables.handle_message::( - namespaces.to_namespace(&metadata.from_address)?, - msg, - &metadata.from_address, - metadata.block_number.unwrap_or(u64::MAX), - &metadata.transaction_hash, - queries, - )); - } - Ok(results) - } } #[async_trait] pub trait IntrospectPool { - async fn process_queries(&self, queries: Vec>) -> DbResult<()>; + async fn commit_queries(&self, queries: Vec>) -> DbResult<()>; async fn execute_msgs( &self, - tables: &Tables, namespaces: &NamespaceMode, + tables: &Tables, msgs: Vec<&IntrospectBody>, ) -> DbResult>> { let mut queries = Vec::new(); - let results = DB::msgs_to_queries(tables, namespaces, msgs, &mut queries)?; - self.process_queries(queries).await?; + let results = messages_to_queries::(namespaces, tables, msgs, &mut queries)?; + self.commit_queries(queries).await?; Ok(results) } } @@ -107,8 +87,9 @@ pub trait IntrospectPool { impl IntrospectPool for Pool where Vec>: Executable, + FlexQuery: Debug + Clone, { - async fn process_queries(&self, queries: Vec>) -> DbResult<()> { + async fn commit_queries(&self, queries: Vec>) -> DbResult<()> { let mut batch = Vec::new(); for query in queries { if query == *COMMIT_CMD { @@ -118,7 +99,15 @@ where } } if !batch.is_empty() { - self.execute_queries(batch).await?; + match self.execute_queries(batch.clone()).await { + Ok(_) => (), + Err(e) => { + for query in batch { + eprintln!("Failed query: {query:?}"); + } + return Err(e.into()); + } + } } Ok(()) } diff --git a/crates/introspect-sql-sink/src/error.rs b/crates/introspect-sql-sink/src/error.rs index f4e98f05..bacc8750 100644 --- a/crates/introspect-sql-sink/src/error.rs +++ b/crates/introspect-sql-sink/src/error.rs @@ -3,6 +3,7 @@ use introspect_types::{DecodeError, PrimaryTypeDef, TypeDef}; use sqlx::error::BoxDynError; use sqlx::Error as SqlxError; use starknet_types_core::felt::{Felt, FromStrError}; +use std::fmt::Display; use std::sync::PoisonError; use thiserror::Error; @@ -18,8 +19,8 @@ pub type TypeResult = std::result::Result; #[derive(Debug, Error)] pub enum TableError { - #[error("Column with id: {0} not found in table {1}")] - ColumnNotFound(Felt, String), + #[error("Table {0} has not got columns: {1:?}")] + ColumnsNotFound(String, ColumnsNotFoundError), #[error(transparent)] TypeError(#[from] TypeError), #[error("Current type mismatch error")] @@ -36,6 +37,55 @@ pub enum TableError { Encode(#[from] BoxDynError), } +#[derive(Debug)] +pub struct ColumnNotFoundError(pub Felt); + +#[derive(Debug, Default, Error)] +pub struct ColumnsNotFoundError(pub Vec); + +impl ColumnsNotFoundError { + pub fn to_table_error(self, table: &str) -> TableError { + TableError::ColumnsNotFound(table.to_string(), self) + } +} + +impl Display for ColumnsNotFoundError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some((first, rest)) = self.0.split_first() { + write!(f, "0x{first:#063x}")?; + for col in rest { + write!(f, ", 0x{col:#063x}")?; + } + } + Ok(()) + } +} + +pub trait CollectColumnResults { + fn collect_columns(self) -> Result, ColumnsNotFoundError>; +} + +impl CollectColumnResults for I +where + I: Iterator>, +{ + fn collect_columns(self) -> Result, ColumnsNotFoundError> { + let mut columns = Vec::new(); + let mut not_found = Vec::new(); + for result in self { + match result { + Ok(col) => columns.push(col), + Err(e) => not_found.push(e.0), + } + } + if not_found.is_empty() { + Ok(columns) + } else { + Err(ColumnsNotFoundError(not_found)) + } + } +} + pub type TableResult = std::result::Result; #[derive(Debug, thiserror::Error)] @@ -116,6 +166,8 @@ pub enum RecordError { DecodeError(#[from] DecodeError), #[error(transparent)] SqlxError(#[from] SqlxError), + #[error("Columns with ids: {0} not found")] + ColumnsNotFound(#[from] ColumnsNotFoundError), } pub type RecordResult = std::result::Result; diff --git a/crates/introspect-sql-sink/src/postgres/append_only.rs b/crates/introspect-sql-sink/src/postgres/append_only.rs new file mode 100644 index 00000000..9d505c64 --- /dev/null +++ b/crates/introspect-sql-sink/src/postgres/append_only.rs @@ -0,0 +1,106 @@ +use super::json::PostgresJsonSerializer; +use crate::postgres::insert::pg_json_felt252; +use crate::{RecordResult, Table}; +use introspect_types::ColumnInfo; +use serde::ser::SerializeMap; +use serde_json::Serializer as JsonSerializer; +use starknet_types_core::felt::Felt; +use std::io::Write; +use torii_introspect::tables::SerializeEntries; +use torii_introspect::Record; +use torii_sql::postgres::PgQuery; +use torii_sql::Queries; + +struct MetaData<'a> { + pub block_number: u64, + pub transaction_hash: &'a Felt, +} + +impl<'a> MetaData<'a> { + pub fn new(block_number: u64, transaction_hash: &'a Felt) -> Self { + Self { + block_number, + transaction_hash, + } + } +} + +impl SerializeEntries for MetaData<'_> { + fn entry_count(&self) -> usize { + 2 + } + fn serialize_entries( + &self, + map: &mut ::SerializeMap, + ) -> Result<(), S::Error> { + let tx_hash = pg_json_felt252(self.transaction_hash); + map.serialize_entry("__created_block", &self.block_number)?; + map.serialize_entry("__created_tx", &tx_hash) + } +} + +#[allow(clippy::too_many_arguments)] +pub fn append_only_record_queries( + table: &Table, + column_ids: &[Felt], + records: &[Record], + _from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec, +) -> RecordResult<()> { + let schema = table.get_record_schema(column_ids)?; + let namespace = &table.namespace; + let table_name = &table.name; + let mut writer = Vec::new(); + let metadata = MetaData::new(block_number, transaction_hash); + let primary = schema.primary_name(); + let columns: Vec<(&Felt, &ColumnInfo)> = table.columns.iter().collect(); + + write!( + writer, + r#"WITH latest AS (SELECT DISTINCT ON ("{primary}") * FROM "{namespace}"."{table_name}" ORDER BY "{primary}", "__revision" DESC), + input AS ( SELECT * FROM jsonb_populate_recordset(NULL::"{namespace}"."{table_name}", $$"# + ) + .unwrap(); + + schema.parse_records_with_metadata( + records, + &metadata, + &mut JsonSerializer::new(&mut writer), + &PostgresJsonSerializer, + )?; + + write!( + writer, + r#"$$)) INSERT INTO "{namespace}"."{table_name}" ("{primary}", "__revision", "__created_block", "__created_tx""# + ) + .unwrap(); + + for (_, ColumnInfo { name, .. }) in &columns { + write!(writer, r#", "{name}""#).unwrap(); + } + + write!( + writer, + r#") SELECT i."{primary}", (SELECT COALESCE(MAX("__revision"), 0) + 1 FROM "{namespace}"."{table_name}" WHERE "{primary}" = i."{primary}") AS "__revision", i."__created_block", i."__created_tx""#, + ).unwrap(); + + for (id, ColumnInfo { name, .. }) in &columns { + if column_ids.contains(id) { + write!(writer, r#", i."{name}""#).unwrap(); + } else { + write!(writer, r#", COALESCE(i."{name}", l."{name}")"#).unwrap(); + } + } + + write!( + writer, + r#" FROM input i LEFT JOIN latest l USING ("{primary}")"# + ) + .unwrap(); + + let string = unsafe { String::from_utf8_unchecked(writer) }; + queries.add(string); + Ok(()) +} diff --git a/crates/introspect-sql-sink/src/postgres/backend.rs b/crates/introspect-sql-sink/src/postgres/backend.rs index b2855eff..31a5c5dd 100644 --- a/crates/introspect-sql-sink/src/postgres/backend.rs +++ b/crates/introspect-sql-sink/src/postgres/backend.rs @@ -1,6 +1,7 @@ use super::insert::insert_record_queries; use super::query::{insert_columns_query, insert_table_query, CreatePgTable}; use super::upgrade::PgTableUpgrade; +use crate::postgres::append_only::append_only_record_queries; use crate::processor::IntrospectDb; use crate::{ IntrospectQueryMaker, IntrospectSqlSink, RecordResult, Table, TableError, TableResult, @@ -9,27 +10,11 @@ use async_trait::async_trait; use introspect_types::schema::{Names, TypeDefs}; use introspect_types::{ColumnDef, FeltIds, PrimaryDef}; use starknet_types_core::felt::Felt; -use torii_introspect::tables::RecordSchema; use torii_introspect::Record; use torii_sql::{PgPool, PgQuery, Postgres}; pub type IntrospectPgDb = IntrospectDb; -// #[derive(Clone)] -// pub struct PostgresBackend(PgPool); - -// impl From for PostgresBackend { -// fn from(value: PgPool) -> Self { -// PostgresBackend(value) -// } -// } - -// impl DbConnection for PostgresBackend { -// fn pool(&self) -> &PgPool { -// &self.0 -// } -// } - #[async_trait] impl IntrospectQueryMaker for Postgres { fn create_table_queries( @@ -38,18 +23,20 @@ impl IntrospectQueryMaker for Postgres { name: &str, primary: &PrimaryDef, columns: &[ColumnDef], + append_only: bool, from_address: &Felt, block_number: u64, transaction_hash: &Felt, queries: &mut Vec, ) -> TableResult<()> { let ns = namespace.into(); - CreatePgTable::new(&ns, id, name, primary, columns)?.make_queries(queries); + CreatePgTable::new(&ns, id, name, primary, columns, append_only)?.make_queries(queries); store_table_queries( namespace, id, name, primary, + append_only, columns, from_address, block_number, @@ -69,12 +56,15 @@ impl IntrospectQueryMaker for Postgres { ) -> TableResult<()> { let upgrades = table.upgrade_table(name, primary, columns)?; upgrades.to_queries(block_number, transaction_hash, queries)?; - let columns = table.columns_with_ids(&upgrades.columns_upgraded)?; + let columns: Vec<(&Felt, &introspect_types::ColumnInfo)> = table + .columns_with_ids(&upgrades.columns_upgraded) + .map_err(|e| e.to_table_error(&table.name))?; store_table_queries( &table.namespace, &table.id, name, primary, + table.append_only, columns, from_address, block_number, @@ -83,25 +73,35 @@ impl IntrospectQueryMaker for Postgres { ) } fn insert_record_queries( - namespace: &str, - table_name: &str, - schema: &RecordSchema<'_>, + table: &Table, + columns: &[Felt], records: &[Record], from_address: &Felt, block_number: u64, transaction_hash: &Felt, queries: &mut Vec, ) -> RecordResult<()> { - insert_record_queries( - namespace, - table_name, - schema, - records, - from_address, - block_number, - transaction_hash, - queries, - ) + if table.append_only { + append_only_record_queries( + table, + columns, + records, + from_address, + block_number, + transaction_hash, + queries, + ) + } else { + insert_record_queries( + table, + columns, + records, + from_address, + block_number, + transaction_hash, + queries, + ) + } } } @@ -111,6 +111,7 @@ fn store_table_queries( id: &Felt, name: &str, primary: &PrimaryDef, + append_only: bool, columns: CS, from_address: &Felt, block_number: u64, @@ -127,6 +128,7 @@ where name, primary, from_address, + append_only, block_number, transaction_hash, ) diff --git a/crates/introspect-sql-sink/src/postgres/create.rs b/crates/introspect-sql-sink/src/postgres/create.rs index 05df72e0..34df03c8 100644 --- a/crates/introspect-sql-sink/src/postgres/create.rs +++ b/crates/introspect-sql-sink/src/postgres/create.rs @@ -293,6 +293,7 @@ impl CreatePgTable { name: &str, primary: &PrimaryDef, columns: &[ColumnDef], + append_only: bool, ) -> TypeResult { let mut creates: Vec = Vec::new(); let branch = Xxh3::new_based(id); @@ -306,6 +307,7 @@ impl CreatePgTable { primary, columns, pg_types: creates, + append_only, }) } pub fn make_queries(&self, queries: &mut Vec) { @@ -316,9 +318,11 @@ impl CreatePgTable { queries.add(pg_type.to_string()); } queries.add(self.to_string()); - queries.add(format!( - r#"CREATE TRIGGER set_timestamps BEFORE INSERT ON {} FOR EACH ROW EXECUTE FUNCTION introspect.set_default_timestamps();"#, - self.name - )); + if !self.append_only { + queries.add(format!( + r#"CREATE TRIGGER set_timestamps BEFORE INSERT ON {} FOR EACH ROW EXECUTE FUNCTION introspect.set_default_timestamps();"#, + self.name + )); + } } } diff --git a/crates/introspect-sql-sink/src/postgres/insert.rs b/crates/introspect-sql-sink/src/postgres/insert.rs index c94ec895..a49fe6f4 100644 --- a/crates/introspect-sql-sink/src/postgres/insert.rs +++ b/crates/introspect-sql-sink/src/postgres/insert.rs @@ -1,18 +1,18 @@ use super::json::PostgresJsonSerializer; -use crate::RecordResult; +use crate::{RecordResult, Table}; use introspect_types::ColumnInfo; use serde::ser::SerializeMap; use serde_json::Serializer as JsonSerializer; use starknet_types_core::felt::Felt; use std::io::Write; -use torii_introspect::tables::{RecordSchema, SerializeEntries}; +use torii_introspect::tables::SerializeEntries; use torii_introspect::Record; use torii_sql::postgres::PgQuery; use torii_sql::Queries; pub const METADATA_CONFLICTS: &str = "__updated_at = NOW(), __updated_block = EXCLUDED.__updated_block, __updated_tx = EXCLUDED.__updated_tx"; -pub struct MetaData<'a> { +struct MetaData<'a> { pub block_number: u64, pub transaction_hash: &'a Felt, } @@ -48,15 +48,17 @@ impl SerializeEntries for MetaData<'_> { #[allow(clippy::too_many_arguments)] pub fn insert_record_queries( - namespace: &str, - table_name: &str, - schema: &RecordSchema<'_>, + table: &Table, + columns: &[Felt], records: &[Record], _from_address: &Felt, block_number: u64, transaction_hash: &Felt, queries: &mut Vec, ) -> RecordResult<()> { + let schema = table.get_record_schema(columns)?; + let namespace = &table.namespace; + let table_name = &table.name; let mut writer = Vec::new(); let metadata = MetaData::new(block_number, transaction_hash); write!( diff --git a/crates/introspect-sql-sink/src/postgres/json.rs b/crates/introspect-sql-sink/src/postgres/json.rs index 7e8cc911..02d78188 100644 --- a/crates/introspect-sql-sink/src/postgres/json.rs +++ b/crates/introspect-sql-sink/src/postgres/json.rs @@ -1,8 +1,9 @@ use introspect_types::serialize::ToCairoDeSeFrom; use introspect_types::serialize_def::CairoTypeSerialization; -use introspect_types::{CairoDeserializer, ResultDef, TupleDef, TypeDef}; -use serde::ser::SerializeMap; +use introspect_types::{CairoDeserializer, EnumDef, ResultDef, TupleDef, TypeDef, VariantDef}; +use serde::ser::{Error as SerError, SerializeMap}; use serde::Serializer; +use starknet_types_core::felt::Felt; pub struct PostgresJsonSerializer; @@ -48,27 +49,40 @@ impl CairoTypeSerialization for PostgresJsonSerializer { seq.end() } - fn serialize_variant<'a, S: Serializer>( + fn serialize_enum<'a, S: Serializer>( &'a self, data: &mut impl CairoDeserializer, serializer: S, - name: &str, - type_def: &'a TypeDef, + enum_def: &'a EnumDef, + variant: Felt, ) -> Result { - match type_def { - TypeDef::None => { - let mut map = serializer.serialize_map(Some(1))?; - map.serialize_entry("_variant", name)?; - map - } - _ => { - let mut map = serializer.serialize_map(Some(2))?; - map.serialize_entry("_variant", name)?; - map.serialize_entry(name, &type_def.to_de_se(data, self))?; - map + let VariantDef { name, type_def, .. } = + enum_def.get_variant(&variant).map_err(S::Error::custom)?; + let mut map = serializer.serialize_map(None)?; + map.serialize_entry("_variant", name)?; + if type_def != &TypeDef::None { + map.serialize_entry(name, &type_def.to_de_se(data, self))?; + } + for v in &enum_def.order { + if v != &variant { + let VariantDef { name, type_def, .. } = + enum_def.get_variant(v).map_err(S::Error::custom)?; + if type_def != &TypeDef::None { + map.serialize_entry(name, &())?; + } } } - .end() + map.end() + } + + fn serialize_variant<'a, S: Serializer>( + &'a self, + _data: &mut impl CairoDeserializer, + _serializer: S, + _name: &str, + _type_def: &'a TypeDef, + ) -> Result { + unimplemented!("variant serialization is only supported within enums, and should not be called directly") } fn serialize_result<'a, S: Serializer>( diff --git a/crates/introspect-sql-sink/src/postgres/mod.rs b/crates/introspect-sql-sink/src/postgres/mod.rs index d9d75201..5bdfab78 100644 --- a/crates/introspect-sql-sink/src/postgres/mod.rs +++ b/crates/introspect-sql-sink/src/postgres/mod.rs @@ -1,3 +1,4 @@ +pub mod append_only; pub mod backend; pub mod create; pub mod handler; diff --git a/crates/introspect-sql-sink/src/postgres/query.rs b/crates/introspect-sql-sink/src/postgres/query.rs index 514a5a74..bef6ddbb 100644 --- a/crates/introspect-sql-sink/src/postgres/query.rs +++ b/crates/introspect-sql-sink/src/postgres/query.rs @@ -20,24 +20,27 @@ use torii_sql::{Queries, SqlxResult}; pub const COMMIT_CMD: &str = "--COMMIT"; -const CREATE_METADATA_COLUMNS: &str = "__created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __created_block public.uint64 NOT NULL, __updated_block public.uint64 NOT NULL, __created_tx public.felt252 NOT NULL, __updated_tx public.felt252 NOT NULL);"; +const CREATE_METADATA_COLUMNS: &str = "__created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __created_block public.uint64 NOT NULL, __updated_block public.uint64 NOT NULL, __created_tx public.felt252 NOT NULL, __updated_tx public.felt252 NOT NULL"; +const CREATE_APPEND_ONLY_METADATA_COLUMNS: &str = "__created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), __created_block public.uint64 NOT NULL, __created_tx public.felt252 NOT NULL"; +const APPEND_ONLY_REVISION_COLUMN: &str = r#""__revision" bigint NOT NULL, "#; +const INSERT_TABLE_QUERY: &str = r#"INSERT INTO introspect.db_tables + ("schema", id, owner, name, primary_def, append_only, updated_at, created_block, updated_block, created_tx, updated_tx) + VALUES ($1, $2, $3, $4, $5, $6, NOW(), $7::uint64, $7::uint64, $8, $8) + ON CONFLICT ("schema", id) DO UPDATE SET + name = EXCLUDED.name, append_only = EXCLUDED.append_only, primary_def = EXCLUDED.primary_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; const INSERT_DEAD_MEMBER_QUERY: &str = r#"INSERT INTO introspect.db_dead_fields ("schema", "table", id, name, type_def, updated_at, created_block, updated_block, created_tx, updated_tx) SELECT $1, $2, unnest($3::bigint[]), unnest($4::text[]), unnest($5::jsonb[]), NOW(), $6::uint64, $6::uint64, $7, $7 ON CONFLICT ("schema", "table", id) DO UPDATE SET name = EXCLUDED.name, type_def = EXCLUDED.type_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; -const INSERT_TABLE_QUERY: &str = r#"INSERT INTO introspect.db_tables - ("schema", id, owner, name, primary_def, updated_at, created_block, updated_block, created_tx, updated_tx) - VALUES ($1, $2, $3, $4, $5, NOW(), $6::uint64, $6::uint64, $7, $7) - ON CONFLICT ("schema", id) DO UPDATE SET - name = EXCLUDED.name, primary_def = EXCLUDED.primary_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; + const INSERT_COLUMN_QUERY: &str = r#"INSERT INTO introspect.db_columns ("schema", "table", id, name, type_def, updated_at, created_block, updated_block, created_tx, updated_tx) SELECT $1, $2, unnest($3::felt252[]), unnest($4::text[]), unnest($5::jsonb[]), NOW(), $6::uint64, $6::uint64, $7, $7 ON CONFLICT ("schema", "table", id) DO UPDATE SET name = EXCLUDED.name, type_def = EXCLUDED.type_def, updated_at = NOW(), updated_block = EXCLUDED.updated_block, updated_tx = EXCLUDED.updated_tx"#; -const FETCH_TABLES_QUERY: &str = r#"SELECT "schema", id, name, primary_def, owner FROM introspect.db_tables WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; +const FETCH_TABLES_QUERY: &str = r#"SELECT "schema", id, name, primary_def, owner, append_only FROM introspect.db_tables WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; const FETCH_COLUMNS_QUERY: &str = r#"SELECT "schema", "table", id, name, type_def FROM introspect.db_columns WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; const FETCH_DEAD_FIELDS_QUERY: &str = r#"SELECT "schema", "table", id, name, type_def FROM introspect.db_dead_fields WHERE $1::text[] = '{}'::text[] OR "schema" = ANY($1::text[])"#; @@ -48,6 +51,7 @@ pub struct TableRow { pub name: String, pub primary_def: PgPrimary, pub owner: PgFelt, + pub append_only: bool, } #[derive(FromRow)] @@ -74,6 +78,7 @@ pub struct CreatePgTable { pub primary: PrimaryKey, pub columns: Vec, pub pg_types: Vec, + pub append_only: bool, } #[derive(Debug)] @@ -164,10 +169,25 @@ impl Display for CreatePgTable { r#"CREATE TABLE IF NOT EXISTS {} ({}, "#, self.name, self.primary )?; + if self.append_only { + APPEND_ONLY_REVISION_COLUMN.fmt(f)?; + } for column in &self.columns { write!(f, "{column}, ")?; } - CREATE_METADATA_COLUMNS.fmt(f) + if self.append_only { + write!( + f, + r#"{CREATE_APPEND_ONLY_METADATA_COLUMNS}, PRIMARY KEY ("{}", "__revision"));"#, + self.primary.name + ) + } else { + write!( + f, + r#"{CREATE_METADATA_COLUMNS}, PRIMARY KEY ("{}"));"#, + self.primary.name + ) + } } } @@ -574,6 +594,7 @@ impl From for DbTable { primary: value.primary_def.into(), columns: HashMap::new(), dead: HashMap::new(), + append_only: value.append_only, alive: true, } } @@ -626,6 +647,7 @@ pub fn insert_table_query( name: &str, primary_def: &PrimaryDef, from_address: &Felt, + append_only: bool, block_number: u64, transaction_hash: &Felt, ) -> Result { @@ -635,6 +657,7 @@ pub fn insert_table_query( args.add(PgFelt::from(*from_address))?; args.add(name.to_owned())?; args.add(PgPrimary::from(primary_def))?; + args.add(append_only)?; args.add(block_number.to_string())?; args.add(PgFelt::from(*transaction_hash))?; diff --git a/crates/introspect-sql-sink/src/postgres/types.rs b/crates/introspect-sql-sink/src/postgres/types.rs index 6e64dac2..57f97de6 100644 --- a/crates/introspect-sql-sink/src/postgres/types.rs +++ b/crates/introspect-sql-sink/src/postgres/types.rs @@ -121,7 +121,7 @@ impl Display for PostgresType { impl Display for PrimaryKey { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, r#""{}" {} PRIMARY KEY"#, self.name, self.pg_type) + write!(f, r#""{}" {}"#, self.name, self.pg_type) } } diff --git a/crates/introspect-sql-sink/src/processor.rs b/crates/introspect-sql-sink/src/processor.rs index e644a2a3..23c64b16 100644 --- a/crates/introspect-sql-sink/src/processor.rs +++ b/crates/introspect-sql-sink/src/processor.rs @@ -2,14 +2,15 @@ use crate::backend::{IntrospectInitialize, IntrospectPool, IntrospectProcessor}; use crate::error::TableLoadError; use crate::table::{DeadField, Table}; use crate::tables::Tables; -use crate::{DbResult, IntrospectQueryMaker, NamespaceMode}; +use crate::{DbResult, IntrospectQueryMaker, NamespaceKey, NamespaceMode}; use async_trait::async_trait; use introspect_types::{ColumnInfo, PrimaryDef, TypeDef}; use itertools::Itertools; use sqlx::{Database, Pool}; use starknet_types_core::felt::Felt; use std::collections::HashMap; -use torii_introspect::events::IntrospectBody; +use std::fmt::Debug; +use torii_introspect::events::{IntrospectBody, IntrospectMsg}; use torii_sql::{Executable, FlexQuery, PoolExt}; pub const COMMIT_CMD: &str = "--COMMIT"; @@ -28,6 +29,7 @@ pub struct DbTable { pub primary: PrimaryDef, pub columns: HashMap, pub dead: HashMap, + pub append_only: bool, pub alive: bool, } @@ -71,14 +73,15 @@ where impl IntrospectProcessor for Pool where Vec>: Executable, + FlexQuery: Debug + Clone, { async fn process_msgs( &self, - tables: &Tables, namespaces: &NamespaceMode, + tables: &Tables, msgs: Vec<&IntrospectBody>, ) -> DbResult>> { - self.execute_msgs(tables, namespaces, msgs).await + self.execute_msgs(namespaces, tables, msgs).await } } @@ -102,7 +105,7 @@ impl IntrospectDb msgs: Vec<&IntrospectBody>, ) -> DbResult>> { self.db - .process_msgs(&self.tables, &self.namespaces, msgs) + .process_msgs(&self.namespaces, &self.tables, msgs) .await } @@ -159,6 +162,7 @@ impl From for ((String, Felt), Table) { primary: value.primary.into(), columns: value.columns, dead: value.dead, + append_only: value.append_only, alive: value.alive, }, ) @@ -193,3 +197,79 @@ impl From for (String, Felt, u128, DeadField) { ) } } + +pub fn messages_to_queries( + namespaces: &NamespaceMode, + tables: &Tables, + msgs: Vec<&IntrospectBody>, + queries: &mut Vec>, +) -> DbResult>> { + let mut results = Vec::with_capacity(msgs.len()); + for body in msgs { + let (msg, metadata) = body.into(); + let namespace = namespaces.to_namespace(&metadata.from_address)?; + results.push(handle_message::( + namespace, + tables, + msg, + &metadata.from_address, + metadata.block_number.unwrap_or(u64::MAX), + &metadata.transaction_hash, + queries, + )); + } + Ok(results) +} + +pub fn handle_message( + namespace: NamespaceKey, + tables: &Tables, + msg: &IntrospectMsg, + from_address: &Felt, + block_number: u64, + transaction_hash: &Felt, + queries: &mut Vec>, +) -> DbResult<()> { + match msg { + IntrospectMsg::CreateTable(event) => tables.create_table::( + namespace, + &event.id, + &event.name, + &event.primary, + &event.columns, + event.append_only, + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::UpdateTable(event) => tables.update_table::( + namespace, + &event.id, + &event.name, + &event.primary, + &event.columns, + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::AddColumns(event) => tables.set_table_dead(namespace, event.table), + IntrospectMsg::DropColumns(event) => tables.set_table_dead(namespace, event.table), + IntrospectMsg::RetypeColumns(event) => tables.set_table_dead(namespace, event.table), + IntrospectMsg::RetypePrimary(event) => tables.set_table_dead(namespace, event.table), + IntrospectMsg::RenameTable(_) + | IntrospectMsg::DropTable(_) + | IntrospectMsg::RenameColumns(_) + | IntrospectMsg::RenamePrimary(_) => Ok(()), + IntrospectMsg::InsertsFields(event) => tables.insert_fields::( + namespace, + event, + from_address, + block_number, + transaction_hash, + queries, + ), + IntrospectMsg::DeleteRecords(_) | IntrospectMsg::DeletesFields(_) => Ok(()), + } +} diff --git a/crates/introspect-sql-sink/src/runtime.rs b/crates/introspect-sql-sink/src/runtime.rs index cc1979b1..1c3667eb 100644 --- a/crates/introspect-sql-sink/src/runtime.rs +++ b/crates/introspect-sql-sink/src/runtime.rs @@ -46,13 +46,13 @@ impl IntrospectInitialize for DbPool { impl IntrospectProcessor for DbPool { async fn process_msgs( &self, - tables: &Tables, namespaces: &NamespaceMode, + tables: &Tables, msgs: Vec<&IntrospectBody>, ) -> DbResult>> { match self { - DbPool::Postgres(pg) => pg.process_msgs(tables, namespaces, msgs).await, - DbPool::Sqlite(site) => site.process_msgs(tables, namespaces, msgs).await, + DbPool::Postgres(pg) => pg.process_msgs(namespaces, tables, msgs).await, + DbPool::Sqlite(site) => site.process_msgs(namespaces, tables, msgs).await, } } } diff --git a/crates/introspect-sql-sink/src/sqlite/append_only.rs b/crates/introspect-sql-sink/src/sqlite/append_only.rs new file mode 100644 index 00000000..5607c0a2 --- /dev/null +++ b/crates/introspect-sql-sink/src/sqlite/append_only.rs @@ -0,0 +1,71 @@ +use crate::sqlite::record::SqliteDeserializer; +use crate::sqlite::table::qualified_table_name; +use crate::sqlite::types::{SqliteType, TypeDefSqliteExt}; +use crate::{RecordResult, Table}; +use introspect_types::bytes::IntoByteSource; +use introspect_types::schema::{Names, TypeDefs}; +use introspect_types::ColumnInfo; +use itertools::Itertools; +use sqlx::Arguments; +use sqlx::Error::Encode as EncodeError; +use starknet_types_core::felt::Felt; +use std::fmt::Write as FmtWrite; +use std::sync::Arc; +use torii_introspect::Record; +use torii_sql::{Queries, SqliteArguments, SqliteQuery}; + +pub fn append_only_record_queries( + table: &Table, + column_ids: &[Felt], + records: &[Record], + _from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + queries: &mut Vec, +) -> RecordResult<()> { + let table_name = qualified_table_name(&table.namespace, &table.name); + let primary = &table.primary.name; + let columns = table.columns.iter().collect_vec(); + let mut sql = format!(r#"INSERT INTO "{table_name}" ("{primary}", "__revision""#,); + for name in columns.names() { + write!(sql, r#", "{name}""#).unwrap(); + } + write!(sql, r#") VALUES (?, (SELECT COALESCE(MAX("__revision"), 0) + 1 FROM "{table_name}" WHERE "{primary}" = ?1)"#).unwrap(); + for (id, ColumnInfo { name, type_def, .. }) in &columns { + match column_ids.iter().position(|c| &c == id) { + Some(index) => write!(sql, r#", {}"#, type_def.index_placeholder(index + 2)?).unwrap(), + None => match type_def.try_into()? { + SqliteType::Json => write!( + sql, + r#", (SELECT jsonb("{name}") FROM "{table_name}" WHERE "{primary}" = ?1 ORDER BY "__revision" DESC LIMIT 1)"# + ).unwrap(), + _ => write!( + sql, + r#", (SELECT "{name}" FROM "{table_name}" WHERE "{primary}" = ?1 ORDER BY "__revision" DESC LIMIT 1)"# + ).unwrap(), + } + } + } + let schema = table.get_record_schema(column_ids)?; + sql.push(')'); + let sql: Arc = sql.into(); + for record in records { + let mut arguments: SqliteArguments<'static> = SqliteArguments::default(); + let mut primary_data = record.id.as_slice().into_source(); + let mut data = record.values.as_slice().into_source(); + arguments + .add( + schema + .primary_type_def() + .deserialize_column(&mut primary_data)?, + ) + .map_err(EncodeError)?; + for type_def in schema.columns().type_defs() { + arguments + .add(type_def.deserialize_column(&mut data)?) + .map_err(EncodeError)?; + } + queries.add((sql.clone(), arguments)); + } + Ok(()) +} diff --git a/crates/introspect-sql-sink/src/sqlite/backend.rs b/crates/introspect-sql-sink/src/sqlite/backend.rs index 14d29ce8..6f0d4999 100644 --- a/crates/introspect-sql-sink/src/sqlite/backend.rs +++ b/crates/introspect-sql-sink/src/sqlite/backend.rs @@ -1,29 +1,22 @@ -use crate::sqlite::record::{coalesce_sql, SqliteDeserializer}; +use crate::sqlite::append_only::append_only_record_queries; +use crate::sqlite::record::insert_record_queries; use crate::sqlite::table::{ create_table_query, persist_table_state_query, qualified_table_name, update_column, update_columns, FETCH_TABLES_QUERY, }; -use crate::sqlite::types::SqliteColumn; use crate::{ DbColumn, DbDeadField, DbResult, DbTable, IntrospectDb, IntrospectInitialize, - IntrospectQueryMaker, IntrospectSqlSink, RecordResult, Table, TableResult, TypeResult, - UpgradeResultExt, + IntrospectQueryMaker, IntrospectSqlSink, RecordResult, Table, TableResult, UpgradeResultExt, }; use async_trait::async_trait; -use introspect_types::bytes::IntoByteSource; -use introspect_types::schema::{Names, TypeDefs}; use introspect_types::{ColumnDef, ColumnInfo, PrimaryDef, ResultInto}; use itertools::Itertools; use sqlx::prelude::FromRow; use sqlx::types::Json; -use sqlx::Arguments; -use sqlx::Error::Encode as EncodeError; use starknet_types_core::felt::{Felt, FromStrError}; use std::collections::HashMap; -use std::sync::Arc; -use torii_introspect::tables::RecordSchema; use torii_introspect::Record; -use torii_sql::{PoolExt, Queries, Sqlite, SqliteArguments, SqlitePool, SqliteQuery}; +use torii_sql::{PoolExt, Queries, Sqlite, SqlitePool, SqliteQuery}; pub const INTROSPECT_SQLITE_SINK_MIGRATIONS: sqlx::migrate::Migrator = sqlx::migrate!("./migrations/sqlite"); @@ -38,6 +31,7 @@ pub struct SqliteTableRow { name: String, primary: Json, columns: Json>, + append_only: bool, alive: bool, } @@ -52,6 +46,7 @@ impl TryFrom for DbTable { primary: value.primary.0, columns: value.columns.0.into_iter().map_into().collect(), dead: HashMap::new(), + append_only: value.append_only, alive: value.alive, }) } @@ -65,18 +60,26 @@ impl IntrospectQueryMaker for Sqlite { name: &str, primary: &PrimaryDef, columns: &[ColumnDef], + append_only: bool, from_address: &Felt, block_number: u64, transaction_hash: &Felt, queries: &mut Vec, ) -> TableResult<()> { - queries.add(create_table_query(namespace, name, primary, columns)?); + queries.add(create_table_query( + namespace, + name, + primary, + columns, + append_only, + )?); persist_table_state_query( namespace, id, name, primary, columns, + append_only, from_address, block_number, transaction_hash, @@ -116,6 +119,7 @@ impl IntrospectQueryMaker for Sqlite { &table.name, primary, &table.columns.iter().collect_vec(), + table.append_only, from_address, block_number, transaction_hash, @@ -123,59 +127,35 @@ impl IntrospectQueryMaker for Sqlite { ) } fn insert_record_queries( - namespace: &str, - table_name: &str, - schema: &RecordSchema<'_>, + table: &Table, + columns: &[Felt], records: &[Record], _from_address: &Felt, _block_number: u64, _transaction_hash: &Felt, queries: &mut Vec, ) -> RecordResult<()> { - let table_name = qualified_table_name(namespace, table_name); - let all_columns = schema.all_columns(); - let sql_columns = all_columns - .iter() - .map(|c| (*c).try_into()) - .collect::>>()?; - let column_names = all_columns.names(); - let placeholders = sql_columns.iter().map(SqliteColumn::placeholder).join(", "); - let coalesce = sql_columns[1..] - .iter() - .map(|col| coalesce_sql(&table_name, col)) - .join(", "); - let sql: Arc = format!( - r#"INSERT INTO "{table_name}" ({}) VALUES ({}) ON CONFLICT("{}") DO UPDATE SET {}"#, - column_names - .iter() - .map(|name| format!(r#""{name}""#)) - .collect::>() - .join(", "), - placeholders, - schema.primary_name(), - coalesce - ) - .into(); - - for record in records { - let mut arguments: SqliteArguments<'static> = SqliteArguments::default(); - let mut primary_data = record.id.as_slice().into_source(); - let mut data = record.values.as_slice().into_source(); - arguments - .add( - schema - .primary_type_def() - .deserialize_column(&mut primary_data)?, - ) - .map_err(EncodeError)?; - for type_def in schema.columns().type_defs() { - arguments - .add(type_def.deserialize_column(&mut data)?) - .map_err(EncodeError)?; - } - queries.add((sql.clone(), arguments)); + if table.append_only { + append_only_record_queries( + table, + columns, + records, + _from_address, + _block_number, + _transaction_hash, + queries, + ) + } else { + insert_record_queries( + table, + columns, + records, + _from_address, + _block_number, + _transaction_hash, + queries, + ) } - Ok(()) } } diff --git a/crates/introspect-sql-sink/src/sqlite/mod.rs b/crates/introspect-sql-sink/src/sqlite/mod.rs index 036ed176..3f8c4ef1 100644 --- a/crates/introspect-sql-sink/src/sqlite/mod.rs +++ b/crates/introspect-sql-sink/src/sqlite/mod.rs @@ -1,3 +1,4 @@ +pub mod append_only; pub mod backend; pub mod json; pub mod record; diff --git a/crates/introspect-sql-sink/src/sqlite/record.rs b/crates/introspect-sql-sink/src/sqlite/record.rs index d530e3c6..ab7d5d48 100644 --- a/crates/introspect-sql-sink/src/sqlite/record.rs +++ b/crates/introspect-sql-sink/src/sqlite/record.rs @@ -1,13 +1,21 @@ use crate::sqlite::json::SqliteJsonSerializer; +use crate::sqlite::table::qualified_table_name; use crate::sqlite::types::{SqliteColumn, SqliteType}; -use crate::RecordResult; +use crate::{RecordResult, Table, TypeResult}; +use introspect_types::bytes::IntoByteSource; +use introspect_types::schema::{Names, TypeDefs}; use introspect_types::serialize::CairoSeFrom; use introspect_types::{CairoDeserializer, DecodeError, EthAddress, ResultInto, TypeDef}; +use itertools::Itertools; use sqlx::encode::IsNull; use sqlx::error::BoxDynError; use sqlx::sqlite::SqliteArgumentValue; -use sqlx::{Encode, Sqlite, Type}; +use sqlx::Error::Encode as EncodeError; +use sqlx::{Arguments, Encode, Sqlite, Type}; use starknet_types_core::felt::Felt; +use std::sync::Arc; +use torii_introspect::Record; +use torii_sql::{Queries, SqliteArguments, SqliteQuery}; pub fn coalesce_sql<'a>(table_name: &str, column: &SqliteColumn<'a>) -> String { let column_name = column.name; @@ -164,3 +172,59 @@ impl<'q> Encode<'q, Sqlite> for SqliteValue { } } } + +pub fn insert_record_queries( + table: &Table, + columns: &[Felt], + records: &[Record], + _from_address: &Felt, + _block_number: u64, + _transaction_hash: &Felt, + queries: &mut Vec, +) -> RecordResult<()> { + let schema = table.get_record_schema(columns)?; + let table_name = qualified_table_name(&table.namespace, &table.name); + let all_columns = schema.all_columns(); + let sql_columns = all_columns + .iter() + .map(|c| (*c).try_into()) + .collect::>>()?; + let column_names = all_columns.names(); + let placeholders = sql_columns.iter().map(SqliteColumn::placeholder).join(", "); + let coalesce = sql_columns[1..] + .iter() + .map(|col| coalesce_sql(&table_name, col)) + .join(", "); + let sql: Arc = format!( + r#"INSERT INTO "{table_name}" ({}) VALUES ({}) ON CONFLICT("{}") DO UPDATE SET {}"#, + column_names + .iter() + .map(|name| format!(r#""{name}""#)) + .collect::>() + .join(", "), + placeholders, + schema.primary_name(), + coalesce + ) + .into(); + + for record in records { + let mut arguments: SqliteArguments<'static> = SqliteArguments::default(); + let mut primary_data = record.id.as_slice().into_source(); + let mut data = record.values.as_slice().into_source(); + arguments + .add( + schema + .primary_type_def() + .deserialize_column(&mut primary_data)?, + ) + .map_err(EncodeError)?; + for type_def in schema.columns().type_defs() { + arguments + .add(type_def.deserialize_column(&mut data)?) + .map_err(EncodeError)?; + } + queries.add((sql.clone(), arguments)); + } + Ok(()) +} diff --git a/crates/introspect-sql-sink/src/sqlite/table.rs b/crates/introspect-sql-sink/src/sqlite/table.rs index 24141628..eb48b10c 100644 --- a/crates/introspect-sql-sink/src/sqlite/table.rs +++ b/crates/introspect-sql-sink/src/sqlite/table.rs @@ -13,16 +13,16 @@ use torii_sql::types::SqlFelt; use torii_sql::{Queries, SqliteArguments, SqliteQuery}; pub const FETCH_TABLES_QUERY: &str = r#" - SELECT namespace, id, owner, name, "primary", columns, alive + SELECT namespace, id, owner, name, "primary", columns, append_only, alive FROM introspect_db_tables ORDER BY updated_at ASC "#; const INSERT_TABLE_QUERY: &str = r#" INSERT INTO introspect_db_tables - (namespace, id, owner, name, "primary", columns, updated_at) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, unixepoch()) + (namespace, id, owner, name, "primary", columns, append_only, updated_at) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, unixepoch()) ON CONFLICT (namespace, id) DO UPDATE SET - owner = excluded.owner, name = excluded.name, "primary" = excluded."primary", columns = excluded.columns, updated_at = unixepoch() + owner = excluded.owner, name = excluded.name, "primary" = excluded."primary", columns = excluded.columns, append_only = excluded.append_only, updated_at = unixepoch() "#; struct TableName<'a>(&'a str, &'a str); @@ -63,6 +63,7 @@ pub fn persist_table_state_query<'a>( name: &str, primary: &PrimaryDef, columns: &'a [impl AsColumnRef<'a>], + append_only: bool, from_address: &Felt, _block_number: u64, _transaction_hash: &Felt, @@ -75,6 +76,7 @@ pub fn persist_table_state_query<'a>( args.add(name.to_string())?; args.add(serde_json::to_string(primary)?)?; args.add(serialize_columns(columns)?)?; + args.add(append_only)?; queries.add((INSERT_TABLE_QUERY, args)); Ok(()) } @@ -84,18 +86,31 @@ pub fn create_table_query( name: &str, primary: &PrimaryDef, columns: &[ColumnDef], + append_only: bool, ) -> TableResult { let table_name = TableName(namespace, name); let mut query = format!( - r#"CREATE TABLE IF NOT EXISTS "{table_name}" ("{}" {} PRIMARY KEY "#, + r#"CREATE TABLE IF NOT EXISTS "{table_name}" ("{}" {}"#, primary.name, TryInto::::try_into(primary)? ); + if append_only { + query.push_str(r#", "__revision" INTEGER NOT NULL"#); + } for column in columns { let sql_type: SqliteType = column.try_into()?; write!(query, r#", "{}" {sql_type}"#, column.name).unwrap(); } - query.push_str(");"); + if append_only { + write!( + query, + r#", PRIMARY KEY ("{}", "__revision"));"#, + primary.name + ) + .unwrap(); + } else { + write!(query, r#", PRIMARY KEY ("{}"));"#, primary.name).unwrap(); + } Ok(query) } diff --git a/crates/introspect-sql-sink/src/sqlite/types.rs b/crates/introspect-sql-sink/src/sqlite/types.rs index a7b3e904..749e69eb 100644 --- a/crates/introspect-sql-sink/src/sqlite/types.rs +++ b/crates/introspect-sql-sink/src/sqlite/types.rs @@ -121,27 +121,41 @@ impl SqliteType { pub fn placeholder(&self) -> &'static str { match self { SqliteType::Null => "NULL", - SqliteType::Text => "?", - SqliteType::Integer => "?", - SqliteType::Real => "?", - SqliteType::Blob => "?", + SqliteType::Text | SqliteType::Integer | SqliteType::Real | SqliteType::Blob => "?", SqliteType::Json => "jsonb(?)", } } + pub fn index_placeholder(&self, index: usize) -> String { + match self { + SqliteType::Null => "NULL".to_string(), + SqliteType::Text | SqliteType::Integer | SqliteType::Real | SqliteType::Blob => { + format!("?{index}") + } + SqliteType::Json => format!("jsonb(?{index})"), + } + } } impl<'a> SqliteColumn<'a> { pub fn placeholder(&self) -> &'static str { self.sql_type.placeholder() } + pub fn index_placeholder(&self, index: usize) -> String { + self.sql_type.index_placeholder(index) + } } pub trait TypeDefSqliteExt { fn placeholder(&self) -> TypeResult<&'static str>; + fn index_placeholder(&self, index: usize) -> TypeResult; } impl TypeDefSqliteExt for TypeDef { fn placeholder(&self) -> TypeResult<&'static str> { self.try_into().map(|t: SqliteType| t.placeholder()) } + fn index_placeholder(&self, index: usize) -> TypeResult { + self.try_into() + .map(|t: SqliteType| t.index_placeholder(index)) + } } diff --git a/crates/introspect-sql-sink/src/table.rs b/crates/introspect-sql-sink/src/table.rs index 61a29853..0b5ad632 100644 --- a/crates/introspect-sql-sink/src/table.rs +++ b/crates/introspect-sql-sink/src/table.rs @@ -1,11 +1,10 @@ -use crate::{TableError, TableResult}; -use introspect_types::{ColumnInfo, MemberDef, TypeDef}; +use crate::error::{CollectColumnResults, ColumnNotFoundError, ColumnsNotFoundError}; +use introspect_types::{ColumnDef, ColumnInfo, MemberDef, PrimaryDef, TypeDef}; use itertools::Itertools; use serde::{Deserialize, Serialize}; use starknet_types_core::felt::Felt; use std::collections::HashMap; use std::rc::Rc; -use torii_introspect::schema::TableInfo; use torii_introspect::tables::RecordSchema; #[derive(Debug)] @@ -16,8 +15,9 @@ pub struct Table { pub owner: Felt, pub primary: ColumnInfo, pub columns: HashMap, - pub alive: bool, pub dead: HashMap, + pub append_only: bool, + pub alive: bool, } #[derive(Debug, Serialize, Deserialize)] @@ -75,20 +75,16 @@ impl From<(u128, DeadField)> for DeadFieldDef { } impl Table { - pub fn column(&self, id: &Felt) -> TableResult<&ColumnInfo> { - self.columns - .get(id) - .ok_or_else(|| TableError::ColumnNotFound(*id, self.name.clone())) + pub fn column(&self, id: &Felt) -> Result<&ColumnInfo, ColumnNotFoundError> { + self.columns.get(id).ok_or_else(|| ColumnNotFoundError(*id)) } pub fn namespace(&self) -> Rc { self.namespace.as_str().into() } - pub fn columns(&self, ids: &[Felt]) -> TableResult> { - ids.iter() - .map(|id| self.column(id)) - .collect::>>() + pub fn columns(&self, ids: &[Felt]) -> Result, ColumnsNotFoundError> { + ids.iter().map(|id| self.column(id)).collect_columns() } pub fn all_columns(&self) -> Vec<&ColumnInfo> { @@ -98,10 +94,10 @@ impl Table { pub fn columns_with_ids<'a>( &'a self, ids: &'a [Felt], - ) -> TableResult> { + ) -> Result, ColumnsNotFoundError> { ids.iter() .map(|id| self.column(id).map(|col| (id, col))) - .collect::>>() + .collect_columns() } pub fn all_columns_with_ids(&self) -> Vec<(&Felt, &ColumnInfo)> { @@ -109,25 +105,32 @@ impl Table { } pub fn new( - id: Felt, namespace: String, + id: Felt, owner: Felt, - info: TableInfo, + name: String, + primary: PrimaryDef, + columns: &[ColumnDef], dead: Option>, + append_only: bool, ) -> Self { Table { id, namespace, owner, - name: info.name, - primary: info.primary.into(), - columns: info.columns.into_iter().map_into().collect(), - alive: true, + name, + primary: primary.into(), + columns: columns.into_iter().cloned().map_into().collect(), dead: dead.unwrap_or_default().into_iter().collect(), + append_only, + alive: true, } } - pub fn get_record_schema(&self, columns: &[Felt]) -> TableResult> { + pub fn get_record_schema( + &self, + columns: &[Felt], + ) -> Result, ColumnsNotFoundError> { Ok(RecordSchema::new(&self.primary, self.columns(columns)?)) } } diff --git a/crates/introspect-sql-sink/src/tables.rs b/crates/introspect-sql-sink/src/tables.rs index 71a5cac1..2ce18e80 100644 --- a/crates/introspect-sql-sink/src/tables.rs +++ b/crates/introspect-sql-sink/src/tables.rs @@ -3,13 +3,11 @@ use crate::error::RecordResultExt; use crate::namespace::{NamespaceKey, TableKey}; use crate::table::Table; use crate::{DbError, DbResult}; -use introspect_types::ResultInto; +use introspect_types::{ColumnDef, PrimaryDef, ResultInto}; use starknet_types_core::felt::Felt; use std::collections::HashMap; use std::ops::Deref; use std::sync::RwLock; -use torii_introspect::events::IntrospectMsg; -use torii_introspect::schema::TableSchema; use torii_introspect::InsertsFields; use torii_sql::FlexQuery; @@ -28,53 +26,71 @@ impl Tables { pub fn create_table( &self, namespace_key: NamespaceKey, - to_table: impl Into, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], + append_only: bool, from_address: &Felt, block_number: u64, transaction_hash: &Felt, queries: &mut Vec>, ) -> DbResult<()> { - let (id, info) = Into::::into(to_table).into(); let namespace = namespace_key.to_string(); - let key = TableKey::new(namespace_key, id); - self.assert_table_not_exists(&key, &info.name)?; + let key = TableKey::new(namespace_key, *id); + self.assert_table_not_exists(&key, name)?; DB::create_table_queries( &namespace, - &id, - &info.name, - &info.primary, - &info.columns, + id, + name, + primary, + columns, + append_only, from_address, block_number, transaction_hash, queries, )?; let mut tables = self.write()?; - tables.insert(key, Table::new(id, namespace, *from_address, info, None)); + tables.insert( + key, + Table::new( + namespace, + *id, + *from_address, + name.to_string(), + primary.clone(), + columns, + None, + append_only, + ), + ); Ok(()) } pub fn update_table( &self, namespace_key: NamespaceKey, - to_table: impl Into, + id: &Felt, + name: &str, + primary: &PrimaryDef, + columns: &[ColumnDef], from_address: &Felt, block_number: u64, transaction_hash: &Felt, queries: &mut Vec>, ) -> DbResult<()> { - let (id, new) = Into::::into(to_table).into(); let mut tables = self.write()?; - let key = TableKey::new(namespace_key, id); + let key = TableKey::new(namespace_key, *id); let table = tables .get_mut(&key) .ok_or_else(|| DbError::TableNotFound(key.clone()))?; DB::update_table_queries( table, - &new.name, - &new.primary, - &new.columns, + name, + primary, + columns, from_address, block_number, transaction_hash, @@ -124,11 +140,9 @@ impl Tables { if !table.alive { return Ok(()); } - let schema = table.get_record_schema(&event.columns)?; DB::insert_record_queries( - &table.namespace, - &table.name, - &schema, + &table, + &event.columns, &event.records, from_address, block_number, @@ -137,50 +151,4 @@ impl Tables { ) .to_db_result(&table.name) } - - pub fn handle_message( - &self, - namespace: NamespaceKey, - msg: &IntrospectMsg, - from_address: &Felt, - block_number: u64, - transaction_hash: &Felt, - queries: &mut Vec>, - ) -> DbResult<()> { - match msg { - IntrospectMsg::CreateTable(event) => self.create_table::( - namespace, - event.clone(), - from_address, - block_number, - transaction_hash, - queries, - ), - IntrospectMsg::UpdateTable(event) => self.update_table::( - namespace, - event.clone(), - from_address, - block_number, - transaction_hash, - queries, - ), - IntrospectMsg::AddColumns(event) => self.set_table_dead(namespace, event.table), - IntrospectMsg::DropColumns(event) => self.set_table_dead(namespace, event.table), - IntrospectMsg::RetypeColumns(event) => self.set_table_dead(namespace, event.table), - IntrospectMsg::RetypePrimary(event) => self.set_table_dead(namespace, event.table), - IntrospectMsg::RenameTable(_) - | IntrospectMsg::DropTable(_) - | IntrospectMsg::RenameColumns(_) - | IntrospectMsg::RenamePrimary(_) => Ok(()), - IntrospectMsg::InsertsFields(event) => self.insert_fields::( - namespace, - event, - from_address, - block_number, - transaction_hash, - queries, - ), - IntrospectMsg::DeleteRecords(_) | IntrospectMsg::DeletesFields(_) => Ok(()), - } - } } diff --git a/crates/introspect/src/events.rs b/crates/introspect/src/events.rs index c4797559..1a3be3cc 100644 --- a/crates/introspect/src/events.rs +++ b/crates/introspect/src/events.rs @@ -72,6 +72,7 @@ pub struct CreateTable { pub attributes: Vec, pub primary: PrimaryDef, pub columns: Vec, + pub append_only: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -288,6 +289,7 @@ impl From for CreateTable { attributes: schema.attributes, primary: schema.primary, columns: schema.columns, + append_only: false, } } } @@ -351,6 +353,19 @@ impl InsertsFields { } } +impl CreateTable { + pub fn from_schema(schema: TableSchema, append_only: bool) -> Self { + Self { + id: schema.id, + name: schema.name, + attributes: schema.attributes, + primary: schema.primary, + columns: schema.columns, + append_only, + } + } +} + impl DeleteRecords { pub fn new(table: Felt, rows: Vec) -> Self { Self { table, rows } diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index 7fccb0fa..fb511830 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -6604,6 +6604,7 @@ mod tests { attributes: vec![], type_def: TypeDef::Bool, }], + append_only: false, }; service.cache_created_table(world_address, &table).await; @@ -6699,6 +6700,7 @@ mod tests { attributes: vec![], type_def: TypeDef::Bool, }], + append_only: false, }; service.cache_created_table(world_address, &table).await; @@ -6808,6 +6810,7 @@ mod tests { attributes: vec![Attribute::new_empty("key".to_string())], type_def: TypeDef::Felt252, }], + append_only: false, }; service.cache_created_table(world_address, &table).await; diff --git a/crates/torii-ecs-sink/tests/sqlite_prepared_statements.rs b/crates/torii-ecs-sink/tests/sqlite_prepared_statements.rs index bed8880b..c6a1c590 100644 --- a/crates/torii-ecs-sink/tests/sqlite_prepared_statements.rs +++ b/crates/torii-ecs-sink/tests/sqlite_prepared_statements.rs @@ -23,7 +23,6 @@ fn runtime_sqlite_queries_avoid_uncached_prepare_and_inline_format_sql() { let root = workspace_root(); let files = [ "crates/torii-ecs-sink/src/grpc_service.rs", - "crates/torii-entities-historical-sink/src/lib.rs", "crates/introspect-sql-sink/src/sqlite/table.rs", "crates/torii-erc20/src/storage.rs", "crates/torii-erc721/src/storage.rs", diff --git a/crates/torii-entities-historical-sink/Cargo.toml b/crates/torii-entities-historical-sink/Cargo.toml deleted file mode 100644 index e03ade7e..00000000 --- a/crates/torii-entities-historical-sink/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "torii-entities-historical-sink" -version = "0.1.0" -edition = "2021" -description = "Append-only historical entity sink for Torii introspect models" -authors = ["Torii Runtime "] -license = "Apache-2.0" - -[dependencies] -anyhow.workspace = true -async-trait.workspace = true -serde.workspace = true -serde_json.workspace = true -sqlx = { workspace = true, features = [ - "any", - "postgres", - "sqlite", - "runtime-tokio-rustls", -] } -starknet.workspace = true -tokio.workspace = true -tracing.workspace = true -thiserror.workspace = true -introspect-types.workspace = true -itertools.workspace = true -primitive-types.workspace = true - -torii.workspace = true -torii-sql.workspace = true -torii-runtime-common.workspace = true -torii-introspect.workspace = true - -[lints] -workspace = true diff --git a/crates/torii-entities-historical-sink/src/lib.rs b/crates/torii-entities-historical-sink/src/lib.rs deleted file mode 100644 index b5fa2bfc..00000000 --- a/crates/torii-entities-historical-sink/src/lib.rs +++ /dev/null @@ -1,1165 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::str::FromStr; -use std::sync::Arc; - -use anyhow::{anyhow, Context, Result}; -use async_trait::async_trait; -use sqlx::any::AnyPoolOptions; -use sqlx::{Any, Pool, Row}; -use starknet::core::types::Felt; -use tokio::sync::RwLock; -use torii::axum::Router; -use torii::etl::envelope::{Envelope, TypeId}; -use torii::etl::extractor::ExtractionBatch; -use torii::etl::sink::{EventBus, Sink, SinkContext, TopicInfo}; -use torii_introspect::events::{CreateTable, IntrospectBody, IntrospectMsg, UpdateTable}; -use torii_introspect::schema::TableSchema; -use torii_sql::connection::DbOption; -use torii_sql::DbBackend; - -const INTROSPECT_TYPE: TypeId = TypeId::new("introspect"); -const SQLITE_FETCH_SCHEMA_STATE_QUERY: &str = - "SELECT table_schema_json FROM introspect_sink_schema_state WHERE alive != 0"; - -#[derive(Clone, Debug, Default)] -pub enum HistoricalNamespace { - #[default] - Default, - Custom(String), -} - -impl HistoricalNamespace { - fn sqlite_prefix(&self) -> &str { - match self { - Self::Default => "", - Self::Custom(prefix) => prefix, - } - } - - fn postgres_schema(&self) -> &str { - match self { - Self::Default => "public", - Self::Custom(schema) => schema, - } - } -} - -impl From<()> for HistoricalNamespace { - fn from((): ()) -> Self { - Self::Default - } -} - -impl From for HistoricalNamespace { - fn from(value: String) -> Self { - if value.is_empty() { - Self::Default - } else { - Self::Custom(value) - } - } -} - -impl From<&str> for HistoricalNamespace { - fn from(value: &str) -> Self { - if value.is_empty() { - Self::Default - } else { - Self::Custom(value.to_string()) - } - } -} - -#[derive(Clone, Debug)] -struct HistoryColumn { - name: String, - type_sql: String, -} - -#[derive(Clone, Debug)] -struct TrackedTable { - logical_name: String, - base_name: String, - history_name: String, - columns: Vec, - sqlite_queries: Option, -} - -#[derive(Clone, Debug)] -struct TrackedTableSqliteQueries { - next_revision: String, - copy_current_row: String, - insert_tombstone: String, -} - -#[derive(Clone)] -pub struct EntitiesHistoricalSink { - pool: Pool, - backend: DbBackend, - namespace: HistoricalNamespace, - tracked_names: HashSet, - tracked_tables: Arc>>, -} - -impl EntitiesHistoricalSink { - pub async fn new( - database_url: &str, - max_connections: Option, - namespace: impl Into, - tracked_models: Vec, - ) -> Result { - sqlx::any::install_default_drivers(); - let backend = DbBackend::from_str(database_url).map_err(anyhow::Error::new)?; - let pool = AnyPoolOptions::new() - .max_connections(max_connections.unwrap_or(DbOption::new(5, 1).value(&backend))) - .connect(database_url) - .await?; - - Ok(Self { - pool, - backend, - namespace: namespace.into(), - tracked_names: tracked_models - .into_iter() - .filter(|name| !name.is_empty()) - .collect(), - tracked_tables: Arc::new(RwLock::new(HashMap::new())), - }) - } - - async fn bootstrap(&self) -> Result<()> { - if self.tracked_names.is_empty() { - return Ok(()); - } - - if self.backend == DbBackend::Sqlite { - sqlx::query("PRAGMA journal_mode=WAL") - .execute(&self.pool) - .await - .ok(); - } - - match self.backend { - DbBackend::Sqlite => { - let rows = sqlx::query(SQLITE_FETCH_SCHEMA_STATE_QUERY) - .fetch_all(&self.pool) - .await?; - for row in rows { - let schema_json: String = row.try_get("table_schema_json")?; - let schema: TableSchema = serde_json::from_str(&schema_json)?; - if self.tracked_names.contains(&schema.name) { - self.sync_tracked_table(schema.id, &schema.name).await?; - } - } - } - DbBackend::Postgres => { - let rows = sqlx::query( - "SELECT id, name - FROM introspect.db_tables - WHERE \"schema\" = $1", - ) - .bind(self.namespace.postgres_schema()) - .fetch_all(&self.pool) - .await?; - for row in rows { - let table_name: String = row.try_get("name")?; - if !self.tracked_names.contains(&table_name) { - continue; - } - let table_id = felt_from_row_hex(&row, "id")?; - self.sync_tracked_table(table_id, &table_name).await?; - } - } - } - - Ok(()) - } - - async fn resolve_tracked_table(&self, table_id: Felt) -> Result> { - let tracked = { - let tracked_tables = self.tracked_tables.read().await; - tracked_tables.get(&table_id).cloned() - }; - - if let Some(table) = tracked { - return Ok(Some(table)); - } - - let resolved = self.lookup_table_name(table_id).await?; - let Some(table_name) = resolved else { - return Ok(None); - }; - if !self.tracked_names.contains(&table_name) { - return Ok(None); - } - - let tracked = self.sync_tracked_table(table_id, &table_name).await?; - Ok(Some(tracked)) - } - - async fn lookup_table_name(&self, table_id: Felt) -> Result> { - let (canonical_table_id, compact_table_id) = felt_hex_variants(table_id); - match self.backend { - DbBackend::Sqlite => { - let row = sqlx::query( - "SELECT table_schema_json - FROM introspect_sink_schema_state - WHERE table_id = ?1 OR table_id = ?2 - LIMIT 1", - ) - .bind(canonical_table_id) - .bind(compact_table_id) - .fetch_optional(&self.pool) - .await?; - row.map(|row| { - let schema_json: String = row.try_get("table_schema_json")?; - let schema: TableSchema = serde_json::from_str(&schema_json)?; - Ok::<_, anyhow::Error>(schema.name) - }) - .transpose() - } - DbBackend::Postgres => { - let row = sqlx::query( - "SELECT name - FROM introspect.db_tables - WHERE \"schema\" = $1 AND (id::text = $2 OR id::text = $3) - LIMIT 1", - ) - .bind(self.namespace.postgres_schema()) - .bind(canonical_table_id) - .bind(compact_table_id) - .fetch_optional(&self.pool) - .await?; - row.map(|row| row.try_get("name").map_err(Into::into)) - .transpose() - } - } - } - - async fn sync_tracked_table(&self, table_id: Felt, logical_name: &str) -> Result { - let base_name = match self.backend { - DbBackend::Sqlite => sqlite_storage_name(self.namespace.sqlite_prefix(), logical_name), - DbBackend::Postgres => logical_name.to_string(), - }; - let history_name = match self.backend { - DbBackend::Sqlite => sqlite_storage_name( - self.namespace.sqlite_prefix(), - &format!("{logical_name}_historical"), - ), - DbBackend::Postgres => format!("{logical_name}_historical"), - }; - let columns = self.load_source_columns(&base_name).await?; - if !columns.iter().any(|column| column.name == "entity_id") { - return Err(anyhow!( - "tracked table '{logical_name}' does not expose entity_id column" - )); - } - let sqlite_queries = (self.backend == DbBackend::Sqlite) - .then(|| build_tracked_table_sqlite_queries(&base_name, &history_name, &columns)); - let tracked = TrackedTable { - logical_name: logical_name.to_string(), - base_name, - history_name, - sqlite_queries, - columns, - }; - self.ensure_history_table(&tracked).await?; - self.tracked_tables - .write() - .await - .insert(table_id, tracked.clone()); - Ok(tracked) - } - - async fn load_source_columns(&self, base_name: &str) -> Result> { - match self.backend { - DbBackend::Sqlite => { - // sqlite-dynamic-ok - let rows = sqlx::query(&format!( - "PRAGMA table_info({})", - quote_sqlite_identifier(base_name) - )) - .fetch_all(&self.pool) - .await?; - let mut columns = Vec::with_capacity(rows.len()); - for row in rows { - let name: String = row.try_get("name")?; - let type_sql: String = row.try_get("type")?; - columns.push(HistoryColumn { name, type_sql }); - } - Ok(columns) - } - DbBackend::Postgres => { - let rows = sqlx::query( - "SELECT a.attname AS column_name, - pg_catalog.format_type(a.atttypid, a.atttypmod) AS column_type - FROM pg_catalog.pg_attribute a - JOIN pg_catalog.pg_class c ON c.oid = a.attrelid - JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace - WHERE n.nspname = $1 - AND c.relname = $2 - AND a.attnum > 0 - AND NOT a.attisdropped - ORDER BY a.attnum", - ) - .bind(self.namespace.postgres_schema()) - .bind(base_name) - .fetch_all(&self.pool) - .await?; - - let mut columns = Vec::new(); - for row in rows { - let name: String = row.try_get("column_name")?; - if name.starts_with("__") { - continue; - } - let type_sql: String = row.try_get("column_type")?; - columns.push(HistoryColumn { name, type_sql }); - } - Ok(columns) - } - } - } - - async fn ensure_history_table(&self, tracked: &TrackedTable) -> Result<()> { - let create_sql = match self.backend { - DbBackend::Sqlite => self.create_history_table_sqlite(tracked), - DbBackend::Postgres => self.create_history_table_postgres(tracked), - }; - sqlx::query(&create_sql).execute(&self.pool).await?; - - let existing_columns = self.load_existing_history_columns(tracked).await?; - for column in &tracked.columns { - if existing_columns.contains(&column.name) { - continue; - } - let add_sql = match self.backend { - DbBackend::Sqlite => format!( - "ALTER TABLE {} ADD COLUMN {} {}", - quote_sqlite_identifier(&tracked.history_name), - quote_ident(&column.name), - column.type_sql - ), - DbBackend::Postgres => format!( - "ALTER TABLE {} ADD COLUMN IF NOT EXISTS {} {}", - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name), - quote_ident(&column.name), - column.type_sql - ), - }; - sqlx::query(&add_sql).execute(&self.pool).await?; - } - - for meta_sql in self.ensure_history_meta_columns_sql(tracked, &existing_columns) { - sqlx::query(&meta_sql).execute(&self.pool).await?; - } - - for index_sql in self.ensure_history_indexes_sql(tracked) { - sqlx::query(&index_sql).execute(&self.pool).await?; - } - - Ok(()) - } - - async fn load_existing_history_columns( - &self, - tracked: &TrackedTable, - ) -> Result> { - let rows = match self.backend { - DbBackend::Sqlite => { - // sqlite-dynamic-ok: PRAGMA table_info requires the table identifier in SQL text. - sqlx::query(&format!( - "PRAGMA table_info({})", - quote_sqlite_identifier(&tracked.history_name) - )) - .fetch_all(&self.pool) - .await? - } - DbBackend::Postgres => { - sqlx::query( - "SELECT a.attname AS column_name - FROM pg_catalog.pg_attribute a - JOIN pg_catalog.pg_class c ON c.oid = a.attrelid - JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace - WHERE n.nspname = $1 - AND c.relname = $2 - AND a.attnum > 0 - AND NOT a.attisdropped", - ) - .bind(self.namespace.postgres_schema()) - .bind(&tracked.history_name) - .fetch_all(&self.pool) - .await? - } - }; - let mut columns = HashSet::with_capacity(rows.len()); - for row in rows { - let name = if self.backend == DbBackend::Sqlite { - row.try_get("name")? - } else { - row.try_get("column_name")? - }; - columns.insert(name); - } - Ok(columns) - } - - fn create_history_table_sqlite(&self, tracked: &TrackedTable) -> String { - let model_columns = tracked - .columns - .iter() - .map(|column| { - if column.name == "entity_id" { - format!("{} {} NOT NULL", quote_ident(&column.name), column.type_sql) - } else { - format!("{} {}", quote_ident(&column.name), column.type_sql) - } - }) - .collect::>() - .join(", "); - format!( - "CREATE TABLE IF NOT EXISTS {} ({model_columns}, \ - \"revision\" INTEGER NOT NULL DEFAULT 0, \ - \"historical_deleted\" INTEGER NOT NULL DEFAULT 0, \ - \"historical_block_number\" INTEGER, \ - \"historical_tx_hash\" TEXT NOT NULL DEFAULT '', \ - \"historical_executed_at\" INTEGER NOT NULL DEFAULT 0)", - quote_sqlite_identifier(&tracked.history_name) - ) - } - - fn create_history_table_postgres(&self, tracked: &TrackedTable) -> String { - let model_columns = tracked - .columns - .iter() - .map(|column| { - if column.name == "entity_id" { - format!("{} {} NOT NULL", quote_ident(&column.name), column.type_sql) - } else { - format!("{} {}", quote_ident(&column.name), column.type_sql) - } - }) - .collect::>() - .join(", "); - format!( - "CREATE TABLE IF NOT EXISTS {} ({model_columns}, \ - \"revision\" BIGINT NOT NULL DEFAULT 0, \ - \"historical_deleted\" BOOLEAN NOT NULL DEFAULT FALSE, \ - \"historical_block_number\" BIGINT, \ - \"historical_tx_hash\" TEXT NOT NULL DEFAULT '', \ - \"historical_executed_at\" BIGINT NOT NULL DEFAULT 0)", - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ) - } - - fn ensure_history_meta_columns_sql( - &self, - tracked: &TrackedTable, - existing_columns: &HashSet, - ) -> Vec { - match self.backend { - DbBackend::Sqlite => { - let mut sql = Vec::new(); - let target = quote_sqlite_identifier(&tracked.history_name); - if !existing_columns.contains("revision") { - sql.push(format!( - "ALTER TABLE {target} ADD COLUMN \"revision\" INTEGER NOT NULL DEFAULT 0" - )); - } - if !existing_columns.contains("historical_deleted") { - sql.push(format!( - "ALTER TABLE {target} ADD COLUMN \"historical_deleted\" INTEGER NOT NULL DEFAULT 0" - )); - } - if !existing_columns.contains("historical_block_number") { - sql.push(format!( - "ALTER TABLE {target} ADD COLUMN \"historical_block_number\" INTEGER" - )); - } - if !existing_columns.contains("historical_tx_hash") { - sql.push(format!( - "ALTER TABLE {target} ADD COLUMN \"historical_tx_hash\" TEXT NOT NULL DEFAULT ''" - )); - } - if !existing_columns.contains("historical_executed_at") { - sql.push(format!( - "ALTER TABLE {target} ADD COLUMN \"historical_executed_at\" INTEGER NOT NULL DEFAULT 0" - )); - } - sql - } - DbBackend::Postgres => vec![ - format!( - "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"revision\" BIGINT NOT NULL DEFAULT 0", - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ), - format!( - "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"historical_deleted\" BOOLEAN NOT NULL DEFAULT FALSE", - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ), - format!( - "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"historical_block_number\" BIGINT", - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ), - format!( - "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"historical_tx_hash\" TEXT NOT NULL DEFAULT ''", - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ), - format!( - "ALTER TABLE {} ADD COLUMN IF NOT EXISTS \"historical_executed_at\" BIGINT NOT NULL DEFAULT 0", - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ), - ], - } - } - - fn ensure_history_indexes_sql(&self, tracked: &TrackedTable) -> Vec { - let unique_index = format!("{}_entity_revision_idx", tracked.history_name); - let entity_index = format!("{}_entity_idx", tracked.history_name); - match self.backend { - DbBackend::Sqlite => vec![ - format!( - "CREATE UNIQUE INDEX IF NOT EXISTS {} ON {} (\"entity_id\", \"revision\")", - quote_ident(&unique_index), - quote_sqlite_identifier(&tracked.history_name) - ), - format!( - "CREATE INDEX IF NOT EXISTS {} ON {} (\"entity_id\")", - quote_ident(&entity_index), - quote_sqlite_identifier(&tracked.history_name) - ), - ], - DbBackend::Postgres => vec![ - format!( - "CREATE UNIQUE INDEX IF NOT EXISTS {} ON {} (\"entity_id\", \"revision\")", - quote_ident(&unique_index), - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ), - format!( - "CREATE INDEX IF NOT EXISTS {} ON {} (\"entity_id\")", - quote_ident(&entity_index), - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ), - ], - } - } - - async fn next_revision( - &self, - tracked: &TrackedTable, - canonical_entity_id_hex: &str, - compact_entity_id_hex: &str, - ) -> Result { - let sql = match self.backend { - DbBackend::Sqlite => tracked - .sqlite_queries - .as_ref() - .expect("sqlite queries available for sqlite backend") - .next_revision - .clone(), - DbBackend::Postgres => format!( - "SELECT COALESCE(MAX(\"revision\"), 0) + 1 AS next_revision \ - FROM {} WHERE \"entity_id\"::text = $1 OR \"entity_id\"::text = $2", - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name) - ), - }; - let row = sqlx::query(&sql) - .bind(canonical_entity_id_hex) - .bind(compact_entity_id_hex) - .fetch_one(&self.pool) - .await?; - Ok(row.try_get::("next_revision")?) - } - - async fn persist_snapshot( - &self, - tracked: &TrackedTable, - entity_id: Felt, - block_number: Option, - tx_hash: Felt, - executed_at: u64, - deleted: bool, - ) -> Result<()> { - let (canonical_entity_id_hex, compact_entity_id_hex) = felt_hex_variants(entity_id); - let revision = self - .next_revision(tracked, &canonical_entity_id_hex, &compact_entity_id_hex) - .await?; - let copied = self - .copy_current_row_into_history( - tracked, - &canonical_entity_id_hex, - &compact_entity_id_hex, - revision, - block_number, - tx_hash, - executed_at, - deleted, - ) - .await?; - if copied == 0 { - if deleted { - self.insert_tombstone_only( - tracked, - &canonical_entity_id_hex, - revision, - block_number, - tx_hash, - executed_at, - ) - .await?; - return Ok(()); - } - return Err(anyhow!( - "unable to load latest row for tracked model '{}' entity {}", - tracked.logical_name, - canonical_entity_id_hex - )); - } - Ok(()) - } - - async fn copy_current_row_into_history( - &self, - tracked: &TrackedTable, - canonical_entity_id_hex: &str, - compact_entity_id_hex: &str, - revision: i64, - block_number: Option, - tx_hash: Felt, - executed_at: u64, - deleted: bool, - ) -> Result { - let sql = match self.backend { - DbBackend::Sqlite => tracked - .sqlite_queries - .as_ref() - .expect("sqlite queries available for sqlite backend") - .copy_current_row - .clone(), - DbBackend::Postgres => { - let source_columns = tracked - .columns - .iter() - .map(|column| quote_ident(&column.name)) - .collect::>() - .join(", "); - let insert_columns = format!( - "{source_columns}, \"revision\", \"historical_deleted\", \ - \"historical_block_number\", \"historical_tx_hash\", \"historical_executed_at\"" - ); - let history_target = - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name); - let source_target = - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.base_name); - format!( - "INSERT INTO {history_target} ({insert_columns}) \ - SELECT {source_columns}, $1, $2, $3, $4, $5 \ - FROM {source_target} WHERE (\"entity_id\"::text = $6 OR \"entity_id\"::text = $7) LIMIT 1" - ) - } - }; - let mut query = sqlx::query(&sql).bind(revision); - query = match self.backend { - DbBackend::Sqlite => query.bind(i64::from(deleted)), - DbBackend::Postgres => query.bind(deleted), - }; - let result = query - .bind(block_number.map(|value| value as i64)) - .bind(felt_hex(tx_hash)) - .bind(executed_at as i64) - .bind(canonical_entity_id_hex) - .bind(compact_entity_id_hex) - .execute(&self.pool) - .await?; - Ok(result.rows_affected()) - } - - async fn insert_tombstone_only( - &self, - tracked: &TrackedTable, - entity_id_hex: &str, - revision: i64, - block_number: Option, - tx_hash: Felt, - executed_at: u64, - ) -> Result<()> { - let sql = match self.backend { - DbBackend::Sqlite => tracked - .sqlite_queries - .as_ref() - .expect("sqlite queries available for sqlite backend") - .insert_tombstone - .clone(), - DbBackend::Postgres => { - let mut columns = Vec::with_capacity(tracked.columns.len() + 5); - let mut values_sql = Vec::with_capacity(tracked.columns.len() + 5); - - let mut bind_index = 1_usize; - for column in &tracked.columns { - columns.push(quote_ident(&column.name)); - if column.name == "entity_id" { - values_sql.push(self.entity_cast_placeholder(bind_index, &column.type_sql)); - bind_index += 1; - } else { - values_sql.push("NULL".to_string()); - } - } - - columns.extend([ - "\"revision\"".to_string(), - "\"historical_deleted\"".to_string(), - "\"historical_block_number\"".to_string(), - "\"historical_tx_hash\"".to_string(), - "\"historical_executed_at\"".to_string(), - ]); - values_sql.push(self.value_placeholder(bind_index)); - bind_index += 1; - values_sql.push(self.value_placeholder(bind_index)); - bind_index += 1; - values_sql.push(self.value_placeholder(bind_index)); - bind_index += 1; - values_sql.push(self.value_placeholder(bind_index)); - bind_index += 1; - values_sql.push(self.value_placeholder(bind_index)); - - let target = - quote_pg_qualified(self.namespace.postgres_schema(), &tracked.history_name); - format!( - "INSERT INTO {target} ({}) VALUES ({})", - columns.join(", "), - values_sql.join(", ") - ) - } - }; - - let mut query = sqlx::query(&sql).bind(entity_id_hex).bind(revision); - query = match self.backend { - DbBackend::Sqlite => query.bind(1_i64), - DbBackend::Postgres => query.bind(true), - }; - query - .bind(block_number.map(|value| value as i64)) - .bind(felt_hex(tx_hash)) - .bind(executed_at as i64) - .execute(&self.pool) - .await?; - - Ok(()) - } - - fn value_placeholder(&self, index: usize) -> String { - match self.backend { - DbBackend::Sqlite => "?".to_string(), - DbBackend::Postgres => format!("${index}"), - } - } - - fn entity_cast_placeholder(&self, index: usize, type_sql: &str) -> String { - match self.backend { - DbBackend::Sqlite => "?".to_string(), - DbBackend::Postgres => format!("CAST(${index} AS {type_sql})"), - } - } - - async fn process_table_schema(&self, table: &CreateTable) -> Result<()> { - if self.tracked_names.contains(&table.name) { - self.sync_tracked_table(table.id, &table.name).await?; - } - Ok(()) - } - - async fn process_table_update(&self, table: &UpdateTable) -> Result<()> { - if self.tracked_names.contains(&table.name) { - self.sync_tracked_table(table.id, &table.name).await?; - } - Ok(()) - } -} - -#[async_trait] -impl Sink for EntitiesHistoricalSink { - fn name(&self) -> &'static str { - "entities-historical" - } - - fn interested_types(&self) -> Vec { - vec![INTROSPECT_TYPE] - } - - async fn process(&self, envelopes: &[Envelope], batch: &ExtractionBatch) -> Result<()> { - for envelope in envelopes { - if envelope.type_id != INTROSPECT_TYPE { - continue; - } - let Some(body) = envelope.downcast_ref::() else { - continue; - }; - let context = batch - .get_event_context(&body.metadata.transaction_hash, body.metadata.from_address) - .unwrap_or_default(); - let block_number = body - .metadata - .block_number - .or(Some(context.transaction.block_number)); - let executed_at = context.block.timestamp; - - match &body.msg { - IntrospectMsg::CreateTable(table) => { - self.process_table_schema(table).await?; - } - IntrospectMsg::UpdateTable(table) => { - self.process_table_update(table).await?; - } - IntrospectMsg::InsertsFields(insert) => { - let Some(tracked) = self.resolve_tracked_table(insert.table).await? else { - continue; - }; - for record in &insert.records { - self.persist_snapshot( - &tracked, - Felt::from_bytes_be(&record.id), - block_number, - body.metadata.transaction_hash, - executed_at, - false, - ) - .await - .with_context(|| { - format!( - "failed to persist historical snapshot for '{}' insert", - tracked.logical_name - ) - })?; - } - } - IntrospectMsg::DeleteRecords(delete) => { - let Some(tracked) = self.resolve_tracked_table(delete.table).await? else { - continue; - }; - for row in &delete.rows { - self.persist_snapshot( - &tracked, - row.to_felt(), - block_number, - body.metadata.transaction_hash, - executed_at, - true, - ) - .await - .with_context(|| { - format!( - "failed to persist historical tombstone for '{}'", - tracked.logical_name - ) - })?; - } - } - _ => {} - } - } - - Ok(()) - } - - fn topics(&self) -> Vec { - Vec::new() - } - - fn build_routes(&self) -> Router { - Router::new() - } - - async fn initialize( - &mut self, - _event_bus: Arc, - _context: &SinkContext, - ) -> Result<()> { - self.bootstrap().await?; - Ok(()) - } -} - -fn sqlite_storage_name(prefix: &str, logical_name: &str) -> String { - if prefix.is_empty() { - logical_name.to_string() - } else { - format!("{prefix}__{logical_name}") - } -} - -fn quote_ident(identifier: &str) -> String { - format!("\"{}\"", identifier.replace('"', "\"\"")) -} - -fn quote_sqlite_identifier(table: &str) -> String { - quote_ident(table) -} - -fn quote_pg_qualified(schema: &str, table: &str) -> String { - format!("{}.{}", quote_ident(schema), quote_ident(table)) -} - -fn build_tracked_table_sqlite_queries( - base_name: &str, - history_name: &str, - columns: &[HistoryColumn], -) -> TrackedTableSqliteQueries { - let history_target = quote_sqlite_identifier(history_name); - let source_target = quote_sqlite_identifier(base_name); - let source_columns = columns - .iter() - .map(|column| quote_ident(&column.name)) - .collect::>() - .join(", "); - let insert_columns = format!( - "{source_columns}, \"revision\", \"historical_deleted\", \ - \"historical_block_number\", \"historical_tx_hash\", \"historical_executed_at\"" - ); - - let mut tombstone_columns = Vec::with_capacity(columns.len() + 5); - let mut tombstone_values = Vec::with_capacity(columns.len() + 5); - for column in columns { - tombstone_columns.push(quote_ident(&column.name)); - if column.name == "entity_id" { - tombstone_values.push("?".to_string()); - } else { - tombstone_values.push("NULL".to_string()); - } - } - tombstone_columns.extend([ - "\"revision\"".to_string(), - "\"historical_deleted\"".to_string(), - "\"historical_block_number\"".to_string(), - "\"historical_tx_hash\"".to_string(), - "\"historical_executed_at\"".to_string(), - ]); - tombstone_values.extend([ - "?".to_string(), - "?".to_string(), - "?".to_string(), - "?".to_string(), - "?".to_string(), - ]); - - TrackedTableSqliteQueries { - next_revision: format!( - "SELECT COALESCE(MAX(\"revision\"), 0) + 1 AS next_revision \ - FROM {history_target} WHERE \"entity_id\" = ?1 OR \"entity_id\" = ?2" - ), - copy_current_row: format!( - "INSERT INTO {history_target} ({insert_columns}) \ - SELECT {source_columns}, ?1, ?2, ?3, ?4, ?5 \ - FROM {source_target} \ - WHERE (\"entity_id\" = ?6 OR \"entity_id\" = ?7) \ - LIMIT 1" - ), - insert_tombstone: format!( - "INSERT INTO {history_target} ({}) VALUES ({})", - tombstone_columns.join(", "), - tombstone_values.join(", ") - ), - } -} - -fn felt_hex(value: Felt) -> String { - format!("{value:#x}") -} - -fn canonical_felt_hex(value: Felt) -> String { - format!("{value:#066x}") -} - -fn compact_hex_str(value: &str) -> String { - let value = value.trim(); - let Some(hex) = value.strip_prefix("0x") else { - return value.to_string(); - }; - let trimmed = hex.trim_start_matches('0'); - if trimmed.is_empty() { - "0x0".to_string() - } else { - format!("0x{trimmed}") - } -} - -fn felt_hex_variants(value: Felt) -> (String, String) { - let canonical = canonical_felt_hex(value); - let compact = compact_hex_str(&canonical); - (canonical, compact) -} - -fn felt_from_row_hex(row: &sqlx::any::AnyRow, column: &str) -> Result { - let value: String = row.try_get(column)?; - Felt::from_hex(&value).map_err(Into::into) -} - -#[cfg(test)] -mod tests { - use super::*; - use introspect_types::{ColumnDef, PrimaryDef, PrimaryTypeDef, TypeDef}; - use torii::etl::envelope::{EventBody, MetaData}; - use torii::etl::extractor::ExtractionBatch; - use torii_introspect::events::{DeleteRecords, InsertsFields, IntrospectMsg, Record}; - - fn sqlite_table_schema(name: &str, id: Felt) -> TableSchema { - TableSchema { - id, - name: name.to_string(), - attributes: Vec::new(), - primary: PrimaryDef { - name: "entity_id".to_string(), - attributes: Vec::new(), - type_def: PrimaryTypeDef::Felt252, - }, - columns: vec![ - ColumnDef { - id: Felt::from(1_u8), - name: "name".to_string(), - attributes: Vec::new(), - type_def: TypeDef::ByteArray, - }, - ColumnDef { - id: Felt::from(2_u8), - name: "score".to_string(), - attributes: Vec::new(), - type_def: TypeDef::U32, - }, - ], - } - } - - async fn sqlite_sink() -> Result { - let sink = EntitiesHistoricalSink::new( - "sqlite::memory:", - Some(1), - (), - vec!["NUMS-Game".to_string()], - ) - .await?; - sqlx::query( - "CREATE TABLE introspect_sink_schema_state ( - table_id TEXT PRIMARY KEY, - table_schema_json TEXT NOT NULL, - alive INTEGER NOT NULL DEFAULT 1, - updated_at INTEGER NOT NULL DEFAULT (unixepoch()) - )", - ) - .execute(&sink.pool) - .await?; - sqlx::query( - "CREATE TABLE \"NUMS-Game\" ( - \"entity_id\" TEXT PRIMARY KEY, - \"name\" TEXT, - \"score\" INTEGER - )", - ) - .execute(&sink.pool) - .await?; - let schema = sqlite_table_schema("NUMS-Game", Felt::from(9_u8)); - sqlx::query( - "INSERT INTO introspect_sink_schema_state (table_id, table_schema_json, alive, updated_at) - VALUES (?1, ?2, 1, unixepoch())", - ) - .bind(canonical_felt_hex(schema.id)) - .bind(serde_json::to_string(&schema)?) - .execute(&sink.pool) - .await?; - Ok(sink) - } - - #[tokio::test] - async fn initializes_history_table_from_sqlite_schema_state() -> Result<()> { - let sink = sqlite_sink().await?; - sink.bootstrap().await?; - - let row = sqlx::query( - "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'NUMS-Game_historical'", - ) - .fetch_one(&sink.pool) - .await?; - let name: String = row.try_get("name")?; - assert_eq!(name, "NUMS-Game_historical"); - Ok(()) - } - - #[tokio::test] - async fn appends_revisions_and_delete_tombstones_in_sqlite() -> Result<()> { - let sink = sqlite_sink().await?; - sink.bootstrap().await?; - - let entity_id = Felt::from(77_u8); - sqlx::query( - "INSERT INTO \"NUMS-Game\" (\"entity_id\", \"name\", \"score\") VALUES (?1, ?2, ?3)", - ) - .bind(canonical_felt_hex(entity_id)) - .bind("first") - .bind(10_i64) - .execute(&sink.pool) - .await?; - - let insert = EventBody { - metadata: MetaData { - block_number: Some(1), - transaction_hash: Felt::from(100_u16), - from_address: Felt::ZERO, - }, - msg: IntrospectMsg::InsertsFields(InsertsFields::new( - Felt::from(9_u8), - Vec::new(), - vec![Record::new(entity_id, Vec::new())], - )), - }; - sink.process(&[Envelope::from(insert)], &ExtractionBatch::empty()) - .await?; - - sqlx::query("UPDATE \"NUMS-Game\" SET \"score\" = 25 WHERE \"entity_id\" = ?1") - .bind(canonical_felt_hex(entity_id)) - .execute(&sink.pool) - .await?; - let update = EventBody { - metadata: MetaData { - block_number: Some(2), - transaction_hash: Felt::from(101_u16), - from_address: Felt::ZERO, - }, - msg: IntrospectMsg::InsertsFields(InsertsFields::new( - Felt::from(9_u8), - Vec::new(), - vec![Record::new(entity_id, Vec::new())], - )), - }; - sink.process(&[Envelope::from(update)], &ExtractionBatch::empty()) - .await?; - - let delete = EventBody { - metadata: MetaData { - block_number: Some(3), - transaction_hash: Felt::from(102_u16), - from_address: Felt::ZERO, - }, - msg: IntrospectMsg::DeleteRecords(DeleteRecords::new( - Felt::from(9_u8), - vec![entity_id.into()], - )), - }; - sink.process(&[Envelope::from(delete)], &ExtractionBatch::empty()) - .await?; - - let rows = sqlx::query( - "SELECT revision, historical_deleted, score FROM \"NUMS-Game_historical\" ORDER BY revision", - ) - .fetch_all(&sink.pool) - .await?; - - assert_eq!(rows.len(), 3); - assert_eq!(rows[0].try_get::("revision")?, 1); - assert_eq!(rows[0].try_get::("historical_deleted")?, 0); - assert_eq!(rows[0].try_get::("score")?, 10); - assert_eq!(rows[1].try_get::("revision")?, 2); - assert_eq!(rows[1].try_get::("score")?, 25); - assert_eq!(rows[2].try_get::("revision")?, 3); - assert_eq!(rows[2].try_get::("historical_deleted")?, 1); - assert_eq!(rows[2].try_get::("score")?, 25); - Ok(()) - } -} diff --git a/examples/introspect/restart copy.rs b/examples/introspect/restart copy.rs deleted file mode 100644 index 33de70c8..00000000 --- a/examples/introspect/restart copy.rs +++ /dev/null @@ -1,109 +0,0 @@ -use itertools::Itertools; -use sqlx::postgres::PgPoolOptions; -use sqlx::PgPool; -use starknet::core::types::Felt; -use torii_dojo::decoder::DojoDecoder; -use torii_dojo::store::postgres::PgStore; -use torii_dojo::DojoToriiError; -use torii_introspect_sql_sink::IntrospectPgDb; -use torii_test_utils::{resolve_path_like, FakeProvider, MultiContractEventIterator}; - -const DB_URL: &str = "postgres://torii:torii@localhost:5432/torii"; -const EVENT_PATHS: [&str; 2] = ["~/tc-tests/blob-arena/events", "~/tc-tests/pistols/events"]; -const MODEL_CONTRACTS_PATH: &str = "~/tc-tests/model-contracts"; -const BATCH_SIZE: usize = 10000; -const PISTOLS_ADDRESS: Felt = - Felt::from_hex_unchecked("08b4838140a3cbd36ebe64d4b5aaf56a30cc3753c928a79338bf56c53f506c5"); -const BLOB_ARENA_ADDRESS: Felt = - Felt::from_hex_unchecked("2d26295d6c541d64740e1ae56abc079b82b22c35ab83985ef8bd15dc0f9edfb"); - -// const SCHEMA_MAP: [(Felt, &str); 2] = [ -// (PISTOLS_ADDRESS, "pistols"), -// (BLOB_ARENA_ADDRESS, "blob_arena"), -// ]; - -const ADDRESSES: [Felt; 2] = [PISTOLS_ADDRESS, BLOB_ARENA_ADDRESS]; - -async fn run_events( - events: &mut MultiContractEventIterator, - provider: FakeProvider, - pool: PgPool, - end: Option, - event_n: &mut u32, - success: &mut u32, -) -> bool { - println!("Starting event processing run"); - let decoder = DojoDecoder::, _>::new(pool.clone(), provider); - let db = IntrospectPgDb::new(pool.clone(), ADDRESSES); - decoder.store.initialize().await.unwrap(); - decoder.load_tables(&[]).await.unwrap(); - let results = db.initialize_introspect_sql_sink().await.unwrap(); - if results.len() > 0 { - for err in results { - println!("Error loading table: {err}"); - } - panic!(""); - } - let mut running = true; - let mut this_run = 0; - while running { - let mut msgs = Vec::with_capacity(BATCH_SIZE); - for _ in 0..BATCH_SIZE { - let Some(event) = events.next() else { - running = false; - break; - }; - *event_n += 1; - this_run += 1; - match decoder.decode_raw_event(&event).await { - Ok(msg) => { - msgs.push(msg); - } - Err(DojoToriiError::UnknownDojoEventSelector(_)) => { - println!("Unknown event selector, skipping event"); - } - Err(err) => { - println!("Failed to decode event: {err:?}"); - } - }; - } - let msgs_ref = msgs.iter().collect_vec(); - for res in db.process_messages(msgs_ref).await.unwrap() { - match res { - Err(err) => println!("Failed to process message: {err:?}"), - Ok(()) => *success += 1, - } - } - println!( - "Processed batch of events, total events processed: {event_n}, successful: {success}" - ); - if let Some(end) = end { - if end <= this_run as u64 { - println!("Reached end of event range, stopping"); - return true; - } - } - } - false -} - -#[tokio::main] -async fn main() { - let event_paths = EVENT_PATHS.map(resolve_path_like).to_vec(); - let provider = FakeProvider::new(resolve_path_like(MODEL_CONTRACTS_PATH)); - let mut event_iterator = MultiContractEventIterator::new(event_paths); - let pool = PgPoolOptions::new().connect(DB_URL).await.unwrap(); - let mut event_n = 0; - let mut success = 0; - while run_events( - &mut event_iterator, - provider.clone(), - pool.clone(), - Some(20000), - &mut event_n, - &mut success, - ) - .await - {} - println!("Finished processing events"); -} diff --git a/examples/introspect/restart.rs b/examples/introspect/restart.rs index d3bb3407..e02f1b53 100644 --- a/examples/introspect/restart.rs +++ b/examples/introspect/restart.rs @@ -3,6 +3,7 @@ use starknet::core::types::Felt; use torii_dojo::decoder::DojoDecoder; use torii_dojo::store::DojoStoreTrait; use torii_dojo::DojoToriiError; +use torii_introspect::events::{IntrospectBody, IntrospectMsg}; use torii_introspect_sql_sink::IntrospectDb; use torii_sql::{DbPool, PoolConfig}; use torii_test_utils::{resolve_path_like, FakeProvider, MultiContractEventIterator}; @@ -11,7 +12,7 @@ use torii_test_utils::{resolve_path_like, FakeProvider, MultiContractEventIterat const DB_URL: &str = "sqlite://sqlite-data.db?mode=rwc"; const EVENT_PATHS: [&str; 2] = ["~/tc-tests/blob-arena/events", "~/tc-tests/pistols/events"]; const MODEL_CONTRACTS_PATH: &str = "~/tc-tests/model-contracts"; -const BATCH_SIZE: usize = 1000; +const BATCH_SIZE: usize = 2000; const PISTOLS_ADDRESS: Felt = Felt::from_hex_unchecked("08b4838140a3cbd36ebe64d4b5aaf56a30cc3753c928a79338bf56c53f506c5"); const BLOB_ARENA_ADDRESS: Felt = @@ -37,9 +38,9 @@ async fn run_events( let db = IntrospectDb::new(pool, ADDRESSES); decoder.initialize().await.unwrap(); decoder.load_tables(&[]).await.unwrap(); - let results = db.initialize_introspect_sql_sink().await.unwrap(); - if results.is_empty() { - for err in results { + let errors = db.initialize_introspect_sql_sink().await.unwrap(); + if !errors.is_empty() { + for err in errors { println!("Error loading table: {err}"); } panic!(""); @@ -56,6 +57,13 @@ async fn run_events( *event_n += 1; this_run += 1; match decoder.decode_raw_event(&event).await { + Ok(IntrospectBody { + metadata, + msg: IntrospectMsg::CreateTable(mut msg), + }) => { + msg.append_only = true; + msgs.push((IntrospectMsg::CreateTable(msg), metadata).into()); + } Ok(msg) => { msgs.push(msg); } @@ -67,6 +75,7 @@ async fn run_events( } }; } + let msgs_ref = msgs.iter().collect_vec(); for res in db.process_messages(msgs_ref).await.unwrap() { match res { diff --git a/sqlite-data.db-journal b/sqlite-data.db-journal index 6673afd43024c4b3ba416929e340e595e4b58e85..51827734ed64f383af6c49499eb36b648a9c2fa3 100644 GIT binary patch literal 1642112 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≫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

pu9cEv>5RK6op4Y__Vh``{P1 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Ν!$n*!v6f)sZVMt(EzJkd_pn+U3zw+N# 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 z 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

1%E@L!-ldpx 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�JQ4abVV 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�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 literal 1646216 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%0A>(Qr^@*xFQ6aJ7|>fmdz{?V`{TyQM&BC)Eu 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

gEvoV7GlvofzyXCj+SJsBoNW7r_XXqn?qMhL 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 B8JSA^OMOvM*a>_m&g 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

yB&_rH{3n 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

J=?qj7QiIOH6#Zw^xNJ_i*=9?T$JJnAkxHRy zP8`7j79Cz!Mp~UYXqL3?QU|FWHi80KCPmVr5;2FE7$>%-D+IZr!P4@yI{lN0$<4hx zlCHfqmN)!4ejS=gCp?1@+-2vX^l}&!9OPrg4gtPFIf$N2-yGc3H1j}x(k#hdDoxX= z0IdPcI#4@AMkd4SRIss9b5meIKv|OOf*cP3w_jUufYzRmi-8VLMt>x@`dV%!e2}-K ziB??ARBS#Vq!47On%3ftLF;_*ti4C$w1UP>K(~K*J7Qk7iBqO&5tM-O!X#mBU2*85 z8wDr-IxcXlcH)vzc_BZ=D+_*RKm>|5yqefX?GS;|-oP)wlbimv%&Y(qm_an#F3$Hq zeMNa8=_Pcs!bsJIDao0qeBIn%`X=0r^^TXZuyq@$It;H>&BlPf*gE;x@^cV;W4-^pMRj!r~m+EYeW|2cRXC z?Gihygq&~E-Me@) zl5FN?@*t*~)|6<&qU(Gic{MS?$4_l*%ZFsrij1JJCB@zTZ#|=U)e2J+wV)A^gNROL z_Iqul^evKA@D;M2`{P6Q>B1_+jG#>4SUv56;)d)$;u(fj!2yGTJeWtnoSU4RD#PFG zJH(H*!7M6A@=E0dGy{LCA1ss?62UP3xMW2d!`%X$sS5xNEyE2XS2oAaJ^+qQrq zsApf={53FH=so+c<%NV&B&e#%N0s_LKD${+M-3}!n06M;YROUi;?Ay?H)dV zWqhG5YQEt5CWJ03fI&E7l3En;oDp?AH&{q;4$a2@<00wRS{F9Arw{*0a{`|j`|~~? z;LX+aJ*G~a>P=og{fzzf{RN|kkNU$ahR+<{bK-`H-Vw`=Gpg8UFQtJpPKpd%y}~pi|^pa;Q{JD zySFg#H&iNQQ`+AchgdXfn?A}jERYu~|D}9moRTZ7o178nHNdXZkGPU{KChU1ffn=TS!{eR2Z}<6-OZ4h#eR zOI}+%S=?1vMd=o_Q3ycBnWn_aWSON$OSF}?`19>=^e6a1A2sQAWvTzwv5ucUZhn4n z%6b%3G%wq$03lybzw!+x4QD z)+qvv`w#?X7aYfvXlepk$(O`MgYY;qa<~it!Z+2r;(rwv$^ozpXAJTZxA%R0iJ;g#@TXWayheU^gklwg%50Fjf z!g}f`qiKOrN46F z1Lde1o|1f|Kv75Z_J0;_dKe|gFou$KP7C38=XU^aGpjEr$*SJjz~);;t(@5!3Hdrk zls3>p+DmOt28Z}0Q7!x>*dv--rbrk-#Zse9!|Gk@z4h$eO=1@_ zxx(8!w}X5`L;4t@mWQuzdfZx5qbv^(Sr~^9 z3a?b}AH%S!zr;gIBc!FMj4#OshB*0bQ1Jembm^sGfgstz^lEWKJSa)ss*!XDS%h(j zia+p@JRt6naP@hkYE`XVi;7`zNg=UBrIDLLdNV z@{BN|;zhS1^7X5Uvn2n)t+&fNsx2F)$_jVBe*{KI8Mm4Nu6o?F0KDV47BQE6=Wrm+ z50+XRT{Q+M?nu)cC`i~$CS)%*>i`)-4$=vfnmy-fDy0%%m~VVZHfoj@f@ZfjMwPf~ zVHIl;a1UAwKD4Tg21!dWVLTBo^KT>Z2fNdaGuMDbySUrGZ0yOzTw%w6L9Ld|ZpH|j zZXl#c>S-iPi;v%}Q902y>5hs9hmu!WggWPsn^IheW~VNSi9XH%i;fBm7D15^n|d!( zL%7<=@=T+quJU0U1eT$(y*C|EyzI;^gcNe1fP2sZWHJOn0`ns$Vg;mpZW0^U@A4H) zLGYT?vyKetT>Gr@LSQYJpcL|**Ci`Vk$F|3i62%}2+TfSoM4m=JkLUA068xL3Ea8$ ze=aWM^Mo06EBqrY_ZBFBT{xJuEW}tq<2Tm@cy<*q1MR?}k)b2Qv!3#!7ZSWMp&7jC ztE9;sB|@H-N$>{DE>Z^l*5Fvc#EyxL~XYkOmkDsKWye43Ht!AkaHR$a=zjmD&)J8KT&m$o(zS#Y`F6eDaMhEBT_uiq;MP~#)4y3< zNWFyLMgZZD*}-IzG!aR)X6Htn5*8y8Wel-@plwX<$2LV8Zm%ts7ZPijmQlTa3~T5P zWU`DEkT$#^*(PUFw926Q<=&^qrJ(JTMhJx$st0M7Nx{lFqNCRkwHuJN zy_8)^FcL9iGIv+)x}IdSzy5+L|fAN)>$BB6ph=>^P1)XUkn3>DF;roQ>`@r7(nqo-iylzBgIn_ z+26F2IE%;(X~aiI0u~^tY>uOGmeKaY^!>gwzL41#@>!w}yO8B=l^})c(Wii!gsoY` zmiPN5Al;{AJ79;rMHy;+u~123|ARQuPSUJ*EwyD9l=+12(k@2ATR5^eT_X;coGmNU z#gsWWH5^lJNm{&UI;#A3A3K>I4)!)IClOE3z(!Jp^*RV2h{xn{Fdkr8oIJK&fGnpm zfko;npIyVU5`u*Tguu_T%NrV6`yz9CE9FqbNnEV>l~@CwTSO7~l5Fa;dw!NlylRd* zi+bS-J|apuO<);hyo9AQR+M?^YH}Hwf8N z-bOSEZIFBbtvU-Z?Y**4HqEKQ+R75Bps0gH6LH>r0wGg?+=%CdKBepv>|&&`HY5b< z;__<$1y_zC1Y!>y#5LMpX(J{Ts#WL-FqQBuLz?l1vEc_1742-rgN5crEKi*Jo5iap z{AXmNA^{>!dx5e5okMi4k7TIrv&?^B4pQE0!=0n&tkH$VUwBFJhB6IGQ5n-a?u8%B zPr4urT4u2cWHxZdCfhf7*Gx3e)DIiS z`n$e;QU8M0NBSq3`gdjLtl4AGLq@^x5~%o>qN*_K2Blb1Fbi z6s#`p%+0i>KQO$&=TQenWmV6(`Sb#@Bfmy5b_{vhAB`*I zgMewzlbw;jQicUK+Grw_8&XR%tLflU2uWY*C?$Ejr!2B4?rFkSp{BS;c;OJk`2m_r z&Z$ekI=-W5Qb^KK-_p4kS}MAL_$H4?%h)B$G-aVAZmp6ikpDZQ%Ua_L5mhuv zS=KuI*aCp7`Wz~HlHot;g3E#T*g-W5{9(^1S1~E6dX|RQH}z!RbL%W%riIf*6c}5P2rC0c(oh4A=?-oM|ahlBMC!dX@68&+n&;-acz;* zVSH##6lSO$exMQH@@TbHN}BeBd}%61+zrMAELP~E?tM;yn7paP@X~Bc{FRykwJ^MR zcKm1-3(3x4M&@HHHzOBRUiLKhlXFs{@_D>v>rCvU%dqCjzae3+ zGjd~o8mpbA=)7A+i60VkGIA|#D#WL7M)0`^q9=6Xux9j39u4Y3eB~f2_9Ts#{v4NQ zyvQ+#O5|8-`-eLaE{|)XE@py!*N2DxL2*YJzfAehdUm3=T`D4>nk^*k7N*i_MM@C4 zRGx@yL2F{vHwGLTGqJlDw5!z4_O20brsmlF~BQ=FopE?njwe zpSzZxu#B3Kv3YdD<6a0_x zy(%VWqHMQ*`62rgU429B4KY4~h#Bvr*0urkvf*;skkoG8u!iV#?SmQE5^+830KfA6 zSI4h9Z7jkH4JTs)ZGY;l5(P?^`@sj%Mc}ZQ=;7E!5T4;2yAN`%w+_3oxKJE(c=|M> zI@*U2qnM7P#m?rzFmghG5sRS%QlK))>PIB&#@wCn-0%72g=}k6V${S|7{6jj6<<%Y z41;n`4AE*YGKpeI5&o4$j>iFg=DXj&XK^7#l*p;hB8|aAIcSb!(e3B{d~0|G9jBlN zQZab75yE@NyX|&9(ZD6|nr?*1#meSV4p@f;3}_1ZiDRAiVOSS5^8 zmzUd1Cyeh1Rt9KAm!t^mhrvdjC8Jt>YC%Ye3ZlZ-D{9(GI2oBJWTp2${k*0pAYb3A z&|M=08e>#XFU&TFNwp|Ok`(#Tw;nu84dV9Bjfk_N{Hn>@KDtTZ}OwU9tkUkgPTN1LU#P;=>pFXP5-`tVPCj7B#fzqAbqB^s8bp#pLW%YVv zwymEFz*GT17}~S^YLh;uznlXxBU0r;CfymH>N_DVxCI#b>(&Y14_LMljDSiznJ39` zM+BH+PQ9X(ntEVUyyX?yf)Sh1dv=08u*|yfK5%rryW9Yj4M)t_f{HHF#Ep9K-to%P z%GA#tS9~-sGjmr7RM;k(P$C!`d6EXn7aa%bKhNAGAv}Gxek|s4!62 zryYu%q+*%xzPM>o%GVD;ui9j!aJM!J*2It>{D_bg?1oweP+(E-9%$g6L{-K+va#L2 z`_C131khy^8Bqo_Qy2y7`Tr_7>6S%7q*kgSTfBW7r)A0WWJt4jGWeg*E-vIVg=Eyg zBt-kI98n5O1f~VXQi2?ifYgX?$v=buP_h(DX6TjfUH_rH5KTHvbU0enIqR-IP9>wCal`7x zwd$>(E-sYGNqI*y628pwEOtkrs}5>yAksFai%kJ*sVt>qV-u7SKETRqwRZ+qz4?VO zF;TCCSjEq6184i$2A+9 zCE;AWR29Mw;GVKoQ@oXt;{ee*Orhe@%HYCRjW47H0)q267#0!?(h4~pLIntf^WMXcEFO(Q z@6ABIV4|TE8n2*pEOxA+CUK|Z0`vevYAniK!_SM{mpr=Qw>)bx>4UrIHfTE3~{M-R){f=(8EhO-5)n>arV zz~J)sXmI-Ap8HM>2z$^wqjz-otKHXjAK4vN7j>@cJgaj|`^NT#P7}N-_5J_bfA&AF zB9F^0bzk~6)zplrDp^Vv)0^jq1HBEgAB4=vXvsK4frZHUw7xyrJKV2(g)HtuIirC^ zMq;Xa__$p&fP$?|wL~CKPZUwg`xJelz?!eI&CqBoo5OE4F6`V9_8t}>vEt1LgPdKU z6^Ly|hE116Sp*f%h$?{#x6k8kk{`srF!9FmlVJ%RL6LJ$+&&P26;mFux*I~L$YqAf zfjL5+_$H--!BTx7s)aW7rH_m+#0iF8woM5i-b{FsXnEcTEh5m^PxyJ1S#(=8u2mLi|kxBp*+Hgt&E)nrjvsQJhdy3K*ie zJubh9#4v%5HIR5`wfnT<^T)bRB%yd@$dOg1H1S|baf}-{Su{dy=J<_Jm}Dr15f_u?Zk7!GLQ`}1=8qP4q;V1p4cgYFnOCEM zG8(PrX~-)iDZP+RASit->7H?y5-@Y%Qt#S>%L`dY$Q`*&ySpXlO{bWN*$b0L(1UV` zO>m9~z`>?n9HdcJa?c*!6w7(E46FnfQzoaE4n~vMGMFL_TcLryRsKbZS-B#0r8f=r z9Idr;%}jAeQi#1StA^=~G2CZ{b$O{JeI$v%9~+y35!jDX6&Rh;bZNf*u7=9b9YsEp zicsdFThO4e4XL{c8BW1%GeSU$Lbxpcv%#?8 zXaF~T06v+Z0;m9&l7(+SCkZnW&#z4U%!`W)AvSfOYvHuttX><;pBJS_hc><1B3X~g z55)ku5wa33k(v6%Ti0DxUI@lg-AS5CAdY0(M5<4GmJSnb0rdoWl9l>0mONy)NUpe~ z&P}}OW#xs!if2TY0uNJa=~~c)M0&Jq#Gg;}rX;QTr_AiY9MBxbYIUdc(Xa2PCi1e) zok%Z)m#SkIQtcq8K*xuv|>ME zATyI6|3HaJdyIvO%o0RVgV7uXrFwXgi_%pA>9HNk<<{^t&4v8YFwZHLS z$_rV#pkGE0YAwl_Ev-Xl0@yK`HQ-GN92R4|C*BZpfCQWVgO#P$u?^|s9g($^MM3Uh zE~(6h)#g&yl~@JYMXkjtfEonx^d{g7Z6&S_Mzo1jzgOImyqS%l)RCzDSGwmp9pEMV zi>f2TVL&Yhx{kCRc}CsHjk&ck@&2Z#yS}5?N<9ntkXKt#rC3sDiM1(|xEDkc5E01D zDHb*!Ai}VglYo0~d|Pox3_s!-syuUd5ciZRA4I`~Y(b62>X2bsIi)O*9yge_7%_Q$ zaWvcXapjJ3|5k-PhFL?>`u0>nX(g69$y1`Y-_u_UReCrWCvBrV&FiB>P8n|yQHphg zVJ3dFoC^ddVDiLPUI_}X84Rhp)NYK$)&bI%Lb;7BU74F|Ecm%0G^mV^okPXPG)YS& zQaQdxK`e`4bZvEy>1Vy4bi->Jp?OkMyN`Nn@rq17#QR4_WIzah2a1>p>~RR26vekkh4ta9Zz%7m zp7cOSLE^|+jQX76^gQrIJP~H8CIYskjtj;X*hla@%k%1X_4UV<7pj}Y(0;_+m=ah? z;ytyVEg4twIZ$m#kkCWchc$tl_1JSe-H$ehm(-7z5ec?PUWE4rA8=a>N+E!RaKBuQ z9Q0>z`-7Td=*GF(g~jeui|j}^(}YN%Z1gN|`j{mWJje3ayh#W)>i`l-Q+E_jkea?+6}G7DtE)jP>{kVh1dZz?Yg6 zo`hT)L;7*Bj?kv82~Eszb%u@0DR+c)w&=lLAD&#MZgJD%Pde|UWo;1BbjG<_*$l2m z)SyXa4Ca{DuN+g{k+KIKg2XfTRosoO9F&!fP&&RMFyLv_1hq{T_>w>AWJw79FEll7 z?ucA(Nmzcuqa;YtPQ6jbXvhTSi4QFEmoSr&2)zbNMy{A&?OyS>#T_ZryaWO}We^ZW z`;i>kA!3}cG;N4feBtsL`7;<01BY}_MQpWy=T74b@x!N;!S~77CBIJ$P%kF#i``xp z-iAvo*g{@{nLsR4Nc15uuC+HB&Ca96*ARWxry#2cX|cs>z1EnIvIQ4;K@kO531x~v zPGPpn#Wr}g`<9}{;%iW>#hXE?wduVf7B_(<_)*N3Qzai0nS>8foxNH0l^G&7%J4~z zT`G5^jum%kB22lN&kSBg>So2l&SM*LVyKFTeq492d09S$^=dL<|M#c(0UlZn-t**X z6>?|hUe)aO%*XuCf&UzM0|(x~fj4mA4IFp_2j0MeH*nw$9C!l<-oSx3aNrFbcmvhB z2fyX;!MU^N&ffkmb7xZ4bva>lSs~Cu^pbdosX6ANawQ>X_4=frO}9@*P3R#~VrS49 zGZJ3oOjI`?keXMaif%CQ3&$A_n#O_BQO~0Gb1tJFWFo|Ct6XD9!ugnY7lRs$5eq1d zb#ckP-F19#G5o97(E(^7QaDnbP>c>GC(#LV<}s-gi-CK^R%>}!7l9Lf}w2@HCKcG&$BZ#7Ybk=>bES`h(+p(^H&#yUX6a8BWC( znL{)2h!lRDlPBXo=X0jt;uM*ZNwpfUc^}xJNIzIL>=V_I)OV(#1)0?5kd$S#15wt< z06eQ+1!QUtzl~Q0BZ8wK7o|s`cG4pia})v2v3YO)YH9t2$2|VHs{7|;{8v=>s9xG? z-Ldud&f`0`Y5#Hi*V;ebJ-fS5{b}bL6YrjQ^2A}Y9~eAj>gJh~TAPD*|AU=3_Mb8O z+u5g0J$Cx6{!zmh_imVc-o*EMuW5aIc;D%{-XnXX>ZRSQXRgbY_Wk_ebECJ8{`2VI z;isoA9=u{^V)pL;*G;vbmc}yU)aXBYfN}kqS4_a!LCwWzNg7A5VNWprsCS*f{J7@2 zVNy8kbblOrB@^&$%RWiTcSH%oV2ilr^&fawx z$qaKbV2X`L8$Ek`J%Cdufn7lG(R8QFNbd^96Z?xDCZ(obRTs(p-A>=TPG(A?T9K$6 z%T_?hd5+iUw%S#xrue12AuXo%93nVpyrn@TKA~IvR&yQfy0d|B^f)V~0m>=~Ff)a` z$`FIv{)u_Gad0}&%`t|DT;|Ap<$$ zOr}k5+LfR>oGdg$Z!u7lo1i(5Vk6ztd;GOtU3;Ebhp zA-h8_m!=29;p`a~HmQ=0g4=9!?aEx`d(( zt7*a?tMKOP5#JbJhl)?;BNFK)#Pt)}GmSjwp4D^sbqfQLiFA=x)ZaX!D% z=bG!(^UD~{v_}aF^|*KbbD>$xHW5NoN*cF>5p;br3U^Mt#g@5e-5R}Rd>y?BIX=Y5 ziZrrVU`7m)?s&FjG0jzcsr+rR{rPrQvrHG}+uNR7y7hy`*NNn$4Uw{}^TTGP9_Z_- zJ)f~==GYqfCr#+ATDtJ;K*Fd2&DLG(`Fq!~PX#2prT!Pw_i16864NI_%Vs~y5nMJ5 zwZ-P+@vxB1^pLJHO?2^AFW9>dAFzPRn4N)JoJCB#v_6CL7+6?7c<;QZC@!4Hex-h* zobN~L;_%xU{^|HS{+1Qo)3z zPjemjsOc{q0%&-Qzit+-Qv#r&9vr-^IrcpNiH^9m4~sk8ye8*mD%kd7b@li5qaz~@STwkXe0`#Wre1cIEP7KmR@YkN@SN!vBCmkU2f|Ne))ysM7miJ|LW<7x zZGJ@hzw47qV`rx#W{%9twgY)TUH#W=FFG2@n(>Ky0%-6|tTSR1p@+dIE@D~$O)a5R+VIxx*g`gxREQJlt3murv~quyT45U6P+$ z^!Bt%TL;~G?=ABu!#p{-#tH42IGDjPdW66cEo{23V^Oj%(nCY>(WaZGNpg$xD3%X? z?f5!81n!xFl~xLpw|tXt%u~&W@63iAa>;u~7ZX=_#2C5bL=*lO*Kbpeuj7&VI5;5c znU>UTw$3!I!U6TN)3I+DqSmwcTXi;P&^Z-SrdwLS-AZ#E=0a+!XJOzlCysALClwKm zb*n}Qi~(RBN2xa9Kve0TpzX5>QHwjbEq1Bp<_UBt7^K6ZU{EmUTw+HY2GT0eP-J}z zBmMQ}TnKQaVC|lpTX*~T-u>_(*h$(T_H_|*I1jMvFJfdhF%}R5GEe5G;?8=ca{!Mx>bg;&@Yib7v$ZakeUnh-|QW$Yt z9JJ*46ezPyFkTTCmf<&^CYBw}37gC-&IDe-kH~$egT~jPvgM%SC5TNBi%pjW+4ANj zvHe*hBMUOxW7l}B14Gu zb$LetLV)A#-`(6#+LYPXOwHpDU;?3*i>AD<%sX7gjCCr2Ya^3>H&^fSzUiy>zh|8TE(K#7z2~__=m0VA zfMGs!vB7R8Olj6#K_#Yxfg}8b-v8R%;BTAziP_XV7^qs~gr)`o-O}YIGc7C=!zl9Z zg8M|DVw~2D53FKZ=0)1Ml_Sn=u46}}HBfZp7}6cU^DBE(beZCru#L4#&k%oyI#s0# z0A&!Zcwpzx&ENGw4{Fj5a|{bvKr}fzeir-I9$|Az{&K9m$%aw5<6Uv9nuG;NSc)rl zXZfxN&0MhmyW121dQ7AgWxqIsG^xX4d%Jg7g}(Y!_{jHuT_b&2{uLF=Tsx$qFn| z5UvF-4jajkp1#ZkR1R5U#*}17u+}J9^^LM(?A&fvjks@raqo-co~xd`5v-xU1%`Bv zn!DiUV(Vk5Nh*R!G)HCLZahrPOt<~*=6=i;q4k^Hi!<;(EDp$9leVRns$8IqDKV{d zY3QjtcysO;_-uu3AM|G`)_wP5E%;@;3<^;rtC*bluY9B&<`kEIP=&!u{#Wi&-m`%U zyt1$r#%=Y4Z)c>0!2zY@Y3T;_|afdV} zM_mH;AzPzBz)M&kWSG;KSYElu*|B6Kxjpzh9hVFo0^E|LK$15$HV=OpKfv+T;9d8L zA7Hj~RW*C;%#)^HK6UxzHz)5nddTq1iQgOi&q2Sx)Z6O5(!W0Np962;z#I4v_y*2B z@w4|GhNEq@&YeXTny|>>#JI^p#n{G41Yqmc!%+bbz&szcBm>cDHb^UlEMx8o$|H@f zb7xAWIZp?qiz!-F?Pt_7IbWEyRe24>`n&ko(7`xH>D1sBSw@%4`dWM79x!UmZ5c8h z+qJ2(IbzmeFpvZJqj4&{0k@Ry60L&h9<`e?6mAh57tTH5v-hc=XjnfHlm%v_c0t^P zW0Bs$yt*+MrpG>qr$N6MA_JVnW9Y<8tqMvv^&IABJ2jqpmo)jjg@XMr_I-NTTA44#(&5kWnbO`1S zWYiRwC~IU4WWDWyex`V!cqzHz>K|9fLke=J3<=NkZ~StmQH`e&X27$UZ=$Nn#4L$87Fxzurb>Cln)^@1 znp4W_W8$O5*6FnM0PrFMqw!A}LuSSkra|9zxE{j|aul8lk9iy8lLHmc)S_X1<@+kO z0gaSVikHmm&>p9ai{l%&XC0{qHQm8e89j}{LNcz*xATegwPw<9Mu@EUCAsUc#`Wh(Y zV;jY8jD)EMDpepD3!sYD0ftt_Rsom)?gyI4qRj~#_KhcJ5Y^5F+oAhB_D((3CC4&Z z8R(1{;60!DByNdMIRk1fx#Q~R*%uYmeRvEVCpZ#S=n6_U16t9DFdC%5Aqrg>Kd7%I zMS9RPm}oBCQCbEofpaRIz$}G|3X3t-&1V1>R%>%3 z9|*0IL5>IvoDF&rAoF=reW3NwvE~+N(t?I8n#`4r%UjG+Fezyk=RMF*7kfxUuf3@7 zBco7o{9d+FP+B3FGoy2$ATk~mghNvw<48m0J5Y=>l;ir}{X`xJY|R{Yr*LMVprXdx z5n%YRy+Io*ws&ujMpL(ap!E@~s6}>99SF-FXuWu#^ecOKhEhCHX2fB4tz0UAVGZ;L zl!B-Wo(nFSo0q{FX@^T!634Zmn}+Lp@P%39F|GQ%syhvU_*#E}C7*6$O{YYrIbm45 zFaIdj&gO;(N@J_^p+(p&Lbhp7Rtw@|L1B$VVXMd?h>46x@YOStPh%c7&%#^xKx@SV zf!a1*>45m}5O*Xb_o7uas6G zT#@q7eW^P%wpgH|oN`aqizy3Fr3C`-DjE?1R1TRbg9ZqnZ)8D;B;ust6OXt=qFCMO zc_4J6jiqFw{E($|MAq#Qekf{}h7xH5+kuzyjg2ohWn5t#q6{;><$+d;2g)#f{a&KI zGefkZ=z$f%Gdsuc&Ou{daXqLq?SwwCnSQdo18HbsIp66_5=5NVs(i5}O(x9W3u!dW z3w&~h2&(h-owuUx`T=`Hn*aPWetE)YDK4qd{KAJ4v86|N0JMT$wl zdQm-(1)c7ZWFDuX>87Ps3TNLbTUEOezK z0-Y&=dAD8~5|cvha*-W;L;{7rVyT6-JhL~%I;WR-przsqVJH>I`V(;aCc0X?P@4cR zvVc%96@Vg2W=fOyl*tJ+ZOnWoxTp*N-A~l@g`|5-i#?^u$ah8nvEC!K>Ex1MdQoz0 z22K`fryj?-nrCj#2QpK>_CSlp1IaGpg;_89fr%PYhRFridJcNY8ItLd(;#K5r!ilk zvZHhcq%|2k3Y})!genLg8V=inNgg}3`=wah>|^I z_Xt4Nq)3Y6WY`yuMJpVT?_sj1;9z4%xiGR5n1n&ZLS&dgv*v*oiU*QTv(9yLx?{^7 zY|^TVNQ#tY!=OUVp$iby84YDo4kcYC0MnIo+8Jo6JI4@71G6Y}O0q4}_%(>lr4-;TlQ9FjM9s33paTx=-X>uN1^u z9z38Kh?206p(Jb@gQguv)1kI9>oy8v&X>qEY04_7YbO)R()w?K$#$rj-NE2Z$g0d9 z%A?Wo5b4@hb08YKfG#5^od8bi4AM$;JRnQoQw}$?Ewt`RvF1;$^{<~VUXf`rnM)_s zrih@9MBvJ~h02%c>ewn<0hy|O3*BuJ3eC#=IT@jURWnvSuSjncVi8OOUX+mJT!CI& zpC~GTX__}xK)eS7Ogzp+!VRyCe(UD??>KwnQPs8kpUkWVcoS9Zc%e)#^A$ZyIJpde z%baWt_JBdU!krnw$e_uVOrv#w@UTZuJgWDL`!1vni0j56w{X*VQlD5gBPf_3rx%!N zVLzE~lb{TfxiYp8w182UJI`*;$IeHSL-jvpa*-R#Da1Kfg#d$c6i*GU7HVZ{6$`Qu z{4h}p1ky0Ny3jlHc@G}HZRLvAEV^0xgba%?hKKNLFpo5tAH^~gPt1|XP$Jx}X{ZQT zw6icUxbnT@&ySLZLk!7FbFt@QSV_aVAqEng6>b^V2l*zc>jSq6cwwYlgF^;y_)c*{ z)^d)%@k+oeq9kBIawUCclrknW6ZDnQW=?@799f#A-7d?-=KA2GmEuBPGCUPlRjpwD zAdqj;p_0k3CqrgPgsOo8jDSx2xDy{TF;LiE>ipuT$_x2UaI85S*lE%m9RX|u{EV-$ zAL3@HhxQPbGA%QvB`CnuhRu!EDW4r*$jBS1f;2~MCB<6&wyk^)+ou&#o>hw>bt5SF z@R6IWI-Syn74=RiKAJ~LBQ;Zp*+gs(>eb9q%!o>x4>D7U^2kscv@oWD&0mxEXajT0 z)#vY0-Vrxk(h@c~tbjkSXjB6OF{~X@yn05bC77wgwxbo@+C|lL+gt5ldu(wbJ-e6& zjIF?xZ)Dbx={Fg4n5FGwQ({DV%M2QFey3mJ!rD-`=G*^ta&e(R48{p_rF{uVJtedQ zBov7;(-=reqxJPYy|tMyX;gBIXntq!3FRGGcs8caVq~^zn~%&ZraHij-04hIbe~>aD2FEc zbD5YUXi?jtXhV$aCBxr=fyit;#)6C?tR+CFVhUMeZhNQcf)qvwSk4Qu0f0H4GD$~Y zF}H}eJ_K1tSSx=LS{>P_9y7~`Xc<|>-&F5Byu2gPJ;o9hL%d7&I6n;#LAWur%WOQf zK3|3FY}F%>(n}Aa08C5Wmk#zT9=Rg|9~gq4%872=YJO0OPmo!VMuKbf+4FKx>~S$Z zuiWH)lk%1q?)#+i4XF~@OJHVj#FM~&?knSzd?+|syJ93j`WSSss>N9(BG&_PcKg5d zZR!0B`$D$mD1AiokU3d4)Qb-C@UfT=<^{Nv>mnm`o%&MFMFWU-O6bMi_7l!7;$x<- zN4pXKu}qd4LxJ5utk2{!TbFp5a}sh>puOrl#7#!Yb^AYGJ{dcKW#_f|E;;eOfbe}tjPbbsB zg-OE!an)F3b-Q2$#7JZeI@)xT=9t44=TB@VPS)2+Ni4bBi{ZEBvlx9MZ#%Hf*9*%{ z3$)aY2#Fl0;hfuvQoi2Vc~tSu7*#-Mb1%J=WW-E|RK>Z;><$(>*otY$=E&AoNjN7S zYnU_iI)C!J<%Kffgz*h-u|H9^nZ{(=o!pk7D@qy&r6`hn#U<1ar8CmIX7JV6{?zVKS7E-utcJ9)QtgbI4l*Y@FBg$0r zgh?JpN9*{N#`VK~kbpc3p$UvCDlyv{&`G|u)B5@E7aw0C#J7Pl<+Lz%F~x_m5Sq)q zGL)MFHV%m-4{*ZiJTfGT#i;e|)@z#i(77R?fS<~5l*uvfDtpMq>INXW6_^w<@z<`f zJ(T?V*)hOY2Ht0-eY?LZ-ZhFp2QJ#tk(@0ZKpCHqQ93?AED1_dmYU!-v4opNB>-v~ z9@{zY#PNloYmf<3oG_X(Z%So=&$uFS2%8w2H{|V6z$+#TJb=`a*&izlt*^ae{EGCM z>&DI`DK93+X=P)F1olVyWf)b>XNjekTy4C7qz8|)oM1XT7c{eqydqpO>}rZYeJA*C zk*qe`s_8*$qh-{L@mSq&H$CgQP-cO+WmC`NNk!s2DU!V=ftebO z#Smd=9a)=bcz2TjhZl8RZSNt?ypmif7$5bN5U=_MJbWIby95CXkat3wSBCmap^_6~ z-w+%c0O;1ePP%B3{TYH+4ANkxB#Y%_F`-lW94J(`nmTl zFT^CvV8uh=jXK8I>%{-E;j7vpINM)26KjMrghL*M#?72kZeg`I_(Ac}U}Y91mf4(e zCWy!v5)f`kuH?YS;VC9rArp;|i!2iiq#kg6rFGVaiyK1nm=;FQkW-xm0wgH@MQ`7~ z_K=!^W!4y6n0#P=v2Edmun=1t)$>YRY=jKDk!oNI(GhZ}mXapBUpP^_sZTIr${ZM7 z^#SK_0%V%`!b#sw5W{J&ek-M3oA<8HhO0lke$7Q2+rw zzBD&D^#%2uz}CCpGMc{Bc>%Als+(2!KQ*{w>dS*?roNwP_g^#B?SEzRvew!CM^vw$ zeg8y%@)?u&7+p6ye{j#yiKE`|^5N;jqb9DOxM1Sp`%V#bn!qvL8@sRTp4^@6T-`aV zGuOVUeNp=q=L~$LW)iLqlkj7)0L>SWEp3GG+!>&$oCM49YXC+xK`>Qh@uV>*+2Z(O zfeS~K!xZ>-XC8NbaUp2Z$ElBEzs+VT`SC2E5oyl|G;ZJ?DS3ci-WXsS2T%kxvBee@4v3)GTcSb55s4sJD7IMBL?8%?V9Z3LGttD% z?|#pI_xE^Z{?J_W$6VKBGPc7$?|#ektaY#ZzSnwWCMn&>7Lib%*jkvnM>CiWIOT#_^x zKoFM$6iwDh1}^%z{Y;3+pbd zjeNVAs^evQZk{ytA7&r93ch;J{GjN5o0Tqx9+K5XUfEpy4B5x@eFY5P5pX;)(G2*@9m(Bz4}KsA$S7zc zEI@ze{nHU}f#?NBSrG}zQ1dw!gsiIGT;3SD^h3oR!LcGY;9bK=lW7Cc@Lua_BK&PSj&=Fs|A~?Sv?kv6SgxvDTFALIetf zxB3uz3np}EWaUm^wYf4$QjEYUv zkEAWm8tKKWDC^4D!gvCZ*q_69A|msTGSW@n@B9W0c(MdC5^gd+&08r23%HXs1EK=W zXF@|-A(_x*Ve3ys>Dst*&cyL|EpABVYe{>(Ic-h^v9Pg}6hLc1L{O-xloCzytT}{U zl~y-fnaFzFUlkX!poB z87X%efHI&l=R8?$mHR=*c5NxXEN?i3F^am-GUn$3UH5m zhP%kSlZ+K=^RwOWKEHT0sn9mZS{Y-GIZy{GuA=GE>XBp2;a(9U)Av$ms2xVa5piDFF&d1|}P%q&p6^H_C#`>zaSp8+0ly7(0VeP#mh(O(e zm$TgRT_HhkXf~tFTF=bMIuY=gK&FTiDyx{ zp3@8o&F2UELjdGFJE_(SL*D31VPo;{)C&5wwM|8l2E0ASiaa#3+d+%VWf z%MNf8A&p1yo0m+t zK;Uxf(1zkQnO`2cWry1Kj+ohbCWLhKF3FIj9Y#JENd$)3tj7#0Rn=P;mM?ZYTrp;* zcU^(|tY^-67gAW8nJE-F^w{#l8m1vhlA=&jy;4ev_I}irl%0gejj`XJC>||MjS5$< z$+O|g_8M_sP;DlR9%#P$eq>AKkQN2A*7Po7Yak57 z36P@afM>gwbJUFeTdpcDB=5TfATIFGb+2N)Qj{0pF!Sg&zt;n_MHKf`i{C({irH=20wXVfTX9FRWQKCAna_AE zGxFZ6K;!rYxEIVR&L)i=XwOG*Itv^4I3uF=E(Zus@RPl!%>NpGRt4BgPa(t~1qq#((dK|BZGBv+LQ!pIY)PA5s?r4^H>ZQ3i3bVe7%Z%)^zdxJq))V|tTVKjx-x zcvSIZ!kq#wv&!LU45ZF9S5Q5ACWN-2n_07xHa6LeZOnT}0-cSU%dKmh@weWcRzLKy zRV(!Q%$gqj9nGc|xhqlbGC`2}Nw8GA@m;A7ViEw{HYeWJoX?uC4_#SX2C~}u$Sx)Z z9cxUzGN#C+7lb{_r8&D}p?M_7k>vx$-th7!0?- zmpRg6Iy@>r>L}A+m9}U7lh|2-MOuJ`r#{piv*0>Z=%j4zm8Q(9;7~Q*k8HwmW;gRn zX0;=k72CEqIso>JN`V^fUi_Wy6_E?&s9U{5ahf6^bc#TIK1A&TgW^%DcAm-RvOPb5 zlppPlk;RG|dDv)ip#-LMErIKnyX7a5bB|>fg~r%=sDDnn)JBqVl%Rl@5tWeiIXJPY zC~`*x4$UfLRew=5fr!Afc*_JdqgojjTsW)=py_5~GnGZt=Da$3&nt&_a;AH@9&IVAyc-y+9EC*~f9v2my)1~Q)3W=ai zvXbfeldoyU2IoR)Q%6V;L`f>nG7wSx97`G06URHxyE-EiV?mv$>XbgfM{m=@#AUB5 z-VszHD3G!ciSPr4hMkOVOI~t8)V4!^v5MM3B?|Eqi3M2_h&R^B? zfT$p_M9Q8Wzwm0ulJ1e|^0H0jkYJUz{!e)iZZ5WZ# zDJ;gTH}$n!S33JVn`Bqp-IaF8Segr4N*XzR0>PTVi+G;fb!b!PxF<&-=mU4xSwhGf zd*6?MevV|++Zmg*V@3#QnHvs!u&iJN(BzhT=fpFM8}jDjgUnivU?u2a?IBy2)B~U@ z#36V+_L)Dx%|rmfHh2-^XTGQSY|Jn^1X*ly7!I!9f3+M4gQAzC8Sny33*-!*Id9Rs zL#Hr!=z>_EcDH$<)UTFd@L`MRUA$s;#+Yzb`f2sqobDJlZ7fN)n9qhxb9vVE;lVT(iHKrns z0vtpLI1mNi%BWuMA@6l&b8y(5e6$c;`TCY9ux80(+}K;Pkr*NpROo0TQ))m9!zWiG z<@_Xk4^*Ewzq_ICa-GP^xYkIC@MK=3~conB#IYmt1c0BPwqU+~(L< znsX=W3-L9DZ;!Xc8X)1qqvsCU`ah~A;F+vk}{PW^fqpHAA6pJFOo~*-DV{=Mv z2sniu_AG~p1PSM0)YM<;S%#fwTYvki@W>g-y@w73?|4RX->%}ouq{;<;J?DNJHlLwoLxuQ^k{EHCRvK z#Zb)}k;5G0SV?5Ym$!1DobFj#;Oa0$Cr?`+!K>=3*#|ahX51%6D zGXF?oc3{re#oMctq6nai!o7xaoZqNkS8jbMhjt>zqHD!4rA&wbJGXXWlfA$Zv|>*6 zams?qG}DeUb7_5X@K@zW13u&nUSgG{ds9#|6cN92__^2QE0G684`daIn@`Fjg_+QA zo2|cX6bT;RM!J(6Bbh4azz-|N{sn4sND%v`G?4~rhd!KNCox;DJ30*G=B2#YNKS-hD! zRE1Wp4&CS;*D%2Kbx0amA2=1wi4aHls?>daWl2uOQqP#kuu7FqOo5Uzi^J zdjYaF%-1$n2{h`QC}7-9rkqf^QC+bkXh9G6vgfoQ(W_kz4 z#mIvUqt*G_JVSva>Uk&(hE-7Uw}|S%tZ^00qw6CltrYJ%26dZ+*(Y>z&J2oU)6Xk8 z)D2ORRpcl_R^1S3a!0J;qWNln->SF}zz-;Tc_?mVSCl%(w5*W0#4b{mf2y3Z$9xhK zB5>{sPuW{y=-%$d#f2myUo4YiL?Y!s7E`}S%#+|iHX)3RJdsztZd4<3QA3CQw>;f_ zK|@OCs{uf+l-WKRJA}f@!Vwk~8&&;UHKv^jQ%hE1w3#MhF; zW)ZJ&hDSFp!?MGW6H_ymZ5E^9_bb~h>{vwg;AbS>+T7@3LzUDQQefm<#(F-#WbgS% z|60tfb=4KO0pq;(Bd?PENobLJK1Aq}5cPq2W6E&l(Uy^uF5CqV;}WE?^M zv_9iRR>&JbHl(&3edZq*FPnFSlZBT*S&?BN)2?iVx^{~OBq^rG2e#$Rb<4CqBnq%! z-yA*kcxCMyw;?SrneAYwro0Grf~qMjycaYdMDVIXWO4JS_CW(8+i=Q|mboD9LmyMz zk!%iEiVM)4_B^zmQZ^?~!?s}uym1O1Ul-DqVj2?`z$u__tc<+>*5(5|l?mXRV^gQM zW|i;l(eBwJM~rj_e=&IO;K23`{p-4e{#pG;_4~bxdnfen+qr-D`Y;5YOLC%MXLtLY z9gd(rQ?PyH`2J(pR44Dc*RE%e?WqoSx?pGYqUzGo<3|tRCAhZx=#ewGJprfx%8bDF z)7qMrE|N+_Qx|#tq3UwVB515)$?1sE%!GzyZmN7Lr?jt->1P%vu5SpPTqxGxcrLY+ z2{H~16e&ZUBsdDc){&|N#6a;9-Pmwcxj9Y8Wvk7`4d6nuuEhd&Fr`p~A#`l3l8!M? z`R-O@dW*LR)un^fZR3pOXtLhy#Bn!mxs=aUV(F~!&k;nb1JhfiZ2dzxU#ALXa80py&Nb;Q+NJE3Z z1+mn4lUFxEJWpoWleCY1^xwGW5!~dB+86;6a5!lF@G-Um1t46VXaqC#ho73Cd|Okz z=R&>?XDq4}_-D*OCvhFdB&*~J>Z405FIkEc>r@RHvt`{%?$eV`yP|kSC?ZYA=9Ynx zGQEX{O=QQAchy;-SF#gANz$>vU|xT21Q*J8b#n9N!wV@oKs>*dODaMvl83lJ2cY|U zGC%}}0+%2INLi|TcLvPnfR~xc$3J*@A#+sJhr#tqXhp%U z_rGyd=z+>Zf?@r*yS%OFGQsaWT5+MiqYw!*hMX<80(>t8BxrQfsf;^#A=rcp29{W5kdBfjLbHT z{>sdh1KF0BMz)3r8L|!g&GE1aXc>^0Q4n@^6v6a4hg%j(j9WAlP)v^rQq`r9BXRVP zZA#oc8k#hu9l=j2K+;TaD@0`eSd3(XhY&4`8OsoCNTdb>d{HE}BSViY9xbLc#Hw_P zl~tX`R%H!%JMfmbZgRI&;Mbugpb@`;zJaI9*MwVx0)~mkoN5cy_DHvIt6FI#v`8d;86qej1?7JL~bw!&2V=5rIoIgpIg;Xng zFLpk1ad9C_+K^Xhhh;_%QY&L6$TgaeFO)yC zEBOW^Hr0y=+z|9*Q$hKe2Lmbj&kRJ6Mb&$uQB)|MTgpwVCb4QYy5jXRfLd&i(LS-# zWQK%_VxDzn^wewCUhw%9AJQv;~0va>`Vq_RZaKiF>=L;L< zg#>NNiPfPAA?HJaHy~3Evda-~;mW)^vBsbJicA$~c!&;)Zohcn;zIIa)>+QFG^U0* zCVY@3Op?~gujmy+(0VpKdDY>R4r#ShWYmSl-qXHPUdUG_h@k#Rgqd-~B?0a;l-TXQ z8yZTMt4EHb3BW5~GaL?vaQsmpC@!Rn5VZwifkE^h*+$NU{3w$^5rRx<5eVq3(aQWL zx+i_YHeTxd`1R$5=xk~b^Y%m>c4q9c5|#KLr$RhQYpMW;0oR3yoC1OY-8SLEQtxXo zDKCUf_oJD>8D*QJk>kebI<6TU`%y@ zkek%bvXogFi?buU-#fezQ0cWWkFkIott?dg=wc)j74R=3WI7_!l~IVPid!7m*0v~f z&TZ~GYN5CgmM5b$6zZ8f9BY=WfrCrOQU)VHix7h;CZa2JkEv45vf^4wQ?I$ExR5uK z0nchZLN5uBQVf!C$?8szR{<5Pe>V*|s0HrjxY%QWf=nm=`c8O&*R^^}7mj)B2eof* zjf@R08=O2ixc?s~1Wb01+4XTX{Jl*G*fVwbRA=&{$>S#v*gGGfbIL@oeX|(>Cyd{B z>^oy`?#zunW^BZSfRjcK8o6=g+|Fl5j%vT7{rL7i)fLrg)k5nBt#|&)Jiy)`+M+92xHsvNMP?AqwSvSXJbV76=YX@aKzclj1t@1)#+i^^gC(=@2 zV^fndUdUnz_mUisgc0py|AUE1$YE)GxbC0rDKCUtbbKUJTHGYoA}_C)4mdNX3lbT| z67HG@Q9ie=C{Drs0%GrVYsH12H~~e9&mblHM76IrqJM`1Pw%oo7*D+Sn+6jXzR8PL{(kJ zbK0s)IO*v+s#Z{rU`|xCot4Vzh7)}=?*d`@SNAP1#8(XbiRqvd;hz5s`In}S=%XkK z^E%@6jS~~hRneL$hY1z1CjNDJ9bB~imy!~1kPONBKuMuy7 zAjYQPIi`25eRP`*@QTFCTB*Wc_#NH|Hv!n96vfAY;7qfIwyJ#;IFXo9k+L-3;L^;l zJ2inb*I~f&eu+6a+xQ0+qS2YuD&A1c^J*L&KN|5YX7`8yO%;WCUYq*rLyIRP)cDJG zyYdyGfSIy#*hnE@*b6pPmB`8TOTJ79(=Nzll2Fo9w{Ad6?x^ksjGqDt>n)^6^PLH| zDdX$D6{}0tV`qd$2f)l5NJ+l9F?sB}i#zhTqO?uR{HI~gnv;|i11evj36!H7sYysd zssbPZU{p1rEgWlq&&IIqj?$$r{CiFKJB|725znl0(w!vAWK$Kzz$kNQC7u)m4n>;22t%L}C> z<*r+05DW#FHfmIq^v7%}ISV_nIw;85#!=K+B|bI8ve7M#SAY| zgId-h08Hw#vdrdCFl58Q>FGc-Cxb9DH-76AiwnhPnMo7y5GP8Yzg~K8x}e@Jd^Bf~7cO)6py77W|G#0W^!2^V8iI zHhRw93&GYRL>zPI5}H0gf<hf!cvDze=t)F!CxVnk+2zuDD-uA#;96xfy01pRBo3Y+qVS5&noo(VHR9={6`3 z8Avh%S;fxU3BT02=9cn8q(8MWu$>N1-H8Yby}ohUMcab5@xFZ4$sL-FBCpod7WK!D z+^%Ui_Oit&iC)dtlt6vC;|e%YmxmvX?pxJFuy(>UiY zd1cf>=3KOorPcrZFI|X98|07dF9`c`KAYs>L#3TEDbavB1TpTE0Fus26$@)M*Vp(* zFB$HAm9V)vtTI>{Cly2-l)LnOiL06C;ay}}c?O?K>6tX2V^H9fnd!mzmy0LMkDG0p z_Eh|(VwTFnjHlX@!Nr6arI6_89CiRz0?tDB2Yj-y+Q0bt;)ZztMO64pt7UqV^yz_y zsZeYc9!uXbqY{BOW>Ja+CuNii#(>^ICl@!w!^Y}>1aTEDWV|6z0F-7y#h0dK#sULp z)D|c;6&c{>hVAC1>QNsrZpdUyMs>N>@k$O<5;o+$NT_kVre-5Q#U>J`gTQOpWp zSnZW@-}_hM5l_+MY$~>sedX{oYME*mw2Kvo8tmm6^cYYnbf*^+H0-~kaRX(0#LViS z$@{eW6sqVsjs%^+nmbVtd>5!oF+rK+Khj&I!lyjVO!xQy`{ET@KMW!2G01`A+axhe zwA2=lxymB5^yQMUOpyWQ7S)_^8n2==4$LK_T9q;aJ{5hP zbOlFd6WwC*-_DNy&RB6F$U6eN8eZ*hMb&8lJ)goow)!;A8KS`e8hm28X8K{?=;})E zEB7fcRFBMOB%wfCx|p_j!9i1R7|o=O0&h#_=T}kR#w|bqi6v}xYvLfN`YtMa@Lc(1hYka4s;a|kduSIY0Bk%HQ!3gvN}Kv(zKA29!`m9 zf%1cXPpRvPu}%=X5E?L{efI)?!WrNZs4Msh?_5Mw$7hy|79#c;ug0#UfVn={jeVEKi8!0bG(Ehz zAvhuZ!`Mq4y(tIkcv7&V8Gtt45D^Upl7YFkBEYVKn-I^!8B~i6Eu9Ntert5}%tNV}anY?%BeytlOzCC&2SZD0;sYBb3>6|cf_~=CwXLK$e95`{A zw@0R~?)Jw&G5(zK{i{z6E*iO}{hh&cyKkC0ee9anIsNN)J$v%FscLKwXTc-;z1}B# z&+FaCFZ|X1-}d?p{VXhtSc#}AAqhUMiGlHQzov81n;1rK6L^$J={n4$w_w%jnckTV zo^YY){XUmwGwcXQhMwiDMi?^HGb@Wf;R2*y18fpSJuxg(gB0A|KY8Eqj(9g69-uTtW7Jq_6@bDnoR}{W$B@*aPVDdZ@Zp6JKDb38-|2nPd$LNwS1h-z z5#cAr8t4MCrVRze&7@RN*jT;pAANp!A>@eFtEN)-*;}@j&8Z}z0BY-^kmw{3Nf^lN zWfd&W(X(UpJ!SjlJ5ml#-PpeRSKq%iCKfFB?aTnMvpf7=|5n-U)Ar8Pz+hdHSqmJ`OcRmQ=6EP5zCLa{mV5}+t&K`J*`!|qqZF*+Eg^U?<{oYMydUB%ETvQf^I;kfE)jy=FffQ_)-dqM-JI~m3Od~-S1;e+q!%VxE;C|7F#$3>edFgyP|kB1xLJk^e7ZAh8B#75<>&BTd36 z&G-JYp(OIM5g;l9E6hLuSP5`rrej_+qAOke6lD@YB;HINAZLqiL~yF}=4R)JR~L7* zklD;>TtxV208SVghDFk=30W982};$@Wu8B@(+wD>u~@QrLA-~*gs%8>d^R1z(1m$Y_U zCbpaI-MRjGWyr1_K5BH}I?jNc@IPh0S!y4+BX$XE1ek1V1e6gRU@!rW6a;-+p4gd; z3jm;4X%xG$km6$K=2rL8O7--w51&lABD)|m5ZhE^C7#MdsD(0fuoGO!k%OX9SjNO4 z3lI&xJTy^ncex%z5wfglmcaetc*Rp>GL0Pa(&yk&42uw+!;@K{#1JpdWGU+CdUe4a z%XhS`V z5|W_5kb$Y7m3M}l0w9U>wVw}?4k^UsDVooBCyKYttAi8)u-%k}r}U4>F&)z)wC8~M zKxqt@Y^27Ctw?7a5C_M0{#Vn~Z)M{mVz*Jqh-CJdy~XgsqiE2Wk`!9NU`I898e}5$ zun#O_k@2@WKW<1{7c$U2ZW(+-Exl6);Y&oZ%&q@iLg9|UAz)0!5fcw0c4=n8mv0$+ zeA@7B<5Ia&5c)vcYXubx_+qbxV=#FhD`nAa_A zM9N}&@NeaX$mI%`y0{juVia~Qk(yqm)AMEVN$LFp^o2By-)a-bN^3cbvJ* zek_GGr=cbn_|ImAPUU=C-*U@1IEIbQ_Aiqo<w$FF5~Y~BowhIU{S@SN+$p00i+K4P$7>P zbU!iUR^w+B7gGP`;O4ZRpnyb_sNK3+9GeFfb1ZRS&}ZV!W@IsH7sf-p@FHziPyfa6 zLNE(>9}bY@21T)k(J=!EK`w-P5L4_@xDTBH8A9g;Nep@*7y8HSIHqjc902MU zKD4BzA^d6u;=zxN%3i* zB>3m4GwBxUp7zw@j_h^yvsG!Xq}9e?L#y$x82Mygd~fA5}|a_0U8;X*Sk+?_=H5r@DVuP z`XvaI7%|I$)||;XY;G)+7)?$6x}a1^XdbROX_Mu7b#Tn#!#kp0i065x$d%+}i#!Hf zVp;~fsu%5-G_9*ixCLQ%uOEO=vaJq|`iy5l?RAWiU29PRc-Z zAIkzDEUOGNMTfXB-~0Mycz{b7qPMkII$h{{6 zj2tF4 zv{v3VjVzoi zFk#QUYsX6=FXpPVK3-hNW6-;V+Ax(SEu&yEgMfPCIoX?G>HE-xL{@JhK3h$FiI zJbt}m7!+kZ^&dG{I3@|H)sy6KV$q!SNCN~(n3-dCy>(qPBqA58GhNCxe0DSf-(JOq z)ktT4!XWmJ$CFg8grkn)pE#`2I=9mL_wnH?!p*?C$xi4c^{sR#;Ze}kIZ8ulm`pB@ zIk!9GS8{X&icQN2P+VPb)^?SWJ5m87SbbLC1VGlDhh_4L;K$e~=|B`~D+7KfgCk~b zfi%0VELZ<@+HimH@l)EE-XnCosta(uQ4_ek;&7J=l6-tGqs-!8gpE)kO2>tndp0z@ z`#~gt0a}DJpa+PfBwj)pAs`kwu#?!8 zdQP48DS}=6E;!31$I#N?T5|fPz$nVmyv~o3Cp+wLQ1C)qd=~hp$?R z2qdE8*)5ddSp>v*c3U=SF$B1zGzBX2G2obU>X=UuN@sSh{qRN@$fIf7N$pB__eeH) zptg=&ik+elPirk$%9Iqak=)SCH7&Ir{}A48{RdKhQYD| zVweZ(6O_+KJ zUHBKfP#{!BZKqss|2KwaIyg%g#2Bo(hkwx&Lr z4S_!OIjpm^Q+U3Zx!RLW#pFW5N{$*0kk5EsmU#> z22|MV)q9Q@zH1bk9ZrSgI*WR&yp3s=d)r{GIN|vy=xU z=AkJFvl%*@a*s7G4PuHBO$GcwctP3AVz=NkPy=1zozk?{s;B?+@Iq#TiqQ~lC|7~q zizfJ`P$he_xA4s12e9MdO@=~Aa*iS~E|jIZ`uoMDbTbw>(k-4h%D>k_uf;E- zYBGu#T8`N zGrQ0ctXCA>a`nt-4=)rxrLMWN5XEMEiZUJTBBf%r3|g~L(^QS=!~Y>rec-6rtbNr# zUr}5LSm9Q+0^BrYkQPp_N03PPV7{^nL>5E}c2JIt2ax?)EjP2(o_u0)A%-CXQUrWM z3*y$$HzkgesM8x@9c3(wYBbN8p+do$j=a6q=@|?bMcBeta>>YMsPHe?XOWu{&op;P9bl_SgoB4< zs3lUk4Pfd7MlXZ3_xtwn$wV?#1D~KQPL;9o>TVU;#2(fGj~_xL;Fm1qj0wc&FtVie zVQHb=dvI|fG)f{fS;BU--l$g=j&2OZo?t6KGt zfo42KIw~;pS*V6+efmODp^T7Ws@P4MQ6i^kQC<3r;gfNZ(S+sHAP)Q6nRbAcU7CJA z1c}uF3Iizoh`@7Z8QQL-5Ch2{`N-milrg+@rj;r$Vzu?vk(25p5t0N&KoLLD0n}uu zN3F(U6s~|xq4oNQ;sGAps-F6mvF_tq^Q`)6_RD*-ol`sWbq_#h2EL>F{Y(w47TULL zpBA|P#5L6w6ML%DCJvw2o*bCDfxT149@+Xq`|GX$!So=TKuN0C<+C&3wMWPDGy6ol&q=a zy2Cq)Ia62`(5)N38EZ4K3Qgs|#?h4n=`s+MPX%OQ8-T4;UaE_^seOM?Tu3dV>sJXO zY~o$1BSMLwo)P9u10*NJI?cxxrJ)I>;1&6Sxpie~-$sb@Xfl+7+K$I~K?E?fxmnhQ zZY*W7oRA|g1bdbMe-`sXJtUUOy0kU<(?(^;JIZV?!CID;z*%x^6x-W6qDiWq`LR6A zIyp>xT0D5dEL)CmGQBc+(_4p+7TrYjLVH`7cC(H+tJL#wDJh`9Hsw+%u}t9b?l>$m z8(o~3o16S>W5>&*(XkO2asc)~-yp6qg8|}dx1nMKQR!lO^^OiY7s#iKlXhNd#*lI?~9BPDhSz7h#`KaVxVHKR=Jh1dOS0`U}O>rS8JClCg z7nUtHIA#PuZN>W>>>Cghs(c0&6}Y6=7v?mnRf=1XJ-&ngF4>i+YHO%-NYDtW|(6jakrv z3TX>qu=Q+^2u_G8V{W>)yYZOkj$}FF5s?lMNXxv1mUE_9Oo_$%IV=LgAemqA3_d{S zO6Mq-g|*(BuC>qKKs~Q7B&%jDbKn#ti+oiVM%spX-jd>h z`*nG~_rq6|7edfvLa(REK+#Yu#55Ia5)G$>fGE?`KG>HG=MIo!dBPqnZH%wpw!Dx} zVvF)QAg9piY4(OI!AaXrp@t7WX8Ce<^&(VUtWvR zmbELM4qIV5eGnjr*W)h>q&5dAZnX*ltxJAZTuAlcyX&atZh%bm6gabj^v5xfS!U@< z$vA5P7*mg^hcU=8c+C05@edtZTuAMi=`c(>Yz8?~#NM+}QiO$L&5XbhpY;qnG($|b z=4=8qOVeXNthOP61qn2m7Z)N6LQ343hd&rVh9}Kroc^n_JVC1C^uyJqf~Px z>Te(o@aTbZihvEG%CEsA_%UDGwcX?#f*ICyn_kFUXQge~d9qVwL+rsih)9`)bJJ1~3Xs zWMT~u6^|KJF6IC=kbk54#I?nm&M;2^Bvd9738ktYeT4MEpeO?XB|NOhCH4vQu!yZ{ z)C>>8%&`sb&JD2}VO9kTc`O~bc%R6Cid>byIx704ibHE~06afm-82$!=;p-zmWo#- zBywK?5P^=V+9e>v+;FbEdyF6+k1?FnBj#{^W8+qQIqdu5Y=5N@yK_h8ELp7VR-F3j z8NiN*Y&H%F^P$DmR@T`d{-g>bc_YIzlhd+X9-TS9xFgI5%E*i1mnUyqIGlFM3?-q9 z2oQmvC)wYuE=8ry%ojAh zKKh|X)$oqO%+sWa-Iz5nN(hl~Q;>3P;FOfj7GYhX5GdGTWfO~+o_BcR+f zunl^}*dHY@tVy)6aTUc7b7T{65ihPp^05%|OpLJJ9ut%ZNkhcK`s+04}dMrZ>IKNbg~w|*>?H>WbaxIVQI z1PBeFShn!-7J}W{*md76FT^V2-sR93N5u3beZVJLJinaBWLQv~;_;vvxl_^-PpvnT zc$!INdD*xgaXr3Tl$IT86p(DMpuvjQ2Ym1*WpJoox=ibJTWDbIm8y#B+ix01BjljW zn!c;VQmB!x=BMH$QBbidc~A0^f0i|d)sCP+y0AyP#}#?V)xAP*L3Yq(kT_}Of*>9+ z@LhwaswR2@8jkG*56>?X$U48;JF9>*K94bcS~b{-Gob>5p-8G7{`-?3Mvxo+V>LtW=MfvzFkN z+0kzg2ovN&{G@vkB(2NCgr827($w@{;(N*k_$)n;rif>Un-W7IcBl0i@-Q8+8{}R zV3@ipe6+ZY7{}AFg=$)`+z2x=ukL}Z_3mZ!cz|cMs@so`O&oy-czbK2JN_5Vxqwau z?2leNdcx>^N3I_^dwcr-?!o=~-)eCoh zyqas>JUlJ1VG@3A9$@>4pQ2$|VlG%FnB+{_%=#3O z#Z=sg&BI%l8Y;{`qQD(fhx%7Oc{?W57gDgqvI&+rr6@ZjK6`ZqcG|0B*UA7w#F-6c zSCKQB6LEd(3zJ7RwNkFbeXGlbWE$guA`6F}?y`7Y#dDBZoq(%T(}B)1dk6)uoE$q- z9dtl(L$N;jovI{dTNni}r#@MO=IV*@uEbVR!QPheC~D!;9ptw*J$duvi&yQv)@NWz z%pg9Z+_%;YTu3&9FdAR5~gI#y9}YkIx?kw!4jliA{e1`~lQi&7=$()6Sa zJ2|5}6qTteF~OLZH1~5uV9s?jt}lfGXv{2>L}a<08kxH`@w2up4k39Na+$xIP} zEUiB%XysTAhDmGN=yP|xM!BOLur63iv{Dk_DKlD4JR!tJ0>8S@L#a6lUcM@>QG8`O zP}C3Zy<=H)Au_45B(5Utc4mgllj()50hko*Y{aNJLCQ!gNl2LrS;z9-Kkui-qrpbO z6DmZ%Ur`OTF&IcE+FV8M4CU8cA)HeRGbjwxFJ41<^J`PprM`Z6;k<0X!~yD=nPU@) zX6cSVDs#42D(Po;CFH3gb`q=djD5_~#^cPbKmLUBhVXOBPysqEWpp(8DFP7^A1<~0 z1OX*EjSz^@k54!dPc?#X%(wpRZ95mTOCf1=lYtlUC0I*%5J8+Ohg>7gq$LZOjDHjW zqiKZUb9FAR&LvG8PgH|XG#5Z%HW+Yae_6mrgNff<*&*p7xn)ZW<~e~7siGuQf2<6a zj@WrcV26}sYz7{|hRXO%MRyL?^p%vCX_n8Bu<++lozNsknLjIV&dju%qANEP&VVK= zB&q>SzQKcNb<2Xza{n)>yW;Rfjr=0gNZ<`Bf#EA(f88x~DO7$phpjR^&V6k*ou z%;06eUt9>=iA_LzfnOAMzS1;hK}Bg8vB88$yTT~yELvX`%1>Wq5=`~bdleT-pR!P{ zdap-qgv>W4&dbl>O5HG`48{a{30*6YK#tNlSzu{%dT7BjrCxyt!5 zC}#WxtjVTitd$E!9fGhd`~c0x`QAw{DlSBrVLZ=7r_2z*U5lxR138mY3H%2|0E)sI zYSXI+u4DcVu{yEuFwn+q78L_|qkAJKg(5hZf~Y$_xO|hIG~+q=6R~j2zi18X-SA4V za&mXMj?xYVDAV)oQ;(FnI7%JF& zLXHt^|L9vgY1SRBMq0Ll@Rpn!xF6j>Qc4DLNpY&@bb4oayGFkHc&(Uw2%-xU-?(#m zL!v#F1M7z?jW2U z5bXR+63%f5b~3d&vwC5FL(#qU)S9FZ{S4&7&Gx>(Q``~i3bTo?^c3KJeN=(xVrYu+ zAb@jaBYTxF=s12V&uJ^xOmg=nmzNj9vQY0_BImuw)WO7Sfv>0EB{Pii!sM1rMvH_g z!a83k6xixqe^+Cd$}(a-i9koZ_fzt`yF)0suo(lH^8&?0x=H5~!JYdo{WTmv-d^w4 zw<_<5Vc80@`#I%>ZDSll+frdkH3}64J&Hua^8!dwI$HAq6W+JRkG;OQP)x)r1H%I< zR%+**MwFbQ1`1*$7;OYGcNkkhY9Z+bJoTkJPu|)l|MO^^5D-iFXYoFVSBdr59)q1U zcf`XES%HA^xkGyJ=X@eUi?z16FnGvLE2j&^S`Ee#bCl|AI=pQ`RWccikr5z}FcKK3 zW}3&sK{enH$^bi4HNy8HFWv zqv>JZ8lKgMvm(K4kWfxH#6Vr?lZbj$$>sK*oiU*`#rV!P-kZv7CY%Y$7 zRwJcDAXqm2clI)%CGi?s{nU$#N24rd@{Y0QYESy9poWD&j9?P=g(4vsKdhY)z>qfb z#goGQh6N6G#gSb1-?}4QZw?&nS1c^DKf`Vq;WA|iVmBUJ6)-=e z3%$4@1qwpJXbtHIxsyrW8bQDfz5tbtacig(h?MA}$wWTGjw{T)#O2-{n=?N0u0s@{ zOC)=QTwU$u`~B{abmV(DaaVe4uc-Jc_sWCltEcU%{uX8#evP z!U|XjL@Fb!#)ajncRmvjaCxh9!Ni8BVD ztY)eg3{Du_xAW=#_5HK^k9KC@rLFUNCrupIJE(p1)S<1LCJy^GxPa~F#bb~)sOeM$ z6pwt~Xw+WTO5ZP@Fy1YDG>az=DuXz%g{ot1eXQaf#yMO*?I4b# zu~Pfr{=o1;xMWl-NMv4}x*8bBFJy|ajSQ}ic}Cs^`o`ue~|EBOr^V2**hEH46ZA21B!#T~h-wUL#|0 zwG%2gGGj+DkLgWfoZ0N3|FiCR>kt)Xz8bra50Zpra&FzA$&ci%@N)9QrTpS?NS&!< z3)BPcGMN$IG=2Arjvn5TG$&VUc=AbD?~Me(3u7b94X`4a>qNGQ`8+!!AH1cu#6t7J z%`c8^UN*dt_yb1fKrs9jU0Ep6IHb9k(4tHfE9E6Hh!+H(o4Q1Hil+pa9e+&|r1EI7 z>4G6RNfar0UQvRXm$lu!RwPeCLCGlub&ALc!c5oIt2etjdemztk82%5HglocJII8h zr9X|=1Yd0>Xa>Jm$gfAG(wmZmL!+iP0CVGR-kKZSswoBX_0!=%7_vw*VjZ!Gzw{~Pg@EnMlEjDjeVkdSTMP%j1($>tq6*Zr;(;KcG_0eSs%)YV zj*pKGFO<$%2lDV)ddcWQTcfu3u~G0`@O;^ex_m>8P4^5KOK@6{O)QO0au>r<);7-~PytZiya3MFU4$Q68Ty`{s)LGFd%;jfS zi6o2u49i^WoG4k?fYi3NRy-K0iQE=mU8Sv{(P^x`6>R{nAvk~p-&EX=3r5L{-?a-x zVWyDkDdn=}X(be4tw>Vz4#w`x-m|`;KDP!VrZrEWlWdC<%!&;gm#*aM-TRk!WC3U2 z8=ag9lO{HbDheL)kKG3sA%>W)pb+-m)JseUqFN-D<<|Q?TwF+@jtyfb&lqG80!~&D z;|uLhcoNSdR>>sjctSO52^$6$_I5ZRXZg5N<*h^zxkVl+{sh!6LYF@`AyxB9PbD3`n=tCyuq)nU(L|3J))ZDo88 ziZjSCLjnagixnErbUm{hlE^uss@A86cSP<7h#@LY0d#2^dLdMA4Yb0R80sM6BfRW> zHYiQ8(hLx-jGy1?eD8VXg^*WF4tk;N9}N_YMDEZ%1dycmg5bGFfo*!Jj_SxBa!roI z?7yN|*laC|NGV9#iVeGV{eUs(D8tyW_so7`83>T!AL+_aTCnoiJ8RXQ8UXJdS-3Hb z+SV2=+7Oo=Ye8B9LPcAn^k4;&Wi0^fo8T7lypFA!U1)t~FkIM@BPvFyWl2$j;_kwy zn0SNW^c5gmy*8qOx23%qtR{hBO(lwj>HV6jD>sy-=FKLBf<%5$S%^Op4%~i7ydXlZ zA^;rnHcM7P$NSrE)G5KUZ2fm~~peAnrFHIqsXCquhnGw+(4UW6e zU!aW5_D2Ev1>QC!hq30mL%#{SXf6SXPi*|_quXUyE(B`O{xfTXWlpMzHI+RFSgXe~ z>#{a>g;7d`@YU>$8u1#jv@!m*|2}*)dT5vio<_Ws!4h#&n?IM4P>wH_!Ihw?FF_Jo zk~^_{e198wer9s{(&9p*3Ii(5!A4|H_Br)`Mk}J)tR~hI#uapt_eBJo zxV#z0>d83Y(BBjtP6;$CY^y3Ht+S!Yvku4COp0>zN>WM-zQ9QukDQq@c=UP03*`}rTfhOL z5jM*6@p3>%+>Lp!zLPE*Y!%K^4WORJh-PHm{MP7=hZYxt^vr&6jsQ!Vn4)e>4j>hS zdg+eKY)yMk{BtBBw^Lk@yxqRy+W6sD4KI|~o9P{d32Rz!f{Zn7{EZ7_mM^?$Z9vdO z9~_zgg)p(V zJ_M}FTkNmRrMz*qlgtnChlqvipKrBS?lZhGMQMgP!VvnjF)(;Ec%6w=X9Lp)4mDkh z^%)Z~nqA0M2lL_QHkZ5mEVtTUZiK|}{mSr+vXx>0ZSY-CrV8Mj5Tlq923n;JdbUaj>?!*p9z!#3K6!j*njfl zTAiS<<}SIzA8ga9GgoPe10j{okHTJ2pY zHFt&(&A~BQ|ReCxi5fA#P7hwyK*JhZj@C zsyQ$;zLr#@dWctEV~j__15u3e8@NCWEX|RbyEa;bZ4hcISin9KGUSKd8%-QhwYA@6t^W9~ooj(U^?Wuy2WeBzl$Uh1YHidb=S$@9OT3F! zM_GK5u#n5KJ0A0p$qzM$hmwRLNgoty7qskT>kKfgl%1r67-d1OOm%pUd zz3G^pJB!VCrY=kI{jp`CfiulkPjfmn?Jy9Ox0&-GiZ-6WSrA~3(qwC~+V6v{{@*q8 zw}S+X81P*((av_)xodWi5gTxlaHC|8lOJy2)6TdeN)OM7_aX!>E%dMYM5}Z4w|4H# z8ENVsMWKSCMr;CQ^lUvU9Tkx^GbJXZp75ba{l3Lq^)E_IK-SF88Kzumc5Xj`37 zUKostj3cJ1NO>VGU;Kws05DYmBmQLyFo$QaUcv~@wbmELT7w5&w{tNiBM#fD$kdhC z=~dT)GQ8+a2}NUAFwz)byAN*7d!y`>P!qCXt~&kBt?JoLHDYX@ynyjmfV&k9hXA#* zLMxKzfvT`YPBFFN{4O_?H^Rq00ZapfrIXAsc@Al93- z2td4g1A46&w>nSRwR30OKni9XDN8<$)cRy`=~yXt2V4MA2vZ=dX$Yn7=1-Ml;v}QU z%3%Hntxol{;l=78r{qSZWs12r0OkNG+;WYF*1MO8_tM1iucef6<3BeGFtIC`}bXIZK;^r9)c1tA4n1F{#vV z!u1DasgbA>B4mT9`A0of7W;daakE~Awpp) z=({D$+OQBs;(^_TnYCMR8Oxpbe7e@whdGuOyR|m(9-@$E#psGd6WMsS4 zmh}Kh>4^ps6l!Uv;jEO|{#P@61nrV)FRTsm=L;rU+hKpBVm)#qyiTfYS&$4e7$}EUaZLcl4S16DKM6<__#hZ*t)~;(J02aR-!9$nh2F+Okup7 z@&ZNhF=f;_O(dg1wRu|el;1ed$&O2dV;c{(JA!7?sstWj67^eBym*wrMfarIlES=u zem508OFY8fKgFk@Ulun8hrE1vM|qe`;@0_i4r&tpj$771O>Sg|33ah43K&b1)$u0|9}P>MMVq1M zU{(6glmfhvL6=yRXeZXS0ednk@fq)+P*y5LcItj)q__}}q1p?ZlUYpgkB+u9YI$+> z{&sgDmy{6xC$%pNA2wWIn5k}Q{K5HZQB2td*wO6}G7Gac7ciu)Mh~fwRtNz_(GLNF z4Pt`L?eepmt#7`$xTEw-D^Il)um)WPZ;y7ez)QF=zsLy=DwXMu_ zUitp=LT-tMDVMrkiZ5NzdI~Qcj4whW4MfOvC5uJs4HjUEzdv8;eDM#;3;A2BMU@3X zQ7uBQ7uM3FY?iX(4q&kgxj;lZ1(#}1{ZAN#9eTI^Y*X`iM-ka%P4n}BC^VZs8VEpu z0!VX(jFgJy6wKye;Jxw9>?BQ?bBBMwybk$6<%JFm;YCEqpi{P;utP{XmIU;JEl=zx z8OW~&{;1Jt-}5t1E*?w4rpGtP+oh072tqcwXDYgJe@^BWGz`Pq@IwOp@nR(EX%p;?X@?7U8y)bW<6Be+Ky zrnS+BL?apzL+w&l4}zAir|QCj#YIP7{#K)U?7dJN!SOkA7ijFJ!79HqTM6z3fHc!c z)aV0#Q_F+DT5R&cB%SK~w{Lq?>I<1?VcR2EVw^^^$VG@CVH~l+!Icx^us1%SaBKO9 zatsLsk@er}6>kV8#cArnQ^l&zSY<)Xw2D{&2sYD21R+bwKTQLCXem2b%k<)Ubyefx z%Kh-3xj=@hgUiTUjT4U2;p6nKv7ZbXJTh^=f_%hJIni@N3cMYy*WIzWBW4}D)rdS3 z)>DL|HB_I}X$rHOVRJ$)+dJ`Q*#PNj%8MczEwo-)WLb_4MFiuCW{$M$cq?cX21lPs zD#8j9vY6n*n@VW@I&oja7l+_%?;ed~HIJq|6wl>#eh~pHb40lu0}*g4#wg%BarFF@ zs1YPHq1%2lr;9bYyZeISM&l1sDj|rBa-K{ekXD{3LYkjPZP4(51^_UH3H&4_NY|Y&H9fg`GG67F zF_kM?=n{&>EsDF3qVHG2!E$or$yZ1h6+P5eX9F>1v3gJAQK>J4$mZIyIxxjH86E@q zp6F^%$N=_DPT5n^afk~t;3S(+g7|vxgGDA1piFC!u7c3&+R?19$cXujUNy{!-v=f! z-GYg7PjMS=O$g}!@xI=54Ai+JsY;ETdX7>70QlehJL$r}8MB+&pRlB@9G_sAEa4Nx z@~G`kKVf*C2-A|EkPvrL#-ii$G8EdVMgveF8=SBMwe5}AA!B}lblHLC=c@PaR40HD z3>KMP1|jA|`OHjW7|1_@{Q^^zRW^-f?+KGY#au`OR_wj{qT&7!P~&j*U0DWL5!2if z_=6ZqkQ0>BL<$t@1Hof>>j42)D=MY^h9Woyqi3uyLXw1>3G3ow)*+{DhA}eWWDr&c zW-)KFK&3Ta$&6!OZU5#@8SVZ}_eb-%4+bn9mm;XZ4!!FTcKr03Z6Umx&f%+t4CgZt zgn@DlNAC@X7w_83#E8In>Col%uyz%q{*tN8RX#VYV)t+l^%%y7fHMEKR5R%`;V zjDZ*g^IVWbeD%fk6`b;ZkucjV24mZgF7wfeg3CF$ezAwjM*&?^;TPNj+ZT{nw#oqHF{R~C9d zF3=3Cq|IYOW-HA;VkBgJeN_ zw8#t+E$Yd(VX#0Qkwr}J(ZwPSCG;U=8EQR5WXzTJGp`wbHOo)Nmswek)UxV_)QXv* z83TtVuexn2l8f>fwc`WhDlKg;-UCm?11v=M3=gnqPGB<~FqOVu{)?)G$>XcjCJ!(d z@LHz@JZhq^&fh(LKYoBWr_LW4-Kq1<1RPv8IC*ez|9kzn_K$Y4A7mn6@08wb_xs!D z23(#Agza0}?`S{1z0a@71MIvz;Q#`ldvG^}jA6zFWisFiQi;w)sWjP7#PUUbBfb5= zq<$v|c4=_se=9B|&es0H^xS!E;788zL5hl2d`x=Ryjs$pOIf>00UVjtjSOEOoLS%j z0oOrHxH5&gh!S?z^5zNQHT2hF2h`}1*`y}Q0KW*+aN#((>FL4xM|bW>10P?Q{UT*j zV@%@<7zB7=7Cy&x2kHKTyR@36nFb4BIcHWA(P41Fi;D{ZM?ScGtH*~4Qehq;5aTK6&EAt%yKuUv(y z;S7j}#U5ul-8-Y1@^7O`bqEk|n5-0)*8h-qc_?*L3eF%mBrN->jj^aGedIFFni^zr zelT|I&ZDU@Q5*3e3m6gbm}n}Vt%f7mm&DdG}G9^!{??KPnC?g z7ptIm`M_q&5e>{`I%wq{(NmI%WzW)B@4w^x;?ZPC3D&y6VQ1Wg<>r(pZzd<>WQv}( z4ZcC;ICBk56tZ-AC}y_WXH~_8M0t7K)G=-_s5fpvv`P9_Gt>>hwH!%UZV$p!-gD`O zpCQjKw?EMM)$`R*L_T>2!{ME4h@IJcloxp)5cLkjjT8QG+Q0+;jbqO8wL+^?extY} z(u?Sc>40ByE3qUX$RP|yfShcm4#y*FXYvoy(ayqTIntjt+V47hC*ZjwE!$F|oNLcB zr^T{dAIc@3ipwEmlsNS%v@D1Q3Lq^kFugj<_oq zT*BTa7I2KiKyyi^K8XQ(5L;i}@fLVRz?3MQqvvq%mN6G4LbpDZ8*t0_CWvsdx~?Q0 z|8EQ-YSrc0>b*O3zY8gQHPTCsnwrS6as=+#ge*`EmQU(WT#!sD!ahX?Vnx!y?yh$3 z`my5C5Kr19#iRr!#R%eBUP*^UhV0or>Cf^a)^T!MiYnkuVk*dB_9k0vef(YX0St+qd|-GDE@nOHy3xh9svZ533sPWu97gG zSvW%gMEAkx=!nZPIx{QP>pxXI8Awj{6|l0HL2P&=NB(eL!U>3tD2qx#p`2Fkg{9k5 zY!VTA?|fJBWMY(%ZX2d88E#A)rfMBMrUo~ZPsJN_0n)3R85|TszC||kboXUL8UV=U z=~Z^d(CF(iUg8PO(o*Ky%29JO3e5r{`#_x(4le;#^9vWMmj@7Rf3w)6#HqAwi4Dp@ zz7b0syP;=JKI3yCGb-ZjM9*Z{hEx|cySCohr+C#VH@sPRR78#uS@uFtS&`{p77sE` zO4X!*j&~(fRtUL4JWKQazdm#LilP94SZO@cVF6b`TEbyk!bLW;9em4Duji5(DzFLc zbc@#2%3N>v&|ZZ6*UE*JciVCh_f4u(9(csPuYfR2iPUc*o+>~fB$WZJNkb?j_CZ& zu*l_Xvh0~mPC7q+kCa}qunYH!A+616dR*u|cvue5QrXy4XZD%>kcn_<3FDbk zc1N1lshf5?tB5i{gxCJUtw3+A{ilK9HJ1! zMGZQd*afCUj#;km_M_s_GJps+Ov_zbp4rEUq5yf?RtUz*1Il@#0T-gYp2jz2nERSv z>#W_zo~^A`aNU-wm7zmNWb^VPxKXsTy{BZNPZNz8f4rj%Dv>#;YiS8leyhY1 z2xV)G0EsCQvZ50P&^Jm3B63t8zw6E$64Zh+dG0gsLS>yfu7qHKTP($U#>X8?f>3}3 zS(Q+*VVPNlVj_gm&n$%E){nN9puJNe7z#G)}|Yw2Kl zv3K`^+a&QaYA`#}Fr-=yS!g!CYZ?X0ghOAVit3|urQ~wwcz8U&Y|e#wr{jt{5)GLu zR0TX;!bFsC4p!kd#*l<=eY+e8hE~W1xO@d%TJMmBv+X_2xkbul+;v6+MsCv@0k24g zuoY_sII1*clK?|4PE!rpjZiZQ?fEs!OAoqo=aadPe+s~4*p>Ze7w8g$iu6pV8Ilrl zwJE=a00-BQ2X*a0>7sJ);46yB6ddCqpzFD+2{Ua@m|e73(d4PX`Rw3+TB?onJw zDD%Z5@)AS@2E$jFul!DiE?5)!D4dY}gdedbyEtVW=f~Ps=OrI3E`(z;FGHzML<$WA z@nu#Z%2#_Txr{g?a;W4{TR}#|O31`No?YyH^CRVj(!~^3o~t$zv2Bemq@<+Y3>Tbe zmu6>Q)T&T>q7ji<81McIE-x;GJkeSsuEky}7Ki)KOs1F>oxp(ypwAG6Y%X=Dx9&%f z*Erb4_JiMr2l%acsmG?yXf3qf-syg?`_^i1?1=8s-HFa;{J{&V&vs_oH;rA}KCgB2 z)M2}xZDQbKb~#62{P^}Uqo1r!+4b@EBu~I|CifrfO+7I5?<(WB=U#WBcR1PxqeRJ24U0Mk-h}e0Y45iA>oB z)Dc|kO7CSS?`#}{0BX;cF%{^E#JUI>JVR**bg%Lye*%7i!%@8n5bC&#Cs*3*ophh! z4asU)0IUPop0KIlFpz_(IPEIffDrlAZ_>7QG()Q*9exZ|L}ps3!x4(Gb7GQ zwv{L?2`$7)=up1PoZhgEQHD9?T|){LG!-*5bG_s5KYTK7aPOCcT}2t!SUky5+B0a_ z-Vb*zpX6*jT7X;Pn5t<%1x@wRyY6@@QNS4%AGsg+Q$_$8=G}x)1?m!>@cX=Y{8Bu< zeD)--i0B53dXDa2zJK^=`WkIlp%bdecsNB$y2a!Y#a8Xnhm-Y3rB9dmA=xq0#E>WY zb#~5*@T(#jiu>k%+U`gL{IQ98SUKs~1To_~GWQ_JqxR8x30x6;yP)T0=Z&8)?uaDM z8CTCn#L$aWkrTWP7mDVhM$BU=>-{^U6Xu1rQnVJ6tE)~QUP$zfTI{)uJ5U;7>|tUo z5Y&k7@PoTU(A|Rl-d=(88?zz zLnWrA4#yt3L9;M>%0lM>Grx2pYa3kBr@+`7KLcZn*ypWzGgLQ!Pk{G7ki`~}tjF)4 zLHO&{N&i?}2(jtyGHavDf-nSIJJTDIJWPN|9`qeUkYLM1yzCpGKlbVFB}0KB$2ev9 zhhb+bKUhtVv1KdEF`xl&!hl~PH%Y=N#~igGL!0B~qfB?7c;0Yj3lajNmJy?S{8#&( z=pM<0mCFjEbOBRt&A2ve9(-rSl;xBAyGIR^T_!II6;`#iyA%&!{aIOQo0W;`(+ zj!mAG~_OhDhk7;*0cn{QqV@71we(~!=z-|6S`|@rE`~7 zc_CB+=!s3!nZ_mMqa^8j)e72JWZjZy#SErPFrF!(gRR{eovn)>>Sb@kTvh_3aL_<@ z6omy)1xLf6qaHI=D=o~JLE+fWv#?c7fCAX;{XKa|!?W>{F{xB+5_Xg2=zC!${Bon! z^MbRccrR4zG6E6-p@?`)1wUUs_h-eEiDaBMICgBpXqVk3CXPJKw z+X4c$@PvNrANslBGQ#meaO_7Qh$rK^NnI3a;I-17xp4ULsW{*dcEqE3h5+|ic;GIii?<$H2uKMm$-zl_ zsI?=nYTN*0Ui5pzSB-&{JViB6A$0p5b~ZDSKrO_gtE^!n7m5+Tq?IJPRkE8HI(XjW zijAh|1DYI!fzT9O|2KPg9`|cmmJ9#BfAjNurW~+Lb1EhQd8YLYY2Y?Z1(89`x3u(` zmX!mdfM|-EW@V*m2nrHyr2;ce)Kp}FsBLwtVQITTMPxQD-4<;t!S{RIi{H90-u?bz z!=KjvxD(d8fA?@*=XspRah&HB@{Z+Qj%*w);)$vq01vkXh$WODy&D>NcVYP73Lcr4 zCDKf6tUiZSoI_bu-A!OhpT z%bMT|{%8iKhA3fq{xoL;9GP99<~8KhWG3btgC5e8ZtsV|%F#i~dxtOj=k`JhTPq8% z%CxM&u@N&l9J6SK0c7JDGt-__5o!x(6Gc7E@;dkz2ahe7c8(=txgt?M#2to^7MZ;V z1e|}RT*{!m%;RL?h?hsTV}X!hm$wG%_ipb9Ut#HH>O-g_^LBDXgJ+95)leNAy)xdi z$siLxOinDUclrP&-N7N_;zGQ8aiDrZm|uJX9#h_DucE0?d9oP!2_ljJ1Cb8hEAschMw$?ok(RFz>Qwtz1e+wBT%4N`r$6~Msr=m=H?8Y}MgCH)%uV`5H+YdPGtw%+- z!V6T(teQx=q!k-qmhg5RCW{i`>fjQ$>@(yn$6ltp+m`A)?M=m_$rZMz5j*<%V$3C_ z88?y1Of22-Eb10%6B~%RXlW%#qHciyTK$WybCZH7aYfznbhH?Rk*>Ln*pdL^( zIwQO^6O4m1<49AZLQ;btxuUouZU`l<6`x)iF<0Axcfe08hBs=h-~f20@-sHlh*PB( zUyum4r~dT+DJ~=lp=jf!55&?(CETkr+>~~23yJYY>Q3v25+=l_;T0J{V^&$`;zySk zGG!G`K&3cZ2!Q7Du>az4@K+V~3I;5EnpuIHJUBc~1`uNw`pd0l!dJ^|V2ZYXK}F+F zc8kC#ssdpDy^P_ral9$~Ow=SHEbaWrUed1~Es`-HDX(HZ6!sEv zLzEfp)w{=O?MD+bz=s@ihC>qI;5BTwl7qBBppgV z#F@@uFn3&kUw!oKp}jZFeW7YRf2TK$xjS?3Fa%u7>OOIR zY^bzlD3aFGg*JHMPZt*gG@Z!GKLcBdE@~PRNHMKAeV|$SmMOW$iu#V3y-YZ!r0Ka+ z&(DsZHi0L;ns(zDs%1?q8aDt$#8wDp(F|n6= z*EW)HXn!bAGKf89D{)&f$zrXgI<-WmF+&?tCY?OMM6t1V@r1uUq19CIWHUb~y zXg-eW$Qn)Yl|x0yp;Wb%&h`O*(Hn|@ph^Zva4YN*(qUk>Wld$HoT||^XUA=bL{Ond z*hSWh#%tr3eYw3Obr4>R8^Vhf>Ouv@WR0^#D%d;0C9<5H4ut_^a7UUl)8Dt<85eit zLKt`SI4sJG=jnm|psv&d{-V{5OO8o123mieLhr)JhRwZ$D{d|BNViGUW1&035d3Yc z*d$nQ>%fxcSK#(lSGr{=m54&(H11EKSiS8JiVLapr8h0#k{8dA+zaOdqjIK!GdMDL zEHAhwn4uvxJ*Vgtla)7ncN|b&y=(;zZbm32i>l&m_cW?Q`iN?k5fz2!B`lLBGf$v40=6ET8&3D!mux+PCZ}+8ah-7XRjC>3^U;w3t_<#G`Z)q=t zbAY*3_XJ^9Y=#(qC`)F4!Z4!;#Ub3O=#75MV0J5lCoN``<@)0X+#41JIL5JJSE1r8 z+q}hyO9F}~3OZHWox>NZ`g`)KEh< zU+R|R6nzVO`-i=?PR6c1f-i`orS`sG3Hsa^l)DY_&0W z+fsX>W+r&nhrJ!sWkw*VLuBN%WGf%Faj4v3a&{-+CLT5g7M^QmbLzMwiVNW?V!P2% zkTcPRBMgsj9HhGKfJLyy$Yi>^(4~5O%<%AlBmsG@cjj&Fh4fuSGH2AGUOH+hvr5y= z7Ew#6O^1!-XjGxLHik~yCH7*qE)90BdQN*GBW(#68kba>>4wd!wxG9TvBNCJULpp- zAzC`g(twHZ&wC!Pa{nc-I6!dNYaDPsmQo+SVQfb~q1hFfHW>(HSRAk#1HWYAHOY7= zpcu)us?@LfyEf0}G$QJs+(~6knJz&HB^*7$6Sx~)S2B7Ea)kolh6c@WMH&d|v)@-d z8eFTNC6gX^yd$FQ#_e3&25XM3vocI z70nnp7x2?yXSdL~EG3Yp!b$?Bn9++km5YpM) z1%>$gzz~{%yoA+PMlyCM?w?=0BZ13D0$`Na5}~+fmomRA(=m9!E4u*f0rd%s6knPuPMtEkce($V z1G1Lg52;wBwwgXBTCwk@OtIp0=&2~vnB*NR@N-H8!U~^2?9a^7)upMA9B{lRWQz|W zZi0P*5YfTkVFuz?0#XrPnQDjjj3a3mAQ5(D6Zv3yZTjIm?W5Tuc7i*>iP@2aanvG# znv%~K2E?P!d5vhP0Iv0urKEL8%-C6)@3pf8*fw%PvfvmF8tDpqMhLR)AWzXZUFfJu zF3!wU-|_Oi4L|GNx2G1?+B*``F`A+ELW8T*J(l&y_tgvmNYkV= znv5hce~{D4H^bXzM!4?$Jw=4{EfvVZ4VDG_5c7~Ug33(uON20m6ZRunDx$j_oL*?r z6rLL1@goYv3>?Jird<>6L&))28``9hXEqMQ8-pMLDLsYwhP0H}+kls`G!g>XyD+?4 z`T6}T2?Ay1t8)}ad!hXyUI1>zL;SMPOiFUk?6rj=7KG^(oAXcpbo-8gLf;{0B`T4$ zR=F2kpvTnU49|GQf+`x2f~E^Ur$yxGNexKA^Yp`u@)0nWDM&ntM|5H}QO1biC-V=u zRFol^PDRd0`wWsn<2Ke7Mp>A-w74V7U1^Mr5wSCR$PV=^!kWwjyLfwq?99GlHWvBC zZzPS7ncjezm;Nyx;0LPu$L^6ify>o9t7@?C`!grdl)z8Vy?kzE_SV@q&z?BjnR)Nb z&&}Lt`p>F&PQQG5WqgaSfD^{m)VrtlPThO-snJVEOT(LnZyX*!xMT3H!Or0O`~S25 zlKw*PhTgfo$9BKneP?&8dr&3?c8;#EuisEVw)*zJg9rHk`Jb?C{cYb0tT(nO~0L=q{yPqg*wV5v59xqX3OO)ejyb! zMPrjX$%;BmiR4S!^!XSnqS6@Mdaw?q@}PW^m|c zvv78%{`r$t=Rx0Y-@k#v(hy1qu_{EP?U6Qg9N0_;BDROxt|3T;lYRo>gO}G^qf)Ib z&V1xgtNI%gIO@&_t){}tpt6;iPBqY*mhs#)L9!~XRKO*SCn$>C)`oIIX_EGo?(SQw z{<|L9-WePUf{-2%kZEO21=w(iRCd9Hbyz0}3D}e6vcwGqJmZOkvoiIP->kaV9Dd+p zNFUWAnk`mgB7(S_#{2a3Tg-ZsRFfPAq%K=Qh<9GqRnClOa%4A_9rmxifmy-&gftO{%$^@xnb$tRlH1^PvIA8R4Lilm4muij~;j z;RQ|oq+ex_gVv$z5GXS@oKOuPJmH&N46zgoxoHcr=2>8An$*P4@0y_raYBaXvl)4- zyjS%f+0g+=2-eOqovL@mgmZQ=TmZ5{k(5qXrqdkr;L|JJv1y=Z42AKXs)123ieTGK zt~bbXZKMC8+pBu-#I@jJCe)w|B}R;m9}TOc9}ZwJlP?oV(mf1SY4Xo0cxbFNM1%0i z->v%TkE*K6C!QRC9I;`^hHg~g2(eg7;sug!k#DOG*ms}DS;3y43MGzwi_ zjh!X$$r_=5{Xl3+( z!qM}YxSRqVh38jEOcH(`p1i_`qXc=cZTR!>hN^{0xQH~ReDZRHMG-95fSw~ zBOTRiIq^xxL4JwEk>J+1yPZR-{_}sly_hmQd4!ia2Ek01hhNPF7aC(R(4H1!l$7Pb z1A8_Nx?+PO(jT6_`pHJJP7J{wGsP1e;3#MoDgJC5z`mj>F^vFgo>>k=J^L2Eq}`5$ z7qKLu?VZlmkE{ldo>&1~EDhmiSwPkL0VN>{q6$(?3BQ=}g#rZo0A{Lb1~HQM;Yr?V zHon!~Gyi)ve8m~YX=q+J~BhXqedRQbAnXH+`U>zHxcgJ+qeeI(T z+*z8Dz;d)KZl1VpiHiQ_9WgEf$@YN~FQz$`u%LK`ny_>E4oeH&o0qEYugQ!#QY z052JigmTf_kmuGuN_+MfZK}B6p&{rzQ}H=ieDPQVcjo@#9#yxq+FmRIuF@Ij!3ZcG zW2+oB!g-J&#GGSUP^dL^vSf;O?2yV^FM-#6aq8H!s?NvuwHG5aLOg70aGDhYk%p~@ zFEWzRw?xH~KVZDX&sgb2mmHGK`nOYeE)i)z+g?mns<&QlvVr&((5;>a9@348YeKGI z_<{?l$mkU;Lk@tGYg7!&oUuN z3pRZ@EPApYkT6>KVAXp?8#SPvKx3B#lx#S-f?LC;LMnS_$l>(-NKX(S>L$&SvQLZ% zzH+_Cxa33H;7AH>zz7RjEVRV8XeIbYBor}#h9LSzF|_r0K%$m39Ciqlo!$pmtNNIi zx9<$QOqN63DH5}AIr7kMVsqN4(yE=KVF^Qi)N&!1U=-3L1#_&;-45)nOpb)Gu2FKC zROcCeB{q(D^O$zP^4ejEESFw8pH6y`&Iq7z4<^%;ZqW+{TN2J zsrOXJl8GC$e$}@+64fQhv@C5-HXoAJjtP}oJpRPFRej%Qwb#mJ*hKg_*>CMfU*0&- zkkMhFWH)Mb7#p6D3>Zj5zrq>GxV<~`b|vHa%Lm>VT@aDOL*{n?TZk^eOLGpCX>%%b zknK1@AJadTP!Pgs6L=4hnY-%qRdw|B?Trb{k`cT~c9g|!bD%TZ%8DhG;2%>JCe|nr! zU+8~Yu70oTpMF#OkUE^wWkJh8*7Ax$*NCZbCSH#U#k1gnb@-zwxQMtj5Q`jF2;9Z~ zY`^OL!bFjt?!Fcuq z`~VkK@%N8Tp83-7s+n_VPMGNp&z%0?^z%BuGky5@y6V>P8wWRyPjrUhU~1o7J#~8L z76Sr~9NjQFpX>h#gK_`r{#o@$oD^_#@4|Yq_r%_G_ru*6cAnIksb4gA-2T}E!-vd$ zp}L6u;NSBgMK|#+0e+U{D4YItVUf1z07> zp^7n6J96Hk7{9PQ{gyq&g`!>{bVbD+g$@YYavm8oOg5oh(d7V7FDql|a}2a{J!L$L z&G=th4#U7SPI;~akpv%|F|&aKN_tcpx{DxeoqByzxv=DkY*g9Zi(lEUzBQ2r{jwqm zwIb|!bX{tB4Q!zzRb&J{RicIQfzqyLgPk}%)7%K8sDtL7^^Eq>P|nmpqf%r()tkhU zCSxNf(cEdzQt0C-)5yurZ+GfP$P`ygYjyA3Zd-)Qf8MNGJMUTjtcX`ZqjUs@95n`M zD&mOw%2g;5>0XYO8;L6ccW78u7ZZ7Qz@(+KanznuPI?Lf@5YRQYkTEi{l zg6E@qf&)4~>bZ$~y15X%#~bUtiUR_N#go|%Vhyi>b`gl#)l3J97O!-0JOPT;JKS8Y zFZ{dq9qBgmN?3+jqSZq#-Q%ZDg(V$ z7~E)`c`@vO)|>w|HG%^NTY<9IOFp{n@5>8GyEG)J&ibRlz_ZeDY?V?pKxD)_77OBH zokIJ@C1Sav)?DcLPZbx6HI%r@e+0eA<~e%aD+S0i;T7I9EtCz8XTlXCq^o9?zgE_s z=~v&cxRBvy?wUB2)t>)@9TN9gQXytK( z+hMA8Vnk!wK!Ru3bfgC>U#*Wglf~d9EI>x@xYga=?wec8Z7H&e@Lgl6;!4ITLk6+I zV_z&P3ssasFWEe_Gjm8XR7wcIoh%Lhyal2zge%YP%-J_c1_f#kZDV6oJt1L|Q;iKm z$$L-0Hkd;;NR!XjR`-s36z`}(83ZZNlD!5Pu+4E*ImKA6jK3iquiA{v$WUeZ5a9_1 zF5Ca=U$hrOZH2%mykIwib>f!ugTj3#=>~+DT|kA<$_yk}uH;D63y`^I`l(MZ0E_p_ z?1Q5aG!$v}gZ!TY7ky;7i>yv_)$FV7STbOA;Xc3r5Cmj)2g0Qd1fv(u-n0q=Z#D zso>I{BGzUkPCTE{c9z%2ADfIS$%TM?U2vHXp9w7(b{eW5j*GhCi89X5!E-Ftv<3&` zs=-u^F&ivT{YDG+;oK0M2%M0(ncbr{%^6XaDKXmq#JQ^q-II7kUNeh>DNT2@6wl`WW!MvnZ}3Z37cZN;N4&xe z$<)?hCMW>WDG6Z(Tp5f`C*|ByHV_zKD>unP0watb_>BT$%BF%JazR4Z{+!9xDk>Yp zG?JM2Gi6*7O2Mn%7Wjk`=pLwBIrPNhhP*>e3SCsEL~<+9#XJw* zhDhx1p)M4bzP<^gGG(*}`ZYrK2k&3JYXe?_3~eT{H9RSKM$++D%=D6$(nt~N65HVq z;RVpPuy`(5KX>B2$_=r9kQe+R;Un$RP!-D;W-hIIVmyTL3Et%$MND2?#^Co~SY9Z3E84w>Bg)yFnaK%mC=F5c%tjn87A5q_35UkP1%stE;>d3)YYE@KD!fr0~pQ(3?SM9yx{_wD3natxAo5p7@ zCy0-ia?l6AliSHkuvl~Z9185~;MDwcTB#*dlHp~|M=6KpS9sRDrFPT3Gm|>UbWo-2 zFWiD%0`#IO!zQn8&!2L3dq4>_4s9x>hB2WEC88v-Ii#Ny!De^or1xf&2qicloJ zwB-Mj8Hu?u=^7GbbuBB@SY_EQv=jjnSQrGNqjsu4FE8Yz4X#yHlLM)tg-mGmU< zGjD0SGs~G-$(pu%HM^0>U{+Sg(Q|$j4{$t42 z>>ky*v2#J^l+INBq57=)=<4R`!ta&{m^k08^~Uu}F=em}&*WJm<)S-iGZ{dU*kl(9 zr5TR~U+@Tkf}DxF3$w=-MOPw@rLI?rQ#pUcS_{_G$fb!Q{z7~-LV@!veeAFV#n2bh zXS*@nS5&ylT7Zj@Lx_f%nQs-lL}JSy?`MhH&TxE28v~nZBZ3Y9GWl?^cg^ctM9HX* zheqGUGzSUkg$KCvr+2gqf*xQk(IzAhTS}y~ z7LaNd7t{qrsYQ^Z7$*EG6sU|#k~1yAgqKr}FD|5PPa_&hh+-sOi^IUBI0wptNWpB_ zQ8J=W!2C!?RMkg$UtXW@Puzj|Xqu74F`NWIr83rYMUUrg2>1kfbY#VE1SP7LoRWhn z0T66Uv3>rLMKZtxVpPJ4acfAcs#65HAY-wk{nOb2h$@xsLwPeQJ4rDI4(@EuA97If zXkiC}2cSTaSdJp$iuK`IHK+nwv4yAam}nPNIXk6*!o-HQZeQWrmt=S;Y%bp?{AgKlUxb>Q84RkQCi^hOk z&Fnh)n~zA5!lxbw9o1pa^zE$z4?%ESBL0+=QomMxerL9PNCm}g#Du01wNH9Jr9s+a z=C8oI3cIC^@$xH*cLXKK$YO>i;%76@fQdGq4y3%dgH|O~t9~;1Ia4~6zql=K;>Ed7 z+)!RfngarTHCQQ@Ck-434}eBNBmwa9J0F(N8mk^#o$s1C`8m5|?%LM&<9G1BqzoI9 z4?|*ryl`%2S8|Hl^;RAUMLBA48B44*#$2{sUk#mIS5Ee zi!-Sz`$L0)YEEIwub6gaD~rzNmuD{dNbzWqg^6znKO_X-T@J6K&@;_zBq5(64MA5) zG&Kr&PDuz^_-spi=I?fKaUsnNn&`#<@Z>moYYyW^Y+=q!$xSPua}gXAJt}SVhUte8 znz!29xV^X#ZJl*H8i4{h7CJ~*zyMU5$*JDC2of(hYeNXUEFka-B-)()(doNf2$?1g z`FpDNSQc>?Dhk+9HqVItP~Bp$qlseh<0p#jlmob?KKr-jg?xv=0U<{LqFW8V%@*^P zQv0dxqFdrztt4DE50(lPHE+!h9`uCbLf{$Eimc125)(fUw`7@tPITHr$AoT`-M?+d2 z4jph0Th^^A7F{>@e^F1cRLCtAtk0K2zxatbO@^=Qwb{sP5u5EEh6f4`xW~CBY0_L2+bReUJf>2> z+o@&Eacz;;$h6C&XPi>p5W_Dx!+|2us;n~N7q^YN&+tVt4PCzn4d`|$WXOFb7vcp6 zt1;lyh29ZE0UIcbmKS1?^W^w?v$%NqQ?Gj( zMgq^0an%g7Ce|AXfIua+p^Fei%KF9C=_`u>sVL@g%TY&GnLuJ&dAZ!B_;fLtf(1R= zKGIZtgtlbP$L1pCOY6MtUBw+iKXQ>L$4dLA(qBYg?@5G4AK)?#A3_o}Bm$XJ$z@R@ zRJL};M;81)?#~`2bm#zNEaYsH4 z|4K%{B0{VkP*yRagGHTWQk)uI2u*XMP|5nS*UNJayukL>?B*Yq7YYFt>c`s=7Sn_s z>p$uYxDM$r8d~L2uP~KvUA2_#U=HqLci)c}7g7M2Gz{F+KirpqE7xNW`4aNaIXCc7 z{=-{GZQ4(HUt}OWS@&mOR9q;12`|1>k@=EaQAR zHI}FDd2V^3bUdhLGWL{+Yi9}G;Cs3pr8w)_*7qr6h0h>G`>81rRGqU`k&Q^)IvVKH zS_V>}piT6bazw_0uSM1};JAZ75ie{A7Z(Di;ZF$Ec8KQ#%cuDb)xG1$JD~x?)|gBrcZ1u&HC0&@ z->v2P+SWASLa}S+7+oJiXcishO3fP5T6h}{Pm9Pu$>c;maL71ez=Ad3U~o)9+Y1qF z1%i;j8$)EydD8d*vyeP|%5=DLT)7o^1J;0kkoWp*uwR|`6a^gZh-M@Hntdd}(a61i zovOaJLLfD7rZLA;&u9{Fm9yY5)q=+QPUiuq7a^M^z>h8lRV$B^KrLovJe$A4MfqC9 zg(x;07Z}U5!xZlJ!KY}t%Tn2 z-Qr;%z3Ah492=@`fEtEQm0Wu#u_S>I#ihY3G&@RKz)NYPCM1;J1`L zL4{aJ9fl}%%Qw`YRHul@TcI0pF@s4Ns>^1IaiehgJG)!e70+((2#2UbP9w747xd{G zIo<~ckiJfAt>k0h#M}x^uqvQn#B9{W;^OduuPrW=2_SYU;}rcrtz3rj`OS2RK#m$; zRRH>3t^5d5s;f-CGV)9{IQPI$lotwr-WVcL#xgvo1k;^?Eg4FVxXZ)JkeX>AIB5&P z>$om0V|!Ld2e;lPtv7jl!nKJmP$KIEib^dS{*lB*W}pE8J+b5hscJ(-aT+vfO@rfK z|Eh;P?NRZH?B@Y4=yp!-UYQ>L-bv%fjk{AH93C;H+OKXLT{pOX^v2PN)djs_&J7&y zn>#LbetlHuhPit7{j;ae9y0UAnR7;ind4_V(;t|A?(p>KLp$f!SB{HUl*X~D5Z5ijV* z=~*+RIRi~2YvTPyJRBbN8$p?9iULD>hBn7BkB|6V`)H0#(VmuB90*^@f_@xxx?(16 zH^MQqzm7g^v3M!m29rZEnHjP%zVD<3MhvIP;qqX6Vct+4Nt$Jkg$8ODqoN-xeif~0 zJ>osc%vTwXTNUXs{{E+wca$zUnc9zXui?7{P6r~%#+lA5+hood-cyRVlF_q5oDc?h zZBKpsvu%8m0C=caChYdqd)6pC;f_#tikjqc`equ})gqCA(G}6VB*5v{e&*}N9fieG z<47J21BA#Cij-geHn_$HK$Sq)0D^L{pusQ~U4`boXQn%DFC-^sn@6LUB>`Ewz3*rQ zXn?z$f&k37MV9cuqj4+~uiUjU9aDc&6awBZv_RXi!?=1#uS}T8bwZl-Don9h5E=v? zkxOhrG2)g5Qu)1qUdg#gedrbHn^_j{mBS)nd5wlSED(j{BVsN>fGJf)JVc5wn5N5} zt@_j>+eb_1TpGVc3cXTHc`7#LBc4;0LOe$e;fd^>oCO#%7J(+(H`!~dx7l9EHw=B}9nTe0hnpoPMnf*|Eq0E$}WPqZk199BrBmi0o z*Me+hMgTcyr|QGBm7~YegCuh4dbRV@M-?Psx~I9#($xzhOV7v);a~A6J*0b9d$h2I zZBRj*YhWsuB${s7?d|cYUu##S`~y!Z8Z&B1#RQr8yR0$E#g;SWK_ee%p*bwyKzdc~ z8TYfkcl?;*9mQEKBZCW!B)%QIrLhHa#7YbL78iGYyp4>TLPQuoNeG}K@AV(_jpEV# zH6bkXL~>k!dx)}3|MZxl7TFPa!Nn9+GuRHwDl)YLroV5`X!yYPZL332m;ktc>@X$?E7R&44*3z&}zPGLcH+EQv^! zP*1?cp25nqiaS!dll?_{>CV?vM%WzEs|3kQDWX$DNkTD5d)-2A)KGQ|4LjX~u52%) zG{fLi{T#HOmI?<-h#cmp1h`=pQ^Hlj2jAluhMx~s);Mn3qjWag3e|mc? zI+#2jZ)sXnL35k~!x8MQyVZK&hqre;IpDp!JNIJ`ZZBkXk-h_~mBdKGLJGpLo-n0x z&i@WemiZSc2-1%LAz0gfRn<4wd0BfQ76v9lekAo&Rtc~!{$zwJUoOC`|5=dDaRTZ{ zBq#+_;3JD5D`sEND=q||u_0K@iekO9UJ z3^gjo>{j4b`x**CkXI+CX__{K7J~K}OTcgZ&c=54Ed`x~W=MlI!-iTRkvQxs9G}k{ zCs5jtR1f@UTu`a$9oUhcW&m?{`rW@=Jeh1tnI;CR@cpcjJ?d<*!rJ!Dz(DQO*d3_` z6d|V}(CGoR@SWZM!&Zt5AyqMB@k!AE0YQLSjnfFNYDwi=)L`$-at%xF-RS@@gbPCK ze&y2Q6?xBy3_&6WdjMUq$MfMAv4_ePxdZtjuxp5f79$wg+v%3v9)7&2Ofw`U9s)62 zB9{Ndkt#Cm^n6IQwqYiL9%%wne#un-bm1_TV$O6c>{BHEQr%67I-~qJ9io%2RL3cmQq;Nl%G~(k1*vGbX(o{)CL} z9dmGTAuw9oq%z0D>9qD=!n;r)Y$^V1=?)rFwTRqSxS$z(7BLsOTTg$vy^x+X%g|p< zFO`x}3kY2lXOD=4*bx<8p8APMU<0_Gid9)BKrQd>pYws@LKH`Yej0&^LnJFsI14={ zH7i*t|!mlxtag%g=&SwKTlrM4y(BmxLbYG!nlq?Ah6 zu4iNt)IEfHdGIR*m#o_KY9mKM=VV{Q3y7a~6d-MTBW?6gcpvEqh|fhlQkmzty@joM zrch0ZHe6R^4+%$YWPpS*bMQe%=pk7%)Hfs7b&7@;cIg~vNGQq4L7mGA-Nrf%&F9-B z{Mm2nK$@0`15pr@UywoCX)}v5HeA`4wMc9R+N;}-D&7&xBO-(Xo$g$A*tD4E#7K}T z6iEoqG%cZGHmSrhf)T$n{A+8WfAIGe7Ydb`#tA~ZteRDxrR$$cMP3jVF#{Dq8Ux4# zbc~QMjLoyIhJSTdd7(!9ivnfNp)~I+!;%@(=u()h zUMOb@Q_;YUxNZENHA$RebONk1Y9u?|e*#-k-#l<;f219z_v(TLauxBMl*r+1vMY>* zYo&pPR*Jm<9g~G_17w;q78U7DxQIo0ZSbvQiaS#JXpZ8gcGu}yi58FJ&=VsC#NVO4 zB2!Ic1F%NZUqO@f?Az<3r(RZE$S$X*Xd#DG1qWXbcL|?+Uhji*L5St&gyg7l27lUP z&B%6~Z1*d_+g=C&%JCi27C6h!DC!8&a*<7nVa7m91-6$hWQiKLAzcg3^55pd+$XzIZe_UROW)~AED$R?} zykrcIkfzGDUG-0RP^-WK%@jOo8*!Im)uhMX!^ZpouS^3_cz_=o?u#Gb)cHf^zBqTz z-0{v0Y|a5V;0Mqlkp6)2dBc6<$B+9{S4=&B>cOKghaVUXzRRlqdw=YEZ{T}x;CpZ2 zdvD--Z{T}x;J@Y#96$pQBw+&b3ye=^wE7l-sKGym6xMs7P65w#%-~C2;a%1)POzu9 zEzdu!wH3iyxd2LqR)~p0Lij7-c+N{_`bbZ<+J=2P<#RLlm8=FosX=z;-u8gvj$rfn z%9)6G4E$9>1zQJfLa|qKX{&MM0hFg^WrJaVF(m>u4PLKLfB0{T3n5rg<1{R#x{8#- zl<5xX0@1Ms!=?Eu=*%z-J|6{&+8mpPP~55qEqg~8@ONQhW8jUTpy;Wu<7Lnptzb7a zfEMSpA*C0)LY&#An1nXb1h+PQ-xdr;VZiS?+RacR)wf!b)TTZ~_QtRRt*f^bm@#4V zU9rH0;z$$q+QRtyTgyialalk^4C^5HX4DQe8#4?3nNJV)_eyE@(|zgo@{S>xKKpb zG+tpu@Blu(LI8*B*6c1@7_pg_qj-*tCQXk&dd2I&2aR6+&;vY>+CUuz*hc_D)^QWy zYD@ydPGz#~)Kb~nzN;j0d>jI<4sej$Gov8SupXHVN&Gg~Qrx%IQJE-$3x+eWitNd#yfXIS8n zymsmhKPbr^DG|MiE0MrR(&N$MsPNXhSG66A8C+%!a+(W~h*v9{EtU3wBS*&hzt1t96YTr6bF>=B_H5m(=lz|TK+q${ogF?{GK7Vlkh~D+RH`P~FH%>n{X9;x9kJDh(pTZ@~ z{dT4We3u}o{faTLieZ_;o#75>oQ&=g1JF%e^q6ls*t&}-7Nx*9kZl+>$oliIoo_Fc zA!=ELCP)RQ@U_am?~Qx@DogBP0}88lF>gxebOH%g}f#YlemJ z%F}QRGle8X1Z)w96^Sk*lKAYVZz~^-`jQFg*-L_9qkC(hB9m#J;)-&qNMx)}rfX8_ zcuf$7=^@$Ln!V+D#T{AWQi*{b4Of?DZILH=*6CVaoT!JMGYn6gp4^H>Ps6>HOV$~^ zr6u7Yx3te-#WD7}i@BQU47}?IQ*r>+Qn++Z4atOs7e3$=M88sYy!p}VTKNq&5h@Ui z!hvRMe;O&xDV;;F#C|8ra4|)lm#|U!(I%bEAQQQ*o%-Sb+CEy-jL8Pf7K3Rdt#YYT z1%YKzKu*roURH|O^dxY>hQ!SL#0IspHTu1ewioh&4atGNjc?Ov5EMX1~Lt|Q9zJVp(xOp+KYfHT+KdF7$)FUPcZLXYp+6vPlN;}fID**z# z6fWwm$iR#!aH& zbD@ecg5~(a=hw*v4+Dky=m(!z0VYAIlUa@0#T41 z1*f0cCISwaMQ!l1ffMVUAA_n35eQeBNaME`*}Cul`QnZ^Cpiym?V2T!%n+=t z&hmDBSF&eBJcSmy%vd3RAZx7q+&2~%f?d4`jsh7E^)HSXeqa)bq$SzrOlV!bYMp2> z$a<)>*_5iL)#|2J6Jmwu`UcA>uo-iu;Ba%KaX%k#Z!@1$PYS=Xnv7Y{O9XcaPBfY7 zl?Cj^kXz06l8F|25s?0{6M-aZDbtSy0|(IKGI-M~=2P*y87?8Gh0Y6GyQ08`a)+|W z;QS&S)-kO^f~4&Y5U>0OL z1q9^Sj5YV?wDj~1cb-4fUWk?3H_r13@EifAHyAHWW`;CGJ7pSR>@)cCaJgluVsd*r z>Q)x2-)Wtg1Z8!QfMno4SRA1KB&d#N_ zaNGNU>3WuVW4w|OGUglfCS$5Ijmd#4R@ST6UvrlW2}N25)uQ^3ICxnUD2w(mN3Nv^ z(UQ^ZR=`%~3jZLE$1}9u9h8BM^)oQo4rO-%gl!bMp-7LYumJRQgr^`aW^8|ySXd7< z5neWDzfrs+&2rFv&iWD;5FjbcHw!iX3KZPu!%wOZxXd>Wd;v3 zb)^0$-E?Vl^g*&kaO`g#;#;EI|@oOJS<01H!mcZMtdTUI;f+Dp1WJ?P!OGX zKUI-xyZHE&|K>S}1b&Yp(pu!^=N*p!3L4a19^+yJTV2$hC;m=*M+PSFq-5|<#z$o| ztC(z(ELk^aGFs=7lJ})7K@ON(5isq=yZ-X*YwlKD$mmeqoPTdyi94Av6_%m+6(zBDRMaLGN8}C_rlDn(6SXHA7h9<=j>!vjYzBb zk|WG$aLZe3<5%sp7s_G9-cxXNPEOEKq%8)?hV)`lPxYRm2#PExY%o3XO~E!6h8~H{ zxr5uznH;f`4wlT8u|_Oc2?O5K7tR&~_#-r#3gayi__!M(tRxe4+ScOinZ5RouvT)s zMe6O?QASCb4NB;?g8Xf`(&QD1PkDp5X&w!7*j3GD8TtVZOlBK_Ddt7Jhc>;9))WYq)!;4fZ|_J~ zqUsox!U)7OZo7f68i;HWkC!HpjONrvx5j9PEQeQ6#vInZ%lL1;P+W*DB?cHx&ddk~ zHKW`NA4fibBI1b}(BIb!oRg#tiZZd%BpcCKZ8G)nA8Kg;9uGe!%qJQ_jt(vaw4IqG zxbet&v)S;8LsmYBq2&oz#xc3OJJo$u@o1Ulz@h=_W3=sQXc7MgotoFqMYm=YzVoKeNu6PR<>*WOEBepxKe+eh zsndFI+&|?nJppsar4yjKVSg_`b^gpblU{)RCk77sqjT#s(pS(saq6(C%SR`SdczM6 zpVu1<4)71Xw~pvSbjOar%{2kCw8o z5l_MzJS!?tWxJSMquNT#l5tbi z5K-9lCWX9K7jI&HX>i=z%R9;(c4kS1f+kfZHw%0Q)3Giw=qZsyGmGA7;V??bmgn!( zy=h_}2W zXRr}Lnn~=cc<6&+KSt89-(?erhTa884FqL>5--+rC{~2;Bryr{;1!>0bqdx#5h?91P4> zc+QLxvYMsA9MWbtW#-G??fGB*SaBh>zC4=f&pamLv&vcoyyW7&dYcPMMm0h~ZQ!SH z%zCy&Q(oeg>4jfyFCQVarpu7o`ckz)Hi0WUiIp0UpBP zfVDPeW?zccsu~+P(HyWMt_kU~`UNq0 z;B7${6K2rhAiUkXxHQU zRp{FG++`1FFC?&GHOspRUf)XOg-~zlF__ez^6HAij!Bx`IUAxymY;+QBx5|b`-e2382`Sp$VWjlt=F`uCt zq5e#gMi?oUV+zSQp|B;Xq-X&)tg1UxEHXvatJ*WT^$&{+DWl2l+z}d))DfH@CMThl z(kJQnLEDT4aY;xjN8HIwYi-}ro{%vO)Zd#6-p!t-WiYDO+{K&6?Di2kkOif zY`aU<#|n26SGA%TTaX#-0;=I{ffZ1W*UQZyG+SLjuIcOe8~?^8W{r>ucKeSmmte7Zexb;m%PF7)3N7+Ek8A!J&o2)H9>T z`Lfi9G7Pm`C76Ux)Bz0FR)?Q@eQ}|PR|*x$2L~#^hvty^74D=ubeT#38w@NS$ z{6{0OkoJs!p-9a6f_<~`EcTo&YhqI#=>?-7D~#-VO4Lr7ap!6&mgzeD=~atq8nA(WcAR0NAyi(R+(f z8wZIZ6%ul1cpEPjxT8{QY>@8lwX_Q4+&8MEPhyq;T7t9{56?;eq%Yvcs&nDK_yP7* zH+ANpGrG1jH9EI*LH&^VgJ<7A_l4<0>lchppy{8VYJTR6!{-eTpMT%nZ_jkb=X7oy zTsL$4^alp#jgL1k;N;m;tDDB1xq5J7_sppe3LMn23%+3R3(nBbAgU0Zv!ya(gC~nFGU7qs;w9|Biv4y^JhT7KfYscM5 z3}rkg2~upd2QByJ_)5q^vPYPjf(M1MKRO)5wTv~hF5GZ4Tf@R0-Fn$u+B=H8nPUQI zo8)ZMU{DciBd8vgoAYo`PHBxNEEvy(d1QUiCJEYYFOME{pY}p_S!@aD)0`H9aWnLT zj*6jd==3D=`0zYL>9v{bG~LcKvJf-%lU@Y%>*gm zf`F2`kV`;6f8G!VZCsFSmowqI0!Dy=}K-t z9&4RfE!w%3@P!zX&6yZQv2DmgApCkhx9>+U0*qi2vSE6sF%T3e6D|*!FE=o<+Z)AKKu8t zZuc5TD}gQNq@@cB#=z5JCoo44wDe@-shkD$%)&BsFmpH4|4D)DeC9L7yY|V1YPd*; zD1e(DKKT(TZ`fcCagpg*YO=!ZqA)74SSsy<~GTY z^k&Ex5sx4P4Io6j5{-=d+}f>=nTSjIXsHe}u*^QPco~VD9?Iw(oeZ}D#HloSr8S(! zWQ|4z=XrgCP)nNx4^RLvHMY_3g&_A@V z2nNAMgo?DKS)Fk091D#IHzbk2BvnnOD5t*gQqandbfm%B zZ8@DFCv;%~-LMg*-An8CUE6^oRA8ghL#b%=AsRxfg8a-OfXtB?@eyJz#}Xnat^3)r z#@|j~@=L{qkRJ+d_9X5`?Pxn{o%7>dl&RV7vJgKBDZjO&5L-pLW3?nGvw$)|A zE+S7tQT5Dy@bdc?Z<`C6Au5l8iza6%DRT5UOdhX+)@={zx9Ay^{a!& zoX}nf*NC!BOHAfbS$$ETRe}f+;TE)yC#^}8lo>TsV}|DS$vI)eOD1!e@@%|PaG8k^ zK20W3C}2$8ak!4PZaM<7eQD73(gOae`$TqQuv z$QBR$!B*}$HBV&Nrs)HMzun+-?+pL(*y2Kws;o34EBsN_rM~c3E(i}fz}V?gYG;ea z>^s*&CZI%eSeli!Jb1v(#f5;>_$Bb*R({qQKP~p&GLlZA0FGNqkbyid8Iu#ptbX%} zc6J867q%CIAT629j|&S$W!`3yY6&j`+zTev&^a1J`N zL2%v@xI6V<1Qr-GaaTB8UmMl`+TM|@>hQ);w4`vJwhZ4*j}Y&R1!Ke7_UvxZm{6vm z$k<6Nk&V1}dGJT?X)mP9-20b(V4DP7L}&~@_B@s!AEk?or%*w(MV7+vxv8|gq#0sy zwEP$Cg@8jX|6HI5X*Cux?E zP>sb$zCsVzekq*^Q4muAgRd&Tbm3?X zF?B*ChIQ>BP%bu*_=!4KG+Viw@<{)?0(gwy)CqdC(EI3#$&*HuxKX#S>!fP_*!V+ybmN+T2TBc z0dLfq*d?0~X=6jxYNFT@ZCe7bErw&4r;HA;Q(+t)9_1R^%t}&gkkoMKQ}6mP9^lWb zdiUSL1FY1GRqvGExO;W?tnSgBnR!_4FUKj#PZ>lf{x7tnd) z{)qvd3;(ZE1g`3z**~gxV`sW|!N2FcfQcm_ldcj7b1VlE2Yldgjgc$aSc&2_p_DR7 zOT}zy$e@98nJwyx7pp%!`_46*3qi(CVTm0tV-^u|Y57p9iI@y7Z~<%rxXOay2W+Cz zB__kLwAEk!*<&Wo9(f0`l=q8Bz&=_-&#BExB?8tInGp6OJ#AKRZbI%YU`wBznMIcWtdDZX6`tWTNgII1z zw9Xj34B!CcELgRU{zNGsZp)d96em&Cd}^RfE25?|VTX%wb#-{rq&)GG#2WTrN)EnO zHWQ2mBw-togdvkcxQao`2Hm1A{84W#XMG~ThcEr=fwzqnaOhd06rtg))QvR~sOs{FD!@ zoUK81Nqa{rTlcFZTFuBLzPtK5XGW8oooyz?BNOya1`CieRl*Gv!Afp-K7ZU@F2v;G zZ~glX_ImFl z_bV@y={BZY(Vrywv`8RFyw|9T>Fch;s(rza9g10wTbyzvO!<)!+t35K(-Rlzw+7H^YAUWiWw z6B9{{1ORNHlUp!gkbFGwa_CC zG}4G$V{x_qmD|e;MKsN*EN~DJrd)&|l`F_?1tPLKP2p&!KzbO5ewmJn1lo#;e7$j@v~+Bv!dX|>{a196R}VUWQ^Fb(s#Ml`S7=k3wf1-k!llE!!2a0 zl5c?ZkvQdUHWx%oHgTw}$oX93);UdNsrRHwy_~Pcv!5g#iCjiDm{vWgQbOH(`*>yD z4Oj*LPvFR5X^zALt~kb5x2pFP@o|6cF1g~gJPS7m!HtTdb5E0SJSqAf(vh4d3M~&( zvHHoAtLFwUn<^ennp3uG#X`+7>*4U^Q2drSt;ovk&D1p7Ub3e_OKuDVRt}%p?5vzp zTnKIyhz$pj8~vU$U2W1#Mf1ZL1d&%#(PtZZPqfBJvk*!A>Z8HCA5mP$J7EVjE@7Qu z2U|l2{;W)deXy7kQPS!lDQTomFBjm9M}ffibe3;95JfnKC{U;jTp2AOkjN*=jBlZv^jV4v4U_72a`nf%Q~J$OP>M7>H8J12G)*+UR|L zg5a}^gz>-)vJR@i05Y$ByL36*_1SO|_jUnHHxk>v5}riq0!7g8joilx-S z)Y6cL%;AV41y&KGYro`dc=d(wr@rCQWr-p|Y%kZJ`hnunBoI0%Dp3|nYD$61;((qL zf{^BFM}?FMKU3(`T^JA?t|hj(Q-9y2xv;q-AxCoaTd@(V(@`|ga$ui6gUF{Muhu01 zH{B~TwG3<5IS*s-;#RT@f2N3m^v7U{m-=fTsEuq*Yp}-c)-# z{d858|0ju27U%<&FgDZJs1EWA-nxSvxZfYMX+w|w|OMa}yG#sn>C4UiO!5}GiLC@@P zs3dGB-dy8RMqm<6p-JG2Vt{v9T6=N{MA0J3RjQbcpxV<}dg|!_>Rm zS?qm&Vs-HKJ+bAloiwu>p)7QksH6m-OG-f^IDo^J6|hH+#HDC$aCl-o_Jbdrh-A5t z!ko7{&7J}(Uz9q)SB9_MBVAu@6ire!V^^~i5VT3n1b(iG`t}ynAT$9MDmXct$|6;Y z&Iw%x9Yo6UfX(q^=n*@HO$e0D;a=YP-p&4#C+bG-$hR=%()EBuuqPsl~6~y#Xt|Fpc8cdj(>FvW z!Cv{nKB5HjmfS%M7mff5dB0@*g(A?4z$NRbSX=0S`BFTj*rdbcf0Cp=8oEV>Wc4Ub#4}Dv^n%ZClj9t#`MkA)jR_Q{a*;uO|{yW8m zNX&@W9Al;B39&%RTVYmKh-Eas#&tR)UKY=Udrl`Wt`tzm(rs0rIpxkclRM(biA3s* z6LcvhTH`pcK>UT2M}`{ln;{h@PM=#Q)PnYYL4Mm_ctd+byadPu6U5~ep+P*=8f_g| zq-;GZU&NYrd&M>OoY_#u79hoLTdH1vX?sJ~x}^>=;4Bl_@I(Hv)g~E(9JXE(9)KyS z!SmS!ico4g;C|G_#dUJd2O!E=7D2%yg@cvspi`Q%8o-+cR6tMi5*`vfqO-usdsm)z zTJc~?Ew!^f!y*$_-&^oCLa*P(Q-EFlE{ zqun{De&#s&P@7|MU;iI%8{_`Jal#G>trA>poPh|sm;d}OU zURk_nG?6j?7L0N^s-5x?MV@XhSXF!z4#ZVJ1|O&hvN)|b4<0LA=gfoJJEER4z~vld z-y{hH(Jh5wt)r3R=hI#xkRg%fVeu-ZPx|GsBAwH&X)lx$*i?=*d=vuS93x^{kfMmq zS>eV;qTnVMH$ED7um;F4>VKLLqX@q-1=b$`!=&6)dBzwYRt z=)HWFdY%i(VM`j80m)3*Cb1#qfg5Ws_A_;dfe@KN!aaaXRet0ND;K-KhWKBPrA|pXCnvxGV%Bpkzw78H5&so+{;HW1cfjo)8 z!NBS(QdY$N0XJ#S20u~h>5P<&lp~wqdSB@1;jGt zYrRw5tGy!;3yG#kin#)LpmJCG=185mH0gl87A{5Ovk<0AGdDfXZRY&7z4hPhk$BNYe_?4nD^loJJ(y58NXxS`)Zu4S#FZ*S}O=$O{gaX{QCEg;juA z#UJ#d`-gpmFe{4v5zd$Kr7ABI656Vt`mW+a)-GTsLhFi9i1<~pEG~x>YhJBW%4~XN z9wLFf2U9DBEf%(@`g2tq(iBB(Q_P*HHt!=XV%qFv3a^5bzOi?sx`V)}qhKeGU1S)U za`P9TU)+#GFnkT_kW>deYU@#qW^4$WRt1q$dk7c_H24(gin8g2dA!wy>aCZz7ZQAF z)ATT|8i6B45lWD!*Qu>xkQ7V8x#*1;a4-IY@~3eqXL;4%o|J<&nh)cnt1NLf;aQjKhQax=XT5rD z5!HZct}xir&J-I}OaQ6V#Gz4@3NUJ%5_JSmAVv9zDZaUACC<&Ydg;RA(KbYPrDy1xb)0B+Ut0!B$@#9F!h*dgdNg1XJp#^RMMEij1f@yLUF(h54$X(>eyTu z7t4_|Nj~$LoK51V<3Gi)MWTf9(%YF12ZLjDA>+ZMEN;M@h|1Ew-MRZ^ZfLgKBoH#R z#F5q~g%|!dNYwK4*ENK1+PkzsL4{KYCrg}+k^`ryK$hx{61VqG8 z1h~jST96?xFD63>{D@43FXqij!6v$Nex~^L5=59L>x2(7=c~|t6w7#1<9KX8(}~iu z>h&rX5neWPlm?{5)@uE?KiPhJPBz<>nN;euEpis8oPnY6l2J9tC0QBJ_3Ua^L03h< z!X@VJEZ6gwwBJlfK$2R){B@zEkXeu#6&CMj*+D4K4v20MB4!XtLX7yx;IXoM;xWZ_ zydCy*h7Ot?dJ391bx+0(J;`dKMLpfiz6T9Qdd$kyFd!eT>^`U1`0*oSpy3|ZvkF5= zN%sJ(d>C_w!Ec0bEzEAhLdZ~hlZrG5?p^QP?_I?WCDQ|8X?K!`q%&WI``_6I6fCbx zaKuJrmo>Gba#hTfjyd`6IpN6#5CWOWT3{u+a0~(LFzf~DQWd%{9_}==KO?c?#?dh8 z=Ssr?bXniO$kk{FaahTP3zf5z2hAw+i83=&Q;2b_B4ZBebxXPixnisWkBxP$|MK_R zZ=ZQEZk=Oaz7|%M21K@WR7khNAv8%=O`HnV!qw}M$qWGC@^bwLlao;VA^3pln?W^m zbT}N$#X)l;s2EFg><9RbNKyzAgA`||4&{;-4M<|Oy5@fEyN-sC8FcnE!I68yl*f2T zy%|E-#JBeP=yhdi|cO|A1yB=R63g`!C68#HnE}oL?1o{JI9O1mV^Lma-Cfe6E+=W zrGD^lnGf)Ws{3z$I__OuEmxOR`%en!FF7k975-r}U+R8h=G^*|y}Qpmex^UYZ~FA< zBgWTvUpBsAe9Cxg>O)g6=sjiXA)}l6zu5Vi(S@TYcJ5jKQoT|A@9L8I_jT7hU+?^W z?<@Z|v+y5e04$8j+K_dzcyZvR#K!61wM^_ZZGspFj*^$GPvoPhlDT=CBD}EA?ytXi zPkrnmlTYeGOdWB&YJiD#AolfU$HXd%TjbVAIJAXX36a|>sz?^lxR}3lczZ)R=GiZa ztpL8&LGJbmnMRf20FwNup0o7;#;BI6L&ZjHwJO;9Z;mJ~#9U%LYaE~;DUgQrN-+b9 zahxN4kUIjWHKQJ*FcbYbUBh%NZ&k0~*Ir13$w)0gM?LASi0llHPN)%RrA(ndf+gI! zwaE6TK-la&a-zX!cj$5ex11KmYbdGNKe3tmyYAl2qRZS)b4H#d+eGGEhY z5pxh0%9j1+BYVi0iI`hKe)c1qp?=iFMw>fIQ7LGfr3^&k!;?D26{M>&oe~3^TJknyqt`0)5kxki zO}AVhd7$pHLrj1+p-F=T&nIs|9KDDf`CC(_+QmK(CG4JXrQRa~Czfk*c4__o6YINg zmVob%a$5TKYJiM#S3uxzaT}TZtKpQ&q(F+RMlGOz3-=8|EmW_YH23F1*&CQp1T7ne z@5IX%>qqKa;U-0RVy4v?LywSSY9$@P`&(PAAAN26itxPbq^ub_N6?b-pG3J7aQF&M zvgdYCD8}XFW_$pXVVZBrjk;LBVj?i+j)-b<0t&#r5jX5f|0FHW3DYtYtOQN4Ct&bp z2O)+xl6jcTw*J6v#U07SIv$jsSQXa_oD|h^`-|;^3BItg5~&%gi&%&OO*xV} z$5-UD(o}10i%%9N5i@2gh(a~Bw|d(-#f9|l5p zDPj%HEd682i9*%I2goE3X7qLXcy!Urh*rI{M>3MaNbN8@8-)}Q0H@Gn?&AyPOayFj z4As}S+6@~8N-k8KD;o&rSbci}48*$V%K;NvFSHs{mxvq4SbS}Y1_jXWo;%tn6Fe+A zsk8A3TA9M0i6pTksD|+s`k1I~>2jopW7SeqAedr2sIIuJxFNY%sKSULI5d1B#)b5> zB#H((Ws!H1)CplX%~>oyR(8O<1$X)ZYSTu*Q)P^Rn2db}&}k90EPbz-cTvL9AO|Nj zKoLkH?r2RKN;9jV`tqgilbJDNb7r)NNF4z~0MO8)dWz_fFo~5;0#>#uSFwq(GUp-> z%xZn_j}{j~iUq|H>w(`8#~B{zH`RW6WWYM(Vk~X9V%;;?rXjaQW+;aUw z(@l-BuzPJ5lay?K_l*&$F1)CHMahdfc~i7eE~Qt4bT5M-RVfbnbs~%M6;E&4S6C)( z6i9TabfrGF$c)UVFnK06$4a2iaD|+NDjrLSUN9^JEmC`MMA$(t52Ia#B>H=O{tfLN zrMU>A4rgVmkdnhIBH6k&n<>OkZWE{}6r2NT1I>UoSO@F6xK#c6Bq7r_Psg|E0F z4HE;%SQ}l|RtY_A)8Tpq1zX19Hi$L`HvYAk%wvICUw-Jn6gR~A>5k&yk?e^Mc0Elj z6TS$cjQ$pvh9PrNa@4s#UGF(xSsdK1&N;QckTTUz*ncoR~gnLoIl2ADp8ddc|#cXk2{Uod^z z^kL&K4L>wKcYMOQKbo4_H+9C;QKK727mQA+zA}8s;HJTw>t7r^VKDAr-9M{;bnoWg zg}o>Crn?{RzOcK{xutVa=O^orc4q&BT)=<^A)|?;YfMSJU=*VaMwXr9Rub4~X;cq{1UiUtl)*u1wgbF5b@vQUo0#9kF>)^=8n+*TZ$k;2?Mv`mIx-l-q`v*jJ3GcsB@WOXPJ{BcIq z<#3)bRv8@1n1gSOq7p4OZ5ygRC3yF$_f3Lb?nuL%?%>QRh!0UTWdF9SaT}ni!ZB;z z8&_Ju;COKRDUF`-%=}t$Ln-w$v5p#mJEmB0_1HFC5zc6W9Hc&W3EhWm(dK`M7{G>X z4i)>rf@7m2s%&v zTh@h;9^1>^xBYN=p%^`!#LSn4vOm`7F-1KCsRdpbied?fNf!Svd-ol- zU0GcT{G6x19SK2=8e=S=g1o)hz^Dj<(!>PN#P4m!hNwsjLe$Y{ER!e}iYU>5J(fh8 z6$_TcXiPMTii!w`*w7>fCt-f;yx;SjL$0~5A^*p@W=7%r&U4Cr@4fa~YwufOGB@9P z-@_XhGBjHxlyw;-Ko$H!IJ~&1p_xD+{gl#;wG}u)Nb{5sxY0>Vt&?wep-KpK+aMQB zC;nd&PL_;Bgja^K7%Ic!SwEO}d6e>o16W+_oVjn~j)W155azdKE1?B3sY%y2M3F;r zhQzAWC>8W(St`RlK(c5s>%DI^UpBJ}HNr>GCx~QO$B>F{Xd?9!-yO|b=<|lTIfyjO z1@H&PpM`9#cvExpXKb3`8!8F84P#w#W5O7>PbQaPs|C6YK|$Z-;2QOtsFM`AP<(zw zBU+GA3oP!O?UECD;DPjAQ43J<>I7L9(`kj+11CmCdSgr z<<(NVpw(1V=z7YnF>$Q$>4g@kASm063&QeFtIozo_uiM*FB_WVvWCxKZn`wzB$TX` zpF>8}k9e#8i}lImCzS{1Ab!VPG{cs59y@uw2}*{$xgU z3a^4hVb5^IAfhpP(7Y)U_yyaKbyyW&yy=gc7s97YNSP9&9#&wWZUeoQ@707D4pvAC zbk=YwgA-k4WPV~KaPPj4Zd@qL8s5X>GZiyz!*S`r4>m;yqA0{8_zsP3#2$u*nGg^+ zwPSI%J$A1;8`;P5DSFTPp&-aMABS9fh$B!imAF$JZa(Dt$}pGsr$&6F#7gyt;VU@4HSV2iqXnfgCjh?5kZ- zGORl248a?nhyW5Ul&jz$zqx-7$v6{0Y=qv}KH(iXsSv@f z82qo;X1CH#?^ScDrbQ*KN*n9<7%`jfC!D;|g$iSDQeBg_4yjvm&PY*4qx8{}#mLp^ z4*{f5ZzZ?()eOZMicL10hBu-8cI9lj4hIES&pfRSUb-h=`KV}k_ktQK(f(& z%BaG1M;4oBpa!R`VTp=w#1e5!)~{&q^=m0mcf@U^oJ(fIa^g>yTXz|@DY+~dWG`qs zN{h1X(Z(m|{&5 zv4k?klBq$}E8Fp>$oN7~EC*RByLRVaR4>mH5C<(Zl#WhGGv-ki@okTeX z5`zlQ;?aaHEpX|RaP2+2+inHpkN}u2>pHm>bz{c>A#62^-N9`0h5~YMWb|HZlFBVu zh7pf^Y6>|eTz=IkzyxpO^WsJ{hf}%8+sk)tTqq-iD6X{b*lE+;3M?{fyLBJP%ms`x zM6HChi-d{rMA5)R%Jxr3R;i@*D08B;8X5B~0?NAZ2cxAzK$b!_pd)?F6w5AvdQ>-p zKT9j^Q~t1VM*^KYcd!_5bk5M^hQQzv6Z!Xqv$T=Ydek^{a^ytS{2$w?;-~wlmo_dG z2!kYwlRuoKwII==$1{pS8z(W%FR5YFOM;b+8|!Yo6kBWETR+#h5EF>D7RKo~wS_FL zpXq#IGQyG=IpE)Wv$EMeXk-KOj&NjlNv0iT>80$~V;653QYhn~ zIPKV}i0bL=5}%N&*j<}VH}J;EjXP2}5zxYclXcSTl(mv38-zdHT)i0}*8=ogeiFpu z_JV2Vm%6`oaN|Olc9>jN#;tJH>dFA2nKUUZBDM5x#fBeZC9&w=4?Nik5 zH*_u>95MO2L9aOnV7lC?{l`8$bK=>0R49x4nO7(Eix;V|#<{$GfNI`X&w@F?E@lf_L;kyPwu`pgRnIlihp- zSRFo7jOs2@PcXj_xx_Z_Poj|}CDzm*xG(he+QRh9hcVNI)X(7#Gv3CZi*JWX)ie+J zs_OHxo5jeSEu=J{b*g_sSjD}HXX2|vr%CQeLe2SfocD?lUoZnkz$#^394q1$GoJ!O zm?5AFWEs&bLTCltn7C?~4ssz*JKGA&h>HM};+wMul%-;k^e+qYKWSofqv<&$LE`@; z6)UNH!flOr-oq=KY9+xE2Zxby`WAlW=)mqvb)-77%>HcHybw~Dltlzkd zu&!cx*eF(KmTWhmoWV+_^IX_8wSw1}0o%28o=j~0yuPEzD=01WkgpwAaFpd7LRgU_ zXd~hja}=qS;*i!p>&412Qf_hA)I)~BH+KYV+Br5t&cTukK@=^x85Ch52G_>eMQn{A zsTkJXWd@9SZ9d$1`CxHkSmor)(I%J*+=J-vn&P#(P#20?1zQZ&bGXXu_6kju!IY82 zm?NuyZe#48Pp{V`G{cbQm=G0N7FZ>PqyV857ZS3^#W-y*Og#Vi`i3$$K}Pl)ZpkleEn?^Mo0Z(i z@}^TJNJw=7a6?yV+f$d=yxl8*+PF^Drva7O+4_C_Exd}9lIRi(IC|0E%RxA-J(7^h zz|EkX=4SgB?9+HK**}vTPwW^^|vuxFYk7K3F(4Px_JqcN@H-zb#) zK-9=rX8+RvQ~WWz(I8t`pCID7^+TQ?#ysU*ly1$!I%-b&j{u;htVw4iW{gP-u_i zvZ;x&P1>b4oUf3>g%S62t-(pn3&|j%oFsI!B+^`v6SAY*EA5zGX<;PmP%SKnT!9EN zzbw$KuNF7`TYVul2of4#7EJ+2m9RX>!vI2Xp4z`6h+Tr+MYkBd$32ac@!TrS*6$C6 zguHD34%KW4YY0JU!8I@k@0yN|F4K#w!ZA$871i5a2ROfb~k@ZJop7%-}{t@*u`# zXzymiX?lx7V9YI)r{A-2A;J%tRtTj= z0ofA;`6(+Wn0*sw%GUF+0E-5M%pR1z5xAK`9F)7={j;G}DtDB&5nc+kw@O(O0zsqz z|5Oz7$ZUEk%I(>VFjst}$rF6i`ncNL7>?qoE@Uy2~?qo{|6rNzYjOI6#CqTUyRQFq3pmwTnOk&N&r+X6y^~ z%f>dvR~;!-b!AcMR44p-%_*8~WFAE(!kpWyc})mK2k2YW#H+kVM2bg2%n?z!U3H>La-N0O(ZeSuILN^p0@F~SyBt?E|+ZAzaTBvNfGO#I9I%zdkK zx$4$kZjc%Fg;y)AL{g9*Xb5dCD2q8iup<$)ffx?Lf zqOh^rFwf?N3vH1BAwH=cg(iebf+Eb^-1ujQGQJC`10i&)AW9|jF_W$NIzS&)8p#t&jcc_;us2 zZ+&`j#$f;cclzh_AJewyz<6JMA( zYx=LJ&z_#2x_;{1slz94oBY7!*5qC8Xxab&`E$Kz4qb4tt53+B9EBqM4jI&%iQAp* zm`*Jq*O!HiG_i44Ym7(ZqTjrV_4SEUo?o=j9`a5^#T*%x)BqppGxPmG4uMp@p!cG) zb9NhsQM?uRohhL~4_<)Uh^no9PAys|UbB16*(`Vo36g}Lc@4~g`Y_Y$o$t;d>zcvB z3ikL?r5daamy(V<^0aVM7d)-UVDQfx~uIc#66lY@E6Ld7^Om1r!Lf)B^($*eW-KwuWQW zF|&jBZWR5_P=WNAb_KwsdQsa$(t?lPGk-Ci!T}tDjd;c@f!k(;P%7X`Jda!0>>YMV z(cXMa{Q)wZPZt@J262vD5Vr?3jy802f2mia_UifJA67s*2gRQezAPp&O4UdE4}H31M-`L|ZHE&!1kjj~}Wfz9ytD7Yg@YD^}EXtO*Jo zQb4kn_!yxmJCqixT}X|XU-9nhxsCoUPb-S24iys@BUK8vFoM_%D{Bm=t`gwg5^35& zl7hFoNG2gVNGGBv9E7cfm&%(@Dmtfqw|-1?stk=6*U^gjV|e39w=P-LS+|%gqBs(Y*)xEdFi1nWlKee;eskk%vymz!cW&fI-xZVG`=HjIfiH=m5Q|KR9#O;_%Ts zi{}+L6|a;o@z`MX7i9>1REvZYWCL{{yU)qt^E$mvXx6e7cYo)}MeF_T`dXHGCYeLC zUbfmOHSI18& z-y%=YVf=m>umK3CM$MQW7r|08UK?5|xsL7IE6QK|NqwTJ=?awcI@BZa(PQ}GC9X|(=#Pcc9K?-520a1;um|p%>DhPuPsm)%(K~yXk z|1~9e@=-o&vFO#$Yb`oy$OWk2fz?uFd769XM~r%#V59e)6N}FB?~g8Kk(;aGm1RzuwF)Zvs%+T)dJeLL zTIG=p!Ujbo35nn5&SX-^s{F>FXzzF3=wevul-+QFG?$rL`j5ifs=dT#G`vRRM113;qTDcKAFzem=GW;_nnDQdZ_Sc=d@ zsD^l8(P?^p2qKx*LeIyLh>Mw*!=MgX`nXm!5~};)Hx`}y|6+7!;J*aOI;mp7s6rN* zK9^CS1RAASWLkn(DoI^q-V?!{ULen5#miUjQIzKmt!M5`A~b;lU{$qZ8_>G~ysi_0 zf|?-+a;J+RG8<|_kV15UG{_r^diq)KD#}M)QQsNxjQ?ajkgAdEa-)P6`?-)v0%7no z>|s+W>7z4PFf(vsX-kQmIPr_G6s;qEJW2u(Fr_3twa5>pVg{i`66d!861+-i0Nn)7 z#;mUwo;2oWm5`EkdA__kltVowJdR3EX<}2VKuI+Kl#iAbW<~gilB6YQX%i0A0swvV z4zRiRlkXSh&2>%TH*CUm&hyVnk7?8M9=D@g%92A#Lflv`EVa1HN3S^QpERo&J+Ho) zy$xx?I_Vq&lo16rA(2+OnD;a;khsHnwpG9%9;#6;DV@tYoAv_E*u=+02F^1nYU(ShsiO){<4 zCRcZT(AyG;JzNTr^O>%oE{`uh>Y|nG;P2xP0oQ zseLAQP6y~rTsiUFiTjU#d;E>#M~wG$1Drhez`?bHb7w9c961>DKh{5`zklz#-ubKIR4Y%2`gLDsw%M zIP5DZ#)4I`sSR?9s)mhpjHWwF+GxLMXvnGdXVtXikEVkz1GwM;!j6mw9P{rR4;EF4 zr4DonRK~8^R*?95>(hHR?g&c4on>YF?wRHX_cMb?$r@c%{$4jY=1#H*C4h8uv&vwd zW~U$XtmcIj3W`gB-1mm3;SzNU(4o4q-FfEd2g$)!Cgd()TCyr~M3mAXHY8xH|Bg2{E+mCZm5Fuyo-nW0!jyn`8!l179tLoG zAe${DH#_o3MIn|*iGzO}Qq{g1H6f)Q4o{5ms>D!u1g#ArX{J+08O|Upqj@ur35mgn zOovmr?<(*An@*ITMhpwGxZNfh>hi`t=2RHfp@bIq8e$OmZ@um6W|D=SG>lf!b53P&&0H7!VIru1V%>1V0cclm^C!tCv zwE4vo9ZkNRx?Wb{Mk60>w{NNIm|Q4Mel)2Cf?fuwD1+Ko-C5?+MkYryo1>x&gFb?B z!C2FPcsAPqyIp4-*#O6|& z-#x1=C}Ssl*thD~;Jx^AQh7qDzAtzSOu-IxZ2q86*lyYQT2);dj)(stRe5 z8w@{|bPG-TBP=-fai*1aKXQ5VLe@%}mP!GADuvc1S-VHGoxv z4^76{TACiO$xNmk_*k)y1*+f+?l4ui_8mHarOsoJULrY2@{BW{1pzgTk=ojtnE2zy z9g$?yOl&*3TOVK2kVrgIdSqgQ#(kJRF90y##s+5-%0kM>mDc;7-?&f!96xSl2*4wx z^t6~_3sz{@6gs6WzZf#Os;wnbL=*@CaC>s=Gk1^x2DIlD^W_e*-xIacC4?X1g)-Lm>$# zRf<5W{$s2~heta8z3B#~%Ef_H3-U?nvTNy7^_%6g8bcph}M5$$3M- zQGqa1K*fwgVvA7)q6F58=b`tQGwU0I;s7le99L}ZLR($|eO&e2_<&R@ybImW)YO=DYTIM9 zWl)n7k!qD;gN+K*cbAg1pMg6l`Y~RmWZ>!L#30hN4nL;xXqi&x@8oIXB=xCyiI}`4 zOk4=|Ru>M^2QIY&X3gB0;R>=Ea(ttP&zv`vne-lKfPxw(|J*vh8 zW|=V7kvOoK>TpVY;S#D+Ib%B2@Kr^qEROw7lcBG;K6dze^M({A!l!~hP6DNu79KB* zZ^s}VK0>sn5(PD#*})ovbSeo7Zg^p#`^=gbvNe>6Y#K^=p*AOZuwQa<3K*IDlc{`& za0M7Jl)_H#XVS(eOEy#QX>8dDF&XRU{n@rD8@aF;2taggKiZxE3@WI{=q{VkET#cTMOt3HXsvy-3)i)29ciOO8m4{5?)m(1gB*#<^SKn>wyGzXrMe|P+ zhMgkf`b=`Ad?Cj|vFVnJ9EoJaH@H*Y5$`i@gXOugr+=?`A%B5G(1wEMBocu_WVP3^ zST-9;2CTNW6(6offDwlLS$@d5&WX=xTnN761yR8=xF%Av#^@b1ET7D`shH z;*?i4ZiwSl9O6u|uqgr{gb~T6OJ(>34yKx-$j*iMrfMRekQ*X50c>`y^S)sdM!r7x za%LV_Cvu*g26P#GBdRE)G~lweI?0#;$hyVB`4r*}0Y;45p4sCojXQ#93I0MAc8V_* zO`HA#GKCekGhi{JK;%sc2`OXKYh@9|#fF(z4##L#NevEjEx(PKB}{5D7T9A31=Dn| z=%UhTMn<+tWhR|nUS}L+8{0E4JyT!6zl99j;Q=lxXD%%l8WRF)F5vZ(kDKgFe0XP0 z;P|=YM~?T$K58<+euM80&Kn#x7!)`C7cSrv-P60X=`iRV+nH>CvVBH-u61Lk1GJ{g zPnTyF7u`V`VCRq3uTJ+c#0gqU9?>GCU;bhM5$X$nEj|NerhZfmZCXziu-;-$(45(O zSK~q<{CL&ibK4HF0~BDwg)S;I@+ea(S?7CkJ%dj^6 zse*8MhC_g8x5WZ$m9zXJM5p((|FQ<7hL+9NB6R}H`B95REP#2^Ye2ztI!N+>R|7XF z$`Q}TYXKTdtG#po$qtMe*YetAZ&S7*f5jjUT0qzwjYxy8r|YiMM^-<2p?nO!X^lQBx+n1q^;9X0WZ}d6bLsN*h+AoU7TF{qsA*j zuH!LNxRAh+7&x1ta0L=`kcu*`LLvpXZg82mtv$lSDvD<(F8fL2LR2asK)^Kh0~`U* zdCu&3g}1%!L6CpZ_hlH~L+YY(hIuE6v-|CbG%sWirxVA*WE2XC4^|`CBM`_rAb=(* zbOdrLXIy2Jl;7l&UtVfG>F=8tBJ3x^DBa}@5}y`e(!E8cDN0@E-!QS~t$_IIG0Pmu zMGswBpK4#&xRAnK2QCdCRhrU#W!n2qD9CTtiwmctZO;3+i;TXY9GX6oh!LSakFsT(XU`YuvN zWO@t*(_ApZ7@btHgEfn8r&l$toi7XNx#fLPC2wOJ9Xq=HMXpet_XpF zG(r0%*2%OSgY)J*p(HFLUQMW8YzR$8VQ@330b<9azu$N;e^5`OmOUQ{iR4MNbNYnI zj$|oCO)B_|&rt7Dq$NW_FebwZ*=HQxyif`^b-ynb{H>q6Qff7=6V`QwCxe;4kQM`F zOk57IE8Jv(kDcA1Zo%L%I!wHwWCS)eJiS*vER;y(AVfx%2SXXAZO!H=IMh%^wRE0$ zWAl!bn}DE2nCaI##4(T^= zYRW5W;(@;mGqP>EJETXr)GUkg-=5yQ5F#O*3pkQK&~%DRW_lb_uljBzPgzWl4^GMq zth5R-0a(P;`BC>oB6iGh3V#7Y^#$UkvT_AsHfL{HT->}#Vs;|Y(=yVH;nS&UHrhXZ zXycCL7KCVG1Lg+jpoN>tN04`LUq+gNeaJkiNes8s^n|!eh+mGJy6iKJ3$a|POZ8qd zm%(@mi%1RE^vfZixjvN>x(yW1p#j(wL{xO+#>V8Ox4V#*7Sfa|UtHIeEq+J>gg>qq zMFdN&fMG?5lM<;_9Wqu&gIQ+XyVW9$^-MFCXhkZFOTrlSA94tD6Im&vLGlZNfj_BQ z0L;0Ba3#yjtxq&?rH7FDG9H%_iw4B`r#D8Mu0lSeNzy$R_DrZ3<|1~OvI1^$N>BVo zqpINkx9UT(Xt99{luw=k4P_rN`~l?%6g!{Pika0^Ek}USDc{%nhx~2*vf=2wM_guR z>k3<5dm6A15?RbhPZTGEMqm%Vi0Lx6R+~~F>D>C<#)V=ehwa_37@x8J*yQNiP#iLX z_-C(z5&i+yO9aQEbI~Xkwsy4+Y-|yocGQqORn;2G_3KYqK*EZOG%wbSQuROIO^os2 zp(YW_KnXuP*59LXM?SmiCndAmRBCi$5;HCzhY|yb5HQ*5d@pFrV#>(d7<4`9;?_jF zLErEv!D*E}N`ZpH5FhfaX-SDivci7QLt+u-1!AH0RZ{}CR>mIx<~sBni^0p3vxw|4 z29rqNcm=T}GaKrzv~21Ri%QN|Ws?!F=}H+PgFwu=5I!>S0I*@m(#JqZ z!o-ig%SpUO8G~!ckbzjFFyxZn=2< za~n^V@ib}1MzUb}Stc?UfHBk-K&>GwVueYoQ@SgJKvW27IsF#>r|sSN_SP_3)(XNQ zV*6s(7bbnP&n zEFB><3o%1|!InfY$?!)0t4(v+e%QDprY;Fo>mu6UClh%59sMrQu%s5=NZSJzUIiDT z7|sqe02u0`f82?U3o*HwWWZOMAdh!4B#)`f-BXrP1fs8{WP3#PK})LueIQU0{WN{w zs5ZM1ie))7=A>X}uPg@|a2sH<{IZgH@&ONT-jI>^9vDU7 zB}CL`G@!`S*ifr{9+sCi0TkJZaYXZBLIER{jN3`L|?xOhzU$ zu<8kKf)cJS)xD-K3*HAnHX9k%e_jLgtGiSfB31nIVr#HH8qZCt1PF*$glbCOsLa3A z!`M7R2}=;2KW}IxfR~&GYj_)Ww?LXq5%E$6a{H<@C6}&HmlH$rKk3jj&jy4Z96Fp3 znhk;hAb`q>)(tW^*g3W+f!WK#S}^lMU33;qX=p1r)?^QMyVgRb75}gHE-X8AK;^L*zE8CZ!OBD)}Kv& zYx4EgDS*3A2iU3lr%o!~n#zA_pK2=L1x^^8=wCH;dH?kOZ10BNg{_-<$Mz<>pX{E| z+M_$yUg+G|d2?}d>$uJnJJan?x6drEE_3eSvuCPv2Xp4&e~Skwih5o6P~nCp%e0L8 zh|E~D54I2~Sdh?f1xB-`DuIRIjOFuv(vrL~JM+Rb8W&;@@nQnNOd%1?;`Kza5J7fpqM%6IsA7LwT!mjIBFP)W zE0(L4G*rqpFk{?N^y{f>_HBH9d_pV)xrX*7f}1d&UR;%cM1kY?5@T4*Tprdaa7hzn zhQH2lOue<+xKLWV6-xkK8Wg1t&NxZPOA`i-j)9WpRI)OQgX+`T)T3$F;&Y~6*--Ma zA;<_ZGJ}H{@BJ!`h;g2q1mVev4>0q_^4lt{T&%L^rK4eCt+iL(d61N>zW}4+tH6(G z@Kg%WzCDUO1ITBUsb5(y$c$HnSC9e{GVTHf zRxC4!qnm)IiG!va7XnMY1C&OBn2IviUMW07Y$PN^U>quJX+c1U6dT&KWTrC9YVhZ$ zHZK%2t}H-b$-G%PO)aAYP*i;%fseP~+D%>39>8d=J%lJb}v>_)`7lt%`LFfOR!-#C3E zxO#V7B3w)A1x|Hn0Q6gJO*Wtf=xHF3HLXd6ke>-2nax9HiUJ`1*#2T@nq;DVGMY-6 zQc!&J?SmE?k7k+&;+t>6mlsRq%^Y}2LC;hhalp2Rf8zAZ*c>$}d#WX~Wa*B*pkXXR z?j%XY34vS({X{|B5hk-T_wb=A@dXaz5*F1^7tqnj+_cMVb&qM#H!KNW3)%$(U}i%o zHNE&u0a`9#Hnq!k`qfbtE*6go7%ad*!W-+|pYGpyG_gggh}4r^p&FS7eXAs z3;-KFM0MD?_<+V8ksv|)%I~9MV%?zE(j#K%QzE2C#XTv$Vw+EEl*{AJ;uV>1{rCxu z3t1Z(q?K|&SrXPU)hsxU8#6M5dSx5e^0F)h9`zouB@8^FmN_8kH0OF$PeS zH-f!o4t0D$+^3cXw<{7IZRubIHe#*=j@)3|D4)+Fy!YE75jLV)Size$9nM ze`DMPHI1S&XuJ@@2}WUV{TaVnM}EC0lq3r+NLv-5K1C@8dNaL1@rrL>RDO{bfp6J7 zHXnd&ZnM35ZS%n(E1k=ViTG)`4;0!0N$@^PLUs)*E#ZOl3IGPXeRnm2TOPmW^2QCN zTSJPG%-E`8&9VZ`8Ob5IsT+gay<`QZHV{qB>DS^;;XT_J{C;!mQ~l zvk7yY6Ka7BHcKl5ECbq0E9xFO0_b0z?`$8}c(UleQmrNj0-_!dCL6k4%>@%$(ZWJ(cj#0ngIimc zF0VPW-q>-&skPygQXJ}}v`R5t)D&=pjhk_tXAww(3ed@3R0J7$D2{WuC)rn^FgL z+g|{;(pv%I?WmT#W4>VsUO{C4is-?Rers3j)Mqs>gsDr@im62DCqVquAgIaEJJ3QG zjiFQ=6l;y&3>f6fqpr3^o@ZIY&sg;gWx~BNQ7kR=KE8IaqH?#86umY5 zuhw8hu^`V()s~$NJ>a*;Dwx8m)nOlQRcW0_>1!~ zj_$Ne30WR^ack@acdu^JeMymPAC~=#X3v$mU8B&-|&F?LJFC5 zhcWMF^f_^c1PCH#GAx*%)63M!8X_?yapZHUlF${u!P3)Dt-JPY&NN(ubPN-$=<)OL zZp0mHvuCyh9@Zyk38R^+Wc*C zpzlX4Y2n^0RDYzc44tP}Cq#$ENAZpG0Cy%u0B!n+LEz1)&%B|L8u3{$6ygAiu?oYh zb2ljY=s55nSCI5VuFOytSPk`tqr!$m!P^aY63`1gb113yExzjL0Wva_A=l{Ru|JF~ z&{U!3;i$=YnDiQXlZ*3HH$R&n;M+y-=l2`$p6cAd8_L#&ttX^6p!=Zd*G@lnx}3VK zeR|Fe&>gVj2)ME{-kvS5ns{#KdlL^RXUDG%OE4J39nk(n`~l_ZgYR}O7@RkA;^3(M z$7U|w=@%$&=$+p=rZv$!x^+WutUSG(EiSy{JizYvPg}K?tJ+!sb8>`iPwq5a7&^2G zfI;8HMy9HnJ7Jk)(8UR>H2(I9gvHAn>2bD3sLt=CyK~~_Ws4M4= zG8|v#(bcUy##lr0@Ti_oZdoofbhF6gq`f3ks}6%f3t`4XL{EKjSWV_-aXiZ|)Knt}=CgY|kO<BigwgWQ1CY zb;tya3`2};0yDAkv<^9}zK{;dgj88o?*#5%kD?p~7N~S2Wbr!(4rGWz<|PnI6<4vY z;|=F#rhi#q2%V<~ij&iXANL))h-S;|fSk z%1fd(OOvLpDF)I^;H5yx(k-6DcQ)foa4=|{931nX+rm^x@AFGzxBhYChBO365fm2G zbv{`JDG218*etY2W;&d}DeJIch*KCGb(l}dA~*KsJsTH7*BI$Vyz@}0h;{mV-8q3i zvW_$wGbUgOcwI<=D z(;{O-W@m)8eJL7~c~3Sn(a(davU8FVZ9yVVA%TulmRqJ1+gA&LnHS{I+yyx;JcwdR z9SkLNbPIRs!RIQmUXfk$lI^dIKbgJOsDEfov;^;WuHpKsie#qX!An;Zb4wvl!8imLly zKkP3srGyTBKhONm81R6z(SjsMN?dQM~;q zkV>Qk%xp^ZOXpR?+C7g}*>tN~*doNd2pa-ONE}2r;6n@$H#2e2s}p^Bi9H=cWn;Os zaeU*BvaEsE)Cx@H9Cs+36mkNm5D&9h));GcH=^nF8sJ^T1v%giA3J8;>cWz z9AyC@s({m;NAz?zVf2;oJZy7w5s`@8Yz8c$<^{xWg;}JM| z6%A=El`4=7ruVG0|9q}-p>!n(kk~4*I1Mh2FcT`Ej>^Q7c{wt%WT;Hp|Ra zpiJ@d<=@ML@@nTfw~N_vW>jV?%hfC&sDe{3=q@S+5!APku48e6Kzw|%DEA42 z&s^_&AKeYT^Nu2fVJ^gsbj^G5=_Ntch=w_fK)WDjJnsek2y2IpBAh~m9`BUqb+DIW zWSoMe0RtYmG#H2EMSITFLqnS22yL8tuf*#NniSJRpe;UPILIjX;|oz&Q~-P}eu$E% zG>qAc`$9%g%4e*SF&F3!Q`0djIjn>Smd3)h@p@pbBB7{oTvVK9>&f=; zzm!?oYzV0wBLoDbZD-eVc|;RJM9xaTQ^tzpZ^R<3m?e}sIFu+x4lJF4*u)9xTD=0> z=;=?7c<*m6Z`_gM$UX2MgY7|_@(!UcinIM9zF|saH+q0H0}YTyp<7;S(Y$lSFBHS3aF>!PS&QFbW2<}S(CAQIhku1KL^ltOpxV=Fpw!ywobZQXyMy=C1SAm( ziOA=TnqxS>)PBo8jSDd{Fw%()YDIc?MtU)hSmA1Ufmsdij15SzYKY2wAy%o}mA2sa zqi=U1vqg>`2h*1V8_hPm-E&~8>70D{Oc4+U2a z&hWwK3=n@EPX;e%#u>^i{;I9cKMgy=^3_;I1b0tOrQA_L#8~hTL6)?l6whQ{&RL>c z4lqczwimTXt@YmAz(%Nqm^&0R2z?`!!r;eOV^QD^9DXDy8NX1qHXhW ztZM#mmY-OT-RRzPv##1%Uy1&+UA{PE-6u@8?uuRLJp**j+i42~G|`XA|^JpGOS z16$+0Ys=Gm=k|{5^}8RPxvcyA?taA$o$q$e>l~F61KOvw_itU-I=^+y4#RNAS%8rh zKq!NKku4rVElJrHT!2u8RSvc#aOpKSqFAFai!cxj1O&~z86SN{lg6b7-uhj+th6t2_DKN?g z5;&n{>dGMp>s_P#5L{RhcGpl;qN?PpUJH~68aJFrP3L`~8)Pzz-S&fbX*E+9zr69T zsh^$=uJPz-7a3e^g}-538j3iAMo@PVl0jyAx%V%C$Dz^vQm1}0)Rws%z*XExGNxz; zFH#UN`3zan6#a~^jsO=p0_5z0%yijWm^l4?jSC5Cu#_|=`@&l=7BN9{PWpi>KNOoA z`>9})Kasio)CmR-Zk_Hu4{Tn@%s~ab-%(&E9pE@QG~^rJ0V7f4=Z`y2v?9ivZ>13t zKPnk7j(zPB%?qKPpc(IkP=bktYeQ4yE^>_?yua=G?Q?hMUr%%@u)G~=FamyJuP-a@R>Sjl<5*gNd5K> zXA+0G)LD&z$e2umuTWtT$1G!TBgmeb!448B5K60SolCE*?+B!4ZnhBsrJR?k9x%g4 z<);KNfPcq}kpm6GpnJ`3p0F<{__MveN8F7)%fjXz8h#-OBE&P7$6r7Qr}-GI1dFl| zF_yu%9CF(}n{b&ECN_KT_?5;T5hi17@s&lMnAO=zH9nj04fJ8@tZwBy!G6gsV3*+O zfKt@y3)`)8KH9vHhze`zlG1t~6S-LdGCjV~7Z;7hH_jQj6WY$ye+&_)ZWVsV?%jMe zPHfjh#OnR+6}eAjL`1YN!Dg zWh{H%PsOxF#1Eq36OE!=g*R?!(32BHozQ>$UX4dnNmG$nB?MM@P!>kFV+G8su<*Ph zkHax7RB^MLZGcIUgzf5;jqdzVILRIP=26?7VkA6}k1ccQ#PZUS!7-Rgv{o9sG9HwR z5~@y596oVjbK;xB9?@I~p@Vx2J*J=yBE~_+7=(P~W^to&;A0!pISA!poa~O!UWPdy z_6Lne<7?I;!Bdclr&L7TF?g(=js4LVV-taE>2KDdooDiH#ySb%n~USe-qN^`B2d&| zw+4@tRa>My07|CynvGS*PVrJ@mT$5Ok+bUF#i65O#}52d<3eZ|im(9h-!Wmzlp#1( zAE}d-a@uoM%Y^kb>MJiiIo+7#y)`%SjYl>wq^O7Rqw&&5eHwHZ6Rrprzb$SY6NOdG zDI(0BcD7x}j3H)jbWeS5^FkC?AW$90Lts{v9cAVs zB21>URaj>f^E6Z~I%7K9h(UfL`kqXUk3(}s0zl|_y2-1)*}M>x#qWi)OjSW1w?Hsz zR&K~DHKf4r-Fr7_^2MnkbwUtH{=Kos)fd7!DP^oVu4J@mxY{&1Nk*AZ;XjtR_brIb z>h3gaJz+(qhU8xvKj7XqhJb+iU`XJ=Kg5gc7BaCUnA)&N9>L;ItB`7*QCF;iaJlL+ z-htnrM=YyvM4+Xqjon<>F?}igRO~3`>gdh1f-Wrget5#|F62w` z5+HWeS_BAqBD)Jkp)AsgDs3w!2q_+$fhK1l8QmdC%uPK1E6oc5pO{|;4pM}s4sjJw z1RGKW7*CV~?NdkMd@BVN2oRC%x2476bsuP6NGl2zOWcM-7|J3;S|r{XXc94`DM+!&&=<-z9m=giEr9urH${1KKR6;Nu65YZIuZ~btK9PjB zHhK>nPD2-tP`kKqz2?5FX1^Q{B+v==0vP-cY!i_{Cqeg|d-O<}=1VTvpZc49Ap4?s^d)j*&uSg_IpPrf8QYFn; zjKmjykrd>vs{Lqow)6gB4`*JHbQ3x)hj}Unv6=i4=py1tTwwNXTAtH2o|c&` zZJEH#T6u21|AX^XQ5hJY3t2WQ4=<7@oORTzV!2~-hd%ME8q0w|_>82CuFLv&AvFd4 zY;*ECAFJO{rpGBjpibi#G-(plbOzFp5G|GY(=aFF{$UIFG2n}yM_g7L%`JCcJt7pK zBco9Knhj*-ileBvxKdTm)YeSXGY*H6eOUwev8Kpb2pf43af?6-Rh$DFtwL3w zN>1k0t}2&UAO>JV0bUd7Wn<>ByN~opZ(H~R)5U* z-Z|g7ffuy<5A0prI(quB!4Wf;w#Ft8AMbXbKXJv><>iAq*L6SI>rXtV{CMZ+&RF~7 z)2+$&;El!iy8Amv@P6f~#RaYN#~;@_clw*{Qzu_H{`xQl?FUVr)cW4cvwKI5e{1rZ z9nN6vc@z6~&Y#+6`kXt;1PouAY6XGst3m19h_|vfdXHF zU{lUVyYg%TNawFVSYHSp(>Vh-DkZ%MUjqpU9H=iM6snk6hO~T{V`O7^ zYDvC^nn-G}(3sZyos=V{4r1XaUNeB<$ z=15l1Hg;t-F0uxBO0Ud@VBggx5D#Mjqd^uS9YB%RU+vvLxj2N!(DIRW#Ax3eHN~B% z2^h+DFD69-C87G{P~s9Z0j#6YAY0mKu}`k;dF}`?*|ljUM4zh7(^6zxq zByI*vr`6ky=V)u;Ak!@4F6w@Mau|F)S_T}6+HoK$-vlG8TO|h2_;6f6HeMCVuCtdEti8}G~rVdcs&g2Pz+M~04l^o z_Zg=*E<}vB2-P+*qst45FDZ!~JUy9VUW}RZUj-7ir=}6dd1a&Vt!{KTh7%pU>z#?X z-U}e$(Ty447$GQ;PRXb`;60=|+T2|Aq4Z1?H?TkHK zaJWQ2Z<9y>RNye}{;O}=yW4~7I|BR-PpaktdXUIuyj)>eE2AKRQB~lX+!p&u+D}wM znI=V`+$z2{oW<=OvFuwx{JZX)cp@z+(=yjW^S-GBA!F=i!3V!+*i3Z5oY`m0(Ar%4 zU+0{?TVXg0J0tB#EyPKbqE=WX5Begsu&rTof*J*dVl0mO$7fR;@I0x>!PN2>kFFn0 z2O>FJg90WMD)n&~lX8}{cP50ZmO%H)1J8eJ&(hE{*UUEDS|~4U1b>l^g^L>oX4mH+ zBC;rj3=xgeYGF-gP`&`EL4hs6z6U;eCxnUO8#mT>M1UjOWsrKbEfs}?Y(HvFz>k>t zC@`2hlC}vpkg7K%t@$2Se|PUc|D?W|*js@=ZZi?V!g1}q`?%;(RLak}{?cF8k0z-{D6uvO#~eJ$ikSXl z4^(y`TTH-{S}|Z^Lac8oI6^H#2A!|mxsGf8sMipClDB}{i@964B^dw=x`uPgpQVr% zN7W+m0OL?+kT|=#H+`hOA*!`RhSpG_q}NI+;_?f(Vl`87>}Gx^);lOx?5C#5>%OHH z#m(+@BPGw~_iBY#!kzQ)i1cynb7|;|;Qm2L?7R`)l~6F45bS_O4^&%P-LJp0z9VP` z>!Ax#K-ak8s}Wg5E_|l^MI=@e5K+XQ z9FG#IUYAsMlN5qM1tX*)tspV=82>920Xi$iKMozeqKM#$AX6tYpk-Pq5+WMArR$%P z{)~oF&!vNnXCQSRgMF3M8NNH8JEDHH7*nAy%BxT7sn99mw?ojwGw`xHN{0`io0-5~ z5h{qtoKy4G+Q*N|C3gh#DRD)5#R4}>wl4e#$Ha=D`bqUfPu6uO_)7pB#<QQy(X}FG%-Z==OiNel$6Ye@(Ab z-bkAE#V}45jHrSziCZ|r3fm3z;d`SD(o>DLDj5{S83WNeYH7Z2A0@L^u z?VGT%#RW54=oTZ~qCAiCYN>8*b$<1$A62vrLw2Me03Rixuq9hzLHw-1Z)rxux3w4? z7J1M)hPW04<{VMW-M7(M`BCH1@NtS?YhL9L?oiJUtO)xBd02xoR0zHJ*u8mjkb6=` zXL3pR*B(}1D7#bBR0;&j4!1Gx4T}W732HcF!NB)X{>t|B$gD&wK*eN_v_CRp6Z84u z9H=nh81)@aBFKuCAU8tpu{ipsY2%|!Aq{|4o-Y3OxsBe`T75^ZuC`9*Q3osfF-rmh zk_P*ZG8A-mB({5}r(gi#NBj(YxTf`i?T;isd$XWu@JV5GD?>oob-7>EdeyJlLigUIU4- zJvN9eNKoppHfoxTL$Fm@>F73b`9)_VNub7{2Ny8G3#}8*Qcs+Z1xL7P=KsZ|-Vgu9 zf=uIWFl~5M)dkka`k-{mO56`TR_Z7WfryY!pwM3bT|b%am?FyW zz*F30ST2AIU0w~$b+AXKk5g+QG3~SVvfb&isj90h?K7T*2iUXdoqTa?{0GH+aaCFL z@BFQq56(Pw=5EtpoPOc-;?xaO=an=4W2YWJ`Ju_DPu^qVOA{~Y|7c=u{KE00xdSdA zd*;}048AgW>0oWD>|az|)gSae+&igvpYGSXujn4w`B~?Z&hh30e4>4Fd!N?VTd!_C zqWpPzNqNE@j~r6mV7<^d)PvWLm95J5SjW zOBFQR+WQ4X>#Rd}e=Eui$SDulLK03ja7R8)6A$BQ5|f!-k$=SngU6{6a1t>i&K+6! zSH_Fpe)|ru1&UD^V(*h@r7Hzm?B_W@B6F@Ft#n3b9-zn|TthgVJvm<`wCzDx7rmL` zh%)O2s^_w*TBJn_drAzkB%}Nav#JTPBJDe1PbNoTgAG%#wT+HgYdz>qMdu~|zI!3X zVo87U_c0eHwa{!d5X)wG1PMgcfGogbTMO5|qc$=Spi0zlYun}5?oo91Jg&YN&pk#X zM-+;;LMse`=5qoOWmHVfa1Kk>K2p;7r>fC(<-xsV_}2IriuTRN3@>Juh*=!eJvalU z!JU^17cMbQaSuMW)u%dnP-wxlu{g7Q9dY7}#*a*cZ z(5X0+t5t&4StUwTGRV$#%EVt|Nf#kSg$Vzzrw#DJ{`h3)4~RRYkMK53L!cyQ<|Dx4VA~B zAex~sL1!MurSh@gExM=QI(lV<*J$C`vUphhybns=X2byea&DLCn`s9jvT3uZGbN(8 z>%zOXPu#!g9yP>sF+o-JAdH&v6riXDPBXAJsl>JdSY}#ax_ap&-lifyDFEQ-8EmEM&(T#jbt15;txAAI)#$+*SD-ujMHy(J%27TLYzukH#+$Rh{?wxN*TYWV zu;fg?1_|Kv7zx2PK1Rqnlgkus#7XEKc0~?m&}wx`je+#B53g;N3s)5VV{aMV7rlZ@ z36w!_qy<96F@b}DfkJFr4xE9uRe8fj`g7qS{s{k_)~=)dX?H3*-*}&E#mESW`?`>_ zrAY!#e;qFfAZN;vzYnWO6;QD)X~D&|q+bMU!=y-lD86`c(K+}Xqg4TM0lRXt4Z;T$ zJ}@S0OtJjzcJbAGG}4c`d$1@Ytbd70Ci5)qDi8XFq;b6k8FXW%R*sA; zEaXk3CLTRJEJ=&>g0R4ir0`af7*$ce@PMNI#7B-^m?ll44BQJZhHJ!H(uLR%y&0eZ z?*!Q5RJlRY7!d(Wa*SZl@OAouMSo^E(E_I%8ZFIKf`ol-n3WMN4A4eZ3$8k1_evPGap zkBYZoEh2use9YNJ>m_FoACkbC-W(K`9cRj)eg(=OXu}H4MN#$3APO@cLlvo%U|WcT z*Fgqalb^9~(Yw=7ik1s}Ar5FjC<-7#9HSk1R%W-?c@bktw4u_%jhZpdi6U>XpW1SE zySVISMeC{ycDL~QlS+9Z!;s!wx9be zMR~%o#%6u5G*%fV-T*Ix`p5u56_h_RiIRCN6Cl#ik5xjUWzI=vHd}5Bt?BEE{_!sv zy?xmlMXRnwg|JG-+<{NX9P>17i_m5YNP;oSt9%nA;9LuY<#T<$^~9~Bd-o%TZyz^j zslr9+*F^cVxhd8GTNzr#}|4_9M!K*Cj}b z>#}yD3?q>!3I5|Db6Yqc=p9H@`A5o2dnSUh`1_-Z&V4>NdP;vtMO-NkP$OCtkf2B4 zw*82pze%xi`mL>C@CDnn*yA+{psJ6};?|X-b<269r&N-VYSo_1jf#Ebl0PflQAUlE z@Iq0rrXeJUW8n~~7y_s|H@CQY!kIAiczf_>MxeZ&GW}Z}IBp>?~xD z3Y-VlDK6!HuK+0@KYIP?X&1$lkGw4m61^HwK{98Up&~}RFM``cviN2Ai32f0h~tkJ zS6aPWi=y+DPmCUu_$PIdnXw%vWhmYOGLnQYTofpd0Vqwr%ACHm4Oz(Plc_kA&HFv1 zXubc?(YCCbvVnCknjuk5q7b5m;&jvFL(tQP;C1m5tDtO0>qDo8Wrth4%icxzm&NcQ z)50BB4`vLDrf|1beN+{*PeL^V2_O#Drz#K2Adf3-VoeKsJXda?QuLo*Uren=s!?fb z;zHTF32OlgMQ$^PrB_iPbtDa<0N0Xf_x5dwbUARPb*F=h?wP~(=qM1RQfVgm$oiBd z5g4i!f~sani3PhDe5eVZKog7{;pl}a<7qGYZ6gtKnhWUSvbVy(`$Z1M47fcd zWpy}E=I>e;{Hu!8rPcCt*A%UnA7@ciDLlOurjE#m)E7~ULrC)^5sg-?!pq4Tq+l%s;n?_$Uh$j8YDq@g8%0|Z7f(S_n*_O6Qi69Z3)A^<- zu>Zvu7#3Gj-t|jG@#SGR5)_!jV|W%pE48aFz_pJ}wURj8;Xyo*d-L&Z0rtF#FkmTH zjw0{NfB!ijGkZm;y2M?!Evw1Mxftq`50h9k=doz(N8M63xnYfw}~wP z>_fc4P`tReVJ+a=_*$}PqJ@g8QYd-e_a*#RnvRlZY4OnQqI3EE>TB8DCK*M(gbC1V za=*@UL`81YI>313xEfy=U*H}y6*xXOFL~kYwW4$62v}#HwG3@Jk$i|^QmXXt1ya{y zq^cB(SaRXeIKh&X=%~)?5VY6Im+gxOxOl{kdZB#KBbm)BP9p7kfYG{aNq0 z-X87Gb+7K8)m`e`+<9wb&fnqF?WrrKp3^yD>H(AAnLKy$sL8>^$0tsmc+mLu<8K;2 zwzKE>*YZo{AC(6d|607~zft4g?vEZa{KRU_ zkh&Vna|+NpPlgcW*`he$Q5BF`odO6x4&NMo7DFcD`?CwXiYu1u3kh7}o-@Q5LbZFb z`XW!9OqA1aea+w~!>>6h4QiXlY`_G5~#JsvQv$3l);l$ z;>$GLK-)OVndp~BAS$wu{=_FXZb+9<=pd<4F%g~I^U%m#i5mi48*t+TWB9uKK`_@Mu1WW;8*G>dzKByINd1Y#PgjtYY2>Ni8$cl;26xV!Kf? zR1nIlyA`&Od6~FJQv*&j<^U#KI^)#FlOZKw?;Lk7@6g%(6y(UMgf6ZseV9vW=jJkt zS;wI-VvD0T7mBz2qP`G`0^fo-V8|yH66-U%72ef~hN@1#x9uI$i5VI|VDeCD;UnF2 z@zaAF7lMj1jY;FCgiR6*=@7$GynbqWNZ-$ByAwt->IkfjB+D%@x&{It+W|idm`XCU z(~{Q-L8*~aFwpYz#1upIY|bVWAkj)1Y?szsXFYv%A*M}VGeoog3huqsoftE=WabGA zoh%F8>52BKAw1;>pQFW!6kFMBo%|2Ogh<5991|%fDsTp8!D!eCC^I|Ery&Yu46>W` z!O4vYS}dTx$ZYGkM=Xz#_0x_JXN*5k#Xcm02EF(j}Ac1O$euj z;(c{}$akf1_K#J}f;3)V$)+dJW6|0p=|LMD(=oAztMz0a3fX~d+$i60edE!*Ary^~ z8#L1lh=_R?PRHwJa1R|WZX@NLx(u2m*FYU{`d~(j^WI!v$Ql&%ef%_n2@Nq)^8^Dd z7z}|I5ei*!Mhe3cJxd#^lB*aMF;^Zp^p|)?Rg@z~+o=GRpN&)m^O);~O)&)>J%TNP zwiWe49x|Kyq0-x0EnXL5Wrsb=L~(qae+SYb(yXc=bZQ74K$a7-S!8srvaxftC`(cx zsvy}r%D*cc55{ko0RmMVHRQ{N5^QbX2)8=YQmbOw1UWekQx3^;qkzcBlk&h}2TdLf zs{xKs*4VCM4v?0BIL=9%H1%}mJL<}V5yRxl5dJ(pU0z!#zW?pf9YJr<6Os?&M#zLD zR*qQgzLrm5Vfzytx{9ZaS%%i^G#E@z>-uW>^7-b4GPfkn5#e+sj7;Vss8dYS5zY%> zAyt`$_cV-?r{tl49G92M7uV}rfruu7x9ly{@KHsisUi zWGhCc_2N@^uJ6cbK&YYWL(mBul2uftMpDXiz(m%L&mONI$SyrmtH^O2_Ns{TVgJy$ zkS2V&g|4OSNXG-*o7TUGaLP}MQAy~YIgRm3 zC5Fw>{gQEiFo;%L#H1pg?zwXJQLzD!*`_I8sIJxXsddsC$7y5yfX*rd^s&)_*Fh+X z)39v(#1`dh`LKJ8Hi+*_5SJ^`N0uQwf{Fd8`!+?lXkm+ZQuoG9XlX@ow!ly*D_g~f zYWCiBlwL;P&~T_O>JjVQHskx_OIEExXZrf&7aUz`2=U&xbzMzs#Y=Clzgfy8ZW3w3 zIU^+M2s{`;O@bWHXhGwP(A<_mlNNJCEZKo<8IF@Vgx^vMLxe_|#OlQumR`&7 zEt}80v~e9-hhRiHl^<=ejO)OnGx8DdGGHRZ(JRfuqmfoElUShADY>-A=Nk_uQHe96 zs9dGugyS>OAAh6Gm4aqb#CnlDrivDB5{!8rK&{o{<(Ch6hrk)pC;kC*-7{rQRFaXS z209(e(vH$+=i+8ku3~Ld`d0tH6*ama`^tM058)4CMv0cLFBp_*+gDaIBfE3xl-?i; z9#I0UV9^In*OyugFKk@My2DvRSUChe20r}02{@81LYC48bpUQW&_?GUURHbCI`SkIV{jOk;1DiL>4;4lzZF;ktoa#@hQu4fqhN;HR)&@Py{++Nan&$P#FeI&qm}Ob@)s!D%5s>hzd1DPcmvo4`5;t!y=uB5!kGI`ACN`m~Vy5ZTBD1 zcrs&b&=65Pq-Q8bEJFvdbY!4_?au*^qJ^sCP|T_f?^Tz(N3;Tiq% z{zf!Abz^JmKN^oF8>)6BDAcBMU-tpI)g$6IBR}C5a-b0;DDGesbL@Zs3DM0jw2p0L za{nkh*ZI7N13NpyRuY|WL~SKL!D~1I5}*vDIi9b9WMHtX;=6dwA@$dH^WGq1fYQpH z1IxPXtc|khtQzr>Te(Ak)ZvkdH7elNl{lzT({a zj(n&D{~Tcw(<7g>I$Ww_fAAWpLY6XK83NkzGDK7N-N@6Mo5iOd-MElalemX7@FG)s zvl%LA0ckrylCzvm&wwuFO&XiRTNS6H2Iaj}UN^LyS&wL7L}@H-Y0*?x%KwaY7;#*F z`r@Q|zCBhtmO`l1a=OFq$c4 zL_wNZC|-{F^2=w`7YaF_Zyi@pNLgcTwFi6C`c#w;$RA5b>jJ}p1&>+JQ6JjQX;<52 z@5PM^LFAT*CJrH8M`Rcr6(tHG2lN1E!2wW(4M9BgF*tKmL7*YF%8vvy@6>QCk51D7 zLE%4W89m76C>8jJgb50TCk&Fz0Y}lQtFsN$8YK<14ym&_7A_V??Q-Zr+)K=WnWlhR z5%C~Pc>o(!*;q5eGL5KGp^U+TSl+9#_al!834YhYq-sR-if0t)$)g7JXkDhpcxNd3 zOxTwWvmDo#Tb){77k%U9^EPrQ3a$_h8W*L&Y-I#22(wI|dP2g?aGi$xV!(<;puG6= zUQx_+mJvrY)sFX*%5A%|`7)=FoZ&Y&4{CTZ{+KXi??s|jfpVi_4d&O*IH&$*?6U@n z6Z-Xg`2!jX1-W1hFWT;dd}3&bfTZyQ%Y=Ff#i?s-Zlye~CIWb$5PC8YqjojB+`7gb zFw=?%Xvy3yUQC*in{`7}2u~n^Q1Q_(o^ITck58XXLm9*j5yV$U2e#rcn`t|Wy*vGl z%9U6Uv!)FSNyS^f`sa-cWki)r$vD=m`qVb(nOB;I+9rKKEAR{;mILoXVuUVMUTM`X ze{|*u?IOf8aM&~GfK{p}b!m~hckD6KIe6baVMb%CheGJ8Wa5&=39in+pphH@hq3=3 z#{Pd8`_yqm#(sIJb?~$5m=>F^oRT3SHW{>&8j#qI#7D)*K@7|!6M0TiW(oyol1b<0 zwF6BPwI3>;hzwX@ZqV__L?Cy_4jC3Ce#ixQYFpW9zb0UsifYf|_*LF2)b)d-V(*Tz zY2rkTqqVf(@;c$a5KHb1U!&p@ld6XH9LJ$y)(C_Q?eb&ESj!Dk%5`WnNmhWb?kQS| zM3&i+kel!qbt*GZ6{b1oR|9QYYjg&tKzY;U%^Omg%4B*6=)1|BnfwkI!nm2PpaQPw zWW5Gp4E&U-a!wXN#z2yFWTc=dw1imXy5GdClItLUc4_!bnWUOm%BO8zX<8jp9qR_I zV}7kwexPw7<(O=WtOKqE|3Fv#h9{G;WMieRyvtg_@IcDSU6>jno#=lkZhL3_WT38} zl6%<=(3aQ+VRiX_rwQ3yX&w-MFEY|HW(Vn!{OQN{ zH_)Z@J*o{>+cP4RvErFTNd*aZ)GxN!+WVr$4bd*VXzX*W_sA|t*o`0!RJ`VKV3N#I zNWUZMMM5#q4DyrJA;QNs>KN=C!X{>x%y^XPH(9WC6a@bhX0&cfE$BsrtuZ35Pae!r zFW$DrR`00B4e82D^#Wp%Y1yOz7{4XYd&8MfsuBRYW8}fs(j$Y^2?3dgx!;TG>!jcZ z&?jD6i^yjAo*y+Xlo@n6C4|RUg++_gTbqd&%DLFBG3yx& z7U++j%B&cFmNOtH#+3hYLE}QqmZ}c$j-UZD0X@*AGu^a<+xebR=N{?CY#+)Y{f#It z@1tzD7Ryr?ofmLREXCtvA2uK0ZROa><#Kmn?19A(2iLZaADlZlYB1LSgsK0h^$+M> z-@CAP?DT8LyT#jDcWR$iezrF?{n+lOx@WfD+BvQ~d-9yA%ch<^dDztb+DomQJA1UR z?%dS5XtFhN`NT;R`;32U{Pp9Hzr*GJ|KktV4~;|erS#2NOCU<7a{==^qdUD08(i=q z;CoVQAs{&oKS(9PqIGbiz(GBynFeDJq1H%fpPtqdQNe&6kxJ2%0d7ifbTcn%CX5hq z{Mu}5?(+JMOg}P0J>Fw>^S;-yfdIL`vQ(l^Yd~h~nREEw!HTFZG4^36TtLIs&|3 zL;>?Ri#7I~-_688raXFyaK+oIWtwWl9V|{SlyCU=#)ZNF;s#>UqrGsS=9C7Uk`r6C zMIu*_F)1R@vRbh-{!>o^lP#3n+JD#t4VJ6G={H1f77Mi+RbJ>YHW9Ma6iNN%1d72A zGs4QMoCH2GdVFvTtL4Vm>pK#Lgni~OX_9jdlaSVa@ls_>da~U_;W%ci$ylZuD}*va zHDq16>no!RWv;SFu1Y}0seY5mlt+9-#5^HX$D2+pd5P1RTS6P9CJne-3%jp&=d0=q zDOb~qmVusJaG&VBUnw#)zA9$m;SsAL3A;m8|~ ze@w9VR_PhheAUL8vYPe-F zysi`kvoA*4(NV&FxLREJfI0?a2Y7Y?0CZ7Y?P-`7tmrkFX$#;ewYBp~3Y>+E)wT`m zgoQ-9deCqrL!L~IG#(C2utgBBiX8qyKO85E%Eybx4zW#|wu{Toyk^1NZ-FZ1#19%z zroTZ8Ol2WO7~q;|Tgly~57U2$)KPVGVT6_l*zq;AAYjmDca`_QZFC`Kcf}ufpskQ$ zg4C^apu%jTKzbHUYqE?{ceq(Q+7noh^gL zfKgJvc25^evq01grd1h7LALc<4V#of)d)GWue3z?R1%OG1}-Ikq={akCJR7}niXSm zacj8$*bK$N;w@LWq1~KBKxTUB9Ft2Q2TRjZs85kOJBu(QHnJJCJz^vktg*v|=p&*R z?|y9khM3wIB27MJej_0O!?GWx7`a9_>dl2-gSBbX23*om*k0^TY2z5HExJ_0~y1iZ0@kMrqZyN zlBEb@$uWU(2QXM>3>KS<_?IZhQn9jKTs3H32qM>3T1_hOj*+aM3atS4W=;%_Eu2PX z7IA%vLN>^bLvd}n`0$hK3x(_QRW1FR=GP{<|e20gQ37^r53B>-Q=+aN981kCs>K8LqJ*JR-|Fm%(;l?Vm zg>(~ILcCfk0bd$L>mdjLN@u2)vt+j@vPxQt)vfmS-wi&t6=1}Eh=B1LBjvytM%(bos?~{ z`v>VgPv^5WwY^$C`i~oLT2-V1$gJ`la$vYTT2J#ch?u?x%5sPr5;{p19MC%siHUw- z?`CmJL&MD`#_!P55vSwH~w*K}#(MP=qxPmF19@ zpbSo+h_c2sElEbvPZ1SUQU1#THT}9pj9)01ro2oFMo~DT_B{XYQDP9$jBNdN)5- zs-geCJGg2AB(v5c`ife{E5P?SEs?}0khin~FigY{hL_GzN~;@x#^P#}$@Y5lgd08C z?f^nflyszhzJi$BVs^(CL#i2wU{jLRGP_V5iU17@oDw~4GrZHMkLJ)-IOOSnpIHh8vla`L%`fm(8J1@}6mtek zTB1UofEKOMUV+5rVJx>*2{-iA!@KIu1aW zwu1S_BcENrkQHc{qb75x)r%nnKwHEJ}lsd3u;#R_B_JsNWIZ z)7y}$+0)}X!Pa701N8K~SYxsW2?K$TH_Y)xDxMfhvwa$Gs@PFsOJ(jlnV^{hhZf@z zVH3!wuceN=F3Ro z8gt@H!FuC_aieH_2}*Ua*67||Jz6rD(2)PP1>kYH{Ye za`J&V`%{yl5Kv_*Pve#AsuwgEGI@w*DW_}^-NCe<7?G_91|3C;xnp4HQnUZ~$)h1J z;Cd?%ic;*;57|fccENQ*KuEGEPS&MYk5D2&Dq_57Ihnof9k(bYzq04^|JQ_w>W-LN zemXMLPfdj+0rPhQ)Z|y;79ghV=vrh6P3s{hhZt5K0cY5AI*WNvloPhd_Il%_JMjR& zR&;-GD_6HvvoHRJFe@p+u{uA48D{eOx;4ZDJTQ6#@G}fB`)coJgW12tT z_*CQc|CjRqzvYkid{Ut@rXS0b`je&)SxK3PassxQRC(Ug1kRgIbyT=X(wQ7WZ6?pK ziah>+>Ozz&Ws!DU6(k3N5U9O7bAg0^6$_7t9S8FeiAv*{$mf&6AuicGd@SQeFe02` z<4{4q64M`HS!@KGfp6Q`uZg=P3SNvJFe(PtUPoo_EES)ht?mdrB6Nai;7R~ibZDVA zLOt1+aF%hvs9tBRA`&9vO35&GM8w9?r&kwZ2h71gsVr30Kq~Gl8XhiL@1}GrSz0`ovsh zT!J7fR-C$T?S^nZ?D8>O`rT~voV3W(w9=ugmHjcMD&~lQWHY!5{MPH|osxq;G^P}C zLx@iyrld(SJWSA(mQ=J7Ci#t0nFd`Th}VM|OaFl8CvZkiTW@^ng|#O`pNAX`p%N27 zoOZrnK(T|wd{E;7;{HlkWQc@J1oc8uq;ngO{805|IXK;jlYCj(5xPNE(;4*;qeIOo zKv@9!R8@YyOpMaF6}!2E2p4A?7yhr>h0?0UT^~#XUaNz&!J2fZOIE25Dp=KO2=i!E z3ff*^)=Y9WbZK*``PhqV7xD`r@EjVTkW*)aA#$2em2%U7dJx5-KLBHz^ko=iQD&vV zPz%ME$BsqsI&YLeM6SnS~HB?sSmH=d1Y}jfShY1hI&9Jt~cbX zudlG=ZE>mi=Ja;31S!pAbETO=Q7Bc837#vP&4*5=y~}A@vb+iq5CMYYAuYpM=}?5@ z(D?WjE<~RXhtGnB{VKbeebxEd=6%nt-n8vuD>H(mDISr}&a%YB#dV#);f{1DCb@A= z$CrYi(T8SzN$jhQJI5rDH-z~&e<=kUhnwI5So%hMVeS!4mSHTWAD5Ssp<-uhMIL@jKOpEQbU%fM1}XcBF+ygr}nAIBHwia%2U` zNek!{!5x&9KJDs_wZ<1NsV)?A7jKQA$1Ir+e-#odN+{zDRKzRU#vVE+tE6>?9SYXd z2B?#{QJvH2)`4B6BW&(?3dTP>Nn3}{o%0_s6>1iMSXNKxI&Ftd9}A}S11M~K_>nWp zL2$?C&zPy$|5Q5E8tdE?3r+_7oB2V!^9m2JHA6?3dG&V51u(gR_T06N%imQ!n!_8# ziVU4pYiANZ5076g4KNVEu0~e611u%sFh*L_zF-b%io3D#{*PDD5h)@1MS{Z30wu_G z-z^JRVnJx&^~4V?I6QCI0(o|K9}|IP;Wu__*O6D`!Wi!}>mzfojFu4n><5KK_B^+Q zc#_7xI4NW_8Psso_09I!Es+o+YH&{}2w9Vuv@*xQgQ+Fu+45*RQUK*Zwt@v1hP9^d z9vwEfSiEa&>vSQSl+u-cgbcL}r9*vx2-2MWV>S^cUN1$=sx}T}poZt{!sBa=oqft% zYi}B%9t97k_O31KydXKn`mzLs zE)7f6K-3wSjDse{BK}<2zq5HzvqpW&!rr@n!a@Dpqgc$+@%#C$gm`|qs8#4}=mn#Q z8duB92H+$#kDn5n)S2ltD8BHl>YFKt;*m~&hU~9gl#9J;*8ZGHXYO!3oN*Xxn#6#i zJ`mjqL4NA(7meEqy%Bi|4T=;MoHhH)&f=w)YhlKA!U*XJKla7dH#0&p<(p1H zg%{cgWkai$FHpdug|ZAJK%FD=6l8#*RqD<%^JlGb+U2ziu`OAPgkax26K5qF6KW%3l&K8JM%Ga64dqk~)tnM6*gy~H zxbx1thGBKxASkkofwTxF`8;S~VZb0~U|Bt_&&c#|uqd9*vI?fA6yF>7ZstP5Gj1f# zSo|h-#G=M3c+0@8e~C$;>c@8p6-buKN(iUy%UEi>;KkK)jLAxCzqbNEm;5a!05V2# zB$ayien2VU`}-WY2fazCD>bG)y*)X0#0{l1$W&5T4JRTFEm2ax61?#3n-*W#WsJYkA7%a+vI`1BItk$5{4DrmHU;xKH)*t$C`J zykWs9EHS?h(PFJSI*0<-3d&Io7#E?=rF9kv`+6#r z4M2eQLTLp=ACo?L-@E?i}wUf#qXhZ6dw`|Ky+)B(~Ggf^d+bsx8 zs9mi?aK3TWxXsOKjNdU596?dABgB`pJ|k}8cs?9QoIA_jy8045#DD;~ruDo-OJP7AzgGi^NTbK?tXf_Klh6l%@) zu+z0P=L9$y!Nh2$82c#$RES7yoXUsTOS6%!qxs_Yhu{J3RkYvtjr0X9G)^7&1zcC2 z?bn=s|MYQbX<<4{sQrH#}_E9eiML!r(#uoA?F}@ArCF z_D<{_(7m~PLHBXpLFcN@$(;k6qxLQBH?<$%9-0++O5-D~+2*ayH~+Vk{{KUN>7Gvs zh51ey4QWmjZ;3q;kxZB7nB|$Tj0cP5Lb25HwnPQblo}QU7fiy- z!MQ@Dk`Dhazof@EZ4~JpfPGkWX3lzW?a?w0RcS1=k{}td%CUfWLi-l6qH9T`5VYnn z5;O`Rn@(GX9p%*a^tEH_Q|^dTtn`e2gcC8|pB4zs0S|%**4bWi@Sfr~Mhb0-Dif>* zh0M9sqfb1fx+9~cY31SQiB$G-%n^RbePtLcSyDHD-Z9s#+$zPW7zpBW{M=&eH8+U9 zQ9R0*9eM%GRi-N_ZFbKf5-=E$lSEvaggQ{i12G>r;>HZ|N02PgeJR+$i<2~^k>vZxHIQ&WzBVZ~C)0UQptG8=F9e{Nj6l@}5x$R5(63Q>vy_ynwo zY<@$4L59mYb5Ik5;@Dhe+><*V0g$#aEJ9#biQ)OMAnaMDPq<_1x)Bfy(Y8N6) z!G5w5QVlwp)}KgienD^iI$GLG3~=?iEvzX?@T+dCFh` zy+xP|AeV(M;{YY7^iINW*tGa4LsreVzIoRlyO4m*=muB?X6pzr4JJ+R)O8<2*({&N z(Blb>fA)ly(;|iWt!M=_7jU zctqsc=G4t&LuYv*8QIve><#i1s3PBCilkwK(vXw1;ZiO}4pO@#ya7GNnaH;l0pt2o)w5#ZMOd z1^}t<#z;`&K@;#b3{lyn0ot!M#>#T8Q(9!0yu>^}5OTud@R#}EjEabN77msWAhqwlXxLAjUj7;?>@11AsgS5 zhw`?T)Y=&%MFj-J6+fr|f5k7?>5ATF?bON^_Z`3I@>=f$warg(f?revc3QY}Z5ZsW ziUZS9a_$eN3ssKg!r@vxP<l`{Qe6)P8o zsS0I0$FziR=AE$7*M~EYu00xKwak!-k{A~EqQqA|qTEs9<&dE?DrwSIWMhZo+{@AF z^x@UD-k1KcejyZ#a4p?rhmj8et@Ms$mMy=AK)^}?X=yaUfk5d3Jg`qtU7Nc7we<@z z#)u!Z_h{;FHVSbnt6*x;6Rq$=WX&IvG9I1b6v z>G;EodS-?W6pc8B&4MWqF${1D6`Rn)Tpj(}(`$DWOG*|GSBhkXM7A=`GtLCOECp1X zFK3-up5#}6CB_HT5|MduM*Y#!B&l7JbZc!!mGpE10c(&NLS3N3Hc2wA;zlyLB{|#? z6cG5_=3ssAJylK~Ef6`L^Q4GaZ`Dt@H?JCkkl{sM0-^PgfeHv0m0*NwaC~d?$XX83 zW{ASVkg3wqq@)JK4Cf*KGBJn_?Z@!@zHg>WJb#?L0A`yU%hIZh%_9(qg)ilw z-XU}nVpxBAZau2^EB*1qgV&dW#r>@zmUx*uBwP&N^*o1ZdRD%mp zo$>&3TF;j9J(^DGW5-dVi$Zd_&FN>4&8>MfTN@$8T9^JvnizWpUkI3Fwh45GfXAEU zfi$wqw75d=ACTf!8~vXef(YujVEi{F^Qs=w?`xi};@#kB1xnpxGzbZU6s zQSr`tzQ$mq4Yb&!o^>eVQbi0*A8sHPTP_0SE*pziLpgHC{HlZyOL(QfGE>`W8BeXg z7uBSSSmK-us{@mnQ!)(1iU6*n(Hgh!>&RA}4kk z7a@dDx$$u?o4@ z{j*osE~N000u5~uAMuxzJ;g@?vqWLPsIj7Ex6L||(51~W? z@v^r&-iggyRr-%>j`qwEsPhH${lljp(C>}D+8vBuKYDEQiMv^Y z#;NTmOzmHMqw$f>hdQTp4r+hBePQ>4|Bqb2#Ilz0SgHrPRwa@lXHXKEMaN@COr;di zNkQb31~9~lL_iQ~%fb*u8V?z(Z=j>rj(l!pBv@mST1#oAL};_rP&k21Q5>%#F;n-` z45ap@uCOR|zI@xBsOdt)GF*$ZPcX1){>qQ}VRTVws`P;7Q}Vv(;uaKG^<7T616@zO ze~c<~Lxe0moa_s$5pE*(kqHD8d4@uS3d;aBxe3%$lUa&noQw~hpWC%Irt-@tljv|~ zifP&c=FCLQv?{5h4K%TVfTlR;RbU9>EDqqp(xMK}jsEqWdlpxo%#@ML-q3{#p{r~p z+blBEPyiBP*_;fmr)Xz2O2o^g2!(4-@g9Er>gqz)T$Bj&iWs(x0n5x({Nb{N3UJ}` z5&MEy?DOCuLReh}82QdC>$@KQwc3SLVs1##muXccL`=_7vTn?HZY}KxY7Bpd$Hk@D zMqsANLd&yL4|`U1A;}<~!f4ULxjbzqupm($97C?dwy3qNg%neq;Jl5}ygDCwx7qy8 zW%Ub5jY2KPRdfWxd=5#NLslaK$PQ_92*j0PJ!B3U)hpC0t#j=dp609ZCBo|BEsaZJZyFbuf>RR~rN%F})_ z+UNRet0^Nv;T(mVQ?)cbp-QNL)B-#f_lYPkY0`RdQ6W47Vid07KZjc z1#JZ3s=3n!mqtD5PPX$)c<%8(`qQ!OhFV1pvrx8|h8ts8nY|_k`RmjW)tM&|9in)J zZAM4QpX>_M2bv3OhawCQodejV`o*Q;Ur)?$xsabHx4K&zG&2Xlnh8OO1)s=YOFr_b zN;<|J7KvC^RAu1ndh_-Fr}mDN!Jz^2vICqYMhXx(sbBt|WH>Q?U&&6l?~ zzdBs5-;j5RIgt2`8{;>!A#vxHI$1IDEl)Zup`sPvnCxXfc20biC!3#n*ag+Q&Lj{- zlaU0biL0}eZ`h+8KVc1KhXQv3t#^yIWYVx8#8FYjVwsscqPmc(2MD@GXWLgDMWVy$HhLpiJ`9+ba=K zvN^uR!NtYtM^4u+q^~hk2hgmhH!&6=Y}t|_V@@j`icIK=%;R@uT8+=9cSR?nh&wwy zT&i72F(F(9^XbV|nnO(xt)@XWI*7}eU=wS}f^Ra-2xlrwdZ$*$ba#xsvaVGSQ6)2> zz+2C`Gju`FQ7VY;ltX(Nb$xX)oySl)U=g9<==r;TVXC^Lj9>H@*($t(^cXOK7$<pWv^=snN&BGF8G_xF>m(Ny58;o!qs_I$?U$f!>y^TXwLJ zahW9odDKI08UN6G<kzLWn0Jo)s@WERqSj&Q6Fz?08-8Rc$Hm*<{pQU1=7JrNoe| zNo#c9u?MWYkRn@Ji#0l(U zYG@MMGSf)`E2T-kk_X$5sG_GD)ufa|f+5TCa_E=%)f>mw-gQn9VYeo$<~&}NZn{ae z7kMfL9ll!jWN`#Ov_DywEFvy~zj3+VtHuz%d@|)KJ}feWxD%J8mu}pVu{OeGW`Jmx z)VrE9)8vIrA;vMMA8=!8*VuHG3uQoen*RI_^sZN9-W`cT4gk`1cEyTeTgP`I<{>87 zp}5HmDqCsY{+MbR`9s0e0~?E^7?vN@!(#L1j;ch#0uqr1ab7kq`bP}r+BSiWZoDx( z`b$Khm}Sa4@;hQ2*9(9r^9FKMEdth>0FR=TDc|rpLMsn|I*K?;UjXe_+rRaV>W-9H zA;U?pqCgxs8j3R(4#k~N76S~2lPv4sl(IbiQQESM<~N$({7mgaYzNR$yi({7u$AuX z@iY0K!t8VA7`!w#vg!P&F9wM5%`cnqewZ7u}myWYX8fTlcCV!xwhF+ z=adA500vkH1Sli2FZbR)mJ+-pmAdHc+kjcXirAwORSFTY<5M#x3)P)Ts$4S`u6Gb% z>Qnf*ttUUB_Gn&_cuKP2Ba=m_7H~K99j}m65IGLagej-~!hPUZPE5ClaCpm&zgZHo z%XSWTY%QSTIgT(?&^-Dm>7}tO+<1+Ns9TRqyBu~B~vDS#!#RBZ+R*Jwu!`tImObq zZrP~bwU`#B9wLGFg%NYa@~TrX%K-o>Jj(i3a%5#wCORj)ktHzyfH4D{CzHp0cL`bv znkINvl0;&C0+EuoFb&g|2kmJwqWIzG;4dP~#?J7pf2=*3u*$Tn49moXq);f^rxT~$ zoM6v==<{VZvE6H$VBQudLI(X7Uzjvq=Z=6YYYuT>zq1&acPQqd*wV*|ZRJj(Mj54; zepGCUFBTIg9JJZ`*q7^fBpBn_EPJhy_&YBo(qsBKd@xEU1qVY(8bx@c0C~)re7J;| zZBIC-b|Hb;9%OulY>)E%GgeAT0+1vw2?3>rr}N0Y%X0&Zn|^<{AK(S?13YKf z{b#P9ImeX1@WGDX|IX~4Ktd)8YUI(H? zi#TY=#!4M!IL;KB<=Ckqx7-I4CxH5D}|qkot#kVG;L!I4y!`8@sr zD&S(?T$_0efkSX3oMDvxE;^Y5XyO0^aUQkX|!4s(&ynW|8B*t>4WFkEH zLIA{^2fW}(h#oj!wAFg!$v4(6q=w*iMGQyAf)@?8Tp=Q` zyjfID=cG$(7jg~5IkJONscpiLKgfw~rC~-0QEFK+41bnv#(8Ei0aKFE zQmPi{6bxtOMpv+lyCxCG2cW3TuQuN{Zpln=G*q6w#{ad+z*D1;y!r%_CW^j< zs3Ej{qI412iXu)HUMy!|$3~Q|u3qyIf^l?HQBt)$<&5~{;StZT-4PJ!Ev5NW(1Api zF!3VWEGGHkOEVM^epgj0lNq!uRI}W1!ix*tW5*O=UbZMptjS>&v4u15Vn=dXYb+Z| zFu{lwGL>=;Bo%KUX+^&Fr|sFP-yP$V@i#INm(+giH#2(+4{(snM9<*>YDOaPg1hDpqsEx zM%sKm2z6NBoEcxPZIC?pE0X3YBhi#pxit9nSOCZ!c_bPvjVsK(auIO^KmB`FpkL+nH?$oOGF zy$VIw#&-AVhu0p>jtwU!OfxY-H@q$4n`g^+^sPOHRqE-qlwdvV8ignPKs)Pw=+A2x z%3KnJgLDE6MdGQ2sAOf*H!=)d64t^r`+#V?!9P8%en;LScZ`W?mYdpzVJ=lzOfGmN ztJ~w)yJ?A#FZr+VJD_}on8pEP_9k}}4OE%#qi!kF-8VU&RzndIJXQ6A6Fyf_mkz-6 z2{J{h@rX+c{m#d0cN7#sZN~&0eGdD##_HrRfi$_7{0gcrbT|m2>egOnHw6T5l z#8`lA^Ql#XM0%!AMT9UbxjKuP!A{8oNvRS|ib9@hQKC%)p>d|EY1SL(pIP0JWE~2X zHOd=AkE5dE2wxYRkR9Aw$T-|5M#5Hxam{98bHfZMUkCrTTECFXXeRzD&jV$iVZr3=v9`+ts%oP_limx|^%{O(=>mJta zcCPH4)E*3;+j(&N=Ef=Q3*rH2-qO8s*ZumPnd=%KO7B4Hz~v;T&v_YW?gInu!^i%_W%r(^jg8Q0 zl9ULL+Pl!0Zp$&1u<~kr*U)dP<;*ThVQMCu5uhMD@Xw+c2X7lwOfG~F#+j0Mu_aUq zQCAfr2$#|}9Et}AoHA+-Y?fG=h0w#g1SQka)+1_nlv13AqtTThAQ9p9RIzfMATEPs z+kikECrD7yz&1vtDO&Y%3@#aGgJ20e6d4w4q_!tCHPKdKhJnLTX0fK_S3#k8RUtc# zgsD9mk`%w$zjYkMb0IJmdeyN6cM4JBq#D>B00;Bm916VAOoHyf<0JqQ;$~}4m)VI|5#W5Dlg@g>plTjv6+md38LTprGr0j`M6}>Y1 z3>rkqNr-l}^y^ELSo)j)yLv~KTIM1ORDu%^fEt(8o+SspB1w_i;C3XaxEb9U!VG0w zF5b22{#e9!M`|bo9)S4de8nGOQ#66JF(J`efWHg^uxQm&>HW(ILrGQI#rpe>W!zjS z`fXZYLjr?S3Vquh*ocrWlVq?ai=J4g_VCyw;*x-&_ip!o^tRfgMa2j?>my?(-M8Az zQ)c?UwP+K@6+(t{ibVPr^ifAjl`1%cFWsmvq|KHYF6Y29wZdAW8|s0vow{J5V>;9W zf-$KfRV7AMK17}4vbK9K8>>|LYU_k{xl0ch4ocOmZq8(OrL(IV#cy>W$1-P%Gl&Yq z-zF@lYF+5O@sR3{lz6x*ff6gG4PWMl9&`3>ZbTcqpGU_t@d=_9C-59diSYJ)I=7BJ zMY$tTmHuC77gD}J3GfU8%6IW|oZx5;%zdo#%7F|T*5EIyl>`3a zI>iZ&e{}G#)h@(u;;qS}>6c;SCI4D)wrOm%nv>A-UYE#7g7K$xlgO1&-TLBaI4*JX zij=i>5vCpUn9XVSkd{S@G3Ey4mVbnE;tEiXq_{PsP3;J@u8qz)p?^bh*6wenzfNHt z7D;c8Jj38(T`6`MmE4Gdh@=j4gF=s8J60|T+4{&zjLc@UfHXEa zZ;1Cy?zQ%3&gRg9DIoBn82%U_=;!&`UXDC;D$U}Mrm3SVJYGV zLZohNO#jwhstft}DX7s=pounh;n7ZyHs$|W5!&7`twbt-MC8y@>x}hCVd%H%U;a+* zLY&bwML<6V5q}g@w94FkY4JkKs}cg5!+DnEs4t(Xz|JvOsjLrAeFU@-Jvc906~vY- zD?&zTv5EcGe3IC92_<>iGJ|xYEr=-v>k@xS+BK@aKq-!7G175~#}3Ig1#4w>@U8KL$SlbC#&U$B8Xe0g(!&8PJXC68owSRA zPwchxc?L{?4}h1PG3$$?ji0Z*Bjm6Vtymd*idrD;qkH317fIx(RKL#ALAGMiNxj5c zg|jW|y^WrpF%08qByTVxxqZJ=LNwb=e}WTZG=D6sE94@dN!|rc@TkyLQnvrGwmkZe z%U%Z9jkky)aehGtB1JIg8`HV(?XoCjv^UKfe}wuERui#J?BK1#Tjp5$(Z%C7zH*E3 z!F#0=e?}4um*Qf~A$rX0Fa^5`H)v0u!H^nim`)yP+<27kgCA8r8UqYJUJl8n32ONF z5+t)A1~na{x)M07Feg75EoK<-0VU(>%yv#5`(<)N8iw?}hd;;+{g6K*9EviiND{}I z#baVw!dWVAFAh~=3)(8Jm)`%!J{lk~x~NmNOCb;?v4MkobLvS@hKRWZ_UmxH9tPKOO+Rbya}&zy*0?`=l%!++R2n%lx{^P zIz=@GT*)bl|d{h2pirN&^3%FxWJ5q5)!~4 zI8gT6obO!zTlEXcTM{~qq@QE=@sOo&j^`H5COgKDBdTW}V_L(dO|-L~!P%|ita|MC zJnlf2^^s(Mv5+~SG|8DWV&6df)H0DT}7P{1{^Km1y@?Z}>tGcgC65z8v&RZ_g#@2h9*_`ouQ1jh^7i(A&Tegt}xT@x3t zqCPf(as-K~Nj?hS2?c#~rFGl5=*}IXe_$|k3Suh3LxP;7pU7d3?k>H9P&3L0igTYv z_y3Ll3WBHtkJ9bYOBiHo|fPtd?TvTi`{GMq3dPq*m$Q+#jSFS0VbzZfl)5 zwk4N$6wxThN`qN|nBIN-f%;0FBYi+mp|v@fat<0cmX$i*6>w{PySaUQ?T(nY?RhQ| zVTaC<$!}iFQr-fIV6JgBSKvy9%64InASZc zl;Gq;;w|{QncNtw=3AF6=?gf$Xg}!V&F+ti0~48% z)8|b;X7r=crK9c9K2v`?^`fcy;Vq^E95VQi!Mg`rgT4Eo>c6l*-@B!EUhk0RL5-Wb zmv*(*}7Zvlg$_W#I^s=e(nU9`aOf2MBpv&;=;W$VvGML6~ z+m#*0qRr`oaTbaS0DO9A(p5;fB7*czerM5r*_GABj6_qks6Jx?mLCXPk|?TMm62w~ z%;M#Du*GEW7}KZ~5&)WHXTJZsV~b|HS6z$|FKu}=-|%+me^J&$P}pSvEfL`~@x$S# zg&1UO6oPIM+=s+04fx)d<~hVM5GqMV>+@63|F@!j z-WijN0luCAMWo7;5pgM&l|qYJkzs0zIiXw$kCuj^%19{*DyL#RXm(F7iX+Dimv!cy zqHPx4ySuQ9O7ucOdewHfnDSCJISlI2SmloYo)7tSjkC z%kEUhQr;nok^R`O3};^6ZhZ7(Me)E1=?r+%z105EWiZUF65a@etlhM1#Y%T4$)>`77XqQ9ZV)b@!asa!V6hRV3r-a zF?!eyV(r*pn|LNZ^3luX+Jl5P_7EGCaokkRXch1U9ZVxH@13JSFk3O;nVma(bFyrbx?eXF`Lslyk`fJ7)#!zNiNFOJI$ zZ3!_F1ASX`peA}1vNs5dXPDyVLhp^eqJ59e>c-?msSrlbTTu37`l8q(KgE!$dydW| z|7qh^7AXQPoWNE!<>uz}>Aj*g7&9c^nC8ETrPicO;#Xre*k%+#*e^)$A0m50NMO*MiU*A0WRrNycxHn|~m ztljSKOh4&~Mdyx#s>ehZDXjE(#8#SF=*+kRnMh*~T4@pGl-~Rsk;xQsgy$SaulIkx zv$R*yc;mzmqVNw3%8X=8S|&SC+wdM#6NN5AoNSb#z5)QJTI@~obvl-q!8q`yPrpx5 zeD#NuJ5zap*rHP!X>sOQgz&|ZqdJKz8W}8msu1+!@ZBJdG)F1(SpwE(JBOTFbboy! zpZfUTDpf)@N8R{&on&fIuP_ZJX^OU|8Fbm!aB-@}yh_jrB3fUWI{%=ebH8ylpYaA6 zkNVPR`K?{ITB~Y zTT7N*GOdT&7HuhsTq^KAnax}rC$YLzoW4>tcaF20N`Y5Z0(EgfQ|wDdz)IVc^Hg8y zDU|f|;F;+|9?s0+oN|Rli=2)#T>jNh6wUQ^bz|ZFXi0ul7_&fx!}x`4WQmC<+R~)f zu<&z>`rf{ZpHwjWqt*7`pH(zII$K@L2QVOxom&3JHXB4^NBM*qIulAiBN#Gqg;mcM zV84kk-=v8j2KvAkqf{y zg+&%y8Gg*l_~<()uZ-}X^GtLi$+uuFt%^$27zRkdhcOv^cgKufMYB zK6#lrwE#@L`nyHv$X~23 zrtW0GNo#`52DBP+qs}f*$bnh_y&S#kD^p$QhOQm2uQeymEw`ID7rmX^s*BNL!gQ+b z1z0WK@#B!Qlp?8RVN$s{Lm6Trv3__JGGG&B$-LD2%}*BXjkBtYA$PG)Rya)qM9LV` z^d1>%hPuOx+fXu|O2Xtb9W#N1B8s63UAg-rnW3$))_oDHPA5<5kv=aQ>0vN(kV^E20E(wbimWiQ|8K`Mv zX*9C-BQGBQ^h{8WQC(8cr69D_Y;a7*} z4j((EOAfq z1P-x+h@A};I(U;ZkNb`W%W#|yTU*$cfNfU6IAjqX@j#RaIyi_}> zI5VkH%?kg3cB6m1w00p30ds2HHG#fvIwRw#AYct&h}+Pe8OJe&IfzLqt?btpLz@}w z_1;NEpMH4I*Da_%HFam;4Gau;BCY+n0iWu`RDmiAvI&kUvrrvBvcB9|zG(u?i79?G zC$XisoY9#h6hUf6JT8R}tKg0)(~IQijN2h5dC$s$r>3~1_Fy`GZL#QfD5oXCph56|4Y<@Y^C)aj46h=%hia3mGhNvNs zsl;qdOYJ+3u3d=8mJ@Q6w|rn&CU)(}018EK0;x!0#>!yL`KGzcn2mI=qbadjYHI3G+LIE-u_Y;LRd{jng-t-v3U>D+Wo zo*;??hcSAHv`v06Bf`qlZR7?rV2fcu_fTvX&TZC&&^)+ee_co?8&|j!-ApW`C#MqI zy@lzv1j~%hP(rDGKzlkd%3OJsQIso#8+U4thILo4>St8uko_YsFz?|AGHOJh1mkDM z%%I`)pXYyg_^fSPw7v88+J(|tzzd}Q&95T2TXF~&+!79&DT5Bc(T{X7#g5qv*Om^N z4CGuIJ!N84_l{zXQ~(D3GehvQX;mY{Aj=R{`tS)3>1jmsqS2IBd_0`Xy82cZhEKbu zc1H*|+@mdI054*m0M=Dyap4y4h3#3R4vrk|b zcS7=dMLG%-5DlKt#1dPjXCnh};kCZ|hT4U6dt$eEzi^VqN#wj@uP0Of^_pw!S2=s- z2vxIp%p2m;wg1F7L1R$$f_k*@V?LA^=`c3YPpD*v$*^Fy7dtkC1^5uXJa=Tbg{dc; zpy77f_qx4yM^=s#|jv;Z-^6{4Nf;=iXOBuikTw&lev*_t+CMp*ZR)x~ z{X*Ux+n%j!iUipX1(~B;a8`mOPEkJd5wu`o8e&#QvDlqlbE`|k^FQ)q7eXD{68@st z%+KNpbs9w85`NN8$03CT;JxBUM*w0ja4LwXt*O`5F2r!a4dp{=ZSYxu5#bFLL?C0L z6{`4IF>7HjEFr9crKBr>zhZlR>djx(7chz*8y;Y}xUkrDzvAmNyQlw^EWjQP;4#I8 zqt?`4PyON4evJs&#Vfz{V-fTbghBiIH9P+R$j)8|bXsi@`2$hNKW@kJTNw zD?*mv1+T(}=0qsto~<%_FcQw_OUKqO#PfvcjZG?E3e2#$hX~DpV6j0;urBN)FTDK5 zv`CYS_&xb)cO7wObs^tH7>Iukb)zpOW8A{MYVx!U(rE%JGGgW6w~XuNB+Upgg2?8| zu7hi-PTFQFw7Lmb9DEFy1~tJeoa%zF&JzP!$m}Ft9W~5eX=f)b(%82*cP%`=x+9z+ z3CG+ew?aJgzK~yxaCrEHQ(Pl7k!@l}p;%FxnQo+I(zc&@>3ymT#RF>RaoK75MW}&m z8Rf^_2aD<8VYs!{jR)`|*#f<2_)~@^lr2oZvEuh^JDEqfBsDJG>H>@oU%xPpej-)| z(NK;2dddejD;+?D1lkmJV7k885vs=H30=CmOnC7Zq>`i{#2Lg9%Zr>BB*lAaKmg;O z&?SZNTee?#*V?0{pOF2C=8lO&fop@sL%UvvAVDi+dan*mYh!XMlFFztL?sGD`#(NY zyATduG_mWb8%#X>5@fN=@+niU*JUJAly`n;C$-V#bQUQe(&NYGrs9Pig!18|oLL`#U!rZ!IhFVKEeHP_qv} zb?yXR8C=33z2+$YNZWzB;684mjs8g=uJCeNTxATei2~s6!lUB*GyjerZ9%X;@d=Cn zayP(1=u0XGEEl#<8JqA$9=)>OY^ZbCJFSaGvv7-0qdXDW14W#kUc~}YMjs1niI+vj zlZ)H$dT;H?GIb_KcIb-@D+jpBc-k{TFz)Si(`KuQq>(QPFaWjxov*Rfc-imOE+jeY z-4?qu{1P;RuPn6$fEdlF8#%LAr%Acm+KdjbTcms*Brx);!hk_ z%cQj!3e2QsrW+-O%^z=Oj&qIuTk}@`WtBFbcE(gWIv9-3m3n+{D@kUQAzVouG0p+G zPsz~n%o2yu_VBpkjkUqiAFkh#ZiH-C4FKMEjvUOaDJ4>yI>fmmEQidvdgh}= zVb6&=q0ZAaAZzL|fM-$!#XPmx+Pj8xEIl7H8hmE>New^_uv0p76h8Kr%1g^wZp8zq zC139fw+htX{M8zQ_e*15;UJ8fWxlvD!owq1o1!F;OH)cOCIm3jg7vj@JMfwKD2tts zo>RT+%wNsfL9vi{$pDC!!puB%(de*-xWFgg2v|!(N)aQ&#jLQgR!n+=eEl3i?H=^A zfTjGzn$fg^I3UpZnaOF!a99u0o-yhMZuzzR>uOZ8$L8R*AE@0C#y~FQax@Ia><02` zx>JbZbUIPMDvY<1;a$En2p8JaB5HQ0FEn-PXKNP{K?pv!w@=IWBP>JE8iSl&BWsgR z^UI^onA)ziPkN2EV*-{X#Z3(M|HROe8~X-99aChsGDDI%Fi^F^g&J=0u|( z`9-Q2h2!9u@yOb|BlQd42$_+>p0j*-rgS0#;KFsx2~=3`+)B`dC+X!t1v@BH5*9iq zR-UO`NK_|BOKq9)Fo= zcbpLVbED`=3{WY!OX=2lyfEAP(P{OU%{(Gt0S)OxG|S6S1#pAPE4u65bUW$-M3vl_ z?%_=Nkiq$2*PGA0xOO3g0Ry=(;mN!TsZZ4m#=uAM_$82=t)(WRSY}qYm4*bMgzFG~ z-Pnkmua-szS&iVHF+O%M{E~yg!oqOB5y-_9^|(!AxvDHoYP0^8CyR|I&DZXTu8S$q z+7C^WWx0|ORHai9hSVk_Hc7pF8tD|*EaM#7q;vFOw2t%qJuBa;9r> zGZxLP&m8-ZqDdL0#|V^FLmU3VJ+#{X+r#S@%8||}C1cKFugJbb7<$>@7X{N;U~wel z3Ml3PuO3%$Cmw*co%UO?~YLCg%CLRPv@#_f5x@^nJ+K<$6=WplG`r3E$lwcIhHiVKf5%?+3#D}jjL}L&R=1QC z3LH>2x~aS=w@g++R~lo(nQaH=Xgnao-d|}S{_Wa@FjHVE8Z1L?)x`J%okSi)Qgcs1 zLF^;mVtNJ9wOR_LI?HKpbLxGysvD>26XnPhm{mGLDWI`}}jOKQ{R9u8L!?&Y( zS{~DoWao2Sg5B70lW@>E9&veN*sbTsoD7MuW^fhIb?c=vCdYfj=`)O#v;1gs9LUSR z?893a`~fRV{qKw$401=YGVp5#5Nkxr+)+`N@k1(-sliw4Io&`E*4i)Pu!`9QKAc}^ z-?LU@#h2nn;!A>~;Sph#D}n1l8(t1RL_k_!+$e}@V;#f~*evDd(&Ff*U#-3DbVupX zv_Tb$ZU-%B=SsSq3dkQeRE;zlq~T++Q#-T9gd~^@7c)BHbbSGzNiV=~`u@dYaY3{3 z!Tt@+BbxuvcyQ~=UGGa(-@C%3fCm*fw{IGq(><(lQuoI8`J+SnZx}V3Z|s~fbFljV z(C&Hd!`ppsfj{hbruG|tt=VrK(D}e_wqT|azMysD==#C_GuPo6E|`AK%-PeIwa@(fX;JU#d?TJ^Y6^-=Bf+9ViGjq z!ndsalQ@*rv3&u>oLC|$k`zIcL%@xEN`IKXW0e42VdlOER~IUM@L{qn(j2Z)^6*M+ z^$li%)r=b*1uD0t9UBv)xM!SI=A++KT$o)Hs|eu$R4mX-fbLL!3c9{9h7?oiz1>2iERLb}~;Xqr}o39?nvd z1OQwh2e0Jp7YpBFFeD_Ctz$KoMIpk~!99Pyx)4-@b5!}t(3$#x*pL`y)*Q0L1<1Sw zkAYvT=x}i4IW6sIM}yXy=iOLch|w|J5yn>yAQ_p=#N3(l6?7h&*x^)*z?%&IgChb= z6rczkMaEX=J(U%cVB%N!4#|Kx9OV~yW=tFw9x}iVX~$4&frp9`Qjz4F@!I@-bBoh= zyP&!wYcJ7RA(07z3KR7($26FnA?lHaz!E8ji3_Z-Wl{y}nDeez`_K8^->J$jz0(YD zyj}zyV{m;FPs9$3W;9|C+<;nTco>nT)dObsK@3t@-TuB`sqV;i65|XOw?i|@Bpv$- z-i%XAFB{=X!xGxtR6kRlfC4pX+J}*My*p2<-B5WlYODgvM*HBWx2vXO1era5Q)Fr%VZUGZourZ1` z^{!kKz5T}HXJrFbtLP88=bjLO_$O0_iN4VSAPx5;?n(lwE?UC$uGqU+z!xUp9;7SCS3m#|#JVxs z_vy6@DeP4(3MzJ03M}A>fKVOYT7NE z8da-aDj;a0(8|;|YsIqU06c(xe9dxcMwXSs;q#WTKtMX)X)gr~2$u6o(@O_|(X zsF*QrJ}(r5-QeuiS01n|hA5D|K$wSuDhz~FRGzO+-|L0dg`^`@k&=XNWT%=Dl*wAw zw_0D-hM}+ zQAi$#e!tm&+5&Z3WUAVYB`_qeO+oo^@60vWix7-dKMadieT6Lie zvBAZwspU0^(R?ssu52cErPDO$xMR{JahVufh;Z{kGJ$GyrE$z;Ua<&iPh)D#fbfHA z1?3;_tBOFqTsF|DPl8Ro{EQn)jc&Xl&jLcRbJrTXokqaCW<75<3sKzGWn{p=BJ0!b zAFdqZ754=u5@Y717Uxe&0CUaZ{$A|i-uWpfH3jKyy6Rny4gjA5*ZlPF4}_^!1ki3!PRwT0dD#G&UXjOVAZ(z~mbO(R4kI|Wc8Uwmtv;IV zl{i6tqR9b4cr!(wVbMx{%$dCr+$lc8eijFKXVoe?#FeeyyS`-#TBeLh{YZA`8BOa< zE8iW9YZZuSey!=W90X!EYZQQkuuQPdc;9?K5O8=zJ&IWCiWJnE$t`RFm<~Ob;wni~ z6bXpIyg6ApG;E$yZq!g`v6!9p%E-5qJF?tOp~;z6xJT#cP$bg_0aYmG!#H^L@j1*Dw1-#jMW@E5p#|hI}S0;_zy4XD#jOe9dijmD6don5bBlG(KC$Y;vF z9JoXunp^K4^()mKnfm5O1!Zspp5wtOJ391Z=tWeVB3VM$`kskzE6h^54TKpVZe#lU zZ^Z+At|*3=H!Y}z;<|Rxd*bJsZ*LyuWWe|Cdd9AM&U~hE)yzw0R;Rx;ebMw2ru(BS zM#qirJN4zMKc0H%@cYAe44*pOYw*#*DT4#_2AtFXo!-9}*ELS)?cIA<_iwwWHTLT+ zc5dsusdIRz-M*~-?DoA|pKtw9>(`sN_qKjQ7T~AxW9|R=vpr$gbh~(3FtzGmw6t^- zFl0%a9V;>knlKMy2HM~@(4^|ED?F__XrOiRyNmWKUNycJKm)QVA|VM$5lIeyN^_#D z^{;p!-0L{B&R`P71p!`-?-yVzW;;*(e9`#Mk&|l?wS-r{2wmp?177elbsad-dSwh2 z%85QNA{*0z%<;dC4pm^w?EM{mbVvNc_*$Sk-0z-3l(H9r6B$rKLJoe z`cg8HV!iRUYl`-vKR>yazY;nT)0Qz#acUTEi*^Ydj}B}{(7PPDcN&;v zvNinF!;97rZ=75!#J#C1_9Epo4NYohgs zXuam&$JbKl>j%U9vV@2&;;|x`8%VJg2UXsWKo4~aHC&@yJJ3Bh3cxtOF}mLmi{=f7 zj;}>AW1@f?85eWf4`P)QHvT*nu%TUWG8E%f4@{4(PeS(-vS=El*Se3KE1F+EesV3b z$ls2yMA^r^;AEV9|J2jLT^SprjLSgy%uI)naH@(0694i_@v4Uu%`=M0wY&+n7;}r+ zQ6x(aOsSg;>b=EvP*PB82feKlj+_c`W|mrd*A}NPJFaLh|Ni7!{&HG&E%{942PXv= z@&)BXa?~#CGXn}}Ocf@#Bb?|o1{Ehu-&XhMA62x^+G}zxe*{zFrSa56xGkGf5~Hl6 zuCz(fEY#~#36}=_N7Y{15WrGXpPQdMtmy6i?a8&Mdr%(I6R#kTvOpr$WHUx>!<_Iv zDCkV!6E{jZ({*mW_u2WP`Oq=cli(0={+;m;nc>CNpy8doi9UqWun_oOQ5mNqty(8A z5?=&88Y)`pe{oQBpYy!&eW82HJYl7aw?Cu)7zaf)SJV2=L_~ar z@7%uR9!2MhFHEkb&ohE4aw(1QmJ&}hB+t^4li>|(^sX~X&$nP|Ooy+3<~5A}vj3PT z6}=PQHMy2qJ2tQa3SiMNA2WCsb_xhfK1WD!qo4@UKbfc)2d5A31@cC8&wF#xe#v2v zGN-ILdrG?YpcG~vm?afLr0qyecBxRW2fRyxKB^s&B%lWycLeTn%!+fmrjy=h7kghSno|#+JR+KxYeT(8 z#Kiwu{~&Y}_v}NeQl{@vD2Z~a_;g>!nc~DP@Nld9tZq?s&b{mSz7SAci_$r`l37&X zmi3hc<+V9dL%-bvUx9@+q zqSu|o)et7of%+oi1OXX*V?l#i#64E(5L8N7(h~XAe&Ay@7=_A~#)jsJe_AxZ|NO~) zWkgEmUl@15d68+gHZrG!)?3dTuYuHNJ%A`$g1t2P8Z(Q=TihtF?iG!Nu@xuYEZ{L? z@mw+*x7y7dG)NKyf@;T4*o$gUOc0o@AT)Zyl1MM}`sgXIEt*%3&!7QPWpm{X!U7qA zR)mh#KXDe&i?y^`n;363nm38KVyvhcqTSr*?BPu8FsmO`*ZCVKDj8qd*|d@;-p&>J>@?@kUbfh$VM4P z9U2g+#CRiPWBpRE(0C#|=L~?Yl}6{&MQ^YDCfD)`eG8whHgy&hT|eD%Xc_ly@$t|bk5wZL0Eemor>(B7tcVu4Z+(L7-m41?k$ z2jzmBFpiNU7^>lU|6FulG0ABPWvG!J6hpk1ZyGiJUzy6BL+BCm!}y8xh*VrwCia>o z$8OJDxY^wK?V|nZmrm|WAdT?t5GD73;FaiQ5iB&U&6J18X$uXUsN z-ph;ja6B|U1DOe#UL=7i#Ui5^AveSb0)lV>24eh7_~)%PoR)6HRf)i5`(Ixe9MLzz z;LGFt5~y^d1dRCbrk7#xFsA7NEQxZDiF2~)>wYIJ)I>-LXJ;meT%2t@Xh z*aTwlFslb-)9wIjiImC%M=@C#)N|?A^Qp2I2bVmnXngy#lWQRlPzvC-A0gP-e|AcU z?~J0RZJ>^@(#ed>Ga*@Hp$0zbLbL79KA~tF^PI`G%xL8lmbfy7G4+QjM!4>*fpN+U@-_SOrcmXb~!nvK%)F+C@VZSlCmTjvz!G|bv(_DiCDcFpsHRDtS!3^({r?#^(51x^-e9&6pG)F9+*pMkLBVTnK7HCe%O1Uk9%W z;W5d`^qK7FV{|^bQgr|1FDKVR55MxmuD%Qpa7p&j zu(?(&6|X3Y&+a;I*M5!lne%22Z|pPEpT27PlgZKI1uM-{Ia?KO4v)M-$cWK&8uf_XdTtst9hDV`JewYeo5H)Og6^)WGWA1lfr`ei%piH1w3cLgyAH4 z^U+u#awJpwkGuv&_~^p-R@afWEOMwhtU8}~3?m2=EE#!Dxd3GGyIVlCK)3>p$1;Ij zAzd_AzF1vHwW9dQ;mz3e5(^sMEXD_zBUsdl)n}ZjqgOHRZEYW$B8gHyQ z3@ig4HiIzXm#BJ_EFqJoduRKCX9m0rWXuDq-$fZ%;?*Go5}}u_I*NXWbAh}>aS<-_JQaFMTjcj@ zci%Tx*9k7j%wYImPLPmoSdocnVDN_KFmGR)5)kM|C~gh`Gi`W6gz@R8PxuCTMO_p= z)ce=vq#h}KDDEI-h zLeNP$@5*XMVQ76}*m}?8I++H9{l-`T=t^Qw5@?F9mi(azurLjZnZz$x32PF1DapVx zgFmkFt`!63GR|0y%pFmBasoURh=OjL5u<2VP%TBx1r^n>D}I>MYO8VPuIhfYKY4|C zhn#=TTY;ESEEoZ+%F#F)>%2NZDW_9fH<#u$^gUC8a-?y|Z&laf?C^q+SBxV0a%LNg z@NN>E_44`t%C7795@MLrrlw@}4%HNmSAMv<4k#-N=Q)00yfO#L2z;3t>w#jST=>CGY8q(GtLB21kL3Qn%{O zG8sJLjM{Y+6JnLj3STk~vugudzH-K0u?~Q15%~$4JR4e20^j(9HTW(LUwcz^9Z*d} ziS>*FRaPsQyqs82HR%cy*lm@k@)XuJQqYKTb+|H3`MEUcA6~zXej&noSTc1rSB$gq z>}~ubTK=ppu2dsNE zlh}vFCp8Cn;6SyID9EF!OB_mdRuG=n%)!d9LVTSWsQ0#&4n*9w;*>E4VS+%_#bp(_ z7fgnC4GPY-`^(jJh4f0!2>Rsf6QVO28lGtIgl*wf~3&pJ`)b0n75P>?~St_9j zpYo=PMzbVKOA1~AP82`^60v!k>}AkT25O#h|JrrpXA<2rJx}m~QhAI(PcOqX!l+`A zbI@}ne*z%<&XLF1gcs>tUfUN0gz)q6hKcxSlWlyO8U($ALv%x`%2bF(HX4%mc_*mL67r}#)Di7^mRN9DWP|(nDK}~NKewcNsnNu zt`a2ymN-bC#&1cQCW!kZw4<$ZG#6TvI}h@nU733OD<;>G;&`yh?N$f|SzU)*(c@1* z)d`eDCX1^7v~A!@^X>(6qyU@EeD`(j>N=WQ2zmtBczFo(nUpSZkmoX9)Q~MJ#%9&9 zXJ-I3M14SlAJ3Tme|UNAI_iC!lc3?l*#4N74cRqK1KOn11}W{h7J=8h5}J`sE;`c1gp;z*xO<2!w2kX~**RpEcoHLMX7yaaOIW=jfpjs3ck}sb+Nl zq!v5&PioiU!nOx-j5)&~geBK)$)#9{{*>LfEtqDQF@@%gQjk40dSO-&W@rhh0o@q^idV_! z+*mJ8drWm57=#3xnmGVaNKW&bLN}ukyzLBq5Ok$M4;0!>EI=>E+py3*^p4tf2pht3 zsv@L{R9^bCgEp1naGb%h4%k*vaT~>hukiH(BR(t-S`|*6bL1T$iNivm$>qSUuym1HC z5hb5h5E)~kYB%0m8y$G|z*1XI}y0Ga)aHd$< zIjLR-AdI-Czyf}PY_M1W$@<{U=U3M;zC=KfGlE>B=i?#ih#7kB^X5n^9R-$)dk_OK z?WkRC4;IDx)UziPo>~d8LMLZ%6f#O!0HDP>u_J|PtSI1}fPq!Sm&E#pFV;atSsmQ} zrSGY32uTCZk*b9Spa=H%9?5-f$Yzwx(%q9RNOBf~6pug+)XD$U`|2wv*O91!M@3rf z)5L1T0`LytNyFB5eq1hL!Z0a@K4UBTWokwlcfR>&pRBHXM)p0F+7y20sl_ z(s*)PXb9UkhDZK2px4X6S*V)_`~CCyIvxtWYq~Ww395-RSRxM@YojjdbfLx5te9k+ zqHM7^AaxMGlG9G->?*E?L}Y8rs8@YfVNK*S$QSkkzM&bngJZYXS-)@-Y465dOZKx% zyU^HG_i8rxXtpZtUIb17hB zvcw#j`$BId2B!$%u+OQhiErBY;z32$s9*!x={UkF@ouqu*)?Nn?Y~I>+^xEwpBDck z|IRUEC2b(5 z(fPza7o@9VP5P1FT`tpq2Zz6Kd_zPNiiVTZV)HV208c4|p}>JEOI+3Bk7Z)0HjeO& zFP9lmFCKG#GAV6GGn-G+04M-iSLoJ{-jPAS7SZ#MG`cF2kmLF)xgV2zQ6AOB=x2;IK#5u9GRpQ9Hpw$ui^D;d#}P z$3)(W6lp@lvk6l1ymEvR_vz@%+pX&d)pfi#sEw5}1_8qgvLQpHnFzr&KxVJjX;@8nvW1F7$}}Aj z0T&pDIOa(b!{tGE+_th|4s{Rf2Tx>nm_Ub zwcEiJx(>ISl_&JDR3s^f-nZ6bP?NKzN-Dn{&5IN+*_yIkI|p7`yN(Q}4h^ZM@xk~( zl3cKzzAhF74OKocHkptot&yPs!w}QqCfculW_2CxwYN+<v19t z-3VHU1K!diRim^}6nMhUjo+)TqiQF5IjThAfo!ytEhlYAs!eZB6=vc1OKITGtVL1_ z@-Kwh=4xk9)p42L7v(ntHbH1z6Bc#)-(8QqgT%yns2NH~C6tHYHaAD7!~CXWsH^+o z6sJMc&#c1obWL)cs2r!8N=x$>6bDPdO&A;s0`k;PK#X{#b01c_PBaZJIRZYt7?|>E zII=_-9w9LpKT7$?_THvD=?%)U6R;6)Wb4fjudV~IYmvyDLeC)lX;9Ln>p`>%ldb_T zO~P=d0w$ma4#y6F;)v4r2^DWF=urrH?#*=Kk3*~>=j}lXs793Zx)=*$VoYdK9JF?Y z)M$b=1laicg_HYnvmRWXuDVU>4K$l=WJ99`kP|FmK}3=yVhi7rqik3(L%o|fbjR1L z>nIWBB$jM%Hr$S@%5>^JiL7Jw zAf9YeOGg;US$1kTFImNeIRc1czhRSSD zO%(zdwa7mFS|S-$26+-nc>3|LnOw(IFox|sdc6N~LJw9exNOl?4L|=dToH(ypx20N+B6%bB#Oaw7z&#BWq5gX{7b9rpg&Yp3Q26AqDK9ULCPFI z$r!hVVt~RGKv~Br<}p?Df-n&C(@&ekF|3%qo{1h1q*W%ZD@SBdMRxkHGsMe20D>~M zLA|0$kV`C7`O@0pzV{g4k3Y2ge4EISj1FOxNck~#am82?UcWtNw|KeMqMw6}V0PPS zYjBrS#@C5-qPHaTmiR;Zm1I?Exv~6t+iYhI$x~Ob}#l<0WA{h#E zb~^RnD$x5LGzTe=oOzMNpiHoE?gvP*vem!+?$vW)4RVhhM|1L5LH; z{dz^50-eLBKRENX|6~UkKUQ)Ij|>kPOu$1&g~kjM8u8%H6=#|;Eh3~1TPgG?CTA!F zOP;D}Yw977tFDt8E;1UJNv}@fgEijak(5ileQq#arz$kQMKD@~LAK%Q#Im*FFP=TQ z4&8`*F-VTXMIAuu=XAE5G<79!BK?uY%uLCnz8J@jY$?ofCUyH?o?Hi$MG1*nEj|}? zCQ>%mK06BdMenLR)Oh^NHZeb~)&TbcV_{-P2hLBfLkUhtwO0goN!h3l^dWH}wk#Hk z0P>u_o`xy&OnI#+M9lJ}{mrR=o`hBAcYrC=Vl)!O6E2hnbHyKTf|Ig_xM*Ks5}=nP z!swR10ra@me8op6_XA<@|BzgOCXqc>7tUfh4A$j;6Edg>)DK2+OO!Lze$40;o#5;J z?@wrB?ZuWn|6xqi3KGec-61DerE7@B=|VCrY=5*PR@TOq9t0Dwjb`@Cw>iI;F6dC2O>~+d{lK>QPzg-LZdlKe3?8{PAYf2QY+A1)`!vr3}c#xe}Bm|&ddnC+TR%iQ z;Gq!YBBce+6 zCGCeVi@}xx$sr3Z!29`spcpkhWzy8y$5zh;g@?Ki*#tPtt_=SECt^=L%^^l^fgrAm zvsYFuLEQiU!`_{TTUS)xj-QFzbVYrXHBV~#QAe03g3;j@#MT>QkTj};fU*jtcG6lq;psC?mAeWh1|6`8;# zdqLjeT2#jJiFgETvjc+hd1L(yOE0{Qs>_tmr zgtE4spN?asyFLh3?5)Q4M;#Xb|PoIyG<97oNUkIMnWWyXi2<`#O7-G96eZJ%P23K*LaC!ELk z&Xj{baGI$zp}^0;-;tLyy~{W`T%0LIy_H|o*5U67#DKM6Zyk(j-yrE(#GB(PmGP8A zjX~S zW8~sY`3<8>L=_>H+Ale^wvGdyF`tM|`~_1Z&cpyRm86ZFxjqPIvw$IDq?DHjBqw*s z4YQ52NBXk&3HF#8kH7$=cRL|`U&K@rMrK8DQ{o<#F6xqGC_~d^6J8Ld-Dc|@3!~@B z@JaJ1loJVzm{>sw+k%#0Y{VQW3w$+$ZAC+56*->o-_}6StTvmMjMou)vv-wyKB`2g z7-V}yeVWsoDqOO6LY+ZC*XMwfH0#hYVX5Zh$MuCXY8$dGGRz?`K?Cv$VuW!GRqG{- zugoM+IuMlWOTl!UzCvMXxwSQ_-&JM^zr0>n>S&UT!^$5%2XRyir0;2SVI^-m7(!kZ1g#M017$XW(t_5bn2}-p;Kq9Q65$AZPkqyb}Q`oP(G@IMa z>27Tur5EFoNpdVMDYLXJNC<*HA;ItC2mp}yi~T{r$U#@pNIcp?8fP9nS_dB|X2GdI z)Uxe^iPN?~Q_9pgjfKbzu@UyRYzhSM+23{8gvCbpp6NFf$LxU{HUS1fW!ym!VGDMi`B$brw{b7N_x z!*6U34!vdO`U;K_VwqU<;~>>^CMnk$RFV#z`!o~hx`=eW@(Q9B74q0mxWV|s-4pk` zc=SAkR#h4-r(C1p#;aq`m;j>7N>dr4P8^a%L5x_)X(-Z=e2X<->b-k)w2m`};{~$3 z?C3kr4Qi692fvm50ig$pbC1=hgYlRz8rxW7=caj#%VK(?F~!lxHz7% z1c)o?6~Pl(Yg=zQ(Aj&*rFejSi{9ZI&F2-B)&x?0j$PDV?i3PwU*f{mJ%= zrryT?e|PImGaqQ3)M^hu(Y&GYnC7#Z2M(X#_;TZq{(qJK|NVc^I{q4;BNv*=eEG@L zp$r|(v}uNB03-u4?ErNe$`7h7Ka*Ue)N$JIGGc>L;FxQR?l-R5{}U^&&p*2 z#CccZDAUZ?#W_pJQJvB`NQJ;^Xrx?x&=-sD`>)?wD#Lk%;&h^Tx@>JWE{Z$b8F5(@ z$n-H`Q;JTX7wl%5FanYop{?vuw-&wkzouG>iUc8ZChKQGq5>&S57Gc2iH7QAgG+cj zSvoALYA#nPmt)Si7oPM(?X54Ymg2O^zpnNR@dD=SPvT<7&&i^>nIO%7grkhq6k^q2 z5TB#t9M5j;_x7T_`+L>9QaSq*AUe-R;B~Hp5j|3zQgay{^F!0XOqwQ-U^1je8a|;3 zf&aHf?=9QaQsOo!%6=UGHI^9O&X}-B;i9@B3(_!_EsstbQru%Z9cMM1_QoeZt!Vwz zQPonEfsDXTTawZ%`m##d`o0zuLcSWClO0Dd6yW^)2nzgvsV)}p`?;d^TUYHYrSH{g zCUU9qa6pDlpv+ktxYvYF!GTict7jfN7njh4@KP4xF%b+KN4%!!J)zoH#w6I@*a}_N z+7$pcNZCQ=HUBVIOK}+E}FlUqqzY7)tl@+f`b7##Jtuww+!Z^QjtNql9vsd**D5o$2h;-Dp;A^ ztHhh8)>SUSgU9b(^p5>xwN!v2qlEO$K?%Otqh&h<>OSA!r-;lQA1fTmDoi`JP$vJN zJofw5qIJM~s--yOGZI1}inxkF1ptnl9z3MRdh`6+{s#Hit71ohk8Dwq$VZ%g?Ab;0 z7k^kS1+wHqsoZIi;u(~JFA0x~N$F0Jet^z2s_~!1*$irUeL-1*$^olI^IN~Uvy=~o z;FOm|g*0m_+i;7vhAg5;lq+mVqq3ge=55rH}XQJisa%E^@~ z+?0>Itmy9AT`fhCQWO})Zz>f!4JOy^#MgkhCM~=$hAHjPUW?u5Tj2&MNxD6_=t2|WuKj0F9sU4~WjoAn9<){T9(_%< z6gElqZHkyq1Zq9 zjpG(l(7Gxv8dAPE&K?az#!>8RINBgY zB7SGOHBwD(k-9RX+sCC9`b6?M;t}w~pKjf}l(LQ&d(c@`q!=RZv#?)uqMk-g{DF`7a9!hUjqjUP(qRs&1 z=^l{p6=e+i`xw9SmLFH&(~Cs9AqSPdWF6j5P=qMVEdfM3e9B54vuVU8=!(9^9zsaC zDi*_gUs`mpjC*3w7l4{GlbI;Yr-6soVn7$>&=lMyN)8t_mE?m9P>@(N&M+S}Q%Y8j zzPf1tO-j~sEd(M5p~gqD3g3-E>mDw1ih#gSqQKamb_Zy{8N#z@>y>UY0VCCK97ga8QVdGa%BJ+@9QV-y?6Y21bPvB|=QC0rY=7IvIpHe8P@v;9 z!_Y$Q16mTSovTL7o}p?wOJ!5H{lj*&wSD;Huh?bX!!Fucjp+egbN>CM@;f={Ioi4V zD&RNjD9T8qBOQ=EN3et{a1cP_=Ik@RQ*^if)6P=KHP{FkRA&m(1X4wP(Xz0mf`*+c zGG*gxDCHr8aZRjGYg4*ASMGam(fR17ca|a$hFZ31;`#P+6$ruVh!w8Fl(>;uGFA>i ziSyehpcBT>i6Gl`e$hVV0Xs`Mu+SBnf)@>GEhg;gfI(aNr5Ij?QItp(1qCp6AKIpK z5qfuF?u2WL<`ist@L-GFZI}^%G1mNEZpx=iqtpkye*Xg0TBm+-L>~9 z(B7T)Z!8F!jXESK3J=maNhF;`DvpeB2(`Sreb94@=5;q$zmTf|f&t^vJn0n_1<(+B zo#<(js!fNi0Rlh)C=PARL#Dakmkg{pZJ(n1@E`0vmRc**ltkuGRp|iC;6M~b#tX(n z2cQE4xc%H@Zt8id+(h-W8%-+Pnn*XxnbhoQ@2cA)VgiBU;mMfZg2mohY!C$ zd2I2q;k#Q$HBM~4uX$ecLA@U|zS_97_44*!og>N#P!Jje2jDI?qFo3kD?2~qfAZfz zV(L;S-;gmoPtcX#p)!dX$jl@*t0j*tZ|wizon>eena-mYaU$cq(nT4_s0QIZJ;7Z+k&P!v1l9Iel9N1_i58pti@H-*vf46 zH0;ARhI}L6`iodw0z!JKU|2gJ1tl{pdNM{D>CMZ6E@h_@R@OHTzihmWYK{3Io-45) zo=2(WawtnU-YO6q#Banum(4_R)A4*NtDVE6etWcxDMhSvR4m}YC|fkLmxzE-R;P8p zlxYzba5cM->P>Hzyt){oVC7MxkZ8ypD4}N5{-HyM21; z@oExVo4m9*_uvX@mIJ>+{qSI>{}!j1JEv@nj5%?xv{HqVJ7t_X-WZjx zy*opKsVOFl+3uD;wJP(|5*LpLznd{hX(uC&ISyLy^b|TfxFRkchK3M1k|q8I5SC2j z!`+YA7(ESls@dBB{gb!*U5#fF3*#1M??%OFn?;d|u}x#S>9~ zB^#6k6~K{hmrR+Kg~1>ddTEEkQYVb-(t&YvVIBOPiBbxT2Q7_0xKc`5u$R~n6(8x_ z^?syb*^0&|k@_RbK?yJ8`y9ElD%Fp;y>`y9`ccR{I744RIYCEjKE?$06j|ue#(Der zXoYgxDEdSgM!buEfep(`5B|{TY3u@KHkLN#B$^7y@56uzA_KRe51;!S%nw88ig%eJ z0>Grp*S37**}Zcb8|Ax^0}+^Ne3R+10 zcPqVbRZkPQimFO>LOTKw5!Y>2G?oM){750Uh23>s@P*9cC9v=N%HlSx-@xn{UEW~EWl9qO<28sr`=AIV1P+bAd508G75T1)gIONd6$}))(Wf5(QiDno^R@6oZoD@L8x|#2P7Ep0MO`dK_<6a? zlo`Qc{^NF_`s*^MeIw1|i}8bA6Bip4LyJmt zRf!En}xJ-`KkAn2zvdk{Xr4B~NDSdsX zh%%x$okz%F67i7i|8}<7Vrn0I$8X-fe(Pu%HJdCOr4P3O2BtZjPfPR`cK|>Uks~#u znXqo+v1S1~hK9n-uyW7nN8w~MDj);<#COpN{_|7ZwUMz@1Wf-{EP%3>=*t?R{6;59 zrC!F36ZhNWu&wjz>EB(lCM#fmkwEmbr8H?k7BZ zv{V0vZ zM<X_}L_n*FN z=P+o1PS^|4lqbm6Tb(lWTY}w1HxXt-;2i|9Nm$71u(bZ2Uw40wkI+)I+IP*9gvmG1&-L? zoVsce$iz{ZTkBO&z$->;BZT~VHb&W>f*2;8$5BWn$0#KbIgWF#Nw7!t8O55Pab_#~ zUO0LhaXxiKCUB_^RSh7P8T!&CQ(c5CAJOOa-P10`_O34oBd?d-MH!AYa-hvZO<2n4tiGOLX1P5M!M z3W_iii%tpVO|CW0$S0m%;F80%H7RCS{6{)cuok|%4&AcJHggD_w)l2+F(_1&D$DbYs(=?n z(<*}N%xxUXbCp!;U6}-Gl8$5LrCA8WkOZko-xZV@sTv)yey`D&(gH%8h)2jM96xip8r|l3Qx{D=yz$lH_lNHuZZ+T6ZFipEx~=`~ z;eL~UJ9+WsvF)dH|4ZxTjT0xEgAWg$H#mIap5}ul{tN`VaN^$mTf4{iU)KE5%=!IC z_TJk&r}`OwXFSMQVn-xBVaiboBmPO~Qi3t|X9^PUl_cmdp<$fuxs{`DtCsQA#0$h(&b-kLvX9MP&Q+mAxwt@9 zVOYdysEuF=$c0{)YueBTr;YGct{Wp^E8diGydTs?bmSTay9sf=VVpIyC`T*e!`)_@l<)uVfvZEBFK^D20tN^go=iPxYh3 zg{Z~~LY%bl20sw}!cs-GP?V-7W5?SxQOG`a1Zm!}N#%CXqkgqo2D{^aB+75_c6c$L zJZ+tlr5px#BG}ai*$<*6C0Rbqkm4ZN?Z=H^8W|uS&rAoC&)6WsQJUcqjywWE(yNyu z{ijhQ_g?F(6fuLh7S68dW0@M~nc=MY9x+aX&d5l_0RN=j;nToZj*oDIa>cAEnz@VE zayPe6J7n~ukf+pJHXkmL#1(34dNBz`A|}j8YX^tYtdI2oQ<8`6Ajy1n^W;mbWmGE} zQAd+VNtvcHC8>Bt?8xK@JgRt3=1n8FC+1C}3($=-6?gumua1_n6HtmtCx!?^$%2-k zk9qe-g%m&}{e|=(`&7l}x8y!>7*WzY>G!H-j{5cJq;HYzpfgK(=shRtS_uc zzA1(wVTYca!pHY2O`^Gl+y2O97XHzvU0f|gJMi0ay(#752=RFwF&h|w(t6@`WSUxn z9W6*-GOkLJ1nG$XPpjB0dmM3El8d?H2V?FChyF|(6OiLyk#bB+b#DyXT-TTlqjc6_ z%dURbLq<=d4m0^1RR+q6zV;QyD%bNMdkFD(PxX{wW2Z3k(gUXBc_hnMz}bnFrX ze+=$J4ohWBgj%rmmZ$#(R*reWcG8c#x_M)@j4y-cj3W~&z~{m-eh1YRsh>g)l@Z?7 z_9u_T(VeIstgXgc-l+T>xu7|-=t)zN;P4m@sVY)-_c630t*6H^r{9KwERwFoLGrM^ zk%jiv)zcu-d<^rii4sTybwRpyi7(;(&=YhtPZbLw`CBn1;K0d>5%uOmf7fW4G?m~t zv4PSHqY^)sZ$Bu+){b48V`>?om@! zlk=4OD$sb!cw^=!M_Ds&FoquwjxChyz#c$fM+Reoa0g4nRlJgza=QtZ6_x!ST#K*% zuy>E1hUz16DWesuns$g;Ja0M;nYDEz`&1}9ugrfT_XbR0CNq-ASzg}nN!2p)6Qifz zmdy6xTyPp#HbddtfzGo>0BT9Zxi?g4&ZT3OOb6f+o&3wuGJ?NN%7GWY$&G6YAakXZ z;am~KWsq78MWjWz+8Vkpu;5UzSGK--@Y_erc=6UR2k(+K>}Q`Nb|fcDipc~cHF8va zr7LELT%lG}qoV$I-~Y1FGP1G*1pzypc5vC$N@ND~b)Hf-DBRe2oNa&s4nEEP_(1ye z`tAciHCjg4G>apHo6|d!5eK;gopO+2?%qAA+)<%MNTj*$1qlQ80^fe#fe#!lgO)+3 zI@*ezoFEJuI2;+1)RP89Nn3zryd>L6ssL~7JtEue`re0)mdTJnm_h>{b)H)R50}X% zU{GXZpoxHM5|Z;_@8S4-1_f}`@WuHtdoG6Fc7S!GTgM;5yJq`D9-eVk96!z?R@5dtPfU*0s)x1||L(`pVOcknhB4;Y7 z=jJC*94#XP!~n>}5xOC*WQywm8KH$I0g6ecaZ)k1T5kZC-0YO&GQW7}i0Sk4pb*T6 zM>oa;AEEZn&3huhrXF)MNjIuU}0?FhbPl4;!1WF1pYi^1hU@?Gfp{4{osGBmXQH$SE-qB zMe36iOY4JDn|p?p7pl!jIg(J?0|{O}zlu*D6jAPX?RXhJxj6Bo_<=8hJ6=-6jGPd= z6_LqnEAHu9iU-GuBhq-Gn@dxBkCq8rLz$)yg~XLQ(S<&X?C;}Cv`C}OM2dIXd=930DN8sOOqB1T5MMibCF2^(OC_k@kn<7m>}!%rSPO>iYvnGwP^cgr5R zOo8Py`OgWZ{{0N!F7M8ZQw8-Vrzs(XitWK@7bD3T_YnHnDlZy?g<r$$c$WXka*lT1!mLJ%qKeS4mo2xvKmxl6{IN>8$oudq`& z0_?2Uhn`a{L&{)QvgLADFDx2g zZSU2(t@ZNOQOzF>_nWwPOcuO+I zOiM>Tt8zyZ^f)^N+x}rwnP#5n1l+iN6J_(E%34-&KlA#1%9uW(} zh!J2RF3^o?tHgsDtt<>Gpyw9$`R-^L1S@h(2aa1}C}B8M5L>EO^%|E5%bO}LUYr7A= zx>`n}=DiOAZ4bnTlcYwY$ps(K5Mf{Cqe7U3raWdy%Wl-2LyrxYujZxB+ z@Jj(uK8ZnMrM~QJXhZpuD%aPazFqw&6}5kq6E2N3T9xP+hDM_8Gm}}Zqs)-HY!bSx z2!wTx#Xq&Zw{`j`GfA3YB@|@$WaNTZi+S~xQJ)gLz>#`hsudNOC)Hw#8l)VVWoe;* z`{-$CvG74e32{7-T6-vXknRE*7@iHiCr9RO@uhNVBdz0yzCJF+h|(N} z_oo?GDe-DBqNNKF8knDZ`1`A;G10<2MPvpk*-{9FwD*gAlD;yN zqrhK~U;H7$rHYEDAUMMh-&}mqX!~VCu!j-;;ZwyAUx5RGm++@kQKHy$;SlQ0r;0Tu zwU~`Y=GV=8LiIE#-l#Q56@@}Bb6_im4}3ZdM!*{uEy{6N76&3XrRx<57zCF(cU8+o z+YVfZt_=AHQi|6zj+oPv(R;aG z##Nn~7-XKr2#At_Q=Z(|ICgXx7;o)YNrVqi!cGr({Fs8b|3KyD??>Wtd?ibBXbkBf ztVJ4f_uD~7jGo5KGWCsD5Q`_{9N>f8j>ApP&hQ1fmE}m?17`8GtM`+I(a4*t_itCr zh#oPRWuB1&)W_6KmJ!IgOO3|I3g=g`%%{wU!%CN#v+l#uJyt6b0Fvb0&y?R7)O|(M zpKM-%ljy)WmD^EZ3H_fUn4PN}$9$z!l?qo*Iiq?S6^(z_AHggX-WY_v zNKSVKgQc|-N5CklnYssL>U1(?f|n*e0s@1RX*F)!Bz#(-$7M+&KKbHKFTr8$gg1|# zhL9D7Tc|@a`pfAk7d-U=Goy&|rMkW5R6?^78c^-;i4>~yxuY%|Eu(CQet12cO$SRx zL(nM}#5%x>5}Dc8+>e=?WOt>M*95QqSUGn1b=5L@!XrOm~1AN6f`_m~Skhd_o2r1D2YX>Os32^Vq?mLxXd2SO}jDlSmY4l0#wwM0CO&xmYI``D z=8%e2bYan zz*~BK6^=qry!oN$Yyjy3F+@gm9{lVjazD61$In^*jZsJs?opw`S-!P+pC@5>#8qot z09YI+g?8B_$Q~6ACbFQI5c2!!e=+(|O6WBCp@=-SWcs^qI=RFltSw?eR~D)lk*zSNG@Uhq_l`$K4S^$AJ=dj` z1X_-!{Um}r?_p(;R|$uv6M?lcG)m(Fz?rWcy&KPh{z?lQ(jj3g8PUm8&#F#*Zh+ch zr7H>RmXEhEGWB94;HjwCfU9yzOrkZC6t)-?ABtXsNiz-)3eXyBv( zu9}`^H;ZZ+ur9PebO}kxAJjkPh#My}r#7sS;ya@caFFC6OqV?az~EC&b9?Yh$IEED z_87VjQogE$Rl&0S$^<;vrPeAN}%bnHUmGlS8!FIV?4q5P^u0@_0#I>7!Rwh7$9HYyOx} z=yr2Pni@kfHR9Gph28qWG?R%uXzJW6=+Y&B5wXPL7<$+caOu~&;oX?)bPWqzoKg>X z)aYrb9)g_gB`i8_K5z!v3OGO2$S4{Xf(Il@JWs9A{06I-4$YPwM=P zEH9xk=&6uLt!O$7^v3o$mP#Bx6D*vZssP*EYXtVa5YJ3CBii z<>C;4bNdU_~^t16Nfb?``_%psrRw|DgA!$`MtxtcXhAmp4y%0e7y65=INbX?YrB5 z+CHs4Xx-GhuysW99)IeW|7Y|DG>c3b@j=fJ`*1?h^$|iSXh~m9uHaUpWb|LS9?~Z4 zY(}6H5;_h@M&iy*-*NRZT6A{S5jt(R6c!;bRA+oW>f3Zo#z;w-iT_NglTLf$uK3D! zl6Kkc>8l=ITL_05T0r(l^$H6Js-RnhkQA7pTI5F_H#w=~ zlI^Lpq{+B&oC@5eM@hv4#9F~B#C_Mmx3|EmM{JZcW5D$T1 zV|cmaRD`30sz|Cabd;Lvq zp>*{6s=8tXe()g9DHcc7jxa);mC4tcR0Vy=G?V8Mou~)6Yq@p7e)WYgjJy#tt;&ju zApMXs7;{OK;BQi%Sv_LA8dw}6+Ir#ysLh4u^PgH@2nS$JBa5i>ZB`9idURlUkFv<1Y`h}ca-<;z$i||VU6RQLO_VmVegdONaC_b z&z%hOlh40zZ6Udqg@paqzD3nSxv}g^bhJoXjR4MIA|{6uqE?dQ{dOtO&z|`9TWSlD zZ4OqJdC9lx3vm=fQ>igQmk^#<%Jl9i@ZhYnArb(< z!T9gwP8MMdb|z78bZ`4gZ6O3)DVDS7D8b}5-rsO)tYnZP29S5wSpfs_37JwVC*$Tt zt)<4`korQI!4NsbEVDA#M#+Wu?MxY*Zxm^t%fgv(03cw;tT_HDFLR-N=38qE*@0=S z6*6EqXh22aq@q>8NyWPaOW#d_3R;Rrq1%^1MfEL@h_Jv>`Crk20Z$V#p<)UlB^Qs2e_8E) zV^?h<6|0H1$|NL-gTO$A07qv*`;M-l6xj@+gNasDl>SRpghtEt&8a{9RBa*1ULTd8 zoE{zn7|Gd6Z?oBzgvua*(vpA^h7rGO6+ z(*L_p))sOo`HN%`=}7V;c&Za!qb_vO_NdRfHo%$ZBgZ6|8s`iv*kTrGy!n0gg-{9Q z=#vaT_Rf73>HtRA=7MR|iprv-VBOytMvLMO38~=OXzz1XeWAc8uM-1p^e`49lQ)zd zu?t1oKxbp}RZ@<9{x3leTcn9&ZDqK6eSINs!N+09M4%9?b>FFxXfob1YD#Qk;}6kl zPexC1|FC)vmFd#^TaKwMlu=kBj9;E=(JL3=(1-RiN;3TyVX{lX9(c%{BA#v~MhqDJ z&+ofa;slHOq$oGt>q!tck~8JWgC%otF@o4JCp426J(kfz93h#0y}WrqEg2z<1w9oW zBVej{yTyA7%NG%!K&mRHQkVq*+ge30on1#$)~48bd9(Jzs7{K|X!#0ftRmJA$CMnY zs7AK(DmnRSlCfT7Se&5`FIX;gKK;hpLXxl08H=&cmaYtD?0hy*0(@~kQ)Ut{;19YB z*8~73!jZ$*+K1JjDDfCoKpzQT0oQ`h3{(!EVCch(zTg^W27fE}@+%oH>T%IjgFCON zJ(1xeq14IFLOodpTJfHQcB9bw)R460JUqBjERZ7oUqFpoVRN(n`73ss&GXHWd%&Q) z<#ceR$^S(9h*zR`$z{cp$GE7TRk$;x2qCbXzq7dg>$L~6({nR`+Cbl4C=AV)WE4CA zH(wh6wMt5?n)Rgs)i7?IY;D&r&KB={e|@2ZL|;@XBCFBJILiq4@Ga0LKILjyd4ba* zL^HEnu4x3f;fUUP4bu9Kx?_wL(2JbrYaUPTAWazJS$ql*puc4EIePY>(%R4<6%UPk zwlnd>+7m%PULcr{I>Sc-)6`HUSAZ!n6v~%Jk6w^&oZOd0pR|5DriWL&v%Zj5%gkmY zl~c`$~?a4Iau`XMaWP<++ zv^N!*HjXpay{4DUXCTe6Uzv_RyWV)PBmPds}eYAJM)UzA^sdrfO%A*d?42Te16-V9?P6@(C-SV;JjS@D{nj&;dn{|I~`Q zMzafZG25|2YvGiB;}Z&%wYJn+J9)g2ofs5>sn3K#!9dqOpyxIpIghc6uPfujqy+yB z7=zKJzG_(`5>GvA@7hADLuM${SS~zbN6KXu&b4k)#eCfOHg>ivhMOBeGe04R6sJU4 zoczh-#tV6Bjyf(4>M@5^a2(_@Qy~BcNcd>>EgPV&pr&L+I{QSJ7G9<-`?T?sY z0s}5v3|ET5(g<57V~8Phn7zXI5dBDRd}D6%t#924n-&78@yO6xhQ#REG@ptdhY|ER zs6S+i>MQqDsm5&qeJS{uFfgj$nTu{5|1L4yKycp zUS6;am?}-USe>6d_8)2sc^Y&)yiT-Lq5Fh7Mr}}SCwzYPG>t5M>i`Qhqz$#~#GouJ zY__&*FPjVArV#8Yu1FhSMSbj(b8_gV25Dow0JI<=N*hxhAzgF^gjVK?o8DD>qNHrv z5*Q#E`d!gUV}rCE_!~%L;XmYU2U2S1Y)BL%S7WLBH&>!sUUn`g0ArED=zdHFenE+o zmRM2%*uN6JJ^|6z2D{~W$xK_|_S^|4)t*OMmjdEYgNMX9hn{AR4FJ5L&@_lZz2Q-~ zCsnrePXNR2T3Tw|d~JOpE(4sge?E;veqwsg=@RL;5a4y8IGzv*EsQ@Rl(Htxyt}!D z*5Km$LI9qw3px&kk~i39fNUigFvm}y!7q`-yAOlm;$3_HxPxe+qw;+Sb0W* z6Dd}AnogO7IT8ycOTVCr%^9q%?(07?H`|sYe+1f0tcz$y{O}Lz$H7VD$H*{(E5vSR z6WNt{d;nz7OomS^n5ur9NeOJI52BI`kaHvnz;P9W$l3X4nEl76yIy-0dY73dt zif<&cyD>J_$XI>+0!&c+R-tR;1z^D&wy*6|Woa6(B-6%gK3H3bhb`B)i3m)NI&JMe zt+KE;B7$^|^TcuC%fwHp4UZtk;7V+?wf0Z9YYQo*^reWL{+95QNsVb~OCJKmtFpo| zHBmdhf6$&FLy}?bun}e_9=cpxh>pskE^33IOwX7+TqGR=sz4qQBjitEob7~+ttjC# z6)U-(mRBZT{lnTqne7T2<4YlZf5utxh5;1!R5DZAI<_&A0`)0mqw(N4s0XNDZcQFL zUWoTST>?OC=q$rbakW$|-pAQpwQRFlyZ-k)A-*>Zm3aa-es)D84}SWztE z{Kyx9GSdx~31Fe)I2Y1Z138HjX$F)#LYysbH2YQ2oeW|Gq^kupF|2$K7?zl9ZAGv? zet-KcN~2&~I-2D=Vi|L%Y1!SgpSXkJ%2ebycoN|~ZA7b*mqbioiaXB>6E4wJ>7eGN zP{PFYHBO zd~^MQL^TLMRtyRx(C^!cNW>Z73#a6@DZ3TZU>wI&Vr*a(25Ysr`vJ8F^4c`k%)S&IH5BEPD&D@qfSWZDVBZUj7vkEEw6MB zx@WwQiaR}DN^N)-_lDErrW8tbpfKtLgv4qtx~jEE=@MG#c<*cX*7V6=9xs%kfC4g# z17;>gv$->6qDC`xECT`HQo$t!B?p!`g9GQSvAR|Ol<0oQ)q`;thp*&wTlg%_gD{-LMko_E* z>h6>hOop7O8OO*EsNh&xpZdKz=2PuB?D6D#w~SetPV05TegL)}ALOC^iOj;i>#@i< zB8Uw&v%1mzYDL`Tr{R0>>kP;KUqRJwK_-CKBpjeqLKJb?t<%2F*#OcLWK@$b0$Ob! z{MFh|!_Q?kVbBM)%{T!VJTv~zzbKSw0|Kw;N@NA?P~oW3%EYa@GPwN_6}{z=bgF5Y zQ(4)###Z?6;a49!1i$~y3*t0Hp&?M5BJ%@fCeP0Jvb8q-z8Zc^L$C^lr#?d|OA9H3 zA!vsR_ijQ?l}>WgFF%TW^*(wZ`>|1sWN&Go2 zjF(J2teE=pwMHY~O^TR&)op6tjQP(`3rnLk%xE7+g;CQ4*9`qgpACBi;YH1;@eBW- zCNBSmWNA~at`Gm^pxOh0&XO?myonAHzXC=Au(x0#=iR^RZg%(X+}e3bXSV&# z_Uqfnw*IYgS?ikCdh348TN-yXU)0?7e^&bcFaD|a6))X+1=7wU1-`r6%?=mWEhX3 zEChfH)xZ$1v7?yFVC6q#WTwM4k1}WX#-ENC<1G)^Z~#R47}YQadVfPKfEgYQsLuRM z$sy&j)L$~0NIG)SZ~a-(`23T1P)CNMp|-&Q!INz&8I-1{*(n2=Qu=r#6##uCTre6z zB_yASmrAha5f3QZANZZogJtec4zm14%V23!@9J9XgZd#1YEgF3X3%WDF)cN9D=5qYyYer5b*G?%pYs}j=6hUx{4GWv>`!0bz1`p!#b0N^H zhQKnxNd^e8pQARtJ|Pk>3KS|t zmN@>LDwppm47duoH?q4;(hvldK&{(WiuURMI9`mNYD;(tia&+5ca8+o_nz%x^aM#+ zwL)&Dnecqa=ufT)0i*MCc*a7}c;!{&#ZYnhzPLB!yEK|Ah7nW5R+_%&!yZIT5tSjX zSX3#QZ~=m1VSVz38;fH8{PAL5u@13xYh`W?aYfTKOhTyya%?ZcJQ)l!j5O?~N8qAq;a00Re@a9}*0+98N5wtj%On#Q9r_4A{dQKywA-6~S~MvWi!47tOC! z*W@T4WrXxExtsxcj=+prMR+imL_!5~9CD~S7X$hLOmSu5r`!kG8o&6r2NsPlEsUQ` z-~@O*lQW9FfxjHO+}}#-&VaS}9_?(KP9*{$ko+|NIA=7r{(W9swC?`R@nTqZHk9Nu z+!qu<$)fJ1BSXZ<^r)avkF8MGlZEri#hb7x)ql2q-HVIv^)ute)bF`|CCy59HDN(D zV6XeC=F%(8(mldbC?%Aai&1^Z2CnPC7%sJr`a;q9+&_&M!)50jjv#%Rda2ya{UEp? zcHy*t7+k~9!q{M<5N#kRZTIZ(!50;c*WNsOG8Q8wb=nY=hHCIsy>N@PBG0o0ry@ac z0QdfsqnZI|*iQRQ+0=Q}iAC%6tZ;EB|Apcb+o4 zXKA6;d|=T$^-H70bg2Y}1x72b%nVQ@%kdciBm5%<{O{qYC9e3((yBVYd-4xIP&Ds<+33OW z92pZROL0Ak9NMlaXFQ*98h0L0Z2}j&0p%Q%>u+&S!4FWkAKLrkCyUOB`;8xr^CQza z3^OuTfT=WWkpYUb=QyFuU@vSBm58e=kc(5~wLR(3Cf(rq3vvpQ+p+7K;=T(omh0{yHDZpz4^u zZFr;whyg+ClQ5G)Z&${9MK#gQp~P%H<<&*^GnM_uVqQJOE@ngd8t|$42=6pfn2MAx z3XE<>&f~?S4u+3q&`r@G2u)nHU(p>@G7x~RY_iRx8OB5glBCVoEHD3)4ndkS_g&7F zoq%t2+Nd-(n{st?eX=)EG=A;LqmOAGIE_W5bA+T{HL@VVtp$h%p2b10NtrAguM@$T zCX-v(`K^>{%`@&Qniu@Vc(MGsOgK|9!+0Sg4UPdSKn3&$`(t|H*!Q`g^`mk$L}o}+ z1)`^OXQwDW`uXudf1r9|2UP0beREdXYg2@l8W$!%z&TDr0k?H50{tli?-HtuH-h>W#$-<0t#~ z6#+%-J1-xvMVJTx6)_AlN;j#@hV&Ez6`Xz+`zR3xGRBB1IXsz^l^I}Y($>3Yi`K`V zFkUQIN%%>uRr0?#?FFljh5l#{wthGTCKLl%_?gO$XZM0J*r2t+fm4d0@vn3yk;|rn z_`d;mwWiH(EAx-}URw8cy(mvp4#mQQ;^II9SMg<=i`^#_?XOhwmBYkuCM2H#K8OFtNKh71f+3K%$CL>L&Wy^6*p_L3S!x%Lh3!2?{A zSerS4`}HoY`U1W-ecAL0)9tAbPn|#Yu;Dj`Z|L1LJgGnEUHCuk3^=@hSN~7@r~NPL z_Fw*2zkCC~d;`CH1HXI&zkCC~d;_&NFhT{G0iu(>hm8MDb7X0x%m^3r{rI4Br3hyc z27&;yhu{u5k{MPD3&SfvP+LfCL@EWKp+Ei7G!8(8jFUcgebSf^KFtj2V1rc^E82Cw zQe|0hhflewz7PgY<-LJDg@TPZ!#(B3EzFFW2N>Vzn<$)&NFoL*+LZ)&In&XGvwuEb z2+hQq#C}ApKwTrCFuN*2C=qxKb!`cyib;S(b%Z$`9b8dmugy-}@2^3+I8;&x;vuNN zy3x~l!TaxhkO)miM#oZI@;2~i+@1be&llDLr>N9e-#BwzwM7ym;6_jK*Zi!-(lD%B3IWh25DQ zsy!%98B9%XDC9q4l-;{>U-)6{LYPfJ*HBmm0x-`i&y8c?v+i8%(vY;mWOZ$&swJUWpYzXJ!4Y>-A$Y>^197IOJAh^8@KR*7&v}rLy`Xh+d=no4M z&napP`2o3MMt`ORIxII;k`I7!IvRKE-oz@sLE*C3*ZWspQ(s6m;6wSM zh%Z$Ws*3F=zSZ;*;9UtJ2nqkWnhX7>ott-$k$!%C;))m47c%z5=;6#~LySGpoOU#~3o>gwh~h^2U^JvM4exE&J&?%Lp3;luZ+- zVidme!gmIC&A2MR{;S47-a=kUZiVK*wtb?SrX`rq2?1tj#Jr$+3$=t=;q=O>_CvkK z?X~7BKUn)|-kMPl&P6yHC3&Vx;E2m(&)* zWFS*fg_zm&M`#blp65K^n|w1;3O>e2H>{*%lwk~hJ-f-;M(f8_mtr;~dDV1wiJPOK)LzB1=ZZh{u;ocn` zx(V9f=Z+JC(8X~SyB`T#J+phW^{UD%nFm6yXNGFDaf&!OLijL6LJfz;N0n$AAgg4o zm4Yx$Lg;UQhf#N~_pGYjEeqvJYSkNCOm2CjIb{w2Vu|ZV%aUf&veS)NZpyn+nlYfI zN!tY3#l~4<9?6DLN#X!#8`J`=KU&jJ&PuCP*BBtKMT~#R7b8dZT#l(k6zI3xH;w7_ zD9a)%Yg~H0EJ@&C+`@k-9yQMGF}B4_shUJ0;JsqW()b__H;;Qq?d$WhVqnyJ86+3Q z64kDIh~%u{00FDZCA_bmE+Hm9P+Q;M5SAC)TPN4Tntwm7ylVC+AObE$$eTiSpao1G z(EaJ{#4JaUFouBVAyziU@9a^B)E~&t_F~!Y64wn?F<^>sP6%LI5%Tc895j?ZIvPWO zsLg}JhK&VkFP%7ENOTcE4HYmh!C}yhVZ2`^Jxg93AtB8oZ^;QhxBpUe5OTv-U{~yX z;Thv!#&Cj6$LIUzs1q+0lWbQ-iN$?OX=0Cv#F!-L64x~1wYS9@0B(a7Vw_yI^p6 z>%xiWwQd@m)E*4FjoFEh6mM?->CAQgHx}Qj!J+@n|2TgCIDKCK+%{X@|AHt%BxkS@ zX3UU2({5eUlzu8S6nMg1fplkkr{2#^E!EHxFPcfNSTTeM+69Blp)4`M2Ott>r7RWq z5nv(t*(At7ua;Y2cB}cB%Kaj)xNIUU4N=G|_ob73S#3-p^*OLsJaAHDI{he1<_&Fg zg<=xz=f&0jU7s2MG{hB+Ac>Glvw%V8wZWA-!e}`ADi>4;Cni`(d8Iv*(=gLvXw?1B z)fbA<7Cd3rLWqk)K!({Iv0poM8Kx!D#^g(16dQD+@dIcdF;`=L@E6}2Kan14L_2G? zPFF&vy_nk*St^)n9UvVo%(MpQ=`zH8i4)jjmIeEDezkwY14?w@pB?TJJlkDdN|SyB@vUx4VF%L+9<`_kzSPP>opg;+>4 z*DCF2=FiM_zx#;VLK(g8_-eZGxB0hxlkz?W0Z{W0f-t>M0vl*apBC%!7V&OHWo)UBLGMeSDE|j)K2|3IirnoPv&po;*d3@+b}jz%!L4`H7E&A_`uSU_ zq=G@N7Df{43^Mu~6bNM~8p;lUlq3<~GTyZu>N9cvW5)|gP(q~cKyg>EqbL=J5!EUU zlbR<s6K`C}~;*`qM>4;F>qu*?J;B=!$*x+xJvz-hYmTd*>KqFGE zGfYUJtTUs@GfOKIC;olyiEKlYcbq0K6@4uk+9;A zm|vYZbgUoS5y}>UL1O}#l9{(0F~O<+EPFpBPEU#&WbRu0o#s|V#3k}AtW6x;A3u>~ zh5`21eO94Ym698(bacwz`P)%P6dAe8MrIC@htd@Vbe`4z&;N3~P&uhnK?1o*XY6!Q zhrtOC8O}Ik7-$CsA7&ccgrC#J9CQV(>>KS1PaS7Eqktgz$TS(P3Q)inXzR2jDf%c< zfGLq%4|W<3AZsX$aWK8hTlcBV^FEpu4pN;TN9N%=Ab|U6f|^Q2_aNDxiccu9jqHld z&~l1>PrZwaTg^v*qV~%||AT0Dum3-z!1N3{3>naYpSBCcT(W(9ewj$X#LUoVxI8S> z_@jr^79wV4DiJUd*pUk~m=dBD%Z}v8Oa}*0AvVn-=B)*y0h`gM7klSb#@GBbg;g4n zP4D*891CF#$*!`c3=)ft4B#w?U`#~KRD)c6><&E6vS4}-5%o1>-gp)7;eucMj2t`BKH#Ko05W6g3(yMkz-;fBQjzq+S9KZFQh3$-RL`IL_fUC#*nL& zEDsE@@OV{BV=}6ZwkE(oL`z7e&%hpg*0kqMnlFzxW!DBBz!{}K%oMfiC5vx z4&~D`YN>>nM!;4sMCOIzbAK{k2%X}M=&j>+@nuq4Id+byLra&=y*}6%N0priLZy$P z9B@QLxXsDWRvn5ye>7iC7tm9-F0F9L5 z2 z9j5pA+M)G9I9+_pTsb0BTZ6w@(JUnzCgHxR{8mtc0YY<-=wvd6;AERFw0`#3aZ%wj zW=yEcjMtE72Byj-Y_?(2bW$b}kfQ`t5ypix-7sL7`g^|fPn)%0mMsh!0WZ$f*PbY|wG{sihSl#c*R|2=O?Ot)f@ee6VP74v@L z-QdP$KahS!({KuJ(R-J#S@P3Rl@IHg6z8%P_o0X;xmrt)zm_3v9Vx!A8ZHqQhM4jVY# z;i2LpQ3(bDfc|!pjn68So&#PZhJ=_T78}2E={WNnY@pGVFI1ferLL5>OdRJR3mV~=pQ{pXp(CFUG2aEHa z$L(F)M(JNHQMz$Rz)`wvwV7akbAgx`Z7WH(LTu@7;B}&}r?H8txVY{=)?QJ9x{xh3 zD{C~&1tzPj`3M+Y;MSObw7KL?;EbXcM^#5QumOlCOpPB%fW@$2R2U1P5`2QO1}J4! zKN8=5z;0&tt0)CzWWbZ%q2WX!xw|u0hsI3iXlH>&0i*E_=d0-#OqSr(G>)l$5_lMv zm6c)?=VK7R1+e+S(X|o_uaWsLacD`>_&W$!T6XO9%w`k}Q-Y>e|6Qhx%es04lJIaM zbN$nv!4JS;c4U8t2WX^sfAWUmWu3#?-|U~*@APgQo-p<7;n#{c_nzB3qx5YHSwW|=S)1b|MmXsi*GeS&teJ=W-%JP?e*otw%)g^!M5?%pH-^tO0T{s#O?U(9 zqxAd=3>+C;JK;5@3T4>fFytSqMgK4zG76|u>Lh6B8Z|RFox->|`=*rU3sj773 z)xTO`HyUsHm)a8K=;@Ld*WtT&d>L zU__5m(*z4BZZLcLsxtjgKc*cAuQcbMS9>BPOQy_=?mEGEo{dCFk6{_h1Od4kx-{8v z&se6+I?liiU~GM%fBBbc3*j`_rOk;^0h-pE8VBsbOTt^3Y9%vADhRV72jor}j(D(w z;?%tJr{j!iM7-fBf>XqV5QAySKz@o4v7nlPpvvM0280}5w=-yqAV(;u7Md?VejHfv z?!4&eKE^~acl`Q`I!PXr6tyXht^X_b^gUP~--zB^mH2y72wCUnDvtkOxY z)l0fr$9P^_TS$6#KA|;Uc?ZPEHMV&YfUV~cn(pLD*j{rBh@cwhKXR9K%gm`(@6y^r z5H2sFT`Oe-%BgN-4!o`Okz8d;e$+FJxU2~$c)pC+&pe{W6aRUs; zsL7iQf$CPIaqi&It)nJ@F<1MauD>H7M8g3f3+zH5QE-&0s6(g2$5M!?nzXywt4_T) zgH|aM$maU+u3Cw!(^mHw&lexwECffJvL%57*i(uJ3nE%Ld>qk!ppq4|)Q6G&jNx66 z9{)6W4dt9}RoLI&R(Hv)7=I;`#1a-$Dn%`(wv)JF*C1*(*v-Yk!!D{VB%Z0F_Q1um zaR!2CE441RDr4o08nO#@{z2>lxF>^fRq89N6aVs)@sU;VL7_-eC61f8r7$U1$)6kO zd@u3_Sm*x(sy%A3bIGb35wX#G*tjD^zBEn)f1qiSsZcTu$U^-B`u;t%1mV~1x_TEm zbK&-K*bDtqKG^P_R;wp-(*hcwq>aAw<$(wcqJ*Sj#(oG@f`$mQmvK@sh0b2cNo1az zEp9(<{EBSVvI4RUW4MqF^AYIX=%zl%P*|-qK3)!Dz6b5u$wXa(af_`#{@dC@&QWG4 zdxi1ZW<*uG&WM%{8CAzzOuY_%x++p0@eX|ezIG>irE&VWoy7UkK$!v10E0A$EQ4pn zXN{D&R{t#nw>A!2feMll4SM%;9~8E-v3_gqfiN=iufZ2<;!mml+UCk@mU4WcACRFM z8G6kh9rlL6YeZwd@9NZ3>tT(B5*I5{kvR>)6rlwiO%HfA1uNan&3&{bEWRvc{E1i~ zz8GY%wAOp`xamVpYH_2k_`A^%Oy8jnP`}F3KK417uyN3zyuA|Pie&C)pdmpT| zRX~psfQf~uX_N{-Cxfro;m|s5FfX8$#4BeT?gGAQ*UYH)wXN0e3u}V8g%afDa2c(Ne=}fYU6n2S{2eWI+M@()w|&SV9q^u;ec&0|LO)%LO!iGHK{Mi8Av`VZ~qw;87|y(gMW|*-^@Kb)Bs$Lb%>b zJxtpX+=#RpwzV|et7fWK*YgYL{D8jw7Meo3jWlNDz5^f)(h@uEdYF*tZ0lxPq_{#F zpZwk(|HCVS=>b3dZMwo7b!aJyb-C0az>jMv5M^<7@|cI!79zRh z7lXf00Dc&<#X&&w(c4{Z6VxuE#ZP0`qOX+}dH-tA?dChiJ;Uf|O^7lWP^-pJ^=H=v zy|6w-qHxeuTe0{EuxSl7N!(UZk}a<`KK;z`6FFA4o(fiDoCAquG4f6dao{s@Cn}j@ zOUp3&2Fr}IfC+W@#@|2u!E0&@iKQqAP6X;ME*?`R32Andu?eo~fDB^*PBV2xqJVpl zAErl}|2%cl1I7#GHad5_!ZFyUJ5e|e<;rYv`Ss=mzP@PvY;w@}c=6EU?nbjeyfm`{O$pqo^am$Y zRsPgL-8;IMcTeher;qD=Wac4_7j&N2Idph?`_A?or=HzDx!r4hv~@x2u;w?X|D^e* z#;)S-<|%^{ryGOz#D^!&pLkgR4gDuIJ|1o%oI?K_{~Hs)=)d0iu?}MxIyoP715MLm z!zRLzB~#NhRLn%{uwEMW09?BtB~S1XJ(;4WFRz50ETq*6c7t`SWk(}_yje~mU6&4_ z2vN$jjtbsHd=T47V)|57!xJz2SnY{2(^n?6O`$JEp3X@9p7CusA2H(C_C{QAcj!Q2 zg7iJgCSzY=;+&U_7s?k3N9kJnTo|jqvrC1hEE5e>SV;qw5S1$^#D`!H!fGy2n>hR1 zy+g{u6A4(Vc4uGh>5w^VVWU+>JUwVWjw5ccOlMX>+H*)+zZaUPACl>&KV5quViu`a zpE+_8I0E{31ljxa#=B4^eQC@zrlgqWrZdI=k!fW3e}l*A?_L!LnTSne zz~15+jnRN}w9Psdl16F3SX^)4bX4t$JcDwI_6uR-Es(;wt6KFAWaB>}An8`L^FJdA z0VTo0iKT#V_a8rBUnp&4!n0>etSD7f2QHU0#M=R$RPMni@Iu;&DRb91I)7C~ zy8JZWLF!$GrUT8?MfE65DkrIJ4A#;DPEG+X<>QdE)Zw59rPJ>9)&sv@eR>qL*70N%L_q zV@@5+gevVKiGZCD0Dcq@jTPn@7cmGHs1z1M;}CeK#A301wR3(|Eax4$6T-KQA=Nuudgj6=9>YIM029eI?F(9@0qxZ9s?>E%;6+cG(=A?GhS}8F=khUZ~sOG z;PcaPvosr@Sdo`q~aY*s9( zegVTxI$2ADe8yV%$C08L=)|2PG9sm&W&MC;*UhIAFG}zMzh3eVoU;zJ0zrKxpEhz!8Ml0s=kae~XV$$e2sVkE~)6PLL zlahdXwle_~DZe(`{jK|t-!(GHjU!ks46x{f))44jh@;t5RPjbYjA*a9Ylh9(DN$Xe zQsCul{B&4bNa`g7iJwv;mwkr#=87{3EKCV)B$Bm%PYwoL0VCVrG=hv6ng0HJ>I*@> z$%nWN-eLa^4N5r!W0TrB3B#8lI>}aPcjh}#xG}*6EKR@lIrW7gtXzxf^zi>M%`%J- zvTY*12J^+$2O^PVr|f3ePCaa>fha$>)cwMF^@WU+(DspO%M1xvek?MdLVm3=B)(HR zoE1*mm=R&>F%eW1jD}gCy#3tTLa?C9%`7smJ4!>qnRn@+SU+Q3;EBu{L|Mn(6FpOH zf-nN6x-YALengZ2o9pf(7bF~;5rbA>Knivfd!#ZS%v3ve9ukp&>!+f1mpa#UYEPup z5{{5M>NlYg!4MRZ!5%sZd@-fE7mS8OPy>l-GlUcMh2l}%SQ&4ekT}1*4247{@3;ZT z529@#!stT8WyLP?Tx5WgGP{NSEm|5Vx4bp+cmHB`ooJ~Lk zrrP+X$`%%;jAwS3OKm4@;DZzYpW08;tFCqw31L^?qaR)K!@_7CJ&Qri|-J0~LW&f)xl@8A%oM8^aTR zR9i?X4l)IYiN}N>(TKWX%!`eMHgMVjEZVo!&m_G=&vc24^hDSk6H7`7)ja!is5zGD2n~4K2R91`7F zX`Euy!3?0bjLa1%!AWl#cS4OKFc}}SvNZkd-AdchSJU`s=98!&btW^Q9ATbtn+tsi zH!9auOBf0yhYg?k{)$R5V6pei_toB!U94D8GZ^KYkWi08a*{3 zZM{wok|5RI#GU*A3q|9k2Q?d)nG^VL&7ynUFWPssFKs`uySsT<>nDw`ckkP|#mvCl zre8We-@9|_?&023mk)nF{Hx;MhMWB(CSNi+J9+Ein{E_1u5rx7&nDhCu`zS)#IN)} z-G6awug;4)yLy-Pj_Lli^`7o~r;cwuV`jVg$>#4i?(paSUH_-`tO`a`#{$01rS29auvkx4f%u)iPDq2 zAoh5{;+9(=W+5>qDO(jp&M|RxrEbDFO{%@`>x;$-Rey}r5;4z_LDeut<_MeE<0dGw zu@Fo1gk*g${{i1rt_Q+SYJ%Z*;5`^T`T%d}I1g5i?~V!DKEmrey6GK^@6%I|om7M6 zNK-MFdB;28Y1MMcL+HhTNb1X?@gE+wvu84I44xL_z*mGF0yJas_>By};%9T4R&cKK*AFF}J&rnJ&#;k~4HISWn$IPf&F)hRc@qI47h zxQ;~BR)~FeW#SwEU(q`3Mb%;%6CRmBGoFv&kTGIQ4@ug2tijT7M#u|=MEjPPN|=j)+O5^PK7l-s~YkroXnUVA;eTYp{@ zjki^#kD+NwpEO(vk4_|MN92-8a45+)Kw~;2!^DbeSY-I$r?)Q!%GurRgYGVh$5kdi zi}|N$sNC%;gUnsatlVT@(JfX}wT{Nem=R(-jS!ozV)L@)u*KGelSO0eh1Ji@O>EJD z#6ZLVa}0>ZDoYc}Wegy1rg*CZXchrm#NpMH!7SsX6^c{u-1`^Jw~bB!UcxHSWk9a46lzO~N=I*8J>Vgv1-Rt~ zHr6{Uy@*{tVXJH4sn@a>pY4x#i9?pQK&_ZnA&0yV$?y+ zsWN2_`FvK#WGK&gNLJlz9#jjQ31EFja9HokqhL|^)gzRaXULP6E8FN z254FByyn27b(ww@uW-z{0(`LL-3)QN>GG_Wjs}q!QQJ5z)jU+ z&`qYbQ{mIA85frs!jx(Eg)te>;WAuM*&v9SK<|UV`XWg5J70L};3pT|hyQTA7$~Wx zVL1oTOtw?~<%%R?4dqyrA#J87K37#knc5=ZErorUy0zV%jbYJwPG#0}H024MmTDhH zOIy}=45^n2jvFQN5kTUF=0ZYW1J5gwWWlNFC6(%aPS)#g9Hqi8(mw$YPi`lmCf42j_k4i}LzMK+(H6Yz?>Ru^GG?OE2g zxPx%|nt&7~!*e!@V)|?2#WE?ibdK{^r0Tcv(G3o9>@f7ljEW_@QT!M{pxKzwN(-68 z(K&JdqBqqVWpkB=*1C8>g$?#~HI(xw)=+f-T6>yupK0}xt>QK|R~U}*GxhcS&S&l@ z+IRix_{ro_D>#et5*8KFq>2z#!{jS1B}b2D>*3^N_ej067+N~h(3@X7yJ(zS5w|`- zk}gl5NE3D*JRnOUj{u4!=Rjv8*4Y*va{M*@J|{pqmMLJZcm8A1IP{yNClgl1eF0t9 z20J9fA38bzsxmWNgvMjvR_icQ($9`w8@H#C|cfVfr?)B@VcczF+UUTLY@(jGL z2F!riw0LL#XI4hcFLBXi>yd)UY$;Y*Ggp6YzUWR>Rs}GRHzgHg=B!5GAVZVBiGxs2 zhKjOcGiXrdmVvZrjxX-eH!H6Qt#MW?7raEsCB0Dh<-GNr>{2A^z~nZzU_b-5sh z{Kez=e@!fqc^rw%AK-+U+`70Z-c+?eSqu*2RAR3C@9f=qxVB|kF7S7r*IKDWie!a~ z45Diu95P2lR3^1lG}efU10pJdh@!GX5oZMfAu}^IbErU2QIs~A=73fzC^9HvSx#x? zuz%lyC*y3Xr7&+EGNxDzzlN*sN~bnm?8NVVY~L`az` z-JO|0iyaj9eACU@-Z?L+wI4JVVO-1|&}URdf_u)5S0Z4@Vi1s0fE|yIJ15e}6B#zF z9**$kiIx|;_r61|b##CH{!#qVA+WI;56IHqk2Z134A>0PgJV^6N$0*Vxgae(^mI)M zg38K6u4&a;ubqGcp+cb^Dq1=-snItCqpa_gDWSd6w{6%1A`zMel)W%EvH)*&Z2#>K zu61txX}Qc8p?x%10Dwll>#YviZ{@?A;yGwO`qccQo+?>!dJni6G^TpSXFP5n< zN?~1V$c1RHLI=EtS5r)ql`Jt3T}b3Mvba-yD7QT{GuGNp|K~5Rbq;*M_+m-C9s+ko zT=d#jv4y-U(lV0Jw~Qwxq_Hs;YHxvw{u{d-;)4WJ`}nQ3=6{YY>8b$UK;Y66ve5xN zO}3H-wl}N}uEl-D9gWfS=b3@b%FCx{V^YsX$3EXXo1}o^pq(5QBTo6*X!ABbhYMml z$7kSULQn%ysD2GQITc%3s?ImHTdSS-V;M46JD+cX8>s8f;4UrCXr$*!99d%Qr zJYW^jR5(DqTdUKrzPwid`k0M&8zH`# zpb5si&Ec(cwf6pFPYHD3?Rcj-yTacWGDs6*8p|8A1kA|tfkLDSvGFJPJ5zy*BI45Q9rqMOI-icub+NIaX#R)ruH3O$7ArwQFD0d z@Y&8Gd=!7chx;egF8p5*0h8y2IaKMz-sH%P%}!INr4>OQNXJ%Tz}YW6wV0gDt;<3{ zA%-rlwZ3|Oc_C$KETL!=&PUX8dW*>GhCONA^q%uY?URg%C;y^Ju16|B*#GXJl;dfQN;Bz3<_4+BZ zm3NfwF4YFt37f>lY$K>%h2k6|5Z{=mKu%jb(3_e3+?Kz4p=TJzgpqT|oB}x+O%s^9uKUEZ0 z3`sy5xWxV*V*_*=xL9I>&MwXw_%NC84$}@x0QHDTP7E>nEs95ZU)s3mfcKNR3{#Q__ zV1aA8Zz>duzinZ!NZ`~c&UXkJ^+)QaoXE&=kKzDF7mXzt@0y9*EScb2^_K69CqRwl z07XKp(2-%i#^*R}#Go7WlKKN!FuP00Z2xqu2^JS}H)sR$vEBl95z-lhlqHms#Ma>2 z0;ggs7hHiqbSu6OSG&Gc|3atoX!be>M9vq$)LZ%RI}aAMfvBt>8(WC=fRg~de37`i zhz8EOp55txq2vvqJBCs`u#_$Wz~D43<~!RL;wUI-1Ao?Bc^ z6gwL>+^GnLwNxgFP$3WfI}AyhjjzYjV5~GvYxYT%3u*Y|e{-*~dw2&*d3>>_?h2fv3_HZ!KAzu!wXA0<+2tp2dFvHv2Ove}j6tcbc=f8=8; zH{`RVe?SCQDW;bNsSNOP=O#Xj-DzU6FN)JYg!>>cfzEDN=^+ISPo+%YJIxFOd zzhtf9c<91vD#OMwNw{AAFHqIa)w>|y_!h&%f4_2}a0YSLrIn0=4KzECQ|}7yP)Ou+ z;wKWj`4{p$><_{efEQoh=qpbsFC@btk-%Q1kNeg%n>q_fb$Dqy&uJVKFpD`eJ4{}a1_ZYwa|l&UpfN?TNdv6n1n+i3*$sSi)+CJ|dag?FKD z+kxC_Q76$*$V5e{TEhY5I@1R*x|s?990;Wl#KvszcCGS`&|~~!X&cE7P^9PFo>T@A z?YRO72Wf!{!OjU`Ddfx<5_?P*)6YA#yimFgae+$K%r{5fiUc+u3`cFZbD?d&ULg*5 zQ5$?gJ_x7`&9gAQ@8>EPN?lGnBzp4fTKw4@7P_7e(t>uebfZe2{Omj(3{WC0;tO=y zTyFmOq16keji2J~(Y1)!njkCxVGNW|mhTyT5J*ikH1eA+$f%gP3=4DhKYBssLcSvx z5Gag9)}w?ouv4UZZY+Nvv+4ya=b%(7l23~tE>2G*{&&uJPUS-WTc{r2j$F>4kavuM zQOHX1*>G73SSkn>g3cX#ZnYbcrSawK%k+o@M&$8kxueXOLQ_$N6YHr<87nBZ**^rD z*v+9X19Sh_(8di?gF zJ&`%ANA*^51UHMSe$Z>;tn(qE<>>G{kQR~6k?0;$Ek*qN@V!@8UJN;P^<9U1fyAvu{Z{Ge6IJjb3|Jyj zI8&=hkta%rtRZiz50x_r`}s!u6O}t6Z&}M39+;_O`e%{Y_NJo)iO8N5h~d{!;#gT) z%Q6*5OgGqIZe?`$%I2rjfSoD@BL-CVghH@>+3K<0Ik16qgNra(Z0rIsjm@%GqWX#D z&Dy_RRJkMORc(I4dzMCAMPb0aHZR%Mv?Fi^Lb!LN?4mR<1!Od89%8D0Q{_Sw215f} z-#HSZUeWT7e39$Pr@?Ldux!-A43W9Bwxiuo@tWJ}e7Rp<2nVD^J0=)Rt`&@m652U6 zKxH}uOBzdxVPk%eQZ0SHs_2}fgTtSC%|>}4d?P%^k!^D*At?O-t{urF1IuboOmIqY z^Pkvb?T?87oyCE*ML-kXticw6oZ7UpPuYKa>|zzF{4l4xdlX@}+2$lRc<@RnQX1gLx=H8Ofx3Q@PBJhw2ek=BLi;;Q@XU zI&v2ea6!%sNELtWf2red+bfV-ewWujtihwlUjK35K>H)<7|<^ezM$XySo8VKdo^xu zoZmRAF{ppMep3D3wQtrg_@D9sV;2ojNzs&%t+-6>$#I;Sp^<}taHKF4E>D|>Xpn-% zHU}$%oghY1>&%{G^Ghy-*DWkmVE|Na0t}ZNxTBo;EF6kQ}<7RglM?9aBRZmmE#aWzIT z{8kPl;&id&6*YVW^e}Q)y0k*-`Voq*_=AjR?nmk^uC}|kRPTr?VbSFT3!4F@5Fe>& zWn8yZ3x5H5v zaO~AQc|p`nsJ77R^2}ZSs&Yr5y1GllI}AZ0(wrJ~x9}!vgJ{!VDj%JG|H>Vu z#obYABDsntMg<>RuYZO{t;cxiB4CAP0J|OL@EIdSD+U*KT8DhUdZ7$efjE@X0Iyx_ zRSR}%xy*ZD&2{*hxTDb2y9g6unhO&xX`y@epI0t~Ad+lS&gxABMAJrsv{$tt04M+i zhB(7y2(pN>yhs?zB><~`!}lr|qWBszY@0-85x@u->AlLR3~H6QCgTJi<0Hfrdq!~} zr6C~ZhA)~BskTUvl+=c9RU?^1k%_GUHv}zQ;|>IJ-Id&M$|hqL5*xjD^~~aC`-pK@ zR`y!Xlv4reTh*s*v1HH?w}SWvoJckHsh6u&2g!v2P|zthRIRH1Ugv~|wO%r1TzD=N z?*rF^4*FOJ(^%>md~FXJ2|z}tViCT8%-Bs0xCEpb(wA0F{OigaGKC{=hg(%N=TKuU zOp8P@Kqn%F0-A>re*`Prz4n+}3c_4jpL)?Qk~`jy2Q}q{knlOsJh-Y#s8N%7wT~_^0&(V69L*C~hdrcUEI(1~Noug%?0Vd%x6e zk;?bzpv|4pnG-3)8_N9moSkhy*^^Ry%)e=XB>I!}B9~zVRZgG>3P71J4?*-Knfgr? zmXy&N;Iju1)<{En6(whB=Kxl)W(7dJ23XJU-|Va zrJTl27>Vd(U8W@`Gc7zW3XGoTTO00o#%&&rXTU5;suQ9BjhT^g+3to405f!_@IPn{ zSJ11f&5GKZ{%UYzxaVyyWGI5gCeea~a+n4|+3u~qZaluIct>yx z1BhxdMG1Wr%Wb*2JMyWNNP-r?akczwX*N+m2^SP3uIJBIcw5B~{x?mWad!e3)~z}Z zKc|4QWx#IJWr*~?1>OY-!VhMp;Dk2@lWvaOQD#A=Ce69^ni&dK4A8YsRnJ)mYFK(VQyrc9ML7+-=EUOR2?k41hs#K(rCIhyKJ8Dh^hIuYIPA=0g zFbeH&J-Biq>w|F+1LTeofe3bc$+85MOtn|(kln>f3sI%$lf)#g;PLXd+ecUEB(I;& zD!RG_3;>ZvR#Gfsx+yx$#86uR0n9C-r-2r=;I1u`<<{#f1eY#+12bGfk&q5*RU74s z&Cg#5S*l9)#Ih@n0#m4HRvV_th?%^5$UQ2LrZh@(xD7Am$yMpvAoodH&`5%lyMt8X zPoijmHB>e=w5_?)et(6#vt21qiQ1y0N(OAi%?O#A-xXOVQK|{eV<-q52w1-&lcc4j zR-gWxV=Kf2TaZ5t5VS6Kk&9ClOV&`!X%QJ0cZ;SGZrpZAt;q+ zn}@yogz64SQEN~(^(rw?38F~1@w|Q|AGQvv^^r)jUJ}ELxT&B_6Vvui{jSx`FZ@V| zUP6c&X@rcym*)FO*lI&9p@_shQwf z_y{x%snjJ-(A{74RS^VaC(SOI^03@J^62V?(6d5EmLl^;z$EI#VgeWShqz}nZmopH^^`~Ob&;Z#+6ji2ywWnKL4}I9mSZQ4kfn5~F+ul^ql>Kp5zF?b0vZwu#&Mt8p!zovpZxG) zmjLecU8{aM`a64kt9l{$ky@CO9YT~Nw**Jw%pE17s%+?W>?Fdlkn7hbJqnZlx&CLh z%7r|u(bj+i7=e(`d0QAgC&68nX8RA98tL=PR4j;a})wdt!}WjV_QL$ z!tEHe73@mvk+UYR5!!w|{(P4|4&d;#rl z>K%LI0Zxg>X%`Q0QN5`D8&e;ediKvb>hKCgRF=cdkioufK~_Q%^NweLNB?aVV<-)g{&25cb2AC{N|6P_Tp; z;1`JjkDMy=FE=W8) z2L31=Di|SUq@`g`<~J7LnFq1`xnHkdh)s=OCu6=WR!EIUKW7jd34kIGSn)!V7IIoj z=4O!u^lHTCHd?J{9{xJAAU%|Y!${V|Q_G{|N&3H+r$G+l)&$|3r*FasR#O7k1g7&V zz|w_43Ahngsba8=1Y{vdWk9WT>;X(+7iEzW%`$Ksh>017l+=8Ah0(<|Auez}oK1PL zYFdvW&|xJBcu5ePd~#|mw?3gh6RMx~9yi>(wz7_}SZ+Qw0PuBCP$<#KXj-RZGi6suM?E@D*^2|#`Li`VvjUndE(#=Z4w*zo z@nh)`@wP<>tT@;}@ydWz{8fA3icDFM^TF@W@`Jh8&q_CubyOy%%E4Cp5%B$(!T5GU57U>DfL4E;;|2niOdNL z$oH5cxqsv3MKfDIIOX&&^8CeT24fLF*K4oZt8zyY7ZFaez!<7Bjj_%8hyI`g1~7st z=^jZ$vhYbrNE&XidKTB#aOLpIg*X6mS{C%hAeGi5%SVCh=kP0Vb{Gd41l=a2AWI#M zAXaeKY%H{&^TXR*D7H;o4U&x$75}Up)UFKmS;lmIm3t=HWM~df89Sga01DgKnf|ki zJ59$K_DQ+`hgBbTFAtD@Q{6u*0$>{(Alu=!HRwxeL}mrbwgfsi*IJsd-Vy9#_9DI= zm8>x}-cGz4S{Own^O_9ei{}t@0ywS#ZN>AIzRaEO9V>-5jV3FGLBfayaYDnW6Lmy- zmMPTOy0%abCSEt=aPaB=6-3SQ1mi|;`lrer39WgBF+`!q-IjX5SJug%adrL#_D5Ps zZn#p6t}IT(l4O>a2Um6~(Fn~dNIBWTo|cd85eb|B!JCPv#7-1;_vXG>c{1fJPFm)VUx)F@Y$0@o zSDt=sFfNVOzIf*PrvoR{5C?(DCY$Z^w<}AsF7QeAIXag!#jPTdLfQMaXlOh(q0iSJZqNnfioIjq6CkC<*o3(-V4HkQ%+J- zcMlJ(kZu;dY^q(~$}<51fnT_Jy)u1;G2{CPR-~aH)hOA$xQgohLzgy*w3|X;L zQIBLE+ZE3)sLPJ(e}%ntKpe)?<3I3#yl!46nlH80YUkAzXMxqh37CU0?05-UwIEXJ zk#M}rW*8(-ELVm*%TFY$+bBX4Ox^CivwBAoyj|!kIcAUIAB97$n~Qs|xGmS_Qbc!| zUH~PBWdKlY$gTE$Ppn*MUey^M6QCyI`LynY!-*)X+EL;tn(-ewCPdRUse&;lEn+J0 zwc1suRW5`+QZ-_y1sFV(?X`hKe%z}mI#|Pb680>v^Wrq}Q-9V3=GzV~?OZfhD(klk-hFu*Wu%8_! zmxnjwl|vD4Eli!gcX>l@(&E@M3rwaV@DWU)A5K}1xQ2q=v|sFZx6tgH~#W30P?XK+UxzmmH;kAH)skk?Uw zrYRwV6gR*o$!mFj=FmoYN3?}}Pv|MWA4U*_H2&Q@a5A2)<8MHnz8#N34%WpL(JA94 z-&`1-_G{&Z;u}w6p=2eZDPlvwLKAF{=nS#IyWnxmllro%3N4OlV!(N=&+Pky@}mK* zW=E-f(U)>FYqVtSE16Z5aTjiZ=;94Vee>)9Fg)2j*#HxCyZ`C{M7KJ!}|`tKX~_Gb8zSWHT_ri zAKd%T-UoZf_3qmJYWMXsmvj&9HanMfp3^z7ePjE)_EGI&>l3Y0S_{o@H~*;l#O56u zf75tr=tlznIjbHW)|99~2XOm%L?$e~kcA=Zu3qfRo5!k{+S52D6p8z_F ztIWmm-!)V4Q3$vORvi3qmFw8;Dj1ekbfnfoCZn7ZLd!@CIc`eT4*vmJvJrC0-%l^2 zRlLw#KcKu0ZY3ierK6Bs8Iu$iN@BEg*q$|us8aY5I9}Bk764qwCn$mK^xt$%c^&md zG&#CCOvM(2pf!*%%}OR==LkujU38hPPZjfE@O&nGah1-F<}N6&V{co(b|Ws;SGAfs z;$#|xpwmM61;BiCY1*|I8Vo?@mg2ZYb8L2=l3v9rBSyUE%vd2mSThPgNIa2?t|tX5 z*uX%p z`ezNo%2gt=NIpFC>6Pm+4B~WC?J_{oBoJE~7knbbnof(j2MLr|cSApXfBqh|a;`cz zI`|*U>)4WrO^ZS&42lNHLI~rCCYVPGG6mbg322r0f0!v*yL^0~K-FIV%%{rh5cpVr zBJs)$?j+4Y=w^97JvX)=L`1=gR6%ERYic4LhSK6v{pWvMUI&3F+(})51+Y-YtP~Qb zcqo04Y}{~?0S^!|nFhea0gU-R{W~m`*U@B$OHc=*4)88P=lzIlK;}!4*{~k3w{4EFf6il}Vh+%09I|*EscSmFpNf#f6)k ztcg0U4MLvy8lP1pitw6P81>O`}YusO`dy?d)^hDPn; z_4s!bCA1%QKToCHkIH2yVzir&Kd!uvaUc+&U*#x-oIb}wN7J=O0v|G^MwzEEl6OJs zv9>IG5mphSz2=JVl-JRgl;#W@ifoOqkDEQF3VN*E$@HVpqCO;N$H*uQd06#Fe$>+7IqjUdKnY=!l7#*=m1_(ZzlEOgY0N6Y2p?1L2|I z^d!jFn4XLxUTA)Oy1b6rVa0GBABnJ={lG@7vlo@3QuEWdWt*T#rCjUL>*@^3sNHed?gC(-5HWi;7vnkaqRVCZ(T<@x@E7!3Cr2>Tn zrl>gBMp0Op@P$+8!CA`bSmdH|D>fTm1D_>sFRj(r|ERo9Xdf1*3@GvamGNoPicX`I zKNTZzC&F2&)+jnc{p#z-a^$5XpU7{{R&_T(blrGJpVOcKj z^iSNQyq}z{CM;t&?N5c40AZPk9Be-xI69caU-^6lT?)N+2sfmu%9_{}O z`XW_4WWxx>S(0Oe^hd~eHk#Fi1V>m9fkN=8^v%s9%)jWxmFuW_RC5^{L^4t?NcLRl z;n@W(Mn5vRU@NJod50{9`0ycr%NRJ0-9Z}xyO|moSfwiltS_y!_ZU^KlLH#@ZCEyO zUCyAjAcRC$c!6IB9b&D}=FuliNhH$@m?)Zuhv%JBxsGYv2m>m$oo>w_%aFLjjo1@M zK+aax9zaer-%N=ZiI(P;$v6Ec-L(bW!m`Gz3{CW5qAEP`#A%%-}`l#Z-)_)A{ZGVSDZNz3q~^F^9pT z*fXvqO_hZ>>6@7Q6d#}LoMX>ekCLAq-z4ZOCAR1HD`6CySGsv}sI^a(Jf%0%YY@da zXOvsExMZU&@|JRbNHNpJuO*7Mzj;vkSUKuFwoQ-01OPUf?<3@+MkSj}=ztEDF?yXnQr0dr9JP|#ut?f$GEbT{*xsaL$dY& z4LNvhY?)$)ShU$){`c~Jq+{1npNxE$b{y!~o{Xg7na>FAiQ?FYgBkyUHu5@S*j3ob6_L{FSJ3H0({7dyTu&PaA!)GkO-W;Tu{`D8>;Y3Z1+R&GZaSL=c4qLZFWq@Ao89+OfQsVaa*CdbIT zsE}%qW2UcYuxKW!(P(a->bNIK6AyNlWqg`DxXS24I8KQiHOlPNrY>dABpvnC} zgUpF`FNEcThPyRZw)i%JD;gIQ9Dfn#UU1FY0u zQJX$|x;OQ)sgtH=N4JbF8vWkrSB6&&Up!nL{OjPIgJTAF?0>F*X8(b`fA77&_tf5R zb-&zwZTFCFqjPEJgw6r&8)~m;zomU-dq6Wexi#OswfVN@6PmZ5xuo%_#_5gwOkZFB zUj1G5jrv}-FU%Z|aX9A}5do7Y%j!2p(AJ$T1<>1| zntS|%-vCYH*mzYG(a1m{3f2JW7dx+-E$@fSLA5Blp`k7ikvvo65lCxB=FGU2uFyj5ODKPi@0JdhT`Kk6RR*hb8Z z|K4KU$l^+3PScQ$mhL|Eq$RoCdvXaAu#2#FEY;pOKwySlnj!gi^nCb|Ij;;)38cdH z5haM_lt}Asd24X=AtFzk z-z^h{!A2PhA%t@e&>T#z(FjUs#C*d*xL%|i=%i9f!<96zzu!WW&eq$Xd|vr}tSXXB zx`e?Xzz*lBx`+e@#ivkkVNXiV$x6;AM}4_HQsVH`_m$V7E@cvjj#RfAQ9k7H^(Jl%xudcx2WCjNMBJ_*kM#*#w$|3i_;uEJtai?po-rdUU)|pLt9Qs ztIE|+6TQj5s!|o6qAkSAh&y<}SIXN0NC*ju*;y>a;%@42~DnTiQ1?9 zR^P$I00$@GZ1-HgTZin&xOpK#krDQb|2h2zYr~gxCV)d{3F=k7 zu8+fSGy*f@8>}FbwH*&cF?zVcAYEn;@@Ce)Z3J#NE-h~djPvVsy@ox-@R5aaD@f6p z1VAcWfPk9Q8#{GV~avhHgGwXa4Ay6EuL#2stN37$o;v)o#GIB-H z8?zibn`>HJSl?;?^rrGUcvZMWy=1zl5W$PhiJ3M?`3d^a%>(#Il^{X}1Hh$JA0?f5 z*E^}KDx-5?$LQV+hI9;~btc1*>te(T1D>J~<_GyW@!VCUekL6S+VFkXR_;elt`!`1 z6H}BWu^CHS;ez0$8~|X0gqc8(=UfARG&|OJTwLgVxcXeIOc6kGz9-%*K3jVp^Ct6& zKG;;RN}&j2W~40^34tN!Ns{%Kmu!Mvs0N1Qqyajd?-}JSbsDRp<;VKT%xLv|I`qk=)(ne`<_|o$WrZ}bo|YbVkI8E`V8%Vz z-lkOMi=)ysw4z)nve2orC2NNt*`Nmv8n%OUno~!7islQ-GR1YkQ4b-m*b7SSG#ny~ z6rfIAgfK$6T0GFEI+f`Z^UShKP*@)R;}0tL;~iUQG+Pt2iCq!#7;KTFR9;MyrA}WD z%_p+4l;{BOXnz&}M3&)4#0BdZ#`n404e~$GpZ^%~o{4?k zSCyn6pJSxcSR&(f5{B$51&-_H*cTNJu;vEUcAg4UmsxRcs=kGV_Q|&^pG(cB7l8pc zGm;eScs{@-mAJj1gAg$Kwr4WC&&azg8|HKXTw?FypI5G9G%1q;-&We*atI1K4X2-W zzi`M9kj2EI!tn+$#Dt?XN{iES{mKVauOpemNrm!)E=a5jOPu*dNIK9+jt^@sghWlv zh$CVUC;U=#ZGw7pe4Y|RFcf79uerW{04mywZN{c;hpT&(V#?w4zcP~3|9Onowi>6s zq`V((DF}yzPK7x_lNw^}*%*MDl!2mG5rW>p6{mprlu{S-4kQoG-nYCCN-Yvg1`;qd zzXz@;WxDDaVi)I}se`?*aj=aT#c+k(lL8y=)jo=0;nk zx~n`NED`klFSoB;N1>ltz0feak$5Wuv#nqy;%uaWp}o;;GCk~Uyd(G{T__V)R|bzM z*%l5tp&6nL8pP6RzKZ={Qp@lgZOh!TuB>X!d_pq~`y$5XFVJ04y?ltxK;hYp{!1DGfHE`cIxFa$X} z2yC1lJ`{`^io$|_*qUwr_|)-pX}dpC3YYyJ5{sPXR{(cDADgTXs@|V(?TnA; z^;~isZAy8B*jFEdCd1n(WJI*g z&xr%Xl2kcCfHtNInX3zpo^`MKDH?|elk~Z@seM+@xYseiR%;9o+RX#hch~=qAKh+v z_3$ObwZV4>e>zwn?A8B5<39aY^dHpwkKPA*PwVZ|{Yv+B-A8mAQy&|10AT>|062iD zlfnYbTrzz`^VaEecX0t>0xB%PvuF07{>F6w|HlJZE;6_DsY?Uy&Q3?@+a8brMx4aa;V1n(fcO!^Lq3x@@!h+eE(!pgnXv2h~`qf#X~)$%_vJ{9Gz=1 z=+ccLo8`s>m&b3KZ@F+F(%bxU5LaO(ksGnc4Q_UPp-ftgig%hqPH~W`Bo?W5ZL58G ztGrGO1FTy%wd_v87t`sHdV6ARP4_hz!OFo!p5K+eM8i!ZHQN6KNsRPjW--s zUdO`0ssJX+SaXtKarX>8sI@W<+j~Jl`cqMxwnfR*y5Qxfk-B@gZuL50Ets95XQN6G z$2NBiI~hsOWk%vrmS_zN6=NoWx0jP4_6zwEBC|gjeb+m z0?(YxUZV2NQMGhtFgU4P(d;_*7Gji&p0o8V3nQc-dST@{(w_KfV<`u9Wogqu_5`B@qViY;T+bjz_RGyd=Qk?XkwlAWD(*&zQ1NFlJSsg@zw_F>*Ldv&X+9VP z50M6G;e&0jHlFtF@;ZVSaLd2Wk)w)CPb?Q9{ZFU1j^>PEvwdv_I;ulg;*}89iYA=; z&4-rPp;QP;%6-^JKvU)@u)um>A1y5!gF?19RtQ#r+OwS%kv`XKXK7+bqDGpnVz;AD zfFRuf&~wCUMi0N%Xy6Pqa4eDP2@8VXRF^?i!tly+w{>%QKkhpmA3|11&g0{=8EYYj z`DV6dT5>p_#5n8#Sp-_kIqmqajh)u!xs~gXY1PO9g*iRgAsIflbZTYh#4#uiBY`3d zl(B}$EC7t9PsyzR!Ne99l@(+OqFIqF-IGhG`ta#EUYLWh#I~#NLx>01>;~QH$`-uw z;$Y8-jVRag((FNEX$E@5@gspG)CkSQlSC2oH_%=%r~N1KXtZ%$!0cB0{NpCig^94Q z({&=AWt@pE%_8LPOas*)jxX`e1WLwcASxn4pn?KqWpQxz#I8l#PZPBbMN`QOR}x5@ zF+|{kl!A&S)u@Zf_3}QJAq-XA-y4g~CshzDT^%N)p{kZ)Yew#4zZL@C572_8`) zqI+X=?F(O2xeopzEI2POctdM++5=5jLJTKm)E;ryPF6t+yebf{K@yVz<`=qW{c(96 ztwtv9X0Qf&BVtL0R%gtsFCy5OG!yrX9O5e>izNS)DG#g?uXpHlCihXhbz}nB-8No*&tdL423=dFk^ExbZ7+y zDS7%cCPTi!I^*05yWQ4Y=jPRN`S@5^W3CkRkIGBUr|PDfhx@dMc%szNibE+ClJ(9Y zcAFYPS$OD#mtb8>fdjS?b25qn|A4wo7k5S-c(1ZX(txran!^Uf&*U}X+m<`M6U)a^ zk6JyMuf)`#EQhp#QHw@-U_=xDA5jsyCpg%38KNzup*%33?Gw(gT*u;sQwaI#Xv24k z?%on+40~tcNT2Cx&s#xh3fKJYi7Q@q>)QV_xsD=4KQe70Yu{=!o-jiKL{(p0Jf{x0 z4py6x9naGCoGL`r<`Z6ZL|AoR$)3OlL)fdLto(@e;Rh0+R7q+Z3-8q!`6V#Q6B&A@NF}ntcCDLE zm|RDp% zO&3kMpEFUtV&ooHliea75sTiEl*GtM7#xp1H@fUTll$T1^+*7u1t|6DjSw2yw8&r) z7a=j`I+0R8n856FD6l=X<;2bQz^_-XBhY375x!Q`CEKH90-`;DicTLORTt5hrKp+$ z&0<-RtA)1VK_8gx3;c&Atnbv$OWQeIkp$}3iTe(ZMy*Gni5&w^nxin%iKb1L*7f^k z`0<+U=5&lQdg+;Sa3Bp7Xy%!K^my(>E!ZyL0Hr0l10as7XS|vnz5l2D0Dn4Cn0v+C35%v{pkqw(p+%cc)++^_zF(c8iY%p4y^VEX#OpVs%r3f!sx`KgmjUqJ1P zaR!VY-+k@W72QYFx9acNZ%DmnH|1c5l!8iJ zwXpUU)~b;AI06<9ooeel!>jfxuY-Y79>mCSdWoN$XCOq(@>#o4d?jYoVCRWQH&uTe5riTJWc37;WvG$!bDuy#y;vm#p+{c zl=)`<1B1u8OE$9zY^?%4Im!`yx`^?D_newjfMW>j-6abrpCbYQGmAoBHLvIJ{T&r zy~0+=HAoTnhW*K$IzxVhe=8qs>U{or<#nuGLu%3V={8Ptt*KhLI(?d4wY6fN4Z*n}Pd>Eju;JVSxwH8WZTw}WKOphf9k z7|sOY_5=4R9}Dj&``Syo#>EROSE6PaRo9}illF_*6Lto;>t`~)*@F_8=6m~&nRWLQ z2L$5?kx`0=;MDQ%ke-!kCStif%I-v>!=-0x9@c|KhooX;Jni`Me)t9S?bzyqF99B9 zn@$k5LIImH5M1a=6w)jyYBQM0|HxSCOyfT;FJH5u&Jhy;rqP#=NEsD3L+E6NO8q!i z7x^4g&C|#THilmv@A_|FTHcP|j79SxoQaUVi(<;u5ug-9ram~jX@;7m9gct#8xQ$d zB{#d;zpS!J2`6zPX+Oj>dWXgETM3g=pc6@{L>pEi!^Bdc1{T~RWd9V zlCw(%ShcN;##excVFXo0=WGO~T{%FbInAy4xbIKyhn1c1YQb0#>OpFfJeDwTb7&%`0Yf4e|WpxxxamO}G(rBVdOdR?i6Uzbj$!+a&qL z=5^He?}8yl3NUR*dWIti1G*YAOICD`#G$67D&S8t_;$Xz_hIFA7*Cwa zr%YqJl~%)o2;vr!u;y;i9%kPNrM8B9Vfxd7FS3A&v(1BVU%3t%CSNs2h!v&~8^t}RnH!;0RuDF%VTrvepcIV9V&Ll%D10}^*jWZyQ z8@#&DYjbq(`JT#k=nx`{_aY=;x3#Xp`7SZnjL^k9`&a z3>I0JRj4CAimSF=t%`MSyd#C%Tjam(PfZV!fDt|$SCH{FwZ7VN0N zl|sg^gXNMhEl%-q`ccc1>rnXf3N3doXvr_62}Xr9I2#-xy(x$1H^!=` zuNB7_Dhd^5qoS~I3v!NVQP9abTQAnZ^jdL`W^7B`scZ{4#hH8l`{b!eKt#k$GZCFE z3aHd%2a+6l%4iNf!9s`nP&9_>`J#N!)J|UX{M6&mEU&`|$qkQe19LIQ>Lrwvwh*?y z9Nld`1uhYy)sk#EGwom+(_f^Fo4(~Slk52E79lUDxR6D!ESJQUQILlk)5gMZkr~;? z_(y#?hEy%t)Rl#`=_?;LxsJdE`ZFBGq?V{G8wz{r6ezm9GB%LD6jEA$cK~k+1AZqp z$@J6iS6(NNoW64IAbE)|feY1w70|*VSU?E43@lepSr<@%FvCQ|zBWI-^GQ6wlWMKg zKQw3!YWvqNsx?mz^o22>iNJ1TX3y(D_Dj@?dY~?(NIl&uibS zb#v?d=1HxielZL13;%RnyP#B9K3K>s9OyzA^@;^AYlOif=DN&~P5-p#&6E~08%I;D zeaf)m(kpjQXvlRKHgKxU)8dDJ0P~2=p>hZ-CVZ)&WxRJUz<&;tW35JCJgFlxyM+c3k>*mn_J0V?*aYklKCoEw8lvGcK z1?+f5@*tUph7waR__Y`&I_2uz@aAzno(m;()AA)plRla646(HKy>{@GD}$=0uvN-? z|9A@WGpa_d0`U(&Ha^rM*KuZgdNBlM8#v;T7p;L8(a5BfLV<%VmLDq<-lLTol?v@> z?OADm>E_BS@&e&{Q6!a_G0|2sT|wG5$p_wN)wC1z_9(JB0l58bGtk&KTdBYB^y-BK zSh{2EUQ`2kJv=fdHv2X6^R+Ng^p!-aP-w>d2>=jA7SZZwjfd;z(Le>Ivu`E9q?=ea zWn3{|hDFW&Ykeg}+2pM9Fmjro4#|<=1t6^@nP5S4C7i)Y zXkAD4Fi~R%Wi=!REC~89EZ6>FJOnLwB*aE?z?7=u^0^T&e0mmV{#h;&@4`%LBA{4W z1S&K%JcU)%VyJm5m6?QjV)aUsp|oc;-TE#e|C1vZhk8Qxy)AJ3E2B*@!= z(BS&^=;~XhukD<*`$E{aP@961a$3@`B`pJ~N3PER!L+}!PoU!Q-detJuqLpG%`2OY z^S@ZWqm<=pdI>{G=bqBoBTYiJR3x*$6oFnGjWN_lI@eWm*cr9N@@((cH&idA*x|;Z z$i>s@3TBTn^{Bli;$CTwm_XqK{4kB47z z5Sg&&MI+;R+9W}u=H2d9xeyOOg(yy86o`f9@2mLq(enS{r3so~KeW#6AbATjHVzHU z@VDjO{*jYr8oR!Jc!JmwajuD^DD9lQqTN)O$~YUh8R1k`g5ErTdH`)`cKx*nj>oF! z4HcOgn(-BKycf(4I!O8k7^NYQg`59CCl##X2NW5_#3$b1ot@e{?_GJ-VhC|wzZP@F zuKlS^)|*j}rvKB1V`t(0h3@TpeGchLAw=PkogTZubM$!6)pj)7l(me zACKcWftjVb`|uxCFNA`2UWu1N@e6XZ$$hZMKYSYK3S@{$3y@HF5v3M$NP4sR{A)Md zyLurWr3g;o2kq0>2L2+5(pA~e;`2-h7PC-(z6OH=++Zp<`2u514?3)%q>BmP^}1<&Yxi zUHyW6$CfkjIXwuNVIYe%ZA?~Lpj49?KnTQ}VWIlo=pTBIa?dhTG3u)8lx;eOQo<49 zyf%Im1s~ZU61*M?iCc579iZyBS5$>_cNm{woCl+V^ByDqU?KrDHUs2=J}gWF*cwBY zU`xa;=BYD9WMZC3XkY1u7VZ2_mztlg4x6 z+!01x8@Ft%u8k?5Gm`)Updcc z$;GUWT$r8D>%#$MkdUDb>KWZ_2CldmlaeG%rR`nt=<0=#;}Az79(bkR1Mf@7Fy*e~ zj}OI#Ss$dw3 zeRbuIv@D9Tcbffr}*`vWH8h1Oq=r}5?;VY|7u)xZ)WzDKU+T>}q5HSI{S0#;7e z^8#7lkryd35g>|oLrcd~#&aQFdXl4-+pyL?hV6$*(uG3WVaq{jWlEgrkii*#t^W?N zrIw!S{HR%ZG>`!gudv8DB`Q)LLsTP$*jr_4NY6OPtPzF{HgCpqX95wD=jLmF_mk>{ zj2C0LlRm>&_(B4O0GGB!#GADkqNiA9j?(aZ5Y)Vvpxx?H?}%fn7s5qh&{LT+YWQ8` zh72M>co1)j23PI{crBJ5_l-FQQM73;FV>%yI%GE%5u!9Vc_D-w;hMw>vmus5Ik6DS zMjR2D;4n}rgAp?jBeaKkfloO=Mfug;KvYJDuGLrub~2yIsq4*FeIa2rGKD8g^NuZx%eNcox6BN@8n7`BnN8u5brYt=5c$u} zzqT^{;48{k#J$1)5egJxg<}pcnk*4kM6^ZjX%oZ%r9DO|U``r50kMQuo_@&t$_rtC zYy%o&%2}&kRD|n99*uRXNQznxtwi>se&j{>u?S8?`#jVHGE^1s@Ia#n^0;cXU`r7D?Ia#22#jreE z;L(G2|HJ*~G*9jw)<2;4jovxUx!ar>@Cyt6|K<-LzWaeKTq>(W)xp2t^iA4L(&PstOmxz+);@T>a!1k% zPc1nM2r-cz;X&e;h*H0&kw$p~^e8<*e3g{2zz=GX>f!0!Fg|cIcNFd}h+N$XlbTGz zyb>Wz(B>G@_A4;MO)Ty?RFL0*8O|AmKE_6KuR-OG;9NP@2n%l!Tp=CmcEHEwq0z(W z{z4tKf(^tlSi$K%ej}-EVWI!o-zhH?t4|u;c%&?D77TPTu0|qNVdaTMUG$4IZZpva z(%PlNKx6*$?C4E*DK7*hFovkM(kTH{61UU@R60N`RxEj&Gb5>9%mK<(7^a$%jVzMU zAB+!uE8Y=|m(B;A4NHevMg9fWLiDhar9%lplxZc@5t5+{g}g`LsHEqI-ySoAS=rkf zzcMwS9GS6^GywlVcfy>DS>{p(?TCqf51m{+zs9l~LUMWd>AxwT3_ekxi`&}LR27zw zodOT!ux&PFj1PWW<4Srw!w1CN1Xv?;HSAwLK3&lbp^3d(&IR2IbREXDVg`CDI56$eCpJ_TEJ0VMk8z*3o~~fKs8NJn?rRYXhKk5$ zgQzYw2cUL_Zy8I+xg(p0^?~&ZET@7MeG3?7T(lfwBP&VlTBVZmFd)ZE3<8&hyWR2h z>Eb$U{2rf&PuFh-Vr7K5tS1e_g^9mK8^4qSh39zzNc|ESj?jD7c=UKK=wR7^#xW5Tu?Rb#RkBC*FJD@&-c$xU zD+yTfR@JB;F)_rWr*%E<_O<#GUbefY$Q_|0(2M|gG@|$|ZH}}QV4%TiW^e0TTMCS3>5IMOT!0@kLWBegyXaK$xUfhqzR=jKJB}9 zgm;4<1f=PW7CA-0+*D+#=Ty_pcYmi_c{CNDbfdyYg{nBvK#U*RW9kwfJ!LqEglaPt zHNI2|pN=-=3~8!+$8oKkJMyb#Eo3OSD>0mkhdDwir=?0pQeXzJ+BTWKtkHqlo%vO` zTioaz@h_D-;^Rls5IYJM5G~^)Qz((GU^6Dk{XU zr`~tdwre`1{T%{QU}ZYBsGPhkN&+F&uEb-lZj63D9?|TMyp0^~!nPiDls=LM3u03! zNZl;x6=MhKRT+5YC!;3gIUqG=%*L-SmUk3eQ-*B`4Z5un2gq8+ib6dF)xCY3m%=qS zltw~7>n$dQFRcupbU}F`^*T_hEG5vRzwOkJg3(N66l->J@LO?m2ElQ4=hP^Q}pW?z&8L~p~5ok{$C(z8?IC=+RVYedZc`!OxZ&WX&60l+r z()#2hPg|KetuLN%&muNbrKFYgo*E`Wd}7)s4w4qS&wP31LZN+-DswTvDVWF@ersAU z+`g>IUJNX-sfH<{y@*zER{BlrEA@XJpYhs#x%L>N<)`;B5ooDQ(C7HLw2mf zV({&8{a)OWUm43;xMb)4NxOJREeY(5k=kLKUFC#m{TddRsvXeAA*8PLXsAw?AvaroqL($G7gj~g9)d(3glrr;FUKDb0DcnF<{KhkmuiTL_%%E?IiJ05@`J{Y{juN8N9lODK z7zT_WpIHOYgyM}CM5dXoU3p67LZOTyAJHQ7L4x&UIJhrU+0yUg?=WO2z|Hc_pbd}U z(-(?!{otd@B!Z32p*~5&iW|tzi!_xWqi4l8;UL2R_~)#CyG3S-j!N?ucIx}>SGgeu z2qGOELsDg2q;Gh|cyJIpMk0X`+GZyR3vPWIRN~9%7S*%gxvaV#dEFI2vKfSI^&m+o zNt{GdT092!jST4}rHE3xDZpd=&6$6z-4h;Ly(3S{J8EITHV{98BPCs$AU#@&ejuKL zP7+i_NAloV2=BPI(!A*0>V;5YoJ!i`i(x)_DPU2!F?1aqn<3%s1XW$ez?GNBzf-!@o<`Et0J5-Fib+7d)~M-Ev`e#@xA6QaZ>&6-|C}x*?NdoyLN~vOIv@>UkZj_c zi+a!4Ts_df2^d1{P{Yl2J~C!Fa!2XR!icA96|i;7f+JE@3xE1$(v09(wYUM*-111g z{Q!g&Gq+KDMWy7^7KW_GNTfDW$`#Z;lEi2wVN&&tNo zhsexFgSd2pBNp4A?fP7fUW1&-+TyC3hKRKK!zYwZua z_wIbNzRN)fAJsheqtQZu5HRz$lFLv z5@rVtz3u@bL-0qKbw04zhNEiBi6xOe4362H_HLr~ZN+`Ts* zZ6md8W&onCuO|uUeV1Z@JCh713{O3g5l9UBhU~pJ1XDUG38kE zQMXnu6q24&QS?XVV^O}`I+i44w^jo|kVeRP$s(_ffUKM5C;H6N=I9BhS1%L|oO{KK zWeF1=75tG;8+N|Vs9atd+j zY~tuwkr9d#WN~$H#YBL2p-fmq*{9cEVM-wk10Msoybilz;UImGKoza$8S$SZ`XDwe zd$WIG<tc83t;|@$P4FLK~r%lkf3M-8zn;Y#zClW*Un%`>o z(*gxhC`oTRgd$zy4+#3nSPDTX6+I(}7NVxveoSPGt)~xnW1V8t5>7L+lw4>-z_yu2 zVApUDAhB@=U?IqnQk(tJvPv@#6t}kB`O}GTF0QG*BH|e=AC?S^vv-9G7`Xsad~d2O zI;Nc+=dldPS!psc;M8Bgd-;lTZi$)kluj=%b2}s22q=I-4#t48WmFf2q?6*nCzvM~ z$bM;@|I+G(&`-VsC7%(TY!B%pXPmvE!ILhGjf-o?Uk{OL=#OG2cdV-1?j8Nr%7wht z9PtTZlU)7!P4B9CQQxJ7Gz+Mk5QTB-*!)a=8BEId%`M?>UCAK6Vgv|HKeEvJT=!0&*bU?I zXzZ>cq8d0RZ7akZ$seHDgh(Z(xT8>rXKa_^k*~tU#BI57zfV`LV}oFaeNOXVqauLI zx_`3bb?e3XPpc#>3sEY)3?Ph->}OTAjd4F_?uWb1PKh3KlE@u} z2uB|CdDybda$d5MCc|+vBqc1f4mLLm*)phN{>}p`PX?E(D{Lkzh;N?Li!;Jj`QXzBGGr1oiI`nHty5BO4#BX4w>BCd z{ZjQpO1oLn*_dwaBD^l~%xB68;seCuW#pyN4de@2-JlPZ9?6Mhns2`Igfd*mdmxLW z{NW$PseQ|iPuIN~vs@AQc{pHPI}<)UDWk z;-u-}YI8_X^hB7hFVyE>UaK{K8j%t$m_hW3>RjmZIzdJE1=FDS zVllkHdBNMltH&~Fm4oV--I(yzl;9GU0z>OfCRg;X{PpsyX_K(g^fK|)s+DEy2(mHj zMFSVE0VeC*O#Br83SQ9_1dLsOVRY=@)@r-VlDQ+p`x9wAQKkVhlX#J?!^3Y{0_!C^ zyh2stNHt9Xw<*yscD(?qzFgmJT4f!>!6}q3+n#y!8y?&~J$Z&SX@WZn)=PS1#o52#GR;=2Ab6 z|Mjx6=$I|FS&3*!Cf}YxuZB`392|#UnFs|EPcFluqEy0*dMo@N2vbf6A;1s8190=;;IC93%{Pc! zJ&_%X$XQC*&R_-2@A*rPQpgYu6&k>Ar5KOF0bxsSZrAr5A3$iUiJ0LxxWf@fz799C zegcUpUgGe_J|$wCZI>uua4aGL`cv>atFU)-3lH%8TJyjM4W>R+o2?(zY#hVl zA6G5}u*dC1eaL_~)?aRlG$u2(nrx;<6K67!j0MZGa}laY=C%tqgKH)VzRE*@%A80E zpV>%V3weuq3`Uf5=omks^bwe~XYe3lmogAcfTgMSpE}-r9*uKYX(vyn|5ZlB`vN`b zp~Fc@oyu@AFrFDH56=kj*js=s(zmnl$@0+@+t~MjN2e#m@{EOGT+!Xc^^D5MR9p!! ztt4QCbRjE>*W&B;X7jqSIV^W%tTjplEfVi_Va183Q<|2eh;KG5s}}o04Bt$O3UR3^ zY}Mv!`^uHd9f{m1;kZ7nO{p#{Bs~+NmE1D%oo&ho!Q-McgcGH5nmc{mg~p$Z3wL*f z#L8_70X{9`59UUxY`c)((h=>WlW!wkq_k5*z#rIi_-tddcg;JhccjlKbDtSW(SH25 zq*^zTF;zYpI1X`xZ0^^ciIu){JkL_pQfKw9<%RIBE+WkePzy>wa1i?>V&^+DGjKVi z2293qMu;V-BvHkyqE?B62%g3R z|D${~8$kp~J*$EbSoD=5$69%CGutD>TeN#hZZUWdy5nK8^7ZYv|LWSxh0-x0J^Gx? z8{TI+XMK9_f=G!~fi)15_A8#+)Dm0+9)wtLGVgGYJCqmViLm=&BcBxY#TS!aKwC*l za`_Qew&&w{isX{wp2!P$%X^&^ZQyk{Z0v`dhRIs6fIXdiSs1S=QI z=t_^_C0CSpgcVOq47L}9m-o}po}mRU#h_%OxG;x}RKmLpvvMp7Z$9mNOFP5Acy{GN zKwcPZG?Z4`^lNCC6cycG4!5+Ul>A_~HJBF!0x4QNHz9VTb=^MI3tyq#-nVvR)#Ek;lwo_97Gs+v-S{hRmOa$@SI7T_;kG2q{e16jUsFsC0;U z(*Q&=L)s~|tiOb$Bqz_BN~S2i2@djJwcwLoE$ zti=3x9I!Ikg0jGTnAy4R<13j~R@V+?3mQa5)IiT7_qzPrvoa)jLX=#8ikl#Jg|{*yVI|+N(gRP2nb-;}BW`GAHL@l(i9o0<@VkW)o|X*OV*qibVqzul z3tzBVWZ5v}iTdU-<&z2i>HNdClK}jB-)J6m$vmqqGQezvAAOn0=in`vpdZO3X z|NfoT3#FqRJ>&bvtWRi_QZl;Ja0A6rBo4z4l$;W}%1m-7Tpe6av)v;eU%5~i>`Xj^ z`dMKZtSl?wMzjuR3QJ;^gJOMq+>PNP`L6^i^X<~4crkV+L}pPdEt!=VG29zokpKtM(PI$|SsIzp z-#Ft5l~Y5g(RM-=q;iH zx0Fed)OLIsRRweeKr+J|N-dgW%uhhm4W8)HrmrmypmQm$^OOw>#E=!a&yLZvi9cr8 zja4I~3PYTyEse&c1{RB5*N5F19CE+%*+5@YGIhwwUeZ{`F7U`o|43;{yqyB)0$_wp zsnvRiOYKMm>e|BSQDZtO&t|fY@&yVKip1g+t4jAw?uK8O05eS8!cd?H9M}PDtiGp= zW!oJ7%HzsAGV08_bF_q-gwb6f^<4J6@b5`L2+$;62n>6afI_wOF>LF#xz=Z{R8gic zAg@Sp$9Cr^?4ns8o0mfAVJ^l8vQLdAfUS!YbVtoGd3DmPrJR+r4nLOU7c z5Sfd$b8~o~->bE5o*siElC>EtI2?RF7{#BjWPycXBP<#^LhBJ~Lc6SrQMC-2D#g>T z2iR`3e!f}j9C=lFF~E$6iNvcA!vNw)kc}ivM3KHI2tEVh_+x-aM74G|+@z5f4EVF# zgAaYC*4kbzFQ#QBmZczUP6ITsdYc~Qi3}CQ-*Dg1HPa@c-ZrU|0+NCU^xj(NckWPY z&73v47*m3_fk;p4S=D|hAFNm$HJoW_Yvgo5teSli4SFPge)tfwBSS0i)Pgj@=MFJvgX<_)HXVezS{qwa&bxyfds_I_UU+L%blkH2CoASRUGH zl|&v-8D@WJ6V)UVrwE?NeW|qS5Bo~3vCsF)i}7zDOB~$56lz&py4JjP>EZO0>LOQC z=DZg6N4_^ETaA$1wLI-hbM3$TO0B#1k>$k{B)m5CFf~mK0&M-+gfWw%D0#K9kCA~x z0%WRh=2(zoVk(`T{^Crnea(60#S9|llw>nwsZa=V`!K>{1F~h1M<&=P=BY89m5Oxr z9m>hHA5_}%>hMQTuGL@moyo-n2UlQn!I`*&bRFdgJW6)}yqH3kPb#xr42wW>8y%jeRnljAYaAKtts75?m&Tj;K-f3OtrX`J%nwdm zskJYkl%Vlvk?e#jJ2y6>oax8zj2(^?63eHsqIcB2SoaLL?%!uJ$H~tP-ZN9{-haYo z5vojGMT(jQpi(uOi6@;^%IO-+gh&ZxtNPf-^igQrhCr#TtrPoJTjQz6)>@a3?Ssrz z^lBeGonvurB0;FyJQ4U&v4S>(xMjo2X{baFO*^O?gd7T$!c;r!qFU`ge_XyZX9?=f zNG3pTQ_XS|OwI|jQmpZ4QPKn!2wf#2u~)O0iN8fx*3|X`YptDY%8P}nG429UBeD{u z)AeD8>YzwZHxiN;Q!t5PFDJ&PRm#T4;o(cB>z}ICzF0m+`#491+|%rd+qdvpDy-lKPU1nM8}oKyQ|=kQLq{n7Sw+xKkU*gCIu zWUJr&So8VKdo^xuoZmRgFZ-YVZ}PO%0uPkFJuiwr=Knz_OKur3Y#@fn6JtPH=nPcT z4S@Bv!>lYlq}@OGZskJaH2NedljKg87NvD`pnx(=4eOLq5r(26mxT6oix6jVS1czR zGsEl33(18BOct$i7CK=`(B^buS;AX!I^lKP6E^^NscU7PHd~|~S62P$50uD2NXM8O zRmFB2k`sTbg(r89MUyemj=W1E8YM2HRMDD(uY}{n&rY9syUHD9+NPhB@uelZ+uqTh zNE9awa?R(ERI4{;1r(v7Y~qA-zi?73^V55kAq=Z-pJozv&d;%Na{!Z;Oa5uF2QM7k z4WE#xpM%##FD`%TU^La$sWy4?| zuHWYyl{*q)n4co9a(X18vYABk#K!r1lDU^}`=*sie)R@-(o|=Z$=1&B{`aq5NQR(N ziyia~RG{RVQ99H!0o#OSq$?&=7BY`f&x#%$C|0wfk&U&pm#Y_Iw8)g;%wX4bAAN*l zi*jfafI&LN&$GBG^n zP;}rv$L4}U{(5>eR2dp~NjA$%gOB{Qav^AevMwuP%jLMt7l;~A7?ENK;g`@lNo_Dy zLuOM0#c(HYFRpa{AA9#5Wm#FK4ZqUKr>ZcFn8g`MlDfL8ySh!|7(pbPFn3pX>lg@% zf|(#el0bLUbkpoZ29{&Qcd0Hn zq57#Eo;zLFb>GkFHQ+%F@GUP#&LU0?<%s83{}?Tpr6jh#D(}oOXd!@51Os( zEJV_V1{K#cY9a%XnuT#XV`tj+q%Vb zyb$>vvepMieWC~|ADfkfWFf{%f{0)UJs)i#gVF*TbrlCJsf|;Wr^o^M5vFf4mp(Bc zrg>?v`zEvSr6Za+d1;@GHiFltywY-&#!UY>VkNq1eK4frriI{vu{s)`&7B(k#_s)X z#GU1oR9TNi2kjMd-9SDbnv_f?LW9{AEt6p@@^Xe^!U8Ff&(^;1U8RNWJUwlaaU~T; zM%w6A@*ig3$i`S`m_#j@kz2{(^+jZRn0TZe?95Y23%Pkcm&QR+F`1H<3`=2XZ&940 z;q6Qk1+=0nNxsKNMb3HM`HRgAF3-fF~1p&fTY-GYp95t_)rjbe> zW}cZ>l+>Izs%~FiC}eVGu1gy2S@k1IROU@x!Ar$1^sA~?jW8By{D@tx#e-*xcEIaRn*`W7#dEQ;onkt@#vAu!v}5W)=_sbe4eg`RzR2VkV4b zq`Xu*v}gw735tkT)-Nn%Ttud_02VSzAiC99_3)h8kvCb0^h|e;%vNdF9o)-vM4gi9 zC+Xx4qffzMLV6C_Mrn#igdK*8ja)e^Ps>6e1YOBUWC2==9Cu)xSNb6MTvfO9i!En( zjE&&MWei~2#uh9bIrpcfcO+hr0?C{J0dCCS8m2?j(t%H zE-1y61`4${1yrWgT8AWnM3r&!#!DL8e7Emu)B8{DPX?-*L;OnUGDI_)dcr2|OTMJe z7mG}e%OD(4U8r;0&vlS#3Py#tYArNn#Ltjh|nve zPldoawO2k|TF5WSDLP)HCNG@;M0goGl&X?2DZNJOmCRNV=vW8PN;m@1k^a@*@!Il2 zGK_B9VH#|(reWgKucsiUR$#&iTxuDQk~VUwnqtmqC8*qFb?2kY3q?SrmzpP)*JN;; z88wP)DMjjj{4`mxbW1WGAy{=%Rrc&c8qLoZxLPNA0x&PrrXQ1};( zL@MZ#?16BX>Ii_CE;v=)O!L@7OLwID;NjB+3XIfjK+e!@#GVuz}jkLGRIN|GcQq}U_(=Ujz78f70PGi{eHt{qS4QT?6p( zgAyI_KJz)0A z@QO^z1PbWT@g#~1YM=gDc_FY8x35Fhr;r^&DU7M$G7LGeA=RBibWT)F(Dw!iaR7gm zl{0f%OSb-tg&+qozKjZ`)-uO|qMRa#@DW|Fr6$loSEfV~BKK1|0kWj8OBapo*lTu6 z=9K-$7lU#Q}cJ$Tlo7%^S+N^nVbM^Sy%^jPy#s!VfH8!u`QeRWw zsa~&LSo?f!i|Vb_IJ#Qe!}u&n8;jw$O#J}=XK%GjMXnzak=;%Nn1)DljifF?4OF0E zD~OMyumanfKbo!+>Ji#+pKD%oRjGa#>NycxiH1ysCPbA5P)qBt?B?%j^EC@2EhswA zi9DRLo_pmG<}_|Qq4a2aiupHKkKgUtGxJ7(6CTt#6eHf1Zn1QS`Zu5|DH`i0BA2%` z7B4R^Bwf>Dr27-2keTX=e@P)=R2HariYt}O=|-bj5%K^YX%zJ*JU zo@iLN1w>E-UK&UU(KWZKJPhVHU~gu+^3B20LhhQP$Zw-amNCTX@gT-1OERRZnFGO9 zP_y;0LAu;fC>fB-ZPGwP zSY+Q*L+fo*UdRcpIYTzbHvu>4=cFnM6N$GxJw1$3Wu!XSc^Gwej{=x0# zg=mt}G6j?5cI5_eVWn@-1v8;CCLjreooHSX@`6hy-sEBc(qmgZSz0K_mzPV3oIaIk zzd3&maB+P?5{V;cX|EbM#t3Pk$E8G~NH^Sic4%&hlsv!$mxOz44=DVH^i9LEt{n~qUz&Ay06jB*A?SE@JUi0 z;~es5B|;2BBaNh3IZZujppM`-Jw5ulUIVPil4C#Qo^ole4d@P}o`{_xD*n=`Ncz}) z3x6;Qdo>AsoS@CJK*Q?u-&DS%Bt$t5(o_L%5n|)%Rk9T9zLHb}$-o6?K%nHy{!r~E zKAF7Ke#u`v8V9I>IFNXRk%+qV0A(t>5+&+lg^)1G=lV5*d!i%w6JdE&RaWJMy%X`4T z?o%444<*o_Is@qlJD}NJIMMp~+2uz|Usw!E=NtCS<0(*a&b)ALF(PdgZu6!XXQUg@oXFAoS3m6LBYXGjgTs)B9^ZH+Ao zbHtx$ivdrKT|HA;NW&j4+Vo7}IAEw|RhWzIj6jen03j6AwEdhYt54S_CLPhG1{wLy z#ecC-3{w#xOnX^8TaamAQok@JUZk@Uy2HO_)e+bRUx=JyqH_OaX(6?{21V`02w8oL1eIG@KkSy(!@~P7xT0j%C0mKlnaX4BfpjHD2 z1q3SfYbM)_?!8{=j?iMZZ>D(ZOvv1gzw&~P(6tjZ#xy_K(>*2KI8$ixB0E% z@*N?k(;PzG4JVLo@^0BG-hZr$Eo%_B>*ZJO5Vk7@=s3i}Et?)adyDcN`DJc5JDc|t z+=Vb*R#B>Gk)bUPZq_Bbh$_4TI9=xC0lBAZZz)v+-Ds6T8>|qvNPwT&dXY=$ZlqRE zq6GqyGN2&EB_A_|xS4_T=MR6f43$I1d`Z-Sohb3h*-rSj9JUF71Z_izd^6uF4UgI| zK-Nx`N_pcl+( zEGnU{UbJ+FdK(8Km_TtEZiWY@LmU2)E&;lW973bqN~aJ|E})a}HGIowN-tYs46-9- zr#}}&wU!7Yh%jOT!9y{wR*de&tiFti*7C(`D?$aGq2;%g7h*+#Z*+(-kP*c)YC%9V zj-nQzY08gIgA51OwgA~r^AU)iR($@z!>jrL4m94ZEtwsi6X#5mZ@VcD{UnVFF4EY@ zL`$rl{9Sqh_2!V=*5c~5-+LP=)lj5V`l8ash0+EqrRxSbrBGGK=!!=&x~phQ;6ET@o^gSuc{sKLyR7hEF3mq*FuSpZCF?!wl)duN2^4JBofp`*9>1ru8`RxUHD zBTa#dS}P-Pa*C@Eogw4UlQ1_677tytwsb?h4isJcB9VgN2e^E;cJz}O`3JMgv9RbN zm3nDA+f*S%C(lf}xj9zC$yonc|88@sTV@5QS$%qUaVzWq=v`{Gi zpoBA{@B3rvj)GujaD=m8I0tpA<_5&9v>%k4{w;?s>BdP5j6Qh(gu(@Uu4-E_zQb8? zfJYgfSmdvtsGS2o`{HrO0)oY&a1u}S@gp=SNq-b{eOi)ybP+^2fe&@MSs0PEl9 z{MU@^G*TbFaQO4XTMXSgbbNOzU{^~pe)jlo11F4c*xq*R+Og$h?-<;Qw&2{q76&N7 zCp0#a3Kg;hDBXWkQ3H9%w6bcUf)4R05s#R!V7sQRS5c_3U-mV2V`*mz@}Osfhr^1e zH3c!OF$}buIbC*b8ZjVz09-tupoLOH6g2lpnA0k1 z6Ji(ib_lSXZSYAx3~^?1IvtzuDM4%>cu4<4s_rDjm;ruJDJ>n!m=I}&Sd1bd2Eq_w zg#1F&QOyT{7wM+QTP&R#{n8obg;+L%m(3=oMSNmp9CDB4aeise%&>8383m?Z8N^JI zVob=y%;469!>FQy z4dxMO>;rESUxb3R2PY_OOpT53(JE*VwGkeLY6Xz1h=r2DcH3V%v2;WJ5#MTL5mi7& zF)7=8^>ojXCS;SLDI-nY)A$ujHgU{kA@scFm(dI3(_@` zAt1E#JSOKrl1U|Kr}$9l=gSkk~_- zRx{%lEn?`Yra-nO-Z+Kb+qLPX2RZy4kRBi$22we@B)#!gLknSpC`Y>vnAcbD(m8SK zDIc85M)IlBm3vbSXxa=l7ePj4&)M$2JQ|k_$>JG>wah#aTB#)zx{}MJaEb&cIBUt% zrmO6hcl&_QgoV?!9X?QgG(Vro35gwu8YP$RPPWN$fUH3TUOS7WZpiGs%*V@=JV(w< z%^CW9`Oy|q!r+7h3!BBHEle2IuPi_`J!+*WOmTBPe~k z)%7e(ilM#K0A6j_eC_pWT%-hKA!H{34?5dG7*P?7GH>C)f$uIal))JpDo)pn4}(sC zAM9u_CN70pF&2?UQlUcfs)31orhU3>YT&Tvmll#s;Y}zuAd-=-iJ;&gxueJzAjjMh zkb6j8)H9)q?o`_vjxuNQ&_Ibfk=)qO_Am!2KB4}-QO%*g5CiilvZJItV!B!CQXJtc zk&f1O?$9Mal`VCSpE+?EA~oD+>F_W@Y_O z>7nO{l#7H*mdahzv8pyf8+;p?M~Dwdnn{lV^XCqpJg>A6j7ckMhV=ypOvAeDKqz-e zFh}70D%q16*s`$<$Dy@Veo+e~7q4vf;?hFo2mz|i2!xP=p;ST2xb$sPYGgE6=BD^e zFd=3a#xQe{{Mwm?weA0@ybx`KtPCLme4vgc4t3YYCB@|72ZEdz#5Xcwr5hQ8lsiXl zESed3uv+?PQY=HjgV#c190(_0GO4qqE zrN<^O>G&20J!bj>NZ$A(C7TeGnK0gax>4pD8lY-$W%Qe+5S<-yZzn2!$5ANS)=XooJsDN0aLgrCPH?#=& z)&jn`q@poJk>n0Gp`37FMB@#m+RgBeOs<0rqBl)UNBZLEun>%n=rqW?LP^Jg_Fo)! zPJ{OK(fz?74ik%(R(oZS~sz9c9LlHb* zN%uq~O@JssPACfy8GIaeX0Acw-ySY6qzDoAqK6LFNfhm+$j2O+qw<3#+s=B0bKp=a z4BuCJU?QTDVdSUpEiGh5TIhfNF- z<`AI(O9rZO8R|}!qh3{*U@9r*JW||)A_{^rcV_4+4$e#I%O*@^R;hxJ zVNOy6+r%62-Y3THDyOsnLI97in{JrdOY7g?s`O}H zw4FywWB`h=jJtr~`;DgQc%V!$jp!ChB}Y$`rC$K1D5RIp8JsTdBQ+-FpyVllvW*u2 zSV7GTi64^X=t%KUO5Bkp6_)t`0BcVtLgNLCF^nYNr3 z7H~F)W7C9NmS&3^DjoEeS5LJnJ;{99>6zANuPQH;p?hMPSq#K%@OoPa`0pFjCsJ}t zoYU4L&4rfItg>Vq9-g*vVdb;4qc40%iKdDb-#3aI<$jj1#lSmHsAY%|A zsMsQd!1^z3t}Lk>VZzXLFI$2ITIbm9U+qYMd%vHT4IrI!-@9)dmO?U0F5opyFRZ^{ zTR6a+fy%`XG%FVlOb(ndGJbYt@4R`ea9+cz}Vmj1fX_7dqwSYwau%yRM%8@8oPFI ztFh(7dk@?`a_jJxBRl`K2*A3ZTlfB{b0pd%c9A)0IwLD5Y9oQhmIBCx9Q+xvNZJC_ z8@3uGI%-0yZ1VZ~rQ_=$I151uy=ZgMOOc5G0?;ztZ-|T*?6U-V$ih+i7>&z1?DcQf3^ox z=Fv>};ll(44OM|Q;8B1}Vlx>*J|>q!q#5-bzne*EK@mAXIZCb7L*Xn$kD6+WV+uMF zjk07O+MbMFCPx$FIJ=ZO-FOR*4L$8=<={)&mmJ)GG)#opk|`}-x8lffEz`LaGT?Mu z-1gUa>4~AG;vgPhs*lVKNxigs{!jZ0g$mB0DNzy0j}dniK9Y1|A_y*yldekohJ;7X zx)W#EF+f8;*mm`>oFkgv(L9>0l$Y105aq4>(t}A-WSL|S;QdTIgybXknL7$pNn@?w}V-@(xdLkX5q`b&nd-n;*f@GDFdgdx|4 zWd@D3Ywcu!1rXfH3f{QTz>%St)z&I}`6BvrX35AWdmNQJQi;J!Q5VpD6_8sK(}^E> zGf9nViT;fMK!1wj%XT9V%EUZL@uJDvvL5D{g)|}9#TbEnIVh*Xy(>X5vB+c;5L9Yz z?}xrlv5MqMum;A!o@$HkDm@w~IR_S@3saPYO=QJhH(EsDLoqJFgyGvb1|TZQBE`*s zI_!FLeh-++SA*}7Y{8YKTxR{)e0*!-T!vL@0FWUY+GaKwMI%e)&{0H$EVRq@2d*gH z5we3GD97R3 zEnvS_Ym36P=|})z>TRwF%>eo{;Gg}bL{p+HTU;O9puY}vQ;U%~&^sh9W zy4U{Bo=Oq~=9g~!G&<*CMwrvuGym8g?jHD-uO>c$Zlq{1OTUHiy&I&ZBbpspJ}e+Y zex@DdP48V41sNwaIZ=76hbZJ_^GD(31g{(pDmB*?BNt2xftOT`bPsV?e{-J_D>{B7 zdof?&^~N4I_g^;GN2rFPhqFdMgwnU~l<(1`f;QL!AqAsI@~sB8Wob-~;GGZ~fTDzx5C*bTj%Ms`oH8$K)FX&f@Em+;FJsQ5Nz@oc_jIm^ zKz$S8go6wTnI2>5ScLBGP1k~2KzEt6MSZwrzA{~SJB`Cj_`R=kE*hAC*TBWiUNnjG&gbS@JWNEJF-jpdACct zfn(&m02>+4ZI*p1f2x4sF604Xm3h{*@g&GJ!ZUM*F79Q6-3@8negYDzoyd<9N|P;J zW)9}@lq6jER*_Osml0j5#27P%a_*AhJuWESk@pX1ie2ZZ<*3lo^GXWqlr>L6{?RSr zxw6b6An_&>wD(B_=M6nk3fUN%X-T<~O^pRj6{tBJym*Ab0Cuk28$(aK1NoqSB~&A9 zNVYyba^NkcJMxMcK{lOgLg$7MBz^?;;F4gS5I7wuh`G#yQ&fl!+E8tKR74) z9{&=&C~@Mfpem}gk#lzGzaplkcJttw0$^i;l`t77dtioln6Gf8_8;1`<@w)d+!4bTPrD~C7Rp)|)iwkRV*rx%Uv^>3wxJc$s+nc2A>3}>Ja zQGfVwC}jqtI`vCz<@8{qiZTliH%>t^^7mV{uj@{n%ew~b$QHWOWQ7JwiHyZFypS>| z(k*HfyJnILP1^%>l7v&K0p?xOdTCEAmvzXDXe;wO7&}BX3V>ix>7cT6be8cW07-9! zmsL;7nY%3J+{MigJl20QPY;?v+VG4DbJk@yr6{$(6-{L4+JC?ak);s$NWV$6=*t1l zlkH^@9_KjJ+>zAN8bT;KEInbeD0b^l0wN8Z*08AQ+y_h<91*vYrey z3n?KLn-m4Yn>`}&V{s9NWw?eZ$nbZFMsi9F15b=KPMXDYO*RhiiBqx=Hpd=CNt2Z@ z3{V$1TiO!!6>vheP4~zJizO-@FNh@E2T=vgZJt+3vNZ&S0`#8f|G{5ah)7+768(YWMOwI4;IY!BhL>?Z&fq`BQCn;O?>u|D4 zv7iANRF89OAN6$Ut2ye-ZEKCNb@Pg%;Edo>CY8!UeaaUZDdEEgAZ4lY1EmvSqmdM%zlcmkgiv7sVPWJl!iG zrK>oSY6g}7WhZ?{KR`!;C1mDEsI;(pU7QVN@w}~KO$`t<2@*~v zjb%^^Nq7UmM{gHtnD?xVB4D#Q=QqFe#nM88L5?KTWSt{iBOjsFQn;iOEK))Nh<8;& z%5-2xDiH^uO;Wfmo8O!nDJ`V3OEXfK)(o8$l|X_Tue=@}O@oRNo0=dbmSJq8tAPQ4 zCpp&I>t6r|_|U-c5%p&Coda8G+3#xr>Z^JRfSd}@I}>1Cw||fMpY8S^Y7SmBxX<8L z1GnS-&l%r+e50{vy9W>B9If3YBXJ!O$Rg`~9p97aMu{QKpwLXT!#vT9d1x)L z3l>*?(o2}~jvS+i_ECva5&$H8A52GDQbOo>MX78gd75ek8)a(-u&B%>#tSOH>S-n{ zlr5+6RqCx}ORp#liGP!igz5l-$^!X35P+>5iFZW39E1L$=|-bR33k^}Qg|tF3%&X_ zzmgMNVs8RI&D6-GbT2tg0*L&Kdd^`v5y>rCICB1z{Z|CRj0fXVC6@WhqGe7Zr8Y2N zH3Yw`$*#ATZ84fGERq)~saP=4-01D)g|PEdh7juzUpW^3HIbD10vMbVJ#rGE3>FGY zx&Spsp@Q?_IfE~JU1=ekL>*~PybsPrv+CRxD2y*wW$S=a;7aNtH==w*fr67b=g+iG zR=w{xE*r=@O7pa+qzWQ;0VSv;A{?>L;X<0i((2pBDl2c2CN;str0frvPTlG6 z;2nyVg^Pzy?)6`F7YZpL$}u6hpGhvh2z&t(0|!7a^DlNhAkIdYoRDQ>oY)I6vGT27 zmmdwEfT0dFr63nJF;c2$FH9%3G^Fc=NU$=+#2$j@qer6|SUjiw{o(RL zT%FsX(VXQF_bpRHWAXcD&_q__Uoc|jMW)#|8gE`#zGWXN?cqC=ONKuv5@oX7lUg;3 zd}~m@M7w7JUyxhxHlmOX1}WM4UrIL=AKs;+Aq_b$68o+!NklW9ECh^65TacU{3A|K zmj~GLeNjh^5B{dS5I;eADaWSK*OqE;Q>l3CvPh*GJfq8YqOw37slOx?%2VaoOnv&% zzgP&jO#{x56tHlp%!Eg1Q~zR;u|V<)$aKy@vxStJ(I<+?P_X7*pDiy0uTLAAGEFyb|5V^zg$yYBBFRL`LK&z!lkuumpg`9GGmC zx=yYm7Xg_fm=u5knE7pZB2H>)Yq9y?mm> z7i@nG4*jU~jyOatk0enjk`@H!OJh)s%sle>%51nHET2+Ml_BBtHwrrl&2;Og9w^zp zBcI*?K7|XG*U&{kfYvCjcS=m#8~hV(Q%=8)&-ILaEguj%a`?J)N_RvQ5em~s4W($h zPe^aN&92Hlry5y0U1nfnC4i%3)%HFD>EqI&7xk*{+);2|$rXw~mCDYI2#{!i!R#G5 zobm$kC6P?~lT}1h;6To9onBmf^|JCEk#;bzXNR1C4Q;lJ-{+>~)F$U7&qf5%fEbTw z`hzcGk5b;wnQV>C-MUwuxF=j_W@$<~GZM(=k>+V4RTJiwhi^?&G_S{_ODp+vdQ~Ao ziaNjX!yZ`DT_}u$I+rH_y>X|qGj)=O3>TKDFY!|)i;Q9Yh_qxKIrYRLF9-ExJXt9E z3V&)HM0x0XDToIqkmWtW~x%mKiW2cqj&u;H|H zb;cDyf^r~zpfk8iCIj+WOIv65`V{hL%*d}&kHbIG0qmPoGo`^1m@mzy%Am znQS?Leh#Fu6=m^E){Fs6eMWICoErJ>9ZCz)4P*Eadl(TJi6@CCg&5gEz&bvbgCw|t z3c)r>MAF3x)6rxHKLz+gt{`Odmo$Ih%LOeYL6cG;GNNWR z3Jk)R;zDo|P5GtJk?dB~)?mZEiHA}6EwxoAsynSIKbm<(X^Ny*QVnT!${Z8^kn^6= ze9e*L+94;REz}`os1!}?g{e1Q-xFiy(VW3SmZ2Dys?k6Do!Y>p&>@1;!RapDLAY0i zCVwSJYlsR%Jzcrwhy6QJx8UCWs7y$HP8o!n)^kfO4j|N)nXEhdDVQ&xOUJKGEaRlK z*Nhz1)4b;$Df*N-=xh&;zwx7fr9THgF@BB97brtlB$Jl0%F*m9m;&HnWbw|WJMu(o zZtPkLNLBoF#aU4JN%QxDWZJAx7(*n zwxR(?6NU{ncy^EK%-5HfWW<8%p(_KHs7r3tUo1F!b9|DzTogb~VDMF3X=4CjN;T`x z>0vkBC*x^ZdM3s4ZV@Dg_fw{c?Uc71u9}AG(auDAD7ui4_60C*V&I_shMD(yETt~XGvrTiYXFjDm&yiU$3bN>zS58^IgGrzKLs7X zl4-5@K?-Rl^YD91UrpgBiLt)22Fu9qlwoFu!6V>~i`r09o;hG-k?|zXZ%}Qe{3DU-m0=FgUu4)Gj2moJvDIofA=3P+-}PTP!LcW?WlcaI!$bm!Ug_39J3rA7=o$wv%2n81R1|5ma zPEQt|kWWuKoUR^k0@8y_Z5}^bTF9q}`d-mzx&^Y=u1XUn5s>#P8w!Rb4HR`@fE2<2 zE9c$|EK`$}Ru4_g=a2l4o{A#bCI&5{?@|aOp)>QqH`PJe1v-;X@cPV_(MT*NmJJ+y zA$JscLKc!_Dv%(Sevj?|P6gQF&QygWr{QQ?An`P0JYG&%ci=w#JgjK?Q_D+kP41$I z4KWbU$AxK7!UVy(mFg^(BlFpl|M3k`QTcQ_C&7$E3s365A&#Fdk*pwYfLXSIk+;CW zpe-VsSBjUG_txM=tlyOtNqlpgFj>O+_&u)&_DEs-w+=)v{ufrKEF>(Zn_Cdp`Y zJ8`RnCqC1YUFBVqn_+i=qd)`sCw;4k5_Dn_kRf?;#8l*QB!v;rVJ*EZ#SkF3eaEK# zTf(tm&g3B&SYAVX6CSA~GR}eOC8TRK4-mp`kX6V8dzQZd&WC@tUwnHB-Dauglvsc=#l6aPXyxGjlcO7KQo1GT9w@Eb03Seb0CS=e+ayBO$-|G^2r^n# zLu5M=O4yKAW2D=n#??KAxjTwLFRX2*EZ8)<2|@qT5Q#FplFNomDCE_G`i~?59HcTZ z8ngwItxI|hPg#h?g8C(gz(TBu#4lkD+>Vk8iEKBe%P)T`e~1W54lZu<@xz;x-!|*x z7^&KPP+2<;B1br6Y?{PNoC`Y1QSl){q~8Jij>wEoe5QHd55~{#Y9{isbI@RV47>of zJ8)M+0axoj3CJiZlFpg*BX$RE_j?qdaBO+}qIT`Z(#uZ2OJ?=)Sp00JuK2vtdv=qo zOGi6<_kgkiM0_SuCG#hVpPpCwMUQUDJL2(l5!iNw#f&#H8}BO&U%Cp_GGWV5!fGGe zDd;)nRZf$goNBFYmhOns5T43Ui&X-DH04-T3Ieq=tJvU(z;1W&|gwj*|HX84es;Q+4~7~K7B&Bn&`0BZ+ZySFxKUIz!* zwmDS4zP_@)U0tt0aqZXQ`Zvg1f?_=4fjwcjzYwmsN7XLL7x1?yIBoZHv~@bFjuXI(sikWow0 z)`WxM&NHP11{PT^m=u#s>i{W%5250PQ;;!rv7MY`es23)m#lmHLE2$QydVg! z48qL4WSJxaGUGH;c!xv>ko7J@>`V$tJjXfHoVvfiP-MlCXM@+^eTe~}yo{WV7*a34 z@=G}-y;VsvU6e!G@bzPgMUAiYGB0-o-wi&Qic?r{JO@`LCczZVAJNv8!IkFW#$FUc z1SH*5m<7l)T93C%cVrU?1U6-IJoz!Ldr%GkI8lW4jqvuz$P>_c_fdU4aEsR95r2G;+LJVe_ffJm7iN0da zhT$+Ic1q5rbDPsW;-vf4NRn-?bhZkqIhzA|EO*BTNo{x~)t01cnWsOa(1bq)oro!F}>vXBF* z$Zq9u09NTNc?ML2%0LGI{L_Za5T-PN00ouo8AcZ2u`+hy&>;tuzM5*^7xOD&GB7oT zQz$?n3wcbWov?5{QX)HiBE4g>_*5NX3@WcXq_j|=8IB*REJ2RgA@b_bq=`sa9KI5D zVr$r*5$pOLGC~1k!My5vz0jMN&A|)wb}^RDL&^Fw!dS{HoY_cj1ZSBk(nM347@8MG zKAwi$+Bv=ABnwH3;t45G6yBM;#7HUIGP)?TG;oQ`Rat^g11>lU+EUU_?WQx8$-PRC zW>^)sflESd8Wu(Ts=)AfISj=8CE1Ovp5cb94j`cMM7%T~Y2>~$N(-f7fD7r46jQbd z7<_~T3Kc|YYKLboj19{DLmMEIz9XfHhK$9-M_jxv@y?@VPzUl1$V_344Q5}Wx~wtv zdy-t^Dg!110*&)fL8%3}FOF{6`Y$Wp5Fvr2l+ET&1Yefs?lHQYm!Qb%aa}N1APaKM zh>SEH%OJt&m3NjMq+g;v+^gV>SRD=^wG$U2Ul;m=5BlxGIvD^83Pd7jjRti7^x(UH zUAm(j&kg^>ZX+pt43N2EkqSGg9-s@msmnvL)a`kLGQ_87m*fkoU){UEkerbvOA*yl zz(D1@It9S4QqoYHzd|dgP9+$PqqI=?Tt>HS{@@XxFD+!-S;}{iSt{StVoJ_s^WrA; zmo6Z8!SiA)z(^2j;Xw*Q2xV_pK6iL|Awi1A1~(9QVv^Y>x1N&7^C)j@Qq%7UpFFC` z0RBSm?R)SJgFl}tFBGY}os8^di_wF?;MBNgJ>Ya0KJEcpj)@00aE+WEtQa0LGc`Q_ z=cR>YX#AG!%H$aEvrb?|3XTYH>^{11nQ&-&A@C;CW9$@d*5HdJa|X}cxgW5Bx)3`L zuF4XwIbLBIc&(!-+0$%;h$hprg-H;C@HSNoDJEwIJq089 zby)ti8%pCCg7kaw#J~@Cmb4rr?~0>MF=ZH#++1SHu#z!GK1_~)NlnXPn#a?1W^97` zj@D3oBpI3*-Dsmb`i~ZR-hFWnsVN+tW*!IzIxm#D!0^*UssIGTIH*UqDlDKba)RNa z=2PHT}#~ZOb09>>YIn_vnZRJMmo^s+CV{ z?71p68fQs~Nf(*X#zjc0v)KVE>B?Kw*mPDGo`t$oTa1Sgn}70Hmq0(!%wa@-0S6dHcNr=B7@0sagV$kU{Wzz<7^yp^1T6U`%igNT+CFnz{sd+z+orq3(A z>@@zVZ|KAIgOf-pgohE~7WW6ZN5fpOABV~>Mh zsJo>=+3U7oBqgj^4c|R6LJlaoBG~r%$!`p7X}|D)`gfEhThd@6FJYEQ=oJW&87I)i zd+bC#DJm^7!3M?Z2fYTR!3~!-p8JmSLdrMPnoWd8$?1*~NRBc)nHvMX5y@gGz}6Yf zLsF^^6Yg^QPxB9}`wNA5Qu~Fnb6f~cOp%bOCjIW-=FER<=&f&2^G$=R6$AD|oK?rI+{bh?c~6NssSD+@tCg#416Y z$XF(HhV6%~L+r~5U+=Q%20y*dv&j@Wb51(nG$3Q zf=FwgPbV!SbeXRI@PYmv;nK}QlCg3{bV$M$Bar1PMTD`CEb?=;awcmDyOJJ6oFWX* zKQXfOkL87++4jEw8rveV%BV{-7c3ZROsANl8A|4}C;YoTWLy;0xQ&Y5lUk zLG!`dm1Fhsb6Wc~zcu*L#v#oYwHDU@G&lKp3o6GA{I>q_!3PG<9NKqepW!=4 z<_w=W{J!D!YJ=5tt9w>AsU21SUgNj>gvb}DrFmk_{~HKcmqPr-Px%hSB4Q3iRkM;N zNi{#LI&!>hCM*;)3PVxo#XjcR;Bw4iWa*$hwr|Z<=z`ISGumoU|<^zPBkOn^YA*5Jbih$Mn zkKV{i5jBg;@PsV*xGc20C;4QXijjx``V@&!Z3>wd_C)J4${(4#Xld=L`ThGb>qSYI zHhB<(hObEfa8uM?nKVQji{T1YO*Mt-;&DMqW(HE59PMWf=We>ljDzIQ_{}ptsWFZQ6hq%2c#d$cA{Wn z1J+%6-kSb8;x5UzK|(kfw#t2}V?+(Tph$U=P~a&zM%xp5$WN)mp-6Jud5dbdKW}y& zqfx!Vco=4Egt)hr_zzo>8VLO2Smpu?hCFJ#97Irb^Q$mgJMGn9CnT4ENYM`#fq_TG z$AeBtkRk_?t4kNvQ{a4(?8q!Je`zqESytV+RbB_Glh!w`Si6XUQf>oR#!<`v#0h(n zJL8|tnv;Q(nM-VxJ`0x)KXra-9RYfrudkS#1 z2uXolCTHeOjqOnKKeBKbUZf^bJA3mIGnM5T(iZIOJSHKS|6 zCcyN8V-&Y<`OWO@s4cR)G>l~yhZ4gaDEXV|!E!Ujh<}3|Me3_Eh<1{Xv$dSVw_ss& zYR>FBM8%|`qFY3VDgmHu^!-wJQ6IvD+R$^Bak(HdVN>=QJ(;?7YNEdHt+VUEr|A{Y zVNvh^F+hSV1UWyxL(XA_gM=ncO$tQ&L_Cx{jGc9AX&s&y<{8crmB5tkKzXk4 zAUzLMWc*f|;JgzsZ`7ihM<-V^jBeNd{*lB-CP8lkAIV|4&|&bVy=?>wRL4vKp;_d> zx#k1_4i9vnx^40Nv9m6ky&o~aR0q3QLPM}DDbQz&KjDMbo8ho|Lk>f~rnduQ;D?;# zi>q6)ep1+Z?UTRO zUx$f;N#kAYN@xYig8zxkxFHtkMC!II1`G@iTI#?apS$C*f z@FRs}fP_HN-f#dueu?R&Edh+izt~LREx~e5W9AjJ>tr|>19AuC&gP83p%vQTJ5g2v zr%4)9l{yEsB)2l)F8hr#TbfjTq|&!j0zwoU?L^KogdheFHtkPJk+U#0=V- zH?_Q6K62rJ$K8oc2t%#HQbKdvQ_}}oqGlJ6GE|tkCdk!~|8ajE{)-}si-Ah;F~A@S zC7XtN9)2!Ccgn7bt-fQ|7urR1p(rCY?#O}t4UNW(cn^=O+Q^IxHi^LV3IeyPp$tGF zgp*GJV7w!wkdJ4J8st0j+=Kh~V_b#M&C4Yvplwat2DKPm$fisA&FN6Rc-ex9m!Jv{ zLjz=*tSl)7Ft}?@pg>Cd%>YeZ#bhP8VJhv2*i;~B2bOAiFoQ1{q#3iU(iN2^7S?vSclLgiFSfbFA{9E5 zAm6~(cAYtuRd`6528W0WgD;v!!&`&*xXbD3#-}bD-(=QpNMs|lw|({E=5VC|b(scE zN|>AqCd|1zSQ<5y+(rP3ppSr}{;Oa2?}v~@RVK^FA*9^%OXcc8k3}u{89kq{PrWU} zRB$@TgToh+_~6E|XQ^1Xe)hX7?ad6yI5Sley?5X@$xq59!Ba1{tXzp3t}PRCWqa&a zc_w44->`W0eq<6b5dTq`N#K=LqBj(eo#&7hRGYF%#S=U~FWzyU1`!Z;%RI+^y~FG} z+yo+s1cLD}@Uay?=iM@4G)lXA+W1h~e+$IJ)#mx0>156F1| zFRrf|_>12Dq0w_k_ZZ!{eSLdn`mfjsDQz{`0pt z@V7Vcw>R*&H}JPN@V7Vcw>R*A?hUM?a&mG99RRLPhk@ZIp}JMYR6PI{tTh%-TBF3n zrQyz{cJh8)ETj*xIj{D~HTQ zJDy|Sg5jU;TwX|u4hBKP>o_K_N9wE9QPPM)qBjD7?l4p^kd_P}ADS})KWx{6*1vwK zv=Ar&%?YVUMyb_NHjTD7aUmTZYUD7)`pxu*%6AFABy&{y>AIcMzPDXk2$@PDs*Hd* zsHN4$kvm7zFOMZEQ>&RxfeP10O0o>nO`j3KdD*hcub(O}6gCTir>BH~NQIfxKA=c$ zMjL9TG3y;5-2$Yet)hf6WfnQ?M2LY$zE)lcKIU9LC=Ps-$PSeN0u4WC42SYSyPf(k zlS{omRIsykh!@cCOD4t+y{EhonKPhTiyW2~;}E&C|IYzk2n7T_jz?XLMM3i-ox6n) zG}Um|`fWX3QT7ql2f+mB3J9e(R=s3IO=Ki`Zy@|slo>^-`nNMQW6&SL6QG0BONK7( zO_<6;IGaFR;mqky)f|ukk|lx}v)Muc;`PjiG!v4vvpbABV->Us&Yx2|{8yz%v!gSu zL-r3Ez`oc5`iVffN&!MVuq9A~RNY`>C5(4OO#@2+_$?aQ^9$vLFq*I)@Ppl*k#rhy zR0HrBA1_1b@Y`kr;PZ8=>awz_agCW^Gd*%-uWhpXXs8W(XRXtEwXxE8AoE~@)`1JU z;3u6a3yB;slUo6l$}plF}@5V9GlA=H$#!5^hCx`&40w`UHdBN+z+9+O{Lp^ChcOlgp1T90U&{cQ| z?}^+q6Ct!UWxx~UH}gl~JU!g z7ntRpL-U5mkDZ!|Rp7YjGHbh`fYoPXpIaT0%^8k0#`~R8d^{tIt=ML^OaQoQc@CA)Mt2YdPzHweo2CQvT z-LAc2YyAN;qm;dCiNE+6?eqKnN_pR(XqK+tjkybhXEGH#kelV-> z8-fQ+TYNeRB~M_Fl298#dFrfY#X?>XJtC-7G(iUDI6ngM#1Bv|)Cq5H=nI>MDC(#t zoZgNp%Adu6daJ>xB;;P+D1qTvcnhJOZF(zFC&biTa{{{QR~;% zOOF<%JOz|}&3g+%9GMIxjiTE5=ex4+cmN5IfJ@8i!_($O>r^cIV z8+jJc4c4A%`!Hp*hq)GZP9mH(TF*9oNN;vs?kI!BK-e5YMq=hH1A)$rNB%%Sim=;9 zfS1B5g+lopOTvp~^9~<&a`}$vKoJO<9ioMRiHGmj70Xoz?@nKKmN$O`sK+JZO0W|Y zcN5EoH|kA`$sG|hrP+)V7luRvHt#OebBc^jH~~`&0_aVQA);INa6m&C{8VdsvwG~n z);b_9Bt)8-1%P9?%*`u=+GfH(u1IbwCa33&m?w}hF=51JV8NVtIP?5TR@@!*oNc7j z9}$nTjBd`C548dmjC>7|6UsV6;Hi2rXxPY%#m$&YvEvi__uo*a011_JBwBiPBSIqa z0-~Z2O$)_Ac&VZ4Y2O4r^kM`v;A6_R;r8rl0p1WTdbnrJNVZ300ho?%LMSnj`f%%+ zV3(5v{2xNWS9g2D`1It^D|%^8UNs|%3Pi)BsYza~Cqa$OP{E~V2I1<}+aAE~%vDWG zhPNJB{?xp|k>B-SQIrN`;E;b%wCO}3O=PJ)&ET8(2`@0ih7e-LFQ+ey#y4GlxZOq1 z`AKOVqzJ`B7|hJI!#m?<{c3a6SgYG$$kKvze8odVYZo9t-R%=w&Z-qXSmbw+yL&n4 zK`E@QXfx9U2#Cqk9Q>E|PJnyHm8eI6!NB$Yfs!Dj3aorw=1`}T;M5p)?LPv$q; z*VfK^cF=PsuTVOwxOj%l%*uqph`)q1zTcoj!A+v<2JL-Z2>~pkK_Z@EiZ7x(1*c?Ae@DU})=vy`{Eu-%_7HMOqMXK%q%|}@TE93#$|cr_ z+tc|^jG2}Z6m0D~A1d9Ey{{<|AEk!mwTRMC!DwU>G(sJ|dMTwwlqU$=t|%d0bpiPE91BZdOG_rP79%OW1Ox&|0tuosdTfCeE~IbvHYoH;q606RaY^7s}dtF`4tRPqv8a=tdMFCUsMlRwcH3U@X$p-QA- zf?hf#?DO2{vdZ0+b(x^IErE%2m&?#@td0=BWd1_52Z;(Krb|5blJHN> z0}r^cwa36UQ3fZdc?v-XTg2{j5@=!^Pc1hhM&O_Igi#n|L&P>{F;WtFv;}i3AMa@q zEEM69L{@bh@|WbwE>V;yFEY8w&ID`t+O`&V!n3dvS^@&-`SSs5|F93yBG0 znzkaWprpf|RFsHGqC%>EoiE-OrAmW>;g8tutu=NKgV; ziA2&iWq+)O)=RRT)8H`i5^!ah%n(#Ee{SW4v(06;b`m{Z|FlNTgX}%}Z}>$-YNC)L zWv(s(iJ*j0m>>c0UFdIg4b9Zgf5veBb&uv{t3NrLI5*lQH|~pY(E6+tc2XHDNq0?F zl8H)Dcq<(hMwl&LQr)N=vH3`WPe@7!s9hD!te#R+7!0uyhrL5pua0e|Y9s17PyvY* zzGL&0_xImXZl0o0?H@sl(kqhGC^FELF&=9PO&IjF=)jgF<7$}hWcbC^(?8H(h^M7G z5n{yF%ywgahEk>_z(&n@Nck73pWbt!2!@5~mqGd6f_iiNzw0kVW2zB~XhTlK8G1`J zHk5;EHl`T~wrx3)k<6J-1VEAWWR{*cIn{jq=-Be!&gSJUq|}DAm`x!!1e;OPg1F-N z!BVm&|CJ+2oqaS9DlB>Pi%eFJjQmZ*SUYiE*B)JYI zWZ;Xft*j$Kmnt`(=(wZa=hrEzS|qK5al{F!_hb)B5sehanx(&9J>r!ip1lSxJbblE zU}918PnY)JQIt#3I>W9q9YWu}JkoZ_OCa-&rZSov+WaVRC_P+as19QZDNT+lHubZh zsxug@AUTrh>jbkON$_%NL%<>cL+d?{_V0+UQ?{zUf~5M(^p|F?hmVvouS9#Pw7LKE zFwkvjqcUuY77Us^Rk>(Yf1#WQMbH9`1O5=eMHa=IkZqVhV6KXF0$F&;a`n^##ybQ? z0i8~^wk+L|Rz3N-z-Qv9SlX>a(;y_u68xyBs8Fe%IBzI|R`#5=Nf+qjPA_QPGgG=F ziJ}oru&hKgVs%0!Pnq#)?p4y{fysd~l~>j)>iH@Ro91@zRO@@MK4{C2RtH9|y{|d) zwSjp9M+}dx9;>Gpp#9v|f4BA@IAV04)@zy%HNV|l+b<_LvI-U$@m`Qo9Zoi_rT?Y-yK{weE;wnwUxE) zYL)7btDmcGQMqk&PUQr})%5=d2Cy!)QGR-c%s2Lo+!vTg?~UeA(`3m{=xxa*BO1(1 zR6=dIhp`yqpbUM{qUy~(aZ2(-!*gu>yu{21mXEP=g^&_h;0+eQJ#ojdK;6K`0N7Wg zrKZZv8G6@0%-)ZVZ{n4l4@}EsdTx%dl|p2|c;?1~SP5;V%D{KR8Nrt^+ptl3O;z6X zm3Pf9#Y_tNW zFG?HXnentL9MUrl0pVF3Fle-(_{n-S!dEJd+51sk^VqQp=!|koT-OmN8>Bt-!a$Qi zGy)*d3$05qcd~jAmyV8^!RJ0W&|gTr-H<@;=l8kdzFX@J}ryf0t_I zWyx4r?9AlwwlD9mLwE*)CR_7Kec~XAT#5&LHr}dAK?2e~9!~N`SL#au`NYY2gYUed zzfO**mgQ?~gZr81k%QoKd@?b(KAs%UN;7CWNO$0n&C{Krq&y`t8`-9`4pn(~R=Xgp z6CDJpdBdl2)RRViLR!f#ut7NujMg^5%YqC{L}bF%r`|AoKXM>B0YPmV^td1@Fz+zO zgTWxRA81ju6)9`|v+nr5U?PFK{jYNMSNiKntb|0+P%wpL>&d0kIVgs19UWnkvGs0O#>?`6 z^OHJ?7PaphcpINjb`3{>V%gCGi=GnT7e@=vhVT--i$owa=`qBNzTI09;1X@4O&^|p zDskDagL8o8GQ87CDe~5|jPfVo2W1sev!V3H3=mG*JqA9>M3P(AmiNT?o{IW9rzv|c zI#|eHq5Ww__QGknGqfihP+Ar>godYbKgxo*={dF6{cQGrjN}5#CvAksNgzqwWEl4U zl5Rqbb>s;0Hl&l#U@w`XK1wo(P;K7s{dMp>-HFr+U@e23yv`_8AH|*>2HQE8 z2f)r8Et)>ncn;V=iW+t8b*R+BWGZp>;&Arh1KyIor+sty(_^LQl0+KXg@6dKfcuhR zWdN9#YZ6eRO1)7kVoSiJ^oGR3u)oUiiOQxW_l(1Y{dp9EURjXDN>ZVeL&`ux`E)iZ zyAGJt{SsiqbZ>JJ^M(%W@5Anl070H>2|xwR)&7~`SQ!Vx>#NWtEv()XBYhA{WTD~?v$rDwQ%lO$Wyq*( zu?M;>$w_OwcnTo{oSTP#w7}fqwhC42%<1xB~XTbl@;& zj1gqYW}=qV45q)r36UNE4VbBr!@GR6|5&!KCP?mw$3o79T35ls=Nxq^!G_{cNy3fb zY|8AIHK2jHn5O)i*UjFJYBR&ikfjnku#3uD$Btf1T?HZ^evOVBXp+N*b&GM-7-h5} zoMvk1#qaO06CZ<_)@Y%}UfGg!dQiArBO1Od4`z1$H4ab)A}P1mU{=2H+`;v3nSCtS zv77bb({QATTEO(|X&>b6Kuf?P#Urdg;}%S^NCT9H9NE$2y!CpW9AZRwDi|mhu@Mq6 z6T_o0W?5KK7z(sb{>f=&st6)N(UuwWeD2(lH+;7LSb|yTQJF#pU&xmAdiWFu5hD52 zJDK+5_2)I4u;n(B0h`=zGWo#jU-s7#AkwlX*TqyySrl!VrYp!P$?AW0SGumIrc|SUMOaX~mCsov&qKq(NM8P7iF@J9ySqFTB7z6wOXquYofQN_H@2{gA zRFXhFgF*$?&Ck-tfN1y2APw~2a^ zswy&gif98e#TKmYxr8D(k2}W`7`Fl77+Lv({yGvz1_%g%8v8+KV94y8rD7NkP9kli zQX#H_VPvocqyW~VpeA4*df$EhZJ4?K2q55H8vUHIC}lwGsJXpQPpO;KmejeW5Z0?8 zze}8pAb$Sy`k9XzBWZUxxX_0((32%X0Q7=01&&5Rg%sdCH2HL~QcXt53;BgP^M`-X z&kW@ycvyU^a1nT#hu0pOQ)vU8+7ii?muM1~RGByvl0F(Avv%e$9{BO7lH={qW*X6? z#3vK(WO}tE!8{N30Bgi3CNGe!=7Eq(N)VC7-{2MjEQ7r^j=*aqEOwlJQoS1BH$EP? z%?^kha=3pAS@^UeZs}iIRy*m1{jU{#gb+abB}alnVWbGWK@&cnG6b+C z9U>J9=HRE`xW1Mk;FZ=+=(X=~@gcXwD5!X*c;N#yE2@gZj;FqnqL@~P-Y_*7&By=v zhXS~mwqWR0*Ua9J`TJ=FMluH1Okc09D|fLuloK%T*f2O4(w%DAE~mB!pEI2$m5+RR zb{(lt>Mr}tF3h|I?T=!CpaHI3Y7?=qFgBSI;bww6BTl>{^?2p)KGJ`%jKHM+vWG$z z0s;t8Jb#Q6^PMg+{Lskm8z+7)~Ku&Mo*z zrd3h)YtYR(QJJPi6Og=4`phd;U;Eoxv*6^QkW@1qCTk3GETL78F@qeeV5XMLK^G|~ zZd#C_T_IV5pu^4HeAMji825rv1uAA8KM$&CPP zviXC9y?)qyclWQIAx)O(v5Wx0;3)yLpvqIVAA#e{xzRSDFHQ}Evom0cADFkWb`c!l z!#^6RojO@DCt~@?lLG^_AKW+o`1nKP_l(~-q? zpEuebt+bzRKh}PreOLSD_BHLx+P`jJ+`h1VPW$`qZ?{iruhsokqBlTQ{_>Y+V8~`DyDv zTL0eqZtINJiLKSGV_Ju`zTWyu>+|L=e!R7)_5Ri_t#`KG+ImB4x;3Y@Y3uJ>FKIo$ zHQK5+pK1Q7`C#+z<}FTXxV-tl&7U`a(mc2MgXVXdr#4T}f$`1eAmO=EfE@Wz3SuQv8>?9uq=#^S~Y8t-as*LYjw9~%oA6OC6l{-N>G#@{u@ z8nwni{qg!k^?T~K)~~DozW$r~FX|W7&#V7i{jBQ*H^Eo{VHv}Ub1L7j ze7kZ=Wo>0;<;cpxm3=E;sC=gK$;y(-hbr%>>`>Xd@=ul5R3Ipp6`OriubwvYiGrqUDk9~Z0T}vXT^(LKHFI_;e0P`a zJImkiGTmAJR+krbmd|l%cb30op!WSIJIkvsw|9=&)8)6FV?O9|Zs(Y{yPVcJX0FRo zonv0+vUlg0y32<(0?1cA4rNy^YHTouj8*MmtBpVxacDCp$+sU2f|f^*NVc zb&mR|%lVz7wskqBbJTp7<(;Em>GHMCQEiuxcfPr|%Z{CIE_QiC=bPKPyt?zv1uie{ zeDfb%Mmpad8>s#3J)I-J;Bral$R#cpc8=V^<>U0E zmm@ldZ|d^7&f(8@`B>+$ueogBIqVZIZ|EHMZkH`PhrQ9|MV-Sob7^!Ad%-~MUmoim zHt2Fg=g?2NT--VIy)OUOIrL2~Cv^_p!sYPJp)Yj#YUj{lmqnd#?B=q4=Nr4ayrJ`r zx468z^Np=s*6)1d#V*60Z&U_qXWid9WDl1cI){9~<>#G4-sbY}okJ#Ej_(}uQkR1} zhtyp5?i~CXm-lrJ{*cS-I|py=vU%s=Ntg9I2fy59uyb%@p!S`+ItT6La#`n~kGP!Q zIf(4;JEwLIn&)zO=b#N-zS23U<+7}E;OAZ5+c|KN%iB5!zSCv0bKtbg`ke#+-lf_( za8&o+{hhDx<8oQ&>oYDFcD}y7%Xd0oU+A)?^YvG`?BDtNxXT`$1HS0;!Oj6oUAFBU zu%pXV=YZF`yu5S3MlQph1D-Qb`_}!P{lDyTb!Y#Nx%{lN|IRMo@9h72m*YD7Z{o6l zXaDE9?B3b$t1i2C_WNg-H+1%Um&=Bo{r=Hqz0Q8G9;lu9WM{v>bGf^-pG4x!OFR31 z(&gOFzVC54y|eE>xg6QqcXO97b@pA~DLucvA@$VES_S2r=M9o z#r{q|w0MgBo&JU5DfV~zqT(s`clr*+lkD&G$>K@&clry8C)wX=PZdwHztiq0o@9Tg z{kC|L{hfAR@dW!j?X=Fv>kF&p1e_H&B{hj)~;!o`F)MJZ3vAE~zW9;vgdy2={-zirYkFmc~eo;Ke{!aPV z;!*Z@%Btc~_IJwu#iQ)+lz%QBWq+saQasB3PI+zdDEm8Qlj2eKcgo)tkFdX!|6Dx6 z{!YH7c!d3(e0lK*`#brf;t}?D@>#_r?C<2&#UI(<$@>?7WPc~`S^Saxo&3S#kL>T{ zw-$e7eg!E*@fkCw;DXi2a?kxOj;DowQ@|5c@mnHN`{h@1zZj2if0A>lF{OzZ0J*9%O$f z-dQ}z{!YBCc#!>_cz*F9`#bUU;sN$|;?cze?C-=c6%Vk#6F*%%!2V8rSMdP*JMm4$ z1MKg_EsOiv--$0N?q`1|4j1>czs`fj{p_!EWpO|I>-<-7Kl|%^ySR`2bygPlvA@oK z#eM9rvqy0s`|EtLxR3pHwkhsof1UZoAJ|`K!{QI@uQOKsf&CRv7Jp!W#jV93*k5r; z@dx%-oLk(>{)#h-d)Z%cOmQ#!EA}t$Wq-xTihJ2#v1@TJ`zzj5+{^xo$>JXNSG=^i zhy4}R;vV*Q!h^*{aVz^~Hna#ZByQ^_PpA z*x%|;6gRQI)$b{8Vt=dOT-?O|R?jVNVt=b&R@}t?R@aLg+23)G7dNuM<8CQ#WPiu~ zZ*e30JMIU?jqLBZlZqSJ-*I0rZeV}M?Ooi!{*K$VxPkp0w@q;a`#Wy4;s*A2-1@~0 z?C-dN;(GSC>i*(-_P6TF;(GSC>Z0O$_P6S!;(GSC>Y(C!_P1)c;yU)X>O;kK>~Ga} z#dYj&)x6?5_P1(-;yU)XYOJ`9{jC}-u4RA6-cwx5{*Jx8xR(7Ldr@&M`#bjA#kK73 z*rSVU+265y7uT@AV;2?Iu)kxsFRo#K$4(X3u)ky1FRo#K#|{+Nu)meJ7FV;smH$&* z&Hh%NQ(VpdR-Rg1&Hh#%U0lunR(`d(n*FW(SaB8mTe(wl75iH`U0lWfR&G#S#r{?{ zimTY)iu;SJ*x!n)i!0gRii?UX+24vYiYwXQild7w+24w<6<4yq70Ze%+24wti!0dQ zihnGwV1FzAp}2zmt$0px1^Zk6L~#ZCTYh_S1^ZimNpS`HTmF;c_v~-^w~ODizvagi zzh{5TzgGO7{Vo4=@q6~Se8=MV>~HyNi_6*H@>dm?v%lrz#pUepn5T-%+21jD6qmEV zV=gN$XMe|>UtGrij`{Zg!`+?7=~h-(;y>^F*7TO5s3aYYaRLOb@m3W^V@x}sh=Agl zC^b5?h>93QI-ns=`57Bj1i`CDO(b!M8bw7>Q4&xS2heT}5^w^EQDSU0m}r03x%aK} z(0`d<`j7r}x)YIG_tY7lXYaMwT6;fxueSfrIeYKb_TM>Y?7iClJLl&SUS(ZyH%41 zsuEu~ywBk4^!|tSf7*Xnf1`h3?~2|Fd-ru_z`5NcJOA2w_v}HPjn0AXE2>-CFKpkZ zbv;gD=l`M#qBncn{q~Aj=V>B3Fj&pCsTqh9D*TP2*LL?W)BG10(4QdSpy| zGU$D+|KsmftqaCS=<=00(-p~#M2I?r3&55oe;*EyAjJ98wrXHaYlxSenM^D zS{dHXj(O2|hQG(erJ*b-_KY+}W)euatBs*B?S=ISbDA@AxfR?SW{O&nRx#`=@6TNK z>F=%jH=W$PGfsYz8jm0un-w;y%6u&-@QoqN5RXRC7(hn;L~fF5$ZYgFzhiBw_ZMHU zdQX0PbFmDzh}WMbB3fDI;-~+|yVm(uYo!tOFw+!k9Z8|NOhYsh#~7o*;diS#ulO&` z#WJynIUB8qBcuuH7{#V%-WIB#W{@fMJRe(|v^*Dc0vKVJu|MXj*@YKY?HixGdok8< z{y%??ll8g?_gtt4OPXSXI zCBnomGnTw49}(+mDu`i=m{mfxPZCudH;m&8Vb8v>(LM3Xs{Ov-Z!X5a&V0s9=UsXC z#7x=}H6dCFf|>@&5S~+{*s#ooLG&WsMSi(c=MPpew@iV#qrLd7=E^Uhad{Z6)NDOtseD%E-W@XLO`S z2wD^oBSR>SY{~#oyUGxu<(bL7RqtJI*iY$tO7tu?*8h_8GvSfRl`Y9&7w*F}yqcir zpK=;RPAVWF*jnZ^(Gq^r^TINL+fS>un>Dw}?$jUSLlKE> zER0%@GbA+Ql8n!`dYH$FJ)#V$ zZEfz*)vEgWyPKzULM!s!*2z3E${p*XHp7gbi{8YofeA;YTRb#ck_AtO)oTEt#-f>L zDp`NM)m)595kF8GP~%=_1F$Zq(W`xmLs&FI}gXd-J!w0a_O6Gdes4)1*aGi-VkO7*>c@bxc()j@w7Pe<~o$ znmEWo$fIF1(OEKLk>!H~mr1$V={YN;o&`u=b0N};Gi^rIFIWB6*iPhPI@UA6$zP#; z#8DI#L}zqbMl31!>Gv=XiNMyWUB|;gm9ojUI(G%8tM4>V$y!w(LM@^2RX7K!mQ00k zhv7;ej3xT_9LA*K-SUrhm-$Klp(<}qe*Cbi^U-%T7c+dH^lCT~0gIE4$Y>++%ZkpV zIKh{nISwH96yv|xDL3W6ob|*MI&t-{Rh`HD;qJv)qG_-aE~6#`G@~n7RM&~$pDDCn zAQKf?+z7)A5*E%}O;V>$ZY)h+Ja1=?4|n;&36*_&H*z8Tt3*IzY!6I|LRsIrw z41#=SLmQ`-gA^@4OL1%R{V%IJ2mHLbGY)^m3pO6DM6-B zTY}p&6We#9IS(d2TUF0%(p>ClZqA>JRwN@WUm|N}ljb193~1E}OibhJ5wr~hwkug% zcy+WuObrgJ`X4#3xw8y7Pa~p(53F{-Fvsx%LTOjD8pL{5ff#6Lq)fhm2{&|ff3C7& z=N;AHu6HXg=GT$lh`c&pneABJS@JVXkAdB*0)42`)`V^ieqqKWkE_?047XlgacI^3 z@?D#Y5w2NXBi5Q}2eW7iw>`5gcmx3xd5HA5nRAsS@feN;_$bBv?St2yS#{q~+}W~@ zF=CsBEW5}(%GBv?%K6CI!;&E5{Z9`+qXA3J)FbX(wI4jT3R`D1JgOf}k%x(( z>Ho<~0&8Xi67ysN2-Nt~Gz=CvKriBe7=DVsP!eu#+v6ug%`aSwwd^wEL2l1 z1U$xAz5C>JR#sy$9lvjd*_3p^Hoz1SDmiGw~MQHdq)8}0x|J5792 zls`&;NIe+s_~dZAk(LP{;tV zXJ+m;Rrkz;nv21rqFY4XQUtU6y9 z54uQfj?tcTB13R_1=5`AxHR1gav4i+nnAe#9oXTlcx^{sszD~H7<`zCud1k@Fzy6$ zF~ra@3jBP%TvS2s(n>c9!g>`PuhPo z(7||4>4+UcXShYhWWb)FnZxQ)2B~wjX6JwyJ}OydzIEC&s_G5*+I?rfl%wD^+34F< zbjBT?HY(9ZJT+egvS4{(63AE)>&<*~V4k5XgCGVEIIikFbUd&?MF-kANJLbyF%wzR z0TJJ}$5S|Q#aK@a3Pu4-oViI6R4a!?X#V^gZifeWT+sGp`!>~5_1#MS{_XA?x{v8j zbuMfD_3Xv%z14STpVfK6>^(wjgw^j1iMfR)4-f4cflUz}!{&4s~Bp3+>%CsU{} z@+y%S*8$s2NK6r==+zI!Hq1&5h{FGD(Oib?lnil>=2}^qebnum3mLcVG>=ToF`7Q{ zAdW5AAl7zdfaa47XJl=Q)7Op=8D(Kfj9YXxIJmixF$MZl0Aw*ih*z+&!#Tr6x&$dR z76p_N32R@o6kv~8e|#f)%4XhtLUSR&nCl!=(L*6-Y1yIFivKYO8KzNg}Z7Ou26_zme>tOOB5bRkC0`rWy99{M;e@%{$(~&QTY|S40f#yP{ zmvfqO7%?5&E}4Lt5?ZLRb#?j&;3~>(bLLjyFDPAz1qL>^XMg30=0f#O7ngEOr|`~$ znq#)pQ0f7N3JZt-9C#E!YHGk-Y$yfr+gO=x|5|e)#g--|Db`JhN9ub8m#!SXc9}aC zXr-hKkl)3$r860lP&Jw*vorei?-du)o|v=ZWHDGMohhm54S9gKxYM{S0W-Esu`v@* zSqy>XwEEi6qucIjE)=(Y$~?UTewmzr$!^90q`OnQe`etVe7-1`s9vS& z%I)Gp5-U@;GEpZd|2zL7kO>l@d^Glk#(>6TNANHw>B!~0k&H$@Tj$|Nl^4=$tw)wa zR4JjF;*Dh6c0`i(qsP#={+Q@AE3<6d(zc5M4|)_O*Y+7lmKV}npvufi6o>`D7)!!9 zW%5((@tm}bv)~PEqf-i;a@3WT#!J1kFj)TY<%RSZ%1aq}>}^@+3T%5=u7>3hT4IHj z#F8g;q<`J>1rOk`=7<03GsT6Nvb{S!rn&&Ns$}$3ni%1%be94-vaG55fU1H8zoby* z{6Zux&G$c9E=YH&s?KyFHa)>aipaswnd)I&h5gUMoxWIh@>IN>$2C^xY+IbZ^J{iX zYIL@|jcVQ-h37DQxp zNLsaGq%@y6hqQ|TT&B>PMqBjW)H@npRpc_cx;`BPFC#AcO&RgaajpWAi4`XrTGOkb zxHcI@*(eL3IPJU1w?DMFBiY$s7IF06zz-@i-SR3^8y^{=uh*mjnB788yD-*K|10}^ z(rfFfUo9?V>v(FeTqRMa9ED=lDehzoL&Y;in41(sgpuIiR^0=(%68yvYoRs#U_&K| z&2>0*zJ(YavLJn!IxYBX)kkO-23DX`ZD=$zCwNeZkH)Im{&2(m@PZ=j(4?X#&;U2< z7Q?=ILeM7*Lemi*1jWIVAIB>UpEEOXtlQIgu<1||fUbL7lr#*y*~RKx(K_QgLXaz{ zQ~eknm03G%^qc)B6`Z2-ER~zLm^LXaXXfv-$trL0>dL2#;mbq=bcXW^kg4@qIXORI zdE#z&Y#vRBS1|Bt1LRsmtR-}*zFVE=aDyEJZ88O$#ltObJc8C35gRFGe{_y)N@ibV zD~HrE^D_U&{wqJ^q!`}KFf17ol!k(I9wEC>f*ie;23Pjx-0%Z$F760YP$K*Hb^zp@ z1H{7O*9ZP&-Utlhzj}B6H*nhc3D;MvE-y^{;cJTvWpV_j)ChI`4E~GGVp@ZR2SsWW z_Ey|=Xv-X8s?3Et^B;NYi9>&>ybuzFVKrS8B9b_i!$?fdPs0O!#DYh}I}1Y*<3%G; z(Og<~0O958!V}92fuRB(tSvHQa>NNBh6h->vmmvW7eW_dJ8-mLlO;yGl4?uXZn6sYM0mEOvI&uVT+nz8S3$DlX1 zz}L>u9@sI_F$djb{EoB0;3gr(rL8JnbRl44r~B?F6c^I`2rh0a7PZwVw=)kTt4#&0 zl*}>W?ly!BKx3UsnR!Y6X>MiW=D#m5ltFqPfk>gu-OvPLWok;&Brd^=VWOj!>aaH= zpvA6nI4$cq*TI{b%1(u(<_=y_U`wc`QJ7I@S(;pk-|)XcoUviZeJrhIlmR$q1?fhf z+cUiMQ^g$xcA(beE8LiKdV~%IP`u@ul5|=o5IK2VF)R`U%hx!Bw3BcL{ zeH>g!mJJ33(`_ZFanSZqvWXBjiqR=d^I^wmP?@kW=ZLlOfPh>`f1(N-QISJwQov|R zvPfmz5bLUPs+!+3IWq?4a6`7PTN0VWV;UM|1fMSv+=H*c zg=n2j1rFQo^iKPe;$7EYm_A^Nl3gcYK*8E1U{N0)yAryXJY{iey~BX&)*zlZk$ACp zT%kun@w%q~VYfoQz-s`H1U%4Qy(XXNU&OrS&}>~ZIaN^~0aD#vZ@15ExL}>gT85B) zIb)LAp&|qU5NMX4^yC(>x!S@q)5?*ThJp|eDNp@ zf=m8GQ_r5dSNGAA*G|56@~HAGf#K2J$<8M_r*`h!{&stB`}p>B>yxe1TJzP7e%UYl zKM!lZB;v=BWOy(yU0JNomQM`m5hp<<<*7*wNE4NpXrUP}!%>8CUv_7+^^w!c3mGlo zqe;~Qrrs~h+>fOT84r-N+#@((_XEdoW4?%|2(QxaGr3`0)zLz#9jwuogJQQwFeubvfrLI*@ndByeO~`Iw88{l& zwLYv2`X#}Opp=#N_lsCZ*JBY7ex*)hN=(c_<<(6-I8}@lQC<~DB!n%pUUQlbp3Jzl z<%LmI)NeTt&mXD-z$RL`?UybwBR^C>DOPa&W)?VsFg91 z5Iww+i924d$3^Pv@KNPLyzTjOiVG>oMfMC{0JXFP=FDjSqw-f@JHjjzhw&#W7!`(| zcO0e;ToWW#m)qB$TU>0+K5MqDxZD}81TP&@1J;z9zNx8i|7 zb$*GQ2~;0`Xeb_nDo2hGfR&ZLxP+sjjJ*O!WqGYnoOzq#Lh4>wux9)-8O}V-pwuKf zkx@5$ic5nz@#Jn%FZ;Z$kUCH>AD!56yY_cri6M%adMP_3Kw^5mb|cW-zM3*~sK6kD zYbc-Kx%4HF>{W*Pg<#|p#XsWo=U;~0+=HLVEkcp+V_0t=97w7O%u*& zY2+Ny0kzm+{gM%><{3RH*jKvW>9jMs5&tu99F?LvyOj9&dMPLpH zvMZw{BF$VRFdJeCI91lMI)Kb_pc9y;&n|fhGME}bAqZ<}pv=7V6sgEeAk5@6wikap z?cI4fb&;3_WAU%|uKtpDod)HUxI}3(ohE&piIC>SvZsKQic($1xExjtOCy9FIsxUN zRKO=vMFz+IWAS8Q73_yQn8V(B@_Jw)4vX;xXNQLp>8T9|Jw$tZz(w_V1bt$uktJoX3n!mA7+-I?#w6 zfOIfunfQejkr6UL&BFE1P`b#zH8=eHmF0!tKOj(<6Eae|kW;;GAOKV5tynn@5460@ zvoWP0qat%kBx!%8H}}%wLgZA)5-%lG!3(mm@s;8bHVcKqj;3_7A+#oI=~q~AYS;u2 z;-2~8NjDT1@^55TSObL#UxYAHuZwIxoT0deGo`y-p%gw@+SHj1EsLacOVd{uB9qro z%gy{ZX)kl~6xu4ju)tD)z)4e$SIxW1!>5Lm_#tS{t>K>)ObHp0$b~$}C?x8y+1Z)Z zAvy9AirC^T<fNyB!rsbLBPR!S~S~({*%i)a<{5jz91k1JE^Oe z+YQRXN2oK*E6N~wW-VRW_Kxu=bb%153ws7<6r7~g;4OuW1)+E+BY;4i#5`j-)Zl`i zI}yWFKEfsMheDhQgX?Ci`uq{a9i@*PU1g=H%d=?RNd}X-YI@0yZy;NGJ!T~_=NQ$N zxntQ2Y-zv#=eN30VyrmAnUgrVjlvuV0m;;koPl^c~BAa2PnC*q$+~s4%+>fKC-7);h0ioFLvl3@V^`a74NQ z?IaCE8;vTq8{DWy=$r|>7soZ2E$dAY)~J0H zX3$ADHSvR+Dl#B8n9P#1-4}y1~JcO)6n9_R%|?)lzS!ze}6If961^XNIIBjzF!B~CbpmSRtIz)#)% z{mq4HgR0+0kC8Jn`~k~`*G?880l6f9oF#^VS0trOa3l#>TBTrL0L7VVBB02?sPi~J+fRLDd7*@?_+C*XvX&VhS$gV{kU7Gt ztw7xHmGCw|Z#;yUM=JK(dhh*rC@*9If~-_NQ$f_|0f*U}Fl+)HvIfix*nvcxTFDaO zn9Ds#p7qU{R~=JaNaFHDwwooWK+0jrmNh~nhZU0WtN_W**y(sk8G~>N7y>oI>YmQr zGl~oORM;xVTZSTZC3OoDBj=u)A4$ZOda%jnpWE1J*^e*B%~2_Ls!v~9UMMFp_(7E> zSFF{n@KL;ZCR>+kmKp96uH}v{#h1viB!k$qSE~0E*$AzLx?%J|1H^DAp2eFjhFDK< zkcC}wI5XXE$p;U{T?3R8}SA2;{oC>kS_cKDJNq->>$6e9RkkA6;+&Z)iWJJ=MCb^@7%1b;Inls=c!p|H3pt)x0-Q z$`m!lzoQ{M7^MsOWn>NJ#&~5wG{OX~O1KMAg|f!Y)CXKFE_VO$e-;E2Up48zu_Uph0yrQEGrdR&r1W_(rsf_lnWq9 zNG?uol$t+~%p@vXAZFv`jp|=ZLv}1*{L>T!b1+FBVTBP7vRx)bDiW1~@+l$AunD}s z0!obsQ!UI5s>_Ny!gtGy#`$FIDEo=9h|k7JsWVkyVNTE*PPn9S^G#X2Pz(IbdNVrn z`{jk;Tx6{`%t5c>tcg}t7V3Z&9MhrO^_PK4@t(UHrbM2~vWVhVG&GBcaVfK?bLu!d zqX6JBB4HT>hAp%$u$w_t^zhl=XnahDdkF8DGm^2z6rY@Hn%)Zj3s(T!3~*$fr@^Hy z!kIKm=j|LQVWCW2Sl*E*Gn0&`o!!WXlW#>C{Tuc$&dPYR6uO3WaDgQD;CK=f;$&QJ zJ#3|Tw9M916=lJ~{&E%l#ok8Wx^~V?UrSqvrD1C``3MA}DfETP8ho{2Vd4IaZWTF$ zhG8AVkMhZ_cyDTFUR9KZ1V~O4ekiOMW;2xHW*@bRdI?HUHSk_=kD->Ch%9xwSIBh4 zlv*OQuN3Y%n*`I1Y6H8e)|~mH*Ol*xdjmLu$sEMvUBD;{fEmpVg$ML@Jw}9l)S2643F;cB4ar48-hMB$w`=G1)?<~l3XvinB z7)^2}vWulCE+)9hcP_Bzn`0QcX*iDbNFnhpTD3=vv)yO)o39pzKF&mGBKSM*`lL-E zTRottG^|n<5&8K!u)~oC{06DQ>u%rY>&1mQb5o})?~LzbBJ)Cs{}i)S%5s74DG{Nz z6ea)<)=k9J`@z1@f7Wa60q1=Vq8-;rOeb$VdB9Po~d>ytlv_^mD^ zDS+HL&NyfFfu1Bb!z>k31O}t+tc?DLscj6kVN3#K(c!5Dr$9ke{|9e^N$6GSfjXK|?XrPd!#!k< zl8uxW1Tok{W5MzT_q4wC$%enddYOG@Cm@ixs#I{cS8Q@@NfHk$U#8e8R^^9`Blg`@ zxZ%DwMo&7wcttuT#5;vPiW`y*`C}#*9y4QkJ(&?)F)<((GChhlCsPKY2vtz;Z+qp1 z1Y{gR7#oscJkbEaqG;kIYbBvmq7(o!Kb4v^OFaq)OHfEE*cd_oGl!n3tAEKfSiRP<(gF3Ydk%O#~z?aF^tGtejne z9h2s9BwkVa?4opuxgXF8)L9Y?gcX}{}z^IiBDy?BZ#9EKbNxwBVj zctENxvpl`@$Hj%*DvP^}PbdSvWA$RN_f0alJK;d+5pe5@C$ zBbn|JzZk>9v_TT(UyL)9KL({pEg`m|9B`w~LCC~82#AKWKJnR1x!g~=W=35`e9?dT zAamMFOnVA{xx?8}2?7`ySSZW|gcK-9P{s5!lH9+%At?umo@5p=R#EJGsPklGi7kHmm`%fIdaNv zaVIG^?P66^>-m$#22thgGZANOFg;otR0*4!D;NloupsP7NtLT(4WJC-~rp8!Y;k9=a`(%Grv|`$W?f+cmS9drHqVu&)EZ5 zSZR|RML=XDRcJ~63NHCu>x3vJx=j7(wBq9vF+zaUovGwFxiQEyx0lJx83U~X!~!a! z6(m{W{PtiX!QyVG7dOOhy9O&R=pHs9kLbhDB>>1m{=e6{>gHqtt{k_M+5z^9+r?oF zGjBPrypY+#207Z3$h6oE9fQWFne)^nMs=<3J4nD?@s@+VD0{*LpV8({?~?^Hfgoju z5RZHYlziA!wg4Li}HxbiOn%7zI_;?>k!9Bqtz=8_Xm} z-Yxf}@d<9==u8qJHg!K)c+-%Ok=k8NWb{e>6=gW7fNGDqO@t8-)X0{lmI~}X?IbHr z815cWfUKP4BaLbdl>Kx}0vl=Z@Q~PT;h#-ETApfEO4qhTmB}u%5a!oApM7@oXxy!` zg4iYXxi$Smp$)>~p_IcbI#AWwK>?o#D}^O6iMKZacVl7p4-P3Wluv8}>J-I<r)vMjE5idUwoa>NKWNtfy@tcl zwW|7Wj$S)DYSh`+2~hU|96j9|Jb&t=Q_q{a_u%l!uTP%eKd$$2lj{Z(mrk70pO`po zA2%@A^$_3!bQpAA(3xxB(D(svw|u8@n}I*_PYer~dDfWGB{SuPfi3^jTnIGgP*kPa=@JYW790TZdUar?%}rpy)xm;%8nyVkEf?S^Gr*TuyRUpe zaYu9tjeb-Nri8E=5qDHFGEq)608){cIe!tbl>~67@+f)NYT1~4#<^oS;EwRc7+1ID z2Q`=ItsqDFaf{Rdg!mHJ-~7$cu$fYu`4Bn2abi`LOvgx>RJY}Dh z%DTc9px&{bv|{1pm_in|MjzkRmn@@j>&B|o<`dp&3l~9`CBah;3^136XL4U|PM?NX zoz5Y|)%^VEj5C@$LNsCjnV1x|%1{PVb(c_PDeE`2=i>21>1#qzYfveY(h)`eaDDXf z|5jWm29zAzU>v>?!zmVXj$$f3+G&p9C3@#zL)!>#sdhn4T29u*!puMab#tNQ+Z^+P z6V(Ihou?BsP(?Q>LW=fhL~K_R^KSe4=8jMV zS`pItW5`Ub$;1&At^Y2~p|ehGwl&2!13aq$y0VI4tKihdNqKV94 zq(aWDLb;)~Wg+xu$PMOV?PWG9YKxAGEyfS`9$W4;0w3Ba?^({fTu=LYF7U=RXiGij=;*|K$lW0Y5tNn(*o~}tl&!p(edT#=uWqs zJt>ykFY@DmzE^P}i~-6aCk!d7a2qx4i>$yT5n}l_><%}^9xJthm_R;|2}l^oa`P+7 z3qjY)BQHXx;zC5Fr#zRT1xRT~Aumm1-u1w-Ven7am8D&?FgW$y#f79)O|asHbF|QH z-~^k5Am%mX)Fob(5YqN3WPlmS3D8t;B-r{!`&Y})572nWq7BcBMuP-NEEvi-7AK^? zSg5TMuFp}*F$VC#shrZ2GX0$Q6?f!O(h{IYoW+Dc%_$`8Dar$;4~$Q&&-fhAio#*n z6)&wPK7D@w$(wFdUWnRaQ)s*AYDTTd9^rAtTEK~SP~{%K1LH=*W@2$BEr=tFd)oKd zExjyAy=;b((~6)5FE&6ZvbDdfgarQ7&yjh>U0MK{3NZ0D{m1r7@BSM_##Y*xW}t=7 zFGiH$$$X%IqI588bHJVI5=`rHP9`-5hBYk5@+_|Oum6?e$-H7tc^Qi$=0q7Dyf|wm z5d4DfAVz+LpVOH{CIQFpNl&d*F6s8qO1WHHrt)Ok;z)E50xc33l@qDbCzC#~H48GF zg4^}Ekho?$c+!-Jh=AUQUeer<=%{tkXJI%BWhBAxOZWPnBsKI3*@S)_yLqkfxM?cB z!6b7V)wk|lT*yEu%O7i<=4kA-kgM(6dm_~<0CS+OC4-k2Md4q{ANe3qu(b7^rQ z<~YAD!wZ07j<&ReNrXCpJS#9EHgGziZ~0R|Lr^)U51~`2W zgl>ogt^$`3qLwnkgD`2BJR~ZnV++YM%afNDp`Y-_$ROL{C2*S0uwd=-kU`=UQu&@Tw1RG>3;X-iW3cU&)1q17}C8APcb# z06^(doZIgGbeH6CAxSyGBEy9s2(t(LJ;)5pAni*%vRQm*JYXmu$~>0}-c;&dU7UPu zvG-}~7;QTrfk4I(n!>i)=5+iV0d4&#cB0|gu3o6Eroz$F!}!p>L+U(Z)JaGo`Lw~ zZ(ssQ93q_ND&aFRS;qz|3M8qP=*-{U4yoD1TnNm;4yJ*ZmoiFLj?%DGq{#RsIZr&A z@(mTFQW4X6GSDVq-HAUfufs&7mkrIUVZyIBy}&=qymCrVjz|a`1%5(VFoO^&z(7M>NA~x zncf;LOuuLLp#JTrf7bi!;e96`KJ|N@cVtdr@3h|G6aUtI$i!bvY);%^@*AB4hF1LG)wbMuMK#pETsS(eRm=Z6fH1F57ggc=ryANu|iZhdF;6pKor)D)23AcdYtXlt2?CjDrhk`|!iSQ6zpCxQU*kcawa zz4u~s{l0WSb8E4?*^ojuLzHKu#RK^cPJ`HLODZNi_8-P4;;qVqz95|950=+Qx4lc% z`Pi6Z^8t9?5Tl)&R%Ivu?$0 zu(I(hL5;Fo9L6lR_|A-G%tWBDi8;)Oqu`(i-ef|{>vr!<1j=zB(jx4{?JIwfHlqA; zr{xytYs3wXBp)esDP>rmRZzn|ts|aPRqs4>_hPKxp~lmiMujKOdxeStyG;AyRU6|JczE-uaJbw3L=6G4(3hA)nI$Lck_)bk4ZNbc7Djci%l%K@1^ z+tua&x$1uJ=G}`SYbkds4$Fe{5m+L|5F65k50j;h-iJuD0^cKF}Gv7PD zYQ6Ze&BYX5l8_f9b;Gdqj<_XlaA}VM5CgwPJ2?RycE2)fCYBK^HH7>>4_0MtS(W+d+G{N?+AhvbwAoIV^i-xoc8p@3trJUQ7p$Mj`GG69&>r z5h@GiMc%ip2w4$Cd^kAD003`J*{fX}kzr*nPrq-fx>XLqwg~p1G+ZW3>7n({s1VB@ z`3C$ZiVFuusaZgoKVsp@&`Q3o{!d?CwI6lu?wzFrOAv$mPy@O>1qqu`;8CK=r9x!7 zAXpJ%tnsbWBf*SDdA8E0Pxzgx>R%YiFfbTN6B};MX@WSY;7}>%U+LikNE^6Rhuh)8 zLY`tCFdEt;up{xK%uhVvn5z3f#%-Ivrg;uQ-I9$s8WBeH@CI21kj6l5v?n)_IZ>)= zRj`k)o)A2?=et+`P1U_^v(9p&SXvb7@h~P9FdUNm8H|jz^UTqql*3xeDA))Qv$B** zkw(#Oo4uzPVf!n;z5C86CvHbyOb$lW4oQB*U~uagmzFn8EiqOMMzX^LXceBEn016) zT%CB{qpSW`nvI^Z6>L=*O^T~@JNCY{q)q~VT#0Yg{6b&VYjTjF{EE)(zj0yJpZwS6F=XE9 zhhZV1FwOAcGX*iI-0n4+Di@-ErDu$mkTzc>uOFJ7{GF=v&dYW`Ky4&e+fuKbNt$s2 zh5~rrm^GBd)HcbmZU~WwHLKz*B_4#C?ArbE6RO_y^zMye+YmiY;^T2dvv^C^me~%R zXeG+eovZ-V3jQ0f)RtF& zO5~6SQ>W1?%B`i9>CTzoHg|dKe6Z1tEK17?)+;9{SkWwBc6T;R&yaD zJi}R3GFeZ8a`)kTtHBv#%2Na)xkuc_wNf^{T${#(y*5R{!HsRe$?IyTAoS!w}$yRCUO0>l)K3zQUc5x9GsG&HgT+NF#L+tXZ@Ld{3 zz&VwIPK`|Wh=Z0r2b9fua0UV?bSd?=ho2BOkkUY9|Eqsg^`HJ%ySvHDmv3Qwze!NG zdqsF6dVRtj@|XC)uJ7O4zEXePKVf=D#+@wpUi7pRtIn@%?|uMXUyMw`qGXKsRPhj1 z@M4x*1`KJ@g={l`Hr^I*!GvAAk8rN(a%18>S5>{cPVQbT6X(*4D!O|cYFS$`Oc+lN z*aGCnn6!_W!aAV^d~A_4GYsZ;Cf;{;)qU>mb}xnyP`h9TpgO!ENW|m>j^Y0S6gXBH zAt@=JbFUe?g%lA{RrWg@(=Yp0)%oJ{n~QNBrjJUv$XKNm+AMiI);Ww1!A*5flc|;L zjUNjG^4K;Y9wHE} zOAvgsHT*)={>bm`-kB(fZKR=qV{CiEeT-WO4?U?FS7mF-bMOqq6f~LQ4+)$ZItY{2 zV_(A$a7d8ozP^Ar#}9B)YjO5oqiYK~7!F&P|L^?) zt<&2hJp#?-!B2Kh>&&-rY`?Mnxay|r&HpYoVE2i|Y^APAN+NB_J62Beky#w^g8;C# zXFMKmUm6h;*@_WY6BhnybL!D=EH5M|06U^brim(a)CcK%6Z8dtI*Kv{+sP*8&4<)7 z>>-IC4KO_52fG(?-CC5;K#nPh9o%d7FVO%g&?xTtw19!SIsq641CVihGT+wh+?a?H zfx?4(A{|#Sw6Cs|!~Mk_hN7ay>*PX7WR^3QSUgtz0BBZ-s65*q6LGmvj)^7RN@U7b zqyQ~Yl+TDK+@qkR@dZXFJAr$AkiwE02g^>S8U6VQ&7-*^T9$Sh=K9P6va&LZ6}=du zI|lYhVlV?f6GI;bS!i{W9$<907w)DIZSCTdm7O*vg(yOc1vVmMrVgM*^6;u~Jw}+? z^ibkJ6?85sJ{D!Klnd=-5_-bCl2v0MTPDy&)&~@XA|g1wM+t5&5wjsiIxc^W0yCp= zJ6&E;4&xMzIAz$i5Wn`c21X@XdXDTza5xT8Y=88U47G#))1JC#we{`y7O%*pQs!o_ zj;W7vOHr%tg|HAtdM!{uaU`Hi(xfT*Y(W{cLN)U8X79%hG|aH?On^~M#>otl2b~k`?ZO;jz{^{ z7t%8c)exz@Onfz^6L*$#<*}h*i@{*I zdfEGmuP=r{P`tkCPBzP6{nQV1AkIn5n~%rb8kj)ib?KwZmxgEY;hq^M2)gP zBOxmT$bNQ+vVcD%V=kpo#12IopP^>fP$8UzK$@GIIqJajLMUz-HG&{G?V_N9C7Fzh zA>?_%HbNi3uBO`jH>e$~2mO|(CmMzA^`+EW~5E9QkHH>3yM*gx`WT1M~$5(w^#;JDdR?2ASWSys!*w;+!hM zn5epwS48EeCpL0dxr5LW{6zc&sU+$io-D)=qJ|yyN1rbqjp(7y5R(+P$TrlJii>rK zQOaUZWu7jWh~$YkiW~G?M%)u^28WHc?kq@K8iiMnzE^Ab7to5tw5GP)iS5w>6dr6_ z=?UX?Wt; z82)73rj|SM39uB=uY4kjH1k#hCNm*S;UdNuS*2R?8GQwYRC)ruZwkR&_f;P#?r7h! zLN+%zjlSWSQSG#VEaWeoK5;}Smubb#- z_6{SqO@$TnDUdQM5o(s@YPh3Z+kHC|}A%Pl{ zdQI%Y4KSKpJ-EgUr4S()NE)JIXxLBZ3xQM>f}N(RiK^hHjA&*6xFe&gM{0d z_&6jySv&_K3bG~{LD(XNZguWG_Dtlfk^Gr<)NuT1P;07KpCyA~(?nSJWJRYy@ex$r zC1)l36GCuvqc`|bk@+(anP~)Vo&N5qCmaIYfASVDQ+kau!r03R*=LD~`hX7{w>^2o zmy0Jucq>@_>dX_1mz4hD*F&cwp0g0*!O0X3h(L}|=LnNA;uzC8apzav`a%fAm`dW8 z)+%9G9!gZ}a~dePyA(LORKYswf$>Fmk&WohZEp?_dS-JW&1ZOn=o2m`nko>5L9Rkx zEy1uZ!{hDtenSm`zk%HjMF23WH#MA@(lNtH1P2LOg^d02YS7{d1QH|m!26coviW2d zZXY>@WCtg#Or3R7^R7{CxFkW8OUj^GpHOcMnCFHXDRr^Y+2U;bXD_>KwX&rjUq6`p^K%(|(jLfKn#nvsy-0DJeAtvlZ zYOj|VkDA=9i%S`V`jAFqcM#PVFbEmurRp8UzHcal4ZVej6Rx1xm-XikH}aT z60jb^7l}v@e2jcC1%*M9jTZVxy{EX4ScICEK6VV`~Th@rp@oRo^A*<0N!3;k2x zQeG&~3?-k#BR~xB5Pv~rCj#0L$`iC{ecBK-@7#tA_hpC4pw{L77p^P5K6y-iLULlm zNCSrWEIKFJkXSTsXGlc?n(P{@qpxWdx$}jE-pd=Bf*=*^8uEs7aNogggawf8AD%mT)bNqj>z)68N$b+Va|eg?uj{|Ae{{ds z`$+HP-l3ywy4QEl>prU6pZIX+qZ0>@UOjtp=Xsrbw+HR7w@#_P(LTR*SSAX#kI6j2 z$!o_G1x*m_jHe1tJSTGne=#0l_Z!l?v3|@jSxm5u{*sK#z+PoEEC^0k(eoAmktLjo z+!lD~df97!_6|R4E`-t~llf`p!x%XwT(ugk1xUozCw)Wj7*S*DgmvIn1z>VVj_R74 z`gw67;)HMH=NL$opyGm#De0GpYN3Jc>YA|D{Kq-#%(qHl$RL50;o9F67XoYXQZx(P ztnUJ(0>ffB0my#y;jmT05vdM^2<6gtsSs{-eP{BAPi-y)AgI>VJ@sq>>^5>j)f`_c z`#N|Tu91q8&`s*0nyQyjbk^d|%=rzsAsVyRDjd}lJTaE3_RT%&Go~pa#^S}kSiPD} zateV;B5mj36?{KGanX^@9Z_yl^W#w5t#Hc65H5e+r&3;p-3PV_c3zboYI9}CdRnwB z(CJ5P6c_RcgkPp0(L)_UnLd)Er*?lO~O zV@a|`2ge=T+>s1K$5i5CfSe#f?ngXO?nM|l(54_Ok)e|$>n1;wR$07gsgPj%=mz1Y zh*1>_@XFcLxBSUWo9swzz)~LAgvWOkkln4Q8N31f8D9>E!R6!ri0`FgEQYzK3Wu)>?gQQK>?IRHzX3oZmi2K zc1q8bkdf2AWgyop|j88lf64q=CI(EjrVyyp}<-6PBbq*ow2*_ljfQE>KaTi^sV zXe41l*hszQmLg~(_JN!eiclMKPzoUUlL|`})Re5+i8okgvqPDw+=(K`SsyTl1*#d= z+s3MP&;S35M`KqCaECuEJ3iIyUWvrrAawjo@i1@|?zQz;IyDdEEV1|=x)1uV#f6sH z25A*yNX9OxfrG7V{tT=)U@2|{?W}AJMuBM4@omK6w9@YEY2U5kr1XR$dZ=84Z8;3| zNcBKN6cEruZim5?zY0U4G^VwrXP7b;`Fe5UyisvS@)+_jUI+A^pRv6K9`PhHf;EUo z2x3r@#^)ev6497E?2TM6*W}My9s2 zecKF(9sJRsl@~(Q<3a*VTM7$Jy8;QK((-ls7~|>MTKi6SEiNPj#fKr=#;lh) zbNC)^cW;_NLhAGSsEUxEwT+Ba2IXeSM|%bfjhZ9WiZ7-}?GA0q{Ot@^ zWr>fK<^bh4P+*sbtl+?({q@V6JL0a2d)5bwe@9HzF$K9>p%#tYni=UJEetNZ1|#TK zq5E4P+dHFYHY$SJ%%_#M&FnB3MvoCPLnR;Ij^u<{PtYbTVRC&Abt(6fLJEVmzA#$7 zskoz@zT|RZ29;4}<9|!!5apB@?yWva#o2dhT~;7P00$+cqs8q}?_cF^S~0eK3iVHE-u|Xu{vz_vvB9p9OQpV(2Ko$5!v+ao>d8A8pm56<1T^9aR)+H7xx^8$_f|_0$*>iDzaNXC6cO)KT z57PnbeZv5#Sx*?3FFgoDkq(|{9O?$#ropd59sG)~*lOKjrMM7!EIBN51u{iLv6AVH z5s$bT(GyHPw4mff?P)TaBtZ70ysa%we(8_O3n>KE*Vs5N5pNfi)u?JU8b;&aqJp45 zYdXhcq2*|cvP;ZSAOhlR>=NZTA7oRJD*p6AArAU%XMJ6V3r zq=?QPE-mf|rq-jVEXVyglqaKr(@<|Y8kvxDi$LVSYA6tu;`?WGFC_;ynEBNgG#65C z^HtHtAShtfEEouz_as`Di+dMpB6LaKRn6F-Aj;JXzg#dA6H2S%ipr zpcawJLZt(<%O(<}*qe%=HMpj{5H}`*RUX8l1&)dW`gquBq+V@pI8B;iIt|56p$$wi z`OJFUobSA(QOJD6jNAZvRb)a9BZ~S5U6N81Q>(r~EnuS<<5@A#ZsI8Q0vWr#JbT88 zcz_qh7B)HEc5dLCTGOxHH~WA8uNxk{|3ra9``5Q# zxc^LnOM9pE4)1=mdtoyhu=-9W0?gjC^{Mvp?U~(E2R}6P>>1Mse=!cA`Kjj3L5-d@ zZN1R09Vd`*IpWQLZeNGc=~1cqiVJHHF2}%;*QEdX`Key9x_H)1GF9s+khmxn@5Jv~ zD2(GXqyLqaIEkL{H7Sokydyq!$MJ<3(kleVxOY*3yrJ)13YBZ>lUpn-yMRYuC9Sygvzt59Km0=R zWSUgyb_$q!xO1Ani49=^$npHmns(AIW^YO;VxTIM4-3z>yfS%c&@@9k7x{w7DznXi~y#h&`Na&Fkh&}$OO_F{GR4#Jz-(F z5ehX`r?TX&-0pnqxZ;Lr$2g5N1*rnkZBI$azy*7c+lK^H&!bH1t8ACCjpiV*{;T%p zyXy^eo&qbgbQG2LRTWX6d9B;;c>AsFF&3z>n@%R5v$Djth|;)eBLtF!r`l=Ajd7 z)NL4zKvL@oSuNPdPpHqoK8YA*yFT&91*yOv>?5$VTZuS*z#Y(%`v4Xv!emmvm(SbSf|KDJ_ua&EA6d2vIUx~NEX zfPqgTfJ{CIE$HTc1B?)F00G1&)DREwP}Fkv^3Gc8#Xl}qkpzdE&!BWwBVZ5*nrg@F zNW5f7WE>9Q4(KRsgmYGD)rG+g^NZCh4=yj18EnKpYN^u8=L2;etIN*o{>kRnBLYlW zCzxf{CtFNBNSLXu?!zBeTqtN61(eAM_4MG>GU<{)MHtPcbYYdi&C714+Ce(DBKsX{ z`Oa4B?FBdC0Wj(?gq^G3BIlP9{VY$SKICQ9L7c`h@%1XBJUDVr6>dh-{9^Am-z?rW zOs24N8V?-|qOm@MG0eDxqO5tS)tCyuh>swK#0c{0W~I+o@2dM0Plj!?yE7kc=VBA=z`rWaq36*xg4_sxD5RKkhXIG?8fx4A!2wj&4=RLvGP>)03j= z5$PoJ95l>>TerLGMb;LQxewJh8X?Dp*fWG^*iG8D>3#a_F|7;AcNkufvlQhjvNaKh z;-A^k3a9z?&S!2eAB`CyL^gOvISZA;oeT*Oy7WRROx!OKG)=jbPx1iVBn3zaOM_zy zhLg1hSAcS1r8is79#EX-EgPhT-b`7k!xsJn$N_XD6(wHvC@{?pk3GG(BXonZ2H1RRQNwLrn@y}`3(8K(?;_GDGdYZrD#%BK#o%WTDlTLsVVcHrIAbl-K}6Oat}};8 z!;g9eNO}liO-(Eqh9`hw4iDqpoH)3klQCbuEy(Vxxd{{!1SX8yPZ{l;56^HUiP5A| z5d=BwXEg+5ak2NKs#uQ(o23yYv)TM1r(fL5pb64eIVv6EBV)i(Qh?$zw_Tih;tO-# zyEa;vY^lc8_9Aim8%S{O#0>X^=k0zQ1+SM1(YjZzrZ>vKiC8>{&z<`<^0dMHsg|JY zu>0^Z8;62FO?yxYUMdYA-VHj2IIqOP<0z}-1je_CzkEXRuG1t9@GxB<_t7Nmg@UB` zM6tDBJvF_-!(avQu?C0I3F}tj<@wH_c-LfJ5=ahcR9I5xndZs&d{-HSDI>`7b_q`! z0VQXO5MpFaUN?Vd@~*{JbD{cNBjFabQV?=h;4z$fIz1&Hrl z7=Eeo0yriN*Ps{!(;YGr9VukGfG;mwQ21N4ur3DqT-#(oL7*H_L;~wQyI9y-dg+De zYG_&&&vb023{g>oFq1yghIS28#c$``fIK8!8(C0VTP{R_k6R=*QLh8X^Dv zRR-pjU{54XYF}k?ymZW@!Ei>{iL>ffxh9s(t*Hn7m*UaX#!)bN2k@u}pBO!J3_;A6 zG@)7n7s}`P1gP8sdTJj)NkK66Ti-7)nqFkqk9G%yHGuaG0r%K|#%vz!EiaJzv9c;qynaq{fU zcW=4>tu6$tCM%;YY)yDk&v6YUBwQJmm`ky-MU+?mDVxyhcHi^MQ@=SVE(8pR=*4El zx}xhty?`P|4>3vDowSNXAfF_SAantr#EbwYr-ji!JfqAac9&X3&6A$LG^>beqI)vF z;s0Srlts9ikURc9)}!er553t<&rG0Y(4<21NI&XB$XgKrnnNwT8G&47S z?iqdJ;O076axgm9f#D)?6fcW+m5Xz9O|4I<)=&X#)M>C#4KVOSu5+8C_kXIn4i}yL zXRLz~J$_1mI|8rfKVuryT>vccS*7d;XpM2+MoGxb+RmSzRbIzL1%vBQ{eY*$jT!Nh zLC<<@mD>sdhp&NYJg~NA<}Bq29)8prSD!vj9HHVO64aSl_#7E8V2*W>Yu5R=BD@yq z@EA}R4K4QWoLj?-KJnd8H1}gVpBOA`r4>tOhw@TU4Lq=<&}}6F8Z_CEUA@Uo?@6b7s^OfbT!)`4^+N20W9k;rkgoAO|4!Nk$y5ahX( zulQ`N8PuDx0`7{aCel)+xb~cw#+q;aA$brT5?ju1&A^+5_4XZ~-rNtbibjFtElppi1UjKmJm2ot*3dQcFAVE{0Z81ny-sT%R)1 zf8ao@K!pQ1n5ITZGS9v-@!sJ>G-Y#0c`i-~tCvb+FQI(XR!{4pq$5!>l?8Al^H5bR zFOxHA4R|ZH8awwX|J>Y;J&3Wfoa0VFrm($bsJa!!bi~A4Pp`nSgXr=Eb%;SelLDmL z_JfP=qaM+r;^`^vr z<@kaez9VyGA{8#iUNSO`i7bacM}bv%hyp&EB5bYml53jlpkXq<$@>UbrgMZ(QtmXO zEt85RMoCTbj{le27hERVlW`@NrOCxV*u4&l4SA4*X|-kW#HmTs(Qg&yC>QYy*iOTQ z2$+_&%r_$g8(Hl6X1?;e;yU;ywNNI!`%^lF84cEvS`C1;L)h|GIZoBW{=Z@zQ=-Q_ zeFJl&)gL$40g_-EHIunc>R^Wcx|5#IM`$L<(;2x=m3acGLnUAjFJ19w9}Uj9XLB9J zJw-SDvKhP2BQ9M+ga-Vm3^)l%WRdtFQ=c{El6VIB!PHCBn@=pR!*7+-dWgNsu8>+e z!a~0z> zT2TZfDpwFXc3X~nnqM6L+f~i|&~y9@U#X|IhIN8aQ`J#=Yl3_;M1f?a*)&Q)D%8_bM^nm6% z3TGk+0yhOMu!<9g<5XyPS=2E4J|J2xtrTToLtI;-`g2W5Xg}?+<~r6U2*}0?nSp}I ziZGXqmvziqrOlNo$`*w$(sdtL ziLh#B9%W5}{1hlLQ+y?FLiu*@_Eu-qF0KP%b5Wv|(^1R1$3}@`!u?BMHb@L4fi*F| z1e!}upeqJ-es1y;Kim!TH1Rkh{9O(Qo02T+RZ8mMyY-l{EFmbQy-?7q0-`z~p^0E& z=YZd8ZYO=-IW$1s9AivI)iLFG!%{p^QTqw-Iqq9-RD!W9b>54xzij?f*x z#BcWQL~su-)KE^q8w*YcYfOVEdiMSZb6juHRy4-UwSPG70k_?iY$|Z8)&fH+Tzo-kX0_aUH3aUK%q1+D_0Xzw!X&bam(}IyjBZOIOAza|L>*RUk zVgxcW$A{a|FkYe=7TQ0ji_Spv`4vq?b<=@eQd4qA~EAw&bt zJD9_Q63-N9i<^^w|F-5jNXTqHFEDduVwLjVRbe0qm}moQqcV4Lm4QdtNFy+(8^CP^ zwSU&Y4ba$@Py_;&J{b^%?KKe0bb)+sJ2j(?d{6-&BnR+9U|5cBbU59li&%C8m4t3@ zTl~w+p%A@#G2&>?XiwAVq!d0H`4EuAEYg1fwASS(6wiguV5pJMamVUH&IaXA$OS12 z=vHol+{zS{D(s|j$yd;*!4^1r(D(5GcQYm9-IEiiREJb=?zK**``^?awcpg8?tF4| z&G6XKtK;vFyMK5=`*9P8cTQ_vuFL;BvlkDC-Qx!ztKOVb1845p|7QP!{&D@u-Y0r5 z=*2F7rUonX`zaI`vZvLw$>bCzpC2zzW}%MT6l^$yXyXw3#Vd6x5HDQWyTlRcpBkqg zU)<@P^uppoBCLSHYXy_TS#or3c+!!j*q0Yjk@65Gk#;Y{%NY@=ND56t%25XIZ z%gAHS2T&_wvu_~{v(n}eT{bcQ%6(@fQU8{MM*Ej(?g$#UcnKWb13A&e2| zBB4MC3jzl*8Z37XKiM6np(c04WannRXq%5Fpl0&jHHN5w(E=EJDS82{OP{2N3@9y8+zPKTY zJC-8F7(Ngg>{*mwI$bjsnSa1ir7yroJaO0)Q~*psuLDn7x4(OHNABD&&jT^h)%{j{ zo)(sHp3zomm{-nZ00tCEOa-<=aG;=9w|kv878k8}06`!yF*I(egkQ<^$CWH@_?B>eLk9E=##(}zznjYkz9DV6;Z z#Ss_b(pvA!cWEvp8k0J?X2DBa0V)P6&18Vm<<5H0JpM?7L8e$3VjdPOos!yL=X-xX z7S4Tr^n|6#hz+lj@T1Z?v;cz&X6KWGmKhw*H%ND939#PfGs+Aixp&6XiaWAKDQ~RL z3?UR^@77_H-bY-ID3X*7XrqvXU=}%#^*7^mQW~``-)TO-N;+-t{+fc7#E>G?mhhk; zE!zk3o61%!+FgODL=JiKu3IcKAoq6XNjy?=Fn$GPsbNR8KRjQN9aXs^V3PL zXnENGY~Bzk=6iVq!~-~40n8hyOv>ooG!5t9GlKZ+s&#%NF;q78yWMd6k#8<9#Egz^ zW0=AY<@B$NJ^^;LjQBU6$ubZKBFJYTOuEE`FAIKQt$T3yRu@tZx_x9Nj|2dNPBgXqIE6J1PX3! zO@g1L03(wuec+Xy)+IkIE~F~Qo?0%FP>zK0|GWX4*H>VUi2qg$;}nxWd~lx@SRkS8Npk|T z4)3LwC(2tUdbxm1O`()LC@h*eMbz*M(>g@HqWN1M1Q%PHXD)Po1JS0q0SD`1Zq;HqoZ=Ds8SGq z;^9yXpHxYc*U_q>jl*>NF^p!YWFl^E3k^@acxkr@Ug)uNl`$er@U7?T@WD zPo~)xek9$+5uPv^K1Nc)f-@wL+5KX3!O}kgZDy(k$|eViu-$f^wp?6D`J$o8mv>g^C1H= z;r~nv46m#B_xU_ox>tl0sobM|($!%D|fsdm5)Nwlg%#Ffaevk_W^x`}EI zih@~TOAoQ$|MA!cnmdvYh)8HAoDLw(h@f0icWZi!9}n{%5GkqqKly&(7`TOcU)!#B z=UurFeM2^I7_Q|f49X-Z64qibyAFmBGO|HCaQgY>JlG`Gc{IwxPWRZc_?`>F_X39B z@3*AZ;kAeCndKSnC?bB1U!0(jgoOif>Q{+?cPZbZZ2e|fO=8Nh+WjnV#-z>ctf~a%ABuF%caL4 zUBDfy!O!xW8zHec-~QQH#`kDursZrvWhUoO5-427_~p^Ey^Z;X2Guy|AT1R3VYr^!3x{O+RY7zi&QZ_0Gv}Oul~dxXFo$ zk58OBF*m%Sb^qbs;qk4Pv_3bS8GLGR`e3ntQ~%BFi~3LK-?n!}@67fcdn?`Vb>G(g zo$i61&vwr0+^_wE)&p9fYrVAf0Kf46@Bi%o9{Wzdin;-NqK_lMr?O$Ql4?`!W=w6) ze@E_W@5Qu8%A$SLxjn1xqyMsfLiJEZp$ici;TkKmKL=GlM(A zxmi|RjuF+&7Kl~Pe}hqJ(-xGgD>f|>2`rTb*FfeIkfRsd$B!|X>tuu2g@h3&*a<7@ zOhP@_Wq3BM6p0`wvV?%-luABjs>#`P>X`Nc@0h(ub);0~LXHcgG$`{#H{y(3i>(Q= z5#CHeG9{g;M;L?*wV>f6eLZxAhOn)z*0nEhUXiqu6E#rOKC50uHh93&-TOd#L~*GM z?6EIpo}rQ~6Us0H*yGi?_KU~IM7X0E4Rfk>rl#u1w#NkYGhsP3w!u zL-ti%)dE`UvT!g1-_UYx)8lbctBd^X-d ztA;sc*fWs;cf>ZTFwC4dj4IYEWjK7o*QQ@o(=Uw$Gql=T{y?*ekf*E)N*;oXUIQd$ zG@rVd7mhQH7^;eOi*ACyhVh}0WRT63>M!o!JeaZ~lQhgw5RC(Eldl0*q$nCFnZ!3W zw#9PizL49~V+Vi8GYfYa&(rXNL|ja?aw1mcOnMS+;T!cVtFVVeS%C!ZgTV`fjOH^u z!k_EkSZWW} z0TANgTd~ru8Sy{>@pE}({>AF05j=vxav>EL&n#*OXh=VACM$rLbS|2SJw+LCM_h{t zql87j#Cvy(YfGbdH`kG7t@MnC$n0Msf{!gx!qNhJeL5`+@HhoG3ab0@aBA0D{eS2^ znnjJTM7#L0FxvRl0lOudgKJ)TnqO91---6N|5f|9#2b|i7RLxZXo&|4*v56?4hRhP9x@*r zXtou@f@O$;5Z^E+3&Y~c!tPluz7jSFUe9ME4_UP;6OjXTno!OT!{^N$o+t$q((o2q zkNRkHLy?W}fbdX`+GhSw8)e`#_dSv!iwvw2$8B7?h^$0~tPbS-Bm@VelD~79-)ZlVG zO$F#rx=$-hct~`vS7k49#sOzquBv}4A_z-3+DPk8iU>#cv=ydq!Kx)IRW14w6}C#+RZo^s-^h@wG(7Z0tAX7X#&uOYjs z$WoSnsJM;H+SAhG)(GT!7BV@6wIF0xO(e;baWFySGz*nwRH?(RZr)JpNLkOM zB5?{hMPcIpO**D;qAUPr%D9q?m4&4?J;Pjkerr0DTF))^8TbyQ08EJ_7(Y@%90Y&| zW`Jf%Xpws3?+Po3vB;1=WIO_(G3(7-_^dz&oO~b+m=8h;3bnlqFLmgk=A^(w1@-1yd$=f8?%VXWC|YrRT?^sf5{m~ zIPm4Q))mieUNtigz8Q&i@ToyC&Bpvq~23s+T0N2 zK#~@q>fWN7WRK4(^q8C>z-J6T&YQR>j`*DQ*gjX2>#B=iUtCB_4819UgX>C4dHUQXiOgp6%1E@^G za7PNtnOZrf%&v#$cB)sFcNDKA!&!PK)i)V(7g`CFRPGv!Opui(kv1}(@9$Uz<58fo zh^W;|#!`ZhuS8Ri39bH~5MO(G{A#(4(a6N9OzI#caifqLa9{jTwE{!a*>1gMEN#^n zB9+sy5+8kD)>kDiwbwtbK-W?xK&FsGStIu|_g01?*kVw&s@FfQct>;ukCKrT0%+6# z4jO10p#iQL=nV+if(W};pg9B=57};sv;aSak%(^E1Dq9d4wk-&)EUhK6AA5aHoVY3){ z5Ea7tdjI164jGSv6%I*~sg?kc{ulJ2awi|mJ*icYX7Zp)oJejatu*Zox%|rVao=m6 zOQD!{AvHqai`hSEx=oz5j#M;!V-Z-PC6TtCennA-Nzrdhi`DyXEG~rbg#~an{1gsV zh#nCED(to^U|YSE^d(7F`=;L7-LRM)uw1=urg%XF1e-g}a=Hjb!dg5q6A>lB@xlWT zN)o1Kwp~q9gx4e50>`V*9gjZF3zAlIju1yK0*9KK#xffm16dbhOp)25%r^S#L3y49 zE+1u#8C%sgw^6VD-M*0K^?(6LRAqabbd^9Nyx+?om|;LXxS}2M-JI%rtP%1XHZV+W zZBOe?eY z))Ce0#jW3uia)xh{p2_S+6V6Q0?gcV`r7Gpryn`pow{V|&%TwC2u{;lXi^Zp^2O{1m)hwV*7|Ok>-wY5b5v5vHO|K=n@_DohiO!@)CCF zv!WXtjp8)IzUh5wk)Sosx7VJx`;Jrs0E{+3b&y#`Qd_Km_Kb<#nI)a+1273{jF;Wk zP=LkYA|e?q+dgC*g!8fmG%jQGpjg5(7i|C`OEeEDCT&XXOsgy(V27X+pMm)1SIwjsm3RA!zBbEaD;I zT>q@JGIby)HtlKMu(SKg#BS+b7j&lh$($ziGdZfCi0M&`xa-*9{ug`q9q-*$Rtfz4 zdby3}FqA=CUL)lHm2Zb)1-0Yj83Ct(<;xc)%H z+vLsCqFhogv;w7Rdj&|ame8cIPTtsFp>HW&rlQ&vNHX%3zlQ3rF8b}_%^Z>#>om)U zbp7IpQTZ&EzsFK55bZI3Ajpnj2Xyk9BdI)6>x$*#&G0;F29*z&?${bT0GJ*|`p)y9 zZvc~n@0WT2A|`gmaQtZqtgR~g8GnquxoX%P>Qb1RkJsqTr%#q@L0 z`F-F^vQo9NyRF~~t`jMY})hqSW9U(zKUG7?IqFKAOq9ubamgkIo%q4Frh z*;#JQ6mOP-7}SIBjCynyJI`4}B1KEB7%?$q{;9c-t%t}+e6;i(S!ng)V~PiY^f&`a zyeWf({(V#+6~U9v#ss_=DW&j|cmN?*cr2d%o4dEF+Z#w=io`D|3HCwTEolneVE>C1 za`1?XG?)Y*K}gwcxCkJgal`655=N$ zk2)1vecCnonqcT|_2FA4ZzewHf^pfl-447_1*KK#Dw#GOxrk8{tK5$zX;Z)>dB>JO z2LWi+%kEqZglVGuQH@eO5CF)<;Y1gjgebr?`&deWmCm6KYZ!zjA|>pt`~F!mki^=A zU@DOZvDdgNK)DaB8-@%W3bsgk=z}n()PRbY8iyoC8`Vdf)>GyhX<<#k#ke9gFfKGv z0>g@UNa-*bS^L~U@RT9YAV`_=FN=1w^|#+Bo`^bzUjaPnezvLlO~M7}Eq1AQr@f+< zt#HjP`ElT96d%HjptrtQU31=Kqmk%*``n_+JXsq9b@NCVbNJv*pnH^Q;533KdKJY8 zfR*k*izlA`9pivmX_w08XNQS`siscwOB+MSMb@{NreKcHrKnfqHU$+*~tU(;n~`>pSl&8 zlZ0Gt`20xvi(_U0~$yKoYO+y`n?*hI}hZLVq*$h#0Z${1ci0JQzrEA zRd{=wpVclYV2D;JUhFvz-NnV$Vq=-fK+IC9zR%U=G&XTxSi()llK{Jb9cdG6qJ&H1 z;HlE?N@x(~T1Wljcj7iUS(XP<#Q^ zVI`m}=PGk#_=LqQdy4C@l|BT|ynHid*9ghDLNhi=Eh$~l$VS&agx z1YDW;>T2r&A1DUOJuW7jXdtyD*x40;o!3y9Zvo4CQw#;7$9faK3RBMSl3U4I8x6hT z&EP@~D2%NqPH?5f=!7cddP=>aQTAzmV9JF(Z<{_|svO8AD2vw7cPpL9pOBdiIT8jv^`dCvx|oY^MG4A$ z>n)Q5P4W?$m+cs*LmA`)5Q>w4(OQu+h}hH=z*g*K>6?*Y&J#>jS)Fg)`LV?lrA$km zk@gT!tb>g12eO2`3h$iNoZe>sK69Us3t`|Ga-rqsdTXlKvh2BzJPa$LO`KpV^NwmY z3}Xo>{_!NR4It-{(NWk!Yu!eaYPGI@3?AURYVf-s4-atf;UN71PMmm0Op9e>_Y0Ybg6_LDSk+Z6wG640*%2nbW|kQSUKeFBre$r)*=cf?ri3Xjp4>P zx-bJx5o+-C zBB~03F!tn#eKG-5E=pX!EcQVM~QD zBxlIwtCHVXS^A$GlmjsW=*)y?k#Fk8A@y|W2|f&AWVTR&AvdIju_PfSx#e>4fc3F7 z_{05Nz#K7J5bM!>itB8v@LRqtwmIf03M%0fHEwb0l&-qojZ}JTFf_}YdZVg*B1IsK znet^kgaku#A6d4FOKYN)ixJ5*=epsx8* zDpA*lSf##%+{Fr@b}270of;?UN5|dAo7BD~JyPnlI|HTVNEmIlZpMh1IHcZ^QIrz< z2e-O3Gm=6GnF#{+VanCp4DLyqVJ9_uG^0ds3EWxg`vRJKym`DSt}b~y4-C$8C*=Go=EtAjr-0;B>>yte)@sf&%l!}3n& z_!Nidw_;paUwmzZ3`acX!Ojzx5RDt%jeUyT6GiM#2`5&=b`)35D8hpeR9_z3EM`)< zHcn88QH`ex5nV`2+S(XB;f2Ll3zM2o#aJKadW*%RS_^T`$6gs#AGMqtKlmG&fpc*Y z){MBd(7pcnVju+<>`Q4&=B>pT8Mf~dnH52oX3RoMy2D!|DX2{Q^jPsDCib6yTrp5u zzp%?Q>&6_da6~gO%Ao~iSR#`B$rwxu!%0vPd`12TUr98adf|P)V;~l)4tF*m_U#uR@x*smtxwhW1}?Rp%MTDYz;L)DL-AAX-Kdq%T7vnnOnDB!hN^KZXfai`I62Gr-%fFcV>Xy{( zL%c5$7uFVL|72JWqz;R*h-H)hqLLfMCF1iut}utGf8ytL_G9RrohhOx4PjQJ;V<_8 ztPz6`JW;NDQ;0*RSIp_GXS?IZ5&zP2Rv5($=7uG%My6@y>qtpN8;?Wh$Ck<`(vl+a zBL`6w2D>A5Tuw!&5vCt2tUxFjk&#cOpy;0VX`= zlxsN0V^-Jgm{es3fDQ&4=Zfvh-nKdQ`G)tb2hwlHZqO{o2^|tI7X}F4>hIH^6Dg;S zaXL_wD@hN8Ox%As=(VNZpPYLTGS>ruf29Km%0#w6rAdxI%hZ^@czy- z0<43BB)l|!adT;JJ&w~o{d;pNA%jCH!?mPtUny;1;X$2gmBB^hx1qhKXidaeS{%Ok z&6Bwna&@EPw$gKrttf5mU0q>F5dco+>C=FUUSAi`vyAc1V`!mJP00G!-J=+YmWja> zOkg7gZy0;xFHn~okyYM-U64d7JUO7#+<4jg})W zEe7b`^^t(^^@B#-Uh7@@nu7qvTsvN!UJO=A~WbCE;PB0{FlZEl7Vu+1P5vEQE=KK#+f55J*iq<5zRiYpjPddFDX!X zuDpR*DPYW=S$;L(2V!PBVdajrZc)V)MP#O#b5Jk{Y9IhFP*g;zv=SyV(ZzN9ebP@*!2XM7p1=3;6R47>&110V<1$#1}rC?_*b)vaBi7v1bhje#StmH_Wvh;25H z`cx56-YHFG%eGeCqLJGVVhW))`U5H_JGN-MxH9vKrd!E@IT9CAej~-AM#Y&1FUh;D zLQOq#2>`c?=qWT<1PoVP4*Vz5z3JNzpS)T&QGDQlV?Z;nETO|6rlgLqFg{$(cSH^1 zoRccSMPU#@ie58)`TL8#FA~n@k}{x@JeNF93QE>aPbMZ=%0z@%jqzn4o{g~sVGOJ|-uM(v(uEeLzP4Nr6ibwu zvxMLvMlcUVY_sKa*2-*QcEVhekp)e9&9JW1#e|vOg%AwB?k3#m1mc zx4xP)xtGi`0-kLqR{15VMJC3sb+2z69QD^1Fo~s*triq|@ksgI`z>mzZYHSn5GhF_ zq|1LcVh13otJ22ItZ(-&xxRQJIwof|F`x0z1UvlsuUO7Jr}gd35cL@6bt{0}0e27N zB+wXgV{PhR8fiIC#Mz^`Jbe~v%j6_bRw)p~>XdixNcrPa43#3;u&VemP(+Flx92;b zXcbRnt=kd7+om9?ne0swz7&9KpX%knCNwl zXf?*D;4(JrK$gpk+d82k6!Og&-Q#K(+VuKhV}UhE|Bx|kEPa&k*~p-mOJc;3Y%~!! z(O_?{`^a;OR}<*GQGI1)>d4dISV^{#;_8QWl)BOOq3mqs6ararI&$R?Tle}>Igmro z191hX^uTFo`KPW@sh$EE%mA7+$bxZC?Ixw0^IW3{^@fYBXJ0xQC^TZ0tEAEoK()Dv z$pIMKixrf<8Qv=kl2KA)Vey1PglI3LY=8R=V8Z-b_(d=yVUv7%Zq^=EnI;7FJPmx0NDY5u9Me?@TR%j%}$a1iy#T2@v-|j zUUG4zbI}JUM@YgnA_Jf{)9TC8Y757JGi3~P3R;R%-MXEl;Z%v}poZ8@!-dfciX$ZT zb{NSt{LxH1-J8reG@476nHuC(>H?IM`jGmbq2qG-h;$hNyVyIm_-M{S#)vfK=47!+ zV`gA35xayQutogI#eQ{M_jZ9!i6K_?xLLAsIy z+yZVYP#l$88~q>uIzPZ0s`eEhAJ06XTC84MasR)v&i3Ckb;i^K$JdX~pL_TC#Bq1@ z-qD$j_CM?ot{j{*IQ(E|z$WXzxx6*7{kitV?VoHl@-3lz_q{$lE}q#~GfkWua@({Yr@1e8FBV&hm8Utn23$+jrjm^!)10uK!2 zpoqbRbxD&GE^`(c*~vZnV@zTq$ZVL1@pRf&-fZ?pzfR=?7XgcB88uh zX#hwWX)ZoaNhj_%8Kv_|`!!^?r{P;MFoXwIhE%m-4S zBz<_5v>Z4g`E>&q2w_%WAHf`h?n391=JK$-8f}R(kxPqh3`ZlLIiQz=T=Jimf4rBd z4JTO0Sp04(q1kp=DyQDm#JUUwbF%#fZCGxAJYSPSOsqVsY?5N`Tb&Gj3p#=O9`)L> z=+Xjecdz}a`xLJxw!3kNyp*h1_!PfN-gmLF|G6haWFAcBMa{`vN8 zjRcb?awC{8nns5yFiihHG-+@Q(N2Prt8;RTw|a0?5VvA{n{jH>HF__-y?7!i4M&u7 zE%r3G8l}f=yz}0PionZ+^I=*9e!OGUvj|5%oO7agLzCm?iKsyEG~be)%5Q5MctX(# zDJ2l@J$P3vbrl0% z08pmD2mtaN64BmDXMJZfkhEI3R!aegIQPLO26}@D2+<1RqfD(xj`7xoRG{!!xDo{+ ztDQ@4D+Y4pO8|t~pqv=x()d0XG@utmT5Ct{r5pqhN7~Rs07r9`#BTid-zx{Q9g!-r z5i%nKUBZN-NwS}%$LOgyH$xs0O}9>Un@rTXmBaPj>${_Som~usVB^u<7F%tOpNHJ*{9jT zRViHHvPT1Lb=R*g2Lejauuefc8g(JsIwKT62pK7HL5d_>0pA3Yh0H)b2ZBNi=zh>v=o@8ajqncn#Nwt0u5m9*X=%<$hnF(A5QZ!`) zA`q^JXB+36nm4j(ZlaS2_!fHVpl;;3&fe7RkM92bVxV*~Nw2WRC3#ZZH-1OawVZx%*CogtRM=MuZ_O> zzT(X!nRZ}W=dm0pj>@^_Z(CXtKSYn|*WSbjQB_N(C1>UW14uv{tfw@IV3uQ6YOW&J zvH^6*`-l=KS6>*tl>WC8t?U^JCz4TGDAUkyDBj$uH#PEWJrFB`y|2d6ueTYTh5)uO z1hH9!oaU;nsPS09kjr(uBPVfMoQ;3yUB#;*Y!MK=-1$%-jG`S}ftfL8v~pD)FgBhs zZwAZJ4Ydju#kUv7-)Q95`iZo3mFHU{%G@z7@(CteM1^!-Fpal5$jYY9o?ex+s;sd4 zfglyoM-7oPgri%vAK}e>_*wa1$_q1h0YEMLI1D^$){+($Fm{-4N8Fi>7OvQ^)*JF-M{Sm_etoF_kOT zk)F!z=&}7J0_IBQ7KG#z<^~_KATC}r$(`}Ni}O0=J_LIXi}WLpV zFY}Gm#Sz0_Ii`3unLZA-_Tuv+$hv%WAUGrz;?S0mG~rzW#YJ44tYbXaOPQwrEf1Lt zlwP#XOjr*u>m2cwQnBKoZhNb}q zEJH^#$mehkwvwc4rG!{VG?^)FD)n+Q)kq3zQ@TE;hxF99E-RkM;itAKRW(p+_;spG z@Fp0D69Gu$B*G2}bnv6_X_d#_Py25jp2qy~UgU|=od{FrX_GEnHUgWtoU_SS)N#zI zt!NG9$d{4!;fy^Xyy(1g<{OI#3a!Ow1#m_-Hk(RFWdZ6MlwfFQrhL&K&`uOyIY(?_ zJJYy;O7GaikDZJZ&(Q&vP)>>&aW#Se3*o~bV&P#EJP^Vi%P6r=`$&N^*k)mMczLl! zSY*UO(2Tm47G5@${bjYwu$=<}E8mP0TLus8OWWZ7^md7_Vtm%pWR565InDGE&m9*s z$n@GiS~mI{kOk7fe6$Ku^KevbzD&Q}C3|bH>BbRikH&j?hEk zHJzpQ-?v}ier$WL^+$f;_xLX_d*FZPY(c4Y;ES|DAhDO7A6QS484@;2H0B`fE#M&u zhC@MS&mh-sy6X){LW5T>0GL?4B= zglnH*X{Z1C`yKoU268|nSHyC*LOUJ&;02ScBTDtwLGAFH=;xNx0gVTOV5}e?M#0Vb z{?)%Mx}0|4)dF=eg1T-1NWvU19YB%3>}+(N&#p--0HD+*$GR(nAGl{mzLoY`V>ijG z(O1>rX$`IR$axFAxnT;aFDs*WDxzUB0VM^PlxjjyUKPvhDBNg&q)C|Tfpp16WTeG` zgv+vWoi4LbKzdf5sEIQ{Maqz+O;~48N|KoTs{ODpPv%G|KTbLoSm`sBPNtEOZDSOv z+L^RaQ#hKoAe=j;5JxCO4N#6~OG!A^Kdoj-CQ z4PM@~4fa5sr~WFFgyKs_V=xjF>78<2Y*Zl6Qr|OHtLw512$tn6yU`xQSaGFvtoFQ9-r`>-t5P=gI6(dQ)Azu** zl4_E6u3Kg7sQX~bJYaK)Otb~~16xgcS{Q6M+KE>qr%^&=fwFfk#~>zo1sAS|k@1B? zg}$L?v*lnUT0yHJsuaomCQj2s>saNs!x1k&mmS_mxY zzUYOHgczUm)#U!c4TKR}3|W+VVwl*+PnHEgSy6Zys2vt#;y_rb0tQvKyQen7Ks}D` zG-;vepiEn-R4(T}MvD<3V3r9q$fL=gV)m_@Ey)_(8NbxK+i&k-Wc&bgc4nO9ua|Mb+Ul2 zwILGr+g|IOc6B)rzKVlZViA%`(=hGVv_=9~Aw)Wy9-#;hgb<)CMHBrZ@@cKNzS4hE zLj+~A>zh%nV^9XLO!s1WH~LM(17-Z_MdjiKE8U?Sg$W;Q2a?aAkp7*ooIH`k8>LTu z)bm)3mN=$=0-UV8GfI!o&+Lvt%D+?Q?IA*qUt|aLF8y>dkPgQzASi%Po&4Qpu#l0&C*gUFIj>K{AvA~ z5>EdWX9ySAIrE+8ZI=V-2buavW|m+zUJEaTenb%3ae77jWP((hU(`BfG<@OF*em_J zHyuVyHiVB&lXL5x5lvfm>0)#vq^B&~j`$MKA#KO$#!d;^(O6OvyS3GQ(YeJF;SJ@t z@pa=B^jxzRAgA00F|u-~G>vH`CP{pJB>nG%{;9Rk||AB8ak&mX?D=Vj!jkU1ZeJ zYY|UHp|*welk=%Cbzbn~FcV0C(JCpmhUguqxf%kdIkr)%Oi|iig|ZZdbhjg!3I+1Z z`mhHp1S$n1TC6cbIF4QJkgKv-nOFl?dh1`9JP{EF3z=|@SC*?Fo@l5Kaum^Yd4&sC%je#dujo) zNW~cEx;qcS&)-fuVXyh-Tph@xG@DIdowWT)=NcXeL6XM4vD^CL8;U1_eA74@wQp&F zcp$6v+W8;p6C41t*u>%Gc}GaaF&klF(VSE`0CNO+~MhUV#zvX1S}UTZ>_cNU9M{h7MKvQ z&LbMdOo<7`ChdhJ0z6M~E^&TZgpxx_EJUIy7bw5lI^=be<+vv6w>Pi=tP^oIF~#{# zgqwWDz(t~b+*$Fbr~3|Vhr@l}!+ zSKAEF==+*7bkD+8>)u6lgw-f}5@dx2*v+&)6oHVoxdlPenr^dAo00ek z2V#F3u{%*sZWg2Y_c~hkK>)NH0i7Z#r585^IVpg1XT5*cTPDkqYT$EwR7V-g-_8x; zi^uTao%ZtU0*7{<)t>I2I`jMOM-TsQc){?IsV?YTJ?ssx7@ReDQ2(?2i~6VZhrO%1ugO1| zJuZC+XMgj1qyh3{2j5qdH^vr8jZ@R~YYgOVP(k=S{F|UzUqY>j&Q2%LJHXWufx7jT zSnhV=*ydzw0#wkutW0~0!$bb; zcPCGjMiWslIUYrM2M0plMg(Ufr8{pB%Q&m3OR74s6LI_npV?~D5C7+KAZeP6#b01# zhP9Bpiz1toUvIL=C5l%-PV@oSFM>C2{@gGOIre{ZvmD3{v07kr37M8F=`IEm!Qob7 zs_$3~%?Z6&lHm8G!7&X2)imFF;XcV^vf&1~Cdow4^SY9X(q^;M+#pQ!?WXoBI8aSa zFzGg_lNA9Gf_!=QLq|=X2)POeCMQwqf`BkpL43*=h09#v31H}lV?TfcA~Ah{5r%?o zR;NDOR0Y(Z-^oNV^;f8wPCdPg>iUPo+u$Z4f&heUh#g91AwY|>qW<>g)R{k8JP}5O zbxRXcST{!-jOBQh^F#GcNhg5BmO|y1h%=J7IAA@!#W(dc&+6V>9V?&oL^dSyL0Zng zCzT{JNFyNubq&cu+=wG*0W^V&5Q`XrobVhO+gt5Z=Zgml^CJ$WwA7gj!}G~Og+MOi z5yNkL)2sHN^56^-it`YQW3MmFp8YSyKq8N-C2VKzR1vYk?KBvNbodfP0})Huqd>vy zL?|LBsyb@;-p0%oO@^Df&i!k6X{q=D+rPH^;$gHBxXaawXaL$f8X679az*CD%TdMX zh%@heYVkyR$*2moI;3&&^UIu-xe|ydJ4$;|+|Uig8p<*yRcX2w6N1$`^K&nn3fS|_};Qd^sO;_B>i`yVZ+fr7xJDjyZR z8E$=b342_Nd}(Z@u8SxueQM^7Hes=}!vjiHNlP6jJTk`RmO11G}D zbEZn}oVQXc+u7@<_oWKGz<`&>#Y(H;hwGC}R}?EuDwx zhP2h$To~WwGn0W>rIfkCLSnzO4D6TuL+DZMan8UNy@B7=x6)CWBO@yuMo)*O(VsS4 zQocSHQR;00Q>uwn4UeYvSyKH7L80Wq2ojwqLSUmld3_YY1V*$YBf=y>b|9DvBQYw(z~HAFvugcfsfl3)mKxF2Q#+O0v}C!=%OosvuUyODib%sYK-N7_04tEGS4jIq=K+p_TBuYn3Wa6v*;Ynx zC;~qyAj3^-FBV6_SUtsT1$E~yRSQI2qLm?Xg`AKj|01S`E?Agvz4^C_Cqkde_|Ogj zyF`es2_pqrC7lU#Bhits`v1Z}U}o$ue9uzw^{EFncqwy)7#DVMb@T$EI5}FVj%4nZ z9rLrnK`;s|_=gNkCriXx*8b?JWxOW7N?-_y6kGY1C4{7i97Ar4gDY2f0dvijlmoP&Vi^N79{SF&Sgfwy7tIaicyXl| ziciiVn%VUdGe&jh1i@6bx~zh|g=I;|g)yKJ{}`y>Ssz^56!vDa#b>cznYh1Rr#K>* zubg6VIhd3*_Gxr1S|i=|IC10BV|`fN8hxxuCo_W2;h0f})76YZwL5MBcQ~G4=Hvr}fcVm6UCKTrn)ChlHff+aGCy(20Df#bNS0*7 zNvN$Ye?LW(3iV-lQBjlo=*^7mrXT6H*8be}lULITmq2gPCg~Ss{qo3}k`g!@dm6V| zXs=`%5?gPisl9B|Mqg;Zu|Oh(0xTbVLHTvXNHi&}2AwtdD}pjxfZYS<$(YrEIz$C4 zrHg>!#@guj?o~XIXiPb++vb5KZm_^OStJlEuW^cjDTOj8WJ_F*esmiLlLE};o%WYs zUk(I|cv#B_wzJ*IrdFXYgk&c-1B?tTXp%BG|^fGQx-apZjzHswv%3IT6Aqs zphF-^!={&>CZq(Km^4QH*p+f2rVlA+6(@z{(Zvrdo+yn^!9$U-E*MJPGc60oCY)I0 z&=drx#GCrT9;AS z!9?js@;>!z&vJl$2-8<<>Z&#E|qwg>+X&uXy*t zj52eCpG!YLGmF|W)roScnPh%aO(#lm{`h1L8z(JbpygjK98a&6=l$*Efdn2WMa%%X z570paK!rk#Vx2rj>=*8ZVf%zuVY*=w^-PHCTg^KbW5C>NS z&zOw#qe+6dH~Zn!4fNE55ZkY}`~^I_B>YM)u(c_D=R{w!nQa0h$7=$DhbmxkWnOfi z43-NZN>GEvQd-0%3G}LFRKvlmBt?)uq%(m=l^~(5VK4cabqp7)mKERs^~)!7q+9^D zr(y;l$Lrx-0!0aB&K7l>j7SoGSX2gxghNX>tS}bom)W_kJh2_Zh?$hHy6H3X$~8w# zON5iX_$$C*ZrGM!dPbrIT3IzG6uCI};{QE)q6lg97c3wd4h#>T6`{gv+g9;l!*9wC z;JhF)%$IaIG9c1u?yRfb8+h-k|Ebf`Cvc%XKG+{1S^Dg8`!@xAdiuQSl8mweAWz_E>rtCmAV5m>A!TNeux1<2MH&e8DnQfu9eh#ETSAiMN3g0Iu5 z7)P+ydEEyOPFy_@wj zrOJmVH$o$%fs5mf76^K#4rs0WE4|4;NLSe#2{*m+ty1C6EMu>F(U*~-xfR0Sc(YzI2G2X zE?FuDs&6NQfC!X;ZmOli#w8+2z`T_>tED?OSymCAkDlnoDF^H8)t7#)7%2BPq#i5= z2ACm6)f8y6zvns}A)Uj)&WndE+9XBHrCJeccUQ-)J5L7Us}_zzt3!qE2?b5->Ng7u zf6T~j5z;oW-#(QbUvQEf#t*WxHgj0x#j}b`4dm#QBpakDuWBPvowfx?+1utXr6wF< ze8qqeLJ!`-#e*tK-8^Q%zhbjS^mQV*vdFCG-vz478=pllx(qL77L3P$r2 zX%#+1AmY4|xPUt5I;MB@mgS^U6YcA$Ufk@R*L1zetC7f@fR0AJVTsa6X`qqdA*AP+ zW8+8>Ju*;lbub0jlrCWU7i}-k9o>ZS43t6`$u!c&?};o%^iBg}c!2ihkHdni0&%S! zIzLT~Q!*Nf~e7V9XJdJwvv0N|B=1Onu5x=#bKw7rS4OHxEu&IkUOu%EXfsY#RV&e zVCzTDTX_g2vL@If&SLWvc~N$;A^g6*{^{jFEC9jMDRr0hhu9OFF^@!VJT-SpCjle8)i83pmK4 z^C2J^nFIip-g@#Sh=tz>`Bh&!#lTPtz08E-%l6b0zgY|vPgeAP6QKH41$VkB1GtEm zBs9BEUv`As;JwWS7?_S^9oTjs!O3jw!RYsk zft*6}Np@K%Razpwux`%Zb4NwrThTh2k$1eis0KsVNQYZZ(RsfFIP4J&Dm_%v`0PM%n*5P(7$ zSCIFO+|5YiABl#%TL6>X%9{0hYN>)8H#^oYaI8{ z;xzWKVWWxKBjJY>H6c@aUn^n=RDhjL@h6?Y(c#>%hES^Fmnaw%=zCGINy*YM3agyc zr`IrkyZYo$PNoQ01%TX)p3Z`G>vdTbU}DpAyqV|lWquVQDZYFlQ?`UN4_<1$>8|BK zVd*$29rMoRTuQ=96pCI}9|;^+kAtzKEcHBF6oDv+EZ0+O4Kb0q_L1e1xMYkptqDIC zHJ*{dv@@rMNb%?1UZ*6KHIqtAig2m^m)BlhJdq6)#UKKVIY7QycmHH`G>&3!=;H%zR!B~$%hoLCQacym#N7S z;vB?e;E{+hb^ir|pbu_R2q>I2KC4sCQ-_&c?VR$-VjzZc=OFUZrIM1L^v!}>EgHpc z)JSm9M-zM%3kh^$F$y=v0O+Lk<|bLr9EmYlfZV9y(1P?up*W(Y*bHxox9HP$A89g3 zTxj7g^1F3iTpJznt>THugji#nl_?5(>^QF7^y&sxhhNUq%xxd@H`XPMpTMdB zPkJ)%N6dt19*-s;SBfE^Zj5hzdpQus&-16o2@Eykaap3VMS>h`zO$r~F5=X)2`nbZ zZFEYUcl*l?!IiHj(P5N8UV%|kOsX6EAzbT>MMRhuibA0=V)@SGT=I$~3Cv)$ZeZlPF%*`_wR&TBTWqN1& zTho_Ky?aD060ywSHuZy)WB{`2sUhtD4_3~m}+FgULN&HnH8xBLI8 z_YpS-9@)L2`^xUIoqz58ZfCP|xAq6y&#u1yJ+lDcrHu*}NUru8$M6v`19nVfb zh~0)mt-B{nu8XydlSM9M#`P2;$`O;(Y^d|npRL+|(+GS9Q+vuRoz4#SkfjZjqh;d5 z$fn@m!qhM|L6^8G|J~6SJ0M|mer@iU6RYm2%|YB%UmqS^F>I;Xz%Y1ji?LLpOH4zuRfUyAEU8~O zJ_rOPhVAihxpIwui}Bf>y6%Nl@2TVc!R$+`i(qMq+xHTCC{g|-YAe|ZIFmcWnz1;` z{!ojM70f7(Ew7D!>-MTYf9}Df6$QX|22Ukp08C{XGA1B4<#1_qn@!-p5+NW57`B}1 z3# z9#!>km`s^#rW~PKMI^nlD^pCG4!)pII^fv(Vuo#=3MN$rge|8E1U#R9KK)02wd&vZ zk&`F$TF@Fpqa!H=d@y?81fk9eMTnOFXU)QCI2GY84kzD+336p~_6dhn-LEv!&77&% zvVvH?-S*0`2a5WGy8Mp0gcF4UiYO)ACJ!UX5C-v#4icZYyZlpC_m%ISJefI$ThNv; zwieStLvCR+k1@69Y8Bd_V-E8XASt_*`CA$C(fO5`dmd7CZhq-xFl2^QKURHuGl)@$I~!+h_FnI- z+DAWk@?`o=pxs4BRu`K|Y8wJW3htfhJ9Y#=B=Z7HlIcwACa0<_K|krv(xFxV_ERQ< z!S6v)=97j7`r6aEJx*MrJqhLFhmH@XQmK|^2DQ#D<41EWt&QLC+g11WhL!W0Fc@fD(VrD zOpBa@<#~Q%eE(-w)l@@i8LSRBXabxuQpj)TM05~1LUub zANJO&f1kTdJ^B$lSkx|Gj2 z#`#*HjWj9^FhNO1?v!d^?1aS#Dsuf;%)*+|=b?tqn=hz(H{WUUWd7XCi#ixV?aQ!q zaygVV@FZAM-yC|LBq7& z0I3#UAA`cj?(tSOMpf@czp_951PWFM8M_C^ayql+a6Tz;5{ch$5=}sGi-rD;EK1uB zn~JS*d%ktZWmV?~{%kUsy~I-^Jn-~^+^qaaMYRjmQz0Dw@qNj@N$RL_j$K_cVIw5T z>iXb^&aMV8JYzCg9TS~iJa_&?n2GyCGptM)w~y8mSA zDp_X3Ogbuaza#wP0K)f$VqtJ1&;v0ky#Q6srG7dNEpSw-)qlx*s@~RQF#Q-L;MOX% zZA?&cxx#^~=_2r}YpNxfvn@^GxLWDoU zT7V)qJf*{uXq%R{bwx86m=dU6(5&_VrG~rv@)uUE&ottZDDI4du!SK>%zvz*8 zO;%Q#2CzVD!Vn^?&1Clflx4RE#Hkr1mn{#A$*qr7NXt8$L4)iafQG z%a%&~S6MARK*V(}ykFJ&hubHEv1_R$^$?B?(l!Hg?!B}dFzZfFMK0Jq{!5ZJF`4?2 zN_J#OOtCZ7lhp;hIdD6EfYs{NoqoS}<+#(ivUgbL?9O4`e*4DutGYJ~PaK}#KBYZu zUDbL<>+tHPxu=cZbHLl*J$dxNI0w2HP5r^l@6Vh*bI9~T_rS0__4Ml1bMLOZ4PMYc zY5d618N=%b@9mvEIJ2%5xbV9q_}}f1_TQDN5AryB7Im1U_R?EuI%zl}tFVk?)3hr@ zei6=p(N#wF=wJm-7Uq7TaZo{L*vNEbv3T%<3P56`A^0j>Py20Yilg3YwX7XH{2qb! z7$E<*yf_$4RxIUMTT#4^LLSyF)vakc<5#CZfcf9aC~-;Ms*-7Gq+^r2hwq7{d3SXA zb^EVoAcSActwI(4Jq<9@gxu$3HB%fVpkW_ly>Yl;apMHAei6S*Tm6f+%7L`w=Tl^~ zg0z$P`r7JlVva^uIv|-s!y@3Q!4qdEqY(q8-L^V-L_<_&j;vvo^;8YgOd7$Yk5)aN z>y?n?xl10%%!BPKH*B(cxKNNS|Y$aA`^CbOyOL4xyrv8TdPj`G~~ zt|P|gX7{h=_D?fDZ@VU4Vxd4ReH!4P9k`kW-@J^xDRmgOv6??#oSdKF7p$|pF+0iT zjRTT9cTm4VFh-DAqoN;YD$De!fmo|ojj$sebj(Z!1wL^{c$>J`SX_5k#^3+AVu}R5+}_T}h%F%-`D%5`IY`*T z&K*l6bsk>1cT`UggtB0&v`&Y|ex?|Rc?$z9Pj`&@y$WIw_YNxLIDa9^15}BDE5kS^ zg{NEvkl(mF^B12#wiwCEkYQNSQE$W{c_u|M@^Fdt6`j&b+ted>h}%eaVK;^U}+*+2;dtKXT@V4-er=4U3UfzQS#gd(&_ zk%GK!L|4_e8mQX%Kz91-Cq>5~Sv>WTpEQO~c718)2VY%05u-khRO<}N3Ivow1PjWn z0ui~TNz#q|BQiUVYF8f2kmze;&MmC$59Hj({0bYK;G(~aeYorqH~2DuJ4oJsh?~gv z!PLib9*=2^5%Y_)|Lb%619@V<+O|cEB0};OR--PFPE|@AzeMa81c5ZCA!evIQid3u zE*I?XUmuP=7GF0#s4AB~}Le#5FT&@*%(9YifZN)(T8GarN#TLo-0Xi;6 zghX6FOuzzMB$_$_)2SkNX86vQg!!Jn`o?k~x`DW5pIf(nkw#9=5a=vbd4h@-DyTp$ zD{vz;4rUshQTl+b?6y~$rbGBQ?7Lm)L4yXZAXVwMUfp9t-h(#d1Q+uu3$hWboyk0{ z$s7!8Tb;itABd_#mdPC{q+ppEA|+aO#uIhZCz@RWqQHY#VJTUZKa=qmRt8IJ#XwrL z64T{(%4TyvN>n#;uUKLov2+Nj=t&qKsT2W+FChtD+AnvX_Ne`VLXX8Rp>ABFZ7drS zphXXc(Sk%{N66QPbj+Y43ZlH+1e{;on*N{PE(XGWn^tic^8#Etiz(HSveydG5v(bKARmP z=-^$Xhia;r$>Dq)puLb5YVfXjfP{8BdBJQq05<%e`r3{8>G=tU@I>zalbExnaD1tn zNVy6+fq)bWGoEAkLfJ#swEP|>=}z@WpC~394oa0(8ja?1l9*j2S&UA(1%aK+ zmqIF#-NMe|`c&6`~yHjryviFDba#=7chth6BEOTN2&d7V`JjWd3Xpzc^L`pxNv{DW%kE>8^ z_tfitVLvw(M?gIBk*3V|jT22j+_Vt!nCN6tD7U_+pHJ@B@sP35N;2((&YO=b9w?Wu zBMnU=N-I^9CfRR~u+O@eL{z;~Fr=1i)}hRky`2k2$m`zc)B7O81Nos;mH8fNY@AMG zk^du_lE>|1n-QFmiE3WO?m?L0!CcJDQLrDY_&TYFjTKknGgzaBd-C!intx#6nP|G&-Gg)3Odz zn^qbuHJekv(U>K(vh^JSt>fp<_Vt6fyA-B@$pM47D$q>}3OqU00c)E}AhVwrmit#s z_F4vV%x|iZRJx9Suu$|FvQrF3{y@did?YwxopVWg$*P`G6oF>7^@uO;&yj&t1oDJn zM8r~Tm=Pk8l1~=KxHpzMK6^KRrF2N;xxn1x!DaW33rd_zH?h9FSv?TvCLJ#PPU$+ryVm6;Fh-^D_Wn z`htR7HhhXpC>T58;lem8E040yfKSl^OmYViD8ADD@IQXXK)Hvc)>ZJPIM#TXfl0)V zfT6iCdObEbTf_MR91_st=;bpQZyiz$Bq{*&8d75JFlg!-(gOhav|W(OqC5%Rgn8VQ zmPmclYblBFPW!H3EeGNlq+~hRg)b2od5b1?Ovu>mztHOv=M2+U}Lj$ zbf+9BCnpxk9#88PctwcLm9Z*25kja@#h`gn(-dD?WEjo(Gtb2y< zl@pNjNjoR+2_S=am_;L)`goU9c5H^QH$Kkl@TK?Of1(@;ZoFVDfStqGdYfepvQq0% zGf{H5uzWHLRs-NcJ^;3>dvz|^X*$y^QV&k zyx9ZY0MD3tVEdBk>+61iy{Rk8y8|%;ZVwzCR{echDbTvMsTF9uF)$qhs@ET=7-%hZ zRg!$K|B_Zr-Z;!J=!#pG$HuvZ>rneFN7J(fttpV!?sbWqzyPW7Q7StTzIN7TKQ+m8 zO$Z5rVHX07`e5eZR2TV`?dcc61 z8}pO|bbV=drRiS;Hc1B{?fSkGiCSW204Qe!>|5_nEQs?^`VrWiVr1e<5;2|5XJ(T%a%h||5BV!j3cpGr4X;>q`<5O_9aA!^^W{cVB7Z>Bu4fUQE*EC=a zND-dETsRaTmvRtHYJ?TYD~38jD}9ovf_qD|)kF|R&~X!o3}T&5-bXZ~Y^UQcsztgJ z1vjKXu3CVj^Z;kxLc$~?>fHC^lLvAeq65iOOTUEZ^kFuqlq0>F$bL?Fr+BIpkOm4f z>7Wip(TmE~Kj)t&%i59)*`0DSGr$87PlKmL60D#$@AHU{{#X!;@rq9@V(NM}!>DRT8WGSUq zNx7**7*ETlR4dF?5l@{gUR+zRw{|ziL~N8Pf*wSg4dBH z8m@A~l6c4Ayx9HHwsyow|#t2#k3RM@L>slOLPUUW1gJ;eMaJ1qmJltb91kU5?C!&iOx74CJKq%rQI0%Pp{Pwd6;$3HsOgmCHy7kA5G>hd2nNf=3Ai{o z=9+RKVp9Z5O1T9Jd zJAD+L8MPHpbB{DO6ftFraoS3P2KSoi4A626HoES4R7i_GOwFaTYTpLyflCAkG?KGb zENDgAFk)JUq?6!EfBNR))smzko5e>V&tLKe7L-UN`K1QR#*<|w=~aN^ii+Bo?VpJ4 z?Z-Dp?7SL8?bAbqv43E%U^vGE=?Z9z1|yz${d7G^n-w76uBGaf}*0GtiQ6fvCNEuRQ#N?)oNZLxHea%rbN%RFoTu5W;?G=gF! zGHKvvqB_~1pfdg3rb;wVlpCIf1+@ebXR}9qVeyoyUbwV~(&8B&aR{*p?OAH7F;jrW zRCHlsb+Yb!P9R^pNUMdyozpe*L>`bPrGH`Y-#Dav-5ha~|~{(ljDW&ar?fI8hu$wVNLvTA(#wRm~xQ?cC5&Gex{MZLZc6s~HfTw^$FL zAZ9i>hZMo%NUFe|)}NP1|GpT=A+R zSJ)xBjh#c54JR~E#Qfkm;!N^1k_z*%yfAgfOgT^_P3cJ5&8G54aMYhfl@a?gI##Sj zrHV$%h}o{FV0b}sz~5S!e*eD~1L3t(PU|VikoK$vEe*ki+GC`CM^bE_zBqXd(;JEb zT@`I&t^clHECxzHK2AN+F(E5ut&D{Zd9w=s5|F~*InB{lfwr6kbTAMFXHfml(;fW> zoCto*$z!)OHHciawN&KTu;i6cYe*eMQU^#o~Li3JM2L`y3#z(MHxp==0tR3apj zt1(j;2%{j;Y`mx=IVNcR5LVdH8%@RwN+nPab5oIzFj)piyank52(3CLi9pd-$7PAVC95rPVyE?cSW7a8^P zfJcbI478kR(P^+FA}wMEv4 zbItr=zM*yp6PPTGTArUirZ{FbRuQFG(YR>x^BgiTvdnSlr2F@5>J5|R52Ou23!D04N`%WkaVRoN$Yh~?_Z#>Du8c8wJbF-d zWcBK9dpJJ7byeqmopU-5Zr{{?Rqx8-NyGl=y>1FTdvF+|^oiXYyRVviTKkmlDdX$A zgZKmbgW-h-Ita|RhM(=9%olLT)E`tg^)DKCXHK6wqjy;K>fYH?51hOI^rzdy&igXb z>~HpO_#Rn+$)vds6Z{0&?X5s+t%ZpmA{>(vvM{|B)6h3Oa$2TsgdEnoUY-8MlZz*U6D&gD94uL9jvHLA_l-qiQM@z}|slJ1Kf4x+nLkqomdi>F%emEGdx53+7Qlm<}(B0@E}iPz*Ptx2l<3 zTpr(Tu9zeHf_w#Wvs|RjozNqM_*01< zU9?ckgxZuFvOoF3^i?EEAx&~!ukVq*no<&hU41T!lw{C-#N#n{b%%cuiWLIa1KPyF zX)S{9@@oi^L~5n7)L^Q>)Buu1V~Hd}m>7b?s=mVl`?$wVOb zog`;=Z+aF0KZFa=)^vzS5>2U)6NZE?obGM+&ON>SYN~0x0-GEP$Jyz##fh660v$>s zr1M)!rlLB)UKSRNlRI0ej^pEhWAaFGjFU&y?ZYyZ82gT1kz>m4&CLb&B1;FvMBYme z3UriliTvw3v&R&`D?x#OBz8^S78+9~#tOtjXmUcXz)CSDFa`;XKA|i#YHoTGF3zqV zGkGG1V|qn#J_5!HI5~l7r?v7Oxs#qGzoe^2zvsMCtq9!R9)LNMRS-xBg1;L;$Fj#*#w2#aKh9Hj02Pt4v*bN|zB5`st*F zt_c)Tp=M9HvE6-pL6um>qPm|Tn6N=&wFz8=U6>J@tFID^u=gHaJcCJ!cI%?zg#E(3!P%VH5WW_#wMw@fyz^_&JA zP zH$WQV80OU^(T3+MTt&~Mi7Ls5b7HXl#pzF1ujs@i9hZ)DRIi(~=QSKPu z52fH}#o;RY!c^)V5kr|+i6UAZ9QJ_892rQF4l)A*peUit(g-6wADC%{#{uO?P-TE| z;I7MkWU;5n#}~REnT&%{!8#yFJ+ldpG#M+s++10@48SH=bRzz9ED-NBFe1~Dw6Iv4 za}WFAWFUSIDHq8|H1X>J?R3x~?m3#ok=PqSXVRNCdO5H`0}Ioe%6eySEnp2;!PNjH z6Q zjI`PdN#h*PNq<$;Cy9OY{J#2yFNH6aQ9940aoo$XLe~^EA(Z(PEF|k~%%A>S#RK`2 zse2J-9FC9nf_BeQSKWSJP6YOt3Tk1SD$(7&rM#9 zTPmGi93BK$+Au&O-}AdEzVsTIr*hAjK@iRQ16k@}3ox;C-QiE&RSLcTYEpWD+_5jb zT4v%l*PGllEq4Rf{eevsEWjn11Ooo1eF&Pvlkb5Ccv;o{>c!*Hq3#Q~xOJf4f6?jx z!v0CqC-zkf^v>=brq2IW-BYTIyTi^^oo93oKhXKFJ#Jk+zP|OW){)icI0#OkJ7nt6 z*-uZM$wzSfY-fDFdj&ZO_z2FQ?tYKCfAM4HteG}1kj8znNhZwF5_A8atS4pdDg!}t9O@M}z5GFRZ#xE(JC>+14M~Ar7 zlz#1}gVjZu;5aT541auocCWrsVqB6%)Pj9K`si27fgBVftk;9@_;DO22+-u)T1{$5 zOCQ6->!T6cDIWGfR;&~%ptW{XIgp|*@5Qbmp4Cw{jh@BZxC+urO-3E@-ZoFiQ=&Uh zDgY@0wSID+%r!^OHqk&Ixp1V263uvFV#&VfAD?INff-C8O^O*}956{FriGp1Z(rl= z&CNlcMa;yT=PGUi1?GTK(}D>)2s(x7O^HOB;omxd8_YdRF2-+rar&~`iZ=@cLgx{} za>EZ^0BErP+yugLh>egwpmEHTY)7Vu-nCX!{=L53dh%0>fn>AsdgzS?aAEJ@HTYec z1&x>?U{o&Y6C|ZzU{WI+i4DQEvFy&yavx#inrFaqopl} zLjb81)mhL@D{9|J@OKiEeq`8OW8TP*)J;RM%n;=EUhlm99LL93?n9RrOtK?WGo}6z zK%sgDgphcroC?!VqGdvDeP&;K&p;gBbxA#0BH6TwiRTVwlPnxpS0miq zZGa2Fn8AqDJjCMi!r&#pTuf2gWRgf_R(=(4k+jfgxo05nsm$H7N@q5f0X#e?h%6(ccjy`m=S7VxAXXY+-;7yk4+&sF)}PM@mdZ)dFOHaLT1f@N!f=QL`K?S zG_$?wZ@;b>$X}qlv9Jg^kVFdbgh*B%h+P_Kq9b#$G-=RE-qZn=sAZYs>02l66BFi0 zClT2~?uU(;1({R#0diL7sSt+_e-b~MNFpJ|q55dCX<@s$+yCIcrzqKiJ?ne3Z)9mm z%0oMbhR%(V0I~^Amm5hgzDtis_7L2lA6na)zF*VkKlly8!h6Ty6i)(3sR@ZvJy9xB8&4_o9Y?pnpBF;-@dD!3q+jW|>`X!rq@9_#3C3+K zcaGYx!tg}6RdTVTI1H=00t`Uf=o&_A7-uuv2iz+Ni*>S9-W;cdUr(56J@}qe@2$I7 zXO5DVs@~*G=Vs1ErRm}El+2+k8P^GAP$EGL(_|4kC@c#WKW%_UciS&iH;{iyxyZed z@?Xpqj>5QjMEFxiz`-voAPV4M)AX3sWU)JM%~ct8@^S>ff$w{L87VYuuYXy`D*-YVwlNT z9K8MT$v`%|kjCMmS_5o|5rb9SBG>SY0|;pmJ3(50A#o(O!in#P4>$bWIs5)ud(FE$ z^r4{yL$%gq8a@;S;Bq=2(C<$pV@t#oCZ9lCh=1O1ZFlZr58r1>k<^YWM@7oB(se|c zqm?Ue@Ml^~bv=zxU6cD7E%<)fz%dIcKAb!B*5ciy9|@+aN^^}N%G`EE8HHwwX`Ky` z)Joi;A_@}wk1&Bh$gYwif+YxT=dE~|5aN3w^TK>?Zx3F6 z>0}@YP%5w$L1VHl8AV(;9v4%YBfOx9%|J%+hIH&R?P7>C5%(l7d$SXhqsg{j84yu6 zBq_&dwD+2D!%NuVX`iF?N}mIEP|-N`VZwxSfm$~H<|`&ogai*g7$<-+Nu;JEZd)7- z$UqmcdWfsiFI=@A_0n5u83h9U*t+z&8B&0&Et$^|cQ>X6q3TC@ot0?&gc?^qYHy!p_3XQNLOaWG6ZE!}U0q6uhUXS>sArP5vngL$Z#y004(KPC;e?6=G=? zs|$Xh7|5nYhs2$%c1BvN!*3)7N2aRV)Y{^Y#76r#-CtESkYOTC`mWQ@J8lBB>__n~ zunb#Oy*6B~1J`nV&D2g=QW!XDWtC4FqJqPtWm zsX|JMa!gaD6IZYp{AE@b&N7!i&Cfiih>+YQrUc-{@2QRzPMl~gTy(Q2N&Xh`#~-21 z&=w4D>?*7U3E$i8ho4hCk?cel2jMTNiv{S(^=0HTiK=FmV$z@$kkEA@pkht5m4Uc24mpnc2X0ae>_kpp5q~h~y*WR8%RZryankol@+;y= zicBa_MjzvfBr&9I15--M4+v2Vy_6Fi1(`rC)bjYcKgR=ns2a?_KXn238JzRo?h80@ zci@SGbEf~VT7c1&gZGWj9u7u_9jFB;lJ`6Q;~g__#|+#t19!~89W!vp4E$R&a1fs$ zeQA$sZ#QuCP#da9t_yD=py-@?iq16r&t^!8@L z1Q_|(RGjEdSF_aXtKGXb{I)qt3Mo&BI)YeaFiFV+0@81n{-gz}q*Yp=#|rudK&PA0 zO(M|k_0IUU;)xXZArFH?S;pKHl#YJDHSCP0PelRxPUZyrCkexIsf`215dGV||MGXm zK(fiy9!LTx&zLY8Y>e9y&`qBTE6&K7vRbqr0}@zDlvUM(TUhSir6CmaYMhSg!AdX9 zRR!^(N{FCR^d$J4niY~LqEl~fUxT?07}we*O*Q(*A3u2_)&bNMD=sO})1w0@VEi7G zfBcK(LKomhqh$JnAn{xr$1cQ0vOV~|%Zq_z!#JHdB$<~`YnpZt-ouE?zf?eK!$2FL zKFd|qva<8{c&4y`7SKyqp09sNGVSN;R5lgE>9^FO5^Cf-?gN(q5C zHkCXUofAJxE z3eq^%qtrZ;dQ!>HI!xM@8n6n4!Y3GG!R!^>K|dXJgMZArP-)t ze|6+3o!p+Uu4)Y3`D*DOi83(ff{>?{ulq4JMod2sdwOYd;370r<|XyQUZjON9lHC$ z6AosS83)0|kY$ze@ye)ZxLPWs@o~ZIT}Z1`<)t=^Y^JLM1G(&tNVd7yIq!zz#RMp! zK|<;$sJKzv(h$Myk~=j}khG@GfcaHbv;;X`7dA#|*;4iXhTzNt*)*w~$md~_k__Up zEECIUMc)MZTc}P}3 zC|hkZG-tu5bUyw+ih;ZsDTzX7nj2b;cAoKLy8!}4#~+v z#Fi%etD=#Wo#m8TI@^?#Z)v2XQBrwo9=4NZg^glsyL0$f@kAtF)=1_)1Sd<75aB@b zd09|6P86vUX>$trv^pn+T*!4a>0`RyzuRSN|t(L8(~ij$c@VuuOI=Tnnw<2%Vo zW=~^?ytgf>A~aY0bk2QVF_51Q`>1PRezjNPbxmo2dZP%EOifGz%0yA*Q9NQ6m4By% zZmWG}V+XMwQN0BI?0AQ)M^1ZKg|>)1be5N4=CFJ$Zaq9T+Aw;gZe$q&t+my7!7`9; z2l`WZ73d(hZs@+6vjh!Cr}3F=E{h*mK;KSZF^huP3q!rR(cbyrFFxXl*Ho>!Dm=ha z>qU5g!NT0>{m;)mU^qSdnc4GOe=>XGY;Wd@nX_gNo4#Ri&GbdnCr=Ni-Zyp5)Pu)2 zj$b`~)Oa*{|KQo9XO4~-er|a2@X`I(^&iup?fp^j`Ms6yt=%_tpU}Na=fkZRb522I)9iO1erj5}38Qd`!;WN>BPW&8Eto?vv#z6( zTLI2RN90ob7tWsyq%h5{A;u)$#XEA?_Dr{5=W+Hqd0C7|*^WP?XM2f&)G_3G=rgW=PwrBf9H zf}qK^X}!h@o~sbppH&iy#Z0dvtX;z?PJa^LQ)x*L-CTNVbK+$j-Z+SsBmq8(WvRj7 z6jlf#-XX=w&Q34fYC78nbBZyJ{#3;7RquLi@jxb|?iXhFrE){`^>^(P2a~NBCk@Ai zLCjbBO*kQt&SI_-&L7zC(&K^H4$|h;bSiUqi7{KLpNfP;-@~(Y+>yJ!6nn#BS<4eH=M=vJ}u|T0!Ic9jT2yf;} z@d}MVXlKp$yR;Ys?>7&*xOgDd4S*ibHey3uoUB}V4Vi`}7_J&baKD;k`nj+d-x@54sa}fYDYNy?m>s(XknvPm*hR%wp(DYG-^b{xHz}MTHZ+(2K zcrz^}skm_hAe>=C#z}%A^kS#l=H5ysynIAtEQlljP* z9l;veycoc`?yE)NPz)23J^h=Eq88D_gF9PG?VZ77AfS-Vw#B@07|FC!G zQNGpHmB8=4zp3VDG?B)rG0NZs)bOh6m5HK}C<3A&;)KJiS5;}Ff+C6}D9+K?4iS)9 zQGx@SKt#hNf{I2(J1UWMTAY{^B~ESH!~y%W?|ZlIWi7K-(&_%ESEt*F_v+RizTb29 z*?XV!b*Wg*J*d1z(%_R}?y2@UwzC{LylOmcg=qocXg8_dI-xaY^fG`%G*g&dSG2<1jAN}8t;nRharn$N3j$WR$7j;{D5b3G_2^Lc>i>HZnw{MZYUEI%{C>u z+SQ~nA)7NHR78eBa3=F(WJa4n%M#5{rqNJU7_qYa>&`|?@JWYwoJ{rX8V&4WGU~H= zc@scisY$ml2@AWEDG}ZT)00qB?YY^AAyVduU~(2MOOfJDqFU`7hgo+;G6elB1aO=bXW_?woC3>Z=flcoF~#WBE+?*q))iMy&-;C7Mu7`#86aC zh$jRb_K4J;NnNrtlSj^>v%mCnDb0~P9#KNOe$&O5LoXcf4GqYikPZ!xN-042ZyEgv zS3xh_1eqO_y^({eyk_lFbldV#n_ldUelmg0fFvOS2LSu<^yuGVw5R-9(AWdDt!oRK zJ`0041)GhM&0?`UV^hg@p`Gpf+T4XKF;$8cnXLjH4o*qZXT+?8E8$RJAkO)8-l)O7 zSg7sgbGNkb$UAl;dV=`TEm^(FK05z^uO@+M=95%#UUnJOr2|Vp1cRtWk25MRyL;zC zVSL~n!Pq+y&Fx+t9ht`GqP)yfQ&0}>grd%b&W7N&^C1_@Z*&&6KesfTQmG*&voF+; zig+DTY(!d*EOyV8K}9SsJY~$OqKjSvUvRA~AJ@4f$QsXPn0+d3pPc7G_0EqYstV5T z*Ka_(Vwj*yFw&u?36$(P<>8wh9d-9D(oox5W>kr>?vABAt0X_eNvSPJ6qgsJ$#hr5 zH)}Qsfp*){X7`Ni08cz#`Vw=hq5LD~8>Hj|L)9Ra+714UH`DI6>ySjCXuJw@E9F1` zPWxnlvThFV1JRX}=T-j-Qrs;VV!`u9{XRgIME)V_jBSm3a-=W7wyb za&{?~w*UfsGkE&_0?u7N(7qvU$&uJq)4-_SIj*RnL?wwB8~Dk%YBz`C$#`t}7k`^> zbc4}~>ps%Cp_~bBUQfnvVtrwaeHNVU*RR9>G3)#j?VK10|qQgcE@!?=uQ$L{Q;bYqegX+~=GI&h!Yb%K2cH|9G??%0-oItb#pS`h5B4^u&!}Ej&6T$lcl<|d z{{Asdg`uz8HdD@UL12}9RU6ipKrvySS+-PL8vg-QV?XpNve(APW!kINxVEiayS3=u z^Ygo2sV+=HOcW9(s2mW%ldEfkOIgQs1|#8`VPtxLs4A1;O$ zHf>}i5}r{Z7)R_Q2T7|pWO11;vPNcJ%g!8}S+^){QBktXxMa4@x$?~?7rkeGtGTmO z#kfXTMgGSIi0J%c8o6}(gNn|@WF5(%S-%BDw;0VxaF=$f{)uw&@}htI19z>!`os%{ zD3dh&pY|`Cn)Ou*)W{@0BNk~sVI8OoG0Vz5UQC>*?5^uGw-$qTuwJWEn5kftv zk5$dv!~E-+<=4r?x*VHmv*12A7OTDYDvJKEebJqzaIgaKsB)Is(crFZ>%;5b5N$G8 zio&8C$e1(#&72TR2gIe9N&MV+)o$+W)>kzj06Qx`bBzMlQ9n3|y*t`S8aKtb5Xd21 z5Q5?7L@sA8LkZra9`fowCl>wn7dEd9q)Jnz7O-dphTYYJ!7-8I8h#xts82`rQsa`2 z$1w-Cs9NZ8Ya7paP0`Acp6LVZe)fjUoJVs9uLpuhE4j5&euByK8S zJ0s9nSIeJWH~rXRlf_TNyXR!hM3(~`%9{E-QzbR$ECVoIF5~9HnP@%JOd-y|Q|S+0 zDqi*eqW6j?H4o`~=OpcLsyfF-FvD84stQE9ponDgIH_eIF475GpI|ELMx6^jc;-#7 zEc!p%d`c-X^D0Pqz7h>ay{|LEUX>iduqYf>sR4=n>*2ZsbV8D8p^!#PXJ?l8XqcO{ zhg#Z>p9BhV`Qk8qg0=ykg4!e{0NZC{#!F49c+%cw`WHt%Nuqq_hl>8j7d96Lupg2o zld=do{RShF{&O?g7DGTvGa2<~l5~|Fgy4J+vs6*Ea9W{vicPv*=&$GAc8c z$w5szr8Ih4r}m)vI95H1#`N^`$faA-_gP*jKl_bh__L--TjIrmlf{H4sxa0d$3dEM zgka=W^VTF)`A}B|EfM9#0iKx+vOCIQ{dq?fgO_Ilc&(_^fV*z#q-=T(Rz22=?-6yK zt`+ziXQgQxa^=>`I~C6y!3-d;Ek6A|MRi@%#(*8yp%LcW%Myd)XH+jH7OFXMN-#cb z4p3`sq>KTvY6f*)nz!fX%P&tBy^qW`Z_Hwe7{cNT3}jw!qL(po0lyh0g5zV3PH!n4 z1VGR-iIPfx5Qx59yy@-5@b=Abi8QT`FEqJ}zUw`w_g4on9n3&Y6Tm14-cK5EPAJZbo0(UNk;c&jI{3wx~2~R7V+J2E7pP9S~10ss+&ott@dTJ z=e&D>eYM)}u0{3ccWz#cFz6)-HLm8YmGs5?c_ScDGG4SlmGx*C8Q%zF`yQs4h6OTq zbG@3mu^66kO?$BnebV=!dYE|a&6)+GjCaVM(+8W4Ae-(A>ugO-$hc3KJQN8r| z%{voUGEP|c3IRKlHPrr^B*kT6HF+HkjFuHF2sRl7%L$Mc4y@?P*5U&nEk;kjyuFwW zO}kFNH^`4}N(V7UPmr-u;W>05CaTt}U_LmP@JcQeHW${)1MX1_&uTAbpIFhByjOtE z2g=Bf&_BF_%(ezGk=WOiB7WZf=7%P#Vi=jctKA+{3@5MKyfb5H2#V-Y^Jkg8^KJyv z(1hq?a9iF(G-yIi{zjMKfCPaw02_o-e*A^S@YR2`xizsKYIa2>eOg76#ukKwa+019 zEFf0kO38Bqb|6i{obATcAxS^(`eOL<2R1jR5jlO$zKoozhRI)yb>563)is=)9Pect zZHv=OI`&U%AnvuT6+aO(cK`3q#kB22x(<0P#;Eg=3edNxk3ItS_?tmA!5L7yxcjq; z!8x1u5Iqvg8s)nfmBA{iH@v-C5#@vhvzgMw%z=<$v8ZQ-Vg^NsYH24be{SB_T^qx& zm#>e=++@;9T9~j%8Vay7uumil{t_y(#N~sea+OPI_`DcWquG7cUY9u1v*9aJGpf>+ z$1)E-NJjIEtzp0v*rZW`k%$g?-EvcF2asT5u^*b8H_A6&R`ic+=t{jVs&yPi1 zgiX-Zm=P%CDl-aG@%mJ7UZy(44&+^~Ru4O(=>*- zGor!>0+?IZLk`5WD)dZc_`cm)eDE{Vx7KK?&U0=jymjVz@Kng2qym2xLkn^15JK2# zDCEdV^S5CDk;Ew|_1M@QvyXXJ(Z6joWOz$jdJuCQ9W;M<76XYiwWaAF^_Xc(z(f&A zK$mYUB(y#}m=bbfx!V1QYOcV%oj0cYNE@Z3gZ7NmOv$Kv)iBS-B)aLi3pbWJ7kn@x zz`snE!Y*JC=T0S=gTB7viFq`eJrKK&r=SQgJI( zhdj)g!tZJ?ru`*GGujk7lX)$GIQ>cPH;3;4J|2p_jM*$$Deb(HsirF(UFGrn7vjSc163?drB@F6CUj`lkkm4~+`fyC-(e;UFLtgL$nw5la3D0rhff>cwYq!pqnU#SpBcPju&w|7;(h;H zOhEG*wYVy&?JPjsBG*dk{3)DNtV@<{^jL4vi&14~PykG+-oT<{BGhX6reC%fk~uL) zs(NI(xUHat7NA=(M;7$4F#&MC9c+Y;;~6kU8Xl26l+EhUru9%Ppkin63OEX!J82S_ zVZ_s%WmiL@FcM)nvm_%k=j_f5hs;=cTxj{@&5Z!`0QnpzS)pMx$j|_u5N$!(0q+@hg`QxUEDTJ9$Q2YYY)|4=Ptk?+9+G`_N+x!{sA(Bzg5rx(l zSr;{KbEVy~yriLr6(Y*|^l&>TUQwFm<*%spQSljJff-{VWH2<6Oon$Yuv@jP@-*3` zyy$@DW!re{J()lv{MRwZz{iLr@VU5^I3C^tyoK1X@b;&)V22Z7=XaD(IcyUwitMf( zC13AWnqnbtCOrB{Eg4DTl83B}YSVK|@>A}>e!l9$*7DpN+#Q=2LyEreN{cKX&CgfjRfG-2o+84F#1JVs06Kt3&J!K zvF|KnI>yWX&rvw4FuH_%x3XOR&!gIRL@ShQ0tK0I$(>{l2^hU?Ip~N=|07Zh9!wD~ z73J_Pxj7eGEX#e{3(+IJ5bg-OM9+A%CAl7{gOE4R5^0S<^=RR2bB0$q8b`OIU1sOY zH+`^kAyq)8R!iw18_=e!%uWH>*(Ov<@fZN2BC?DSi&xfqj#?tql zjiy*f^@o$erloEqd4&GJi29ahMa=z4^JJok`kxKk8v)|5eiOu-O>eHVescp=FpHdLUlUM>K;z zZCMBrj18EVBACT;LSr0!ND2XlM6LlIn`lfXz-m>a(fEG-HFQmRSkreHh@%d$8uwchYrs*VBtXLkpCd)JK-n=3gqC3D5JR=m3SWXFonE?|{tse3bw{rq; zny4L1Zi#u*?ovE>^dmagp}lZo=QIVdCFdw&m=Y1ZOa4GcQTs;pWfD<#2wZlG)#29W zmnMI`y^a@T!jox55R8>fxN)Spk_>$rVK5UdGxaU!-m&w1B7uP!G0IJi$z&CU`~lGor&KWqZY<3*;R+J(n-Y(#KE#wt8|+a%B;QlCtuXL4h6_J^0|U6 zl?SpaL~Ryq21Lr>G5`Vt5g7q30Sy5zCwT0&=Qj=TUQil3Ej*>adk9v^;HmV9!_LAS zADRD>G2fYP#W`Y!!S6hQB+ugJf9c$i=-~MF%=d%-$@)|zPnYqUL^)89_C!s{NDx64 zd04wx7>V$;3Qv7{$D6UteFbQ^0 zki#AtJ`|3WUpt#6ghb(tKxKkp1wE;ZLeVR!2@t$Ti{**`(77Z01H2*trSf#S%;NLj z~sjEngDJTC?FC- z1`(#N^uTx`4_rR3RZ+w;=`J&Y&^{^)8w&NGiB%ya)%Zvu@m2`Hl6c`_hm@sL2CCb> zaDtD&Yj;3ZNwESv^N~c2bE7imn06~ta?V_iPlVya|=1Jt3##@-q<2T#IW)eN2*S_h9lop@lPF0As#vj8p z0EQavL|^mAh#)sBtXdatocb+2GBGcePkVmnLba#SP$5J%l$No~SP3%=h)khth!>e0 zfc%L(k(8H0v8HMVFEFzxL2`eEEZmlbuXsZ)M#tVzx}rM zI(4?-CX*Y~$5N&uS{WxUVmE;YWSw=z$)ghR($iUjid1f57mj{V`-U=~2yF1r(Ey-J z+@^RU=Z9nzGjQzz^-M6VRoq7hOt2{;5vgj(vIde;aYpFXV_Ir|DnL#|9| zB9!`c0Oe}=Lp6?a49-9p$2d$bo9=39ltxTn6_8bV%gt*EjnDLLc~)nJrjr zACw!FPa+bvIVXRlPBg;;h|>!O&QT_08sEo*&sTT-WP3+i8vJ4!v7x^kwx&WIl;ONF z0#E(pfATvLEUX4F0KHCNCDxMR*5<3J*R&V%5?FA(2I~}WB7vl>$cKy*i^I+TCl!Y4 zBt{5K^eyF51_msxmmj<8wfjE(ml30O@&NBHtMiI?PaRx6wfeQ*%gU2_i_?1z{&+Co zzpa1nRMmg-_!U#9^zSn9wc>l@FPwb-_yfmo+_LAysWS(SozeT7vBS!x>h`g*(N)vO zj9xs^AMHE5Wq8i?r874SpE#VJylisssjm*MDL*|^&YV2)*e#cCIr`tv12h4T^kv8$ z=n_x_;gSypadRLAJsz}VC`65V9$1ExfJ!=6&5NLSt3&6TUFauyI7t<{66JD9ruOW3 zMdske?!#cI0VRbpD4^^#gGCG2*W(NHcBQ%XN-T; zw>eZRsT8Oy1{iwu=;~#Eq!FstN-k z^de={QFX-Q+Y137k^o>A=R9>N=5k>$O5>^kPf5rCR;7J$nETIOed@nzuGXs)po27%j7 za)YYgSqBnXT$RdXC7zd5KJahb3+b`cgA>n{ESY20a|9@M25P~)K>^6=AToFfu2%h! zxzaO7$XP27xv;&EY?&h3D-k$Vx+Ww$F(B%tMG6A5bA}io%mBMGUXZ`^(Tim;}}4&NGi6Spo$jf=L5ZaJ(}4NT7*QvR2;vvi6QdlpJZ~PK0!D z&tz)=nPirr7&SGL^h>tdM zgC-4_2fUZji_KaI)8VKr}PQ+vmImI6DAM~oGDt>x!=R#VXsVJ6n zIuz#oE+eP>V@`7!72f?gcwJnrW>$n(J%E2D(N7Gu4rotX6Z$vL2$ZBC2&9oggHxeQy2{*^pt;HK|uqiQo zLAwwAX?q>?v$qE>h!8+=&iEt6+1lg-ObMRWhu5u`5 zN>Vy!GYgftW`hEIurb{$Doai^BUpP{V2oizuwf5VRINYzg7yVv{F=?4rkkAiN^ig$ zB>mEv^#zJSSg>=0fbwWDzttp^=2E*oD5tbm5pJ$Y{ue>ZNI@L089#7M;a*@|@*(W9bx$ z6rj#K5EN#amsHT z5Q#4)S6PY(2EL^ncM$qn4srn$4a^T zQ`}Hpy#XP(g_y4713{D7RefE{`}u4sQ&E$dvqwzxa?GP*91&q+V=CUdcl(CqR8=dCk4;Vzhn?MNANqx^ISgwXDBSXx2CT>H<|r2*KY z0ldURATn`g%PhEW8#fQ&cLJRl?HfA#p5S3u>*RoIETX#o6+xD^4y!M)jadyg17uKi zJmEG!@XJWFy!N!l$)8uPFv@Ai>{?p?)0?el!cbO)Ag^?0w1PpQAfr)xSaXImaZ>ln z_J#5jA8KEb=Z;s|o3b}RCUlHS6`s?j>@9^c7lOTQi^+Oda;8tq$48eI7dHlDcO;tD zty>5O7>^Q&WF$-Yg=ym!eJIZlt)$utw6sa_TuB5n;w_qZ+i|s{J;FPj{4|^su0kiO5XkY} zy^7Q@i6p@Zb7i@kU1u9r4``a)JQ`^t-5#9 zG~Nf+T-4Qshy0URVCOQ}uPLwdp zTVli^DC)=!8v4)@?loR25kws?gKuA~irw4K&)FEK8X8VT!Q%)~L75%r0>_jr3gGP9$Xz}`4asHNp!oxRb9f3w*0^2Z$TG={S90UW4&i1+T5vR5n zVs1caD>%h|jji%L%HmCn#lUTs=W{rQZJ%dCKy9u z0c}I!^DMoTm5syh{+ZFqh0$ejv z5z~qP5uK%^bT&dq=Vz{3vOiJwSwC0LGH9 zK^EoA!cw{Yi1tFL<3vAbDx(W?Rv`nr@FZ*lgLZ}?v5F~J)&jRS1HWMomcZ3*)o(ng zIRnkJS+#G>X5143oh|82fLjDNt=8On4Zbm`J&-^5!1E14Bv?`#Tub^d`DYHO|6yAC|czi292U++g1n6Z02$f z6{P~x4l5mMnGRz?Sn-DZWclL_L|2)f$=JS#+QSLLJwO@TT0Q)Y?URul#Iba|K)7frNB9$=3#yk;FxnW< z^}H}^UT~=Hw`mZR`iXcNZUG%m03iulm&{~6P9~ejHH95-T0gTSMN_el!^;I=R`;B4 zUy-uK0*Be;?ojK}0|qB26elnPUfOHLOO98>DzQC!g{iml`s!kJV7^&xjG~umB*c_6 z9B@mLqu2uSnsWx2Hyz8C3c~PSba^@?vNhRng*7OC_p90)veo1xi7b=^z(ZQKtAm|G zb$Y?JA2++gQlGUEyh?Go)Mqq{xcI{PoeQzu8=#HJ!`u>Fw@O{uxJ(aMr&DY1j=w3_J?E1F<3$>`l+e=gHAh z<@`DAD?)w9)bSI<#wCz|axka@F5Zb$#Z)=_&PZs=A`%u0l-k7_TRVD_(zS{pH)I(LI-V=@pVLo)XY>9uR+`JHzy%j;Z>=T>tJ_D*L>_JI~$ z;Wlcix*wMhXwYBNKZd;3shI}Vjq(GV-amH)Ttg$;D1+6MuAnovgUG4NCPY8)I1KHZ zdBw7h=mAmNC=gM3)rIXVio8ZRR473gshhD+8J}j3L`EAVFmU2PtR6{^ERsZS)wyoZ z&JA|7A3u$4jzES+jGfi{nepQqYTZ6NBDl$Gn)V4>M09|^bHY3UQ9j+eSbqK^?S-g@ zT%1s$$9ebWUOeZ(GRu+r@#R%L`z zcsd(OdW5%ZDHbY4us#nRf5v|yIZdi|qQH)=#SMSgxg*$LILwJiIoAsn;%#K#am^tB z6#^NBjXNNUxHljp!;v#yPH}plt2-A0%3`B~JOwT7Dr7NOQ`Stki~W~_9=H}zmlisO z1l5S#55Kuu4U6_dqGF6tIrlW(s@6B52mr9bycT{)olWW{@FKOZmnpz-v9P%4mU!f` zoeOzr(|%Bm+zHuqU>3&}V~YYRB_vYRk4m@DrkzKouZK#@O>@n8#BbX%gUyaJ+z zU_s-;iBO0sirPV9apPDbhyYD-EHIU#2H?WEmEtY$Z|}%5;eg0yVtu0OqG?2lRDQ%$ z*QB1O^F7?CIukfIAm0X&w&1wGzGu6z)oGf5q*H4qqu!#pqUN;G_&!z-62L+rFv)dR zT+%|$7tcYY^M7zy=Q==#+aXC%TjP#F^D>MI`xc)P+Fhvoe7%%D)Z|1M&`+n^;@0E0 zb{;H-4Rt7@1QJCx*&#HuR22@701t7Q4zv>7#Dkn;7D`cB$#Jz*zU;G|8 zsjp-)ko3T9a4zmSjiPBq$L?B5G(4F!-W5n|Y5j+t8_Iei7YeZAg_MoqRRJ2tp0K4+ zihLc{hpaF9sdtUd@u0%~>ek}2gSr>8pX~w7&$cWF3;;tP#=DsaCJaO^u4yg9+Tmog ze60HPmf!=+J)2hiR6)dM)=zj3Q>N0DAyF#U6-7|W#0kYvjs~L{$(pGsha~pqDN)2W353ilaQ z5LAKrLOS#^@etl-krYx@na~UFD?@{<@bKQehbr0Pq6f4eEuLV82_ra|qEV10pJ&RS zAIlNX3K1U-J#Ww-QNu#jzXx2CHzeMBZjPJuNhBHzBjO3%VsH433cegRA>}HRxFYd^ zC?H-S0pT1!xe_(I$jS1Sbvx8T6Zb)AqdVWDaHgHY#&NvaF zgb1csF{CrG0A3D;-rQbMM6rag9fL;jD$XjFC=G2QBfs(s=Cbw z(%IE>bH!)h(LNagTDTJT;^RhQrq>Me%ZMY z-awTHq_dgZwmH@Zo5oORl`7Mf4$5i7u?o+068RF*j^)W{q~aTYy?G(g%#UTQ$cR~l zel_mJJ7@IwFqS#$U&E=QIzuE(P{n$n8)J|ypU@#)jG|GC8W|PY&{RqlzX)je<6$y- zKnJZjD}PHFSbT+ptd{MXs(a5(#{`sSy{BO-4v6}UPg~AOPne2Sk1;01lbWG?xHo}3 z<6dPV!(G^JzT7r35c@E?m{K2ua0SN4z=jEr|0bv3n4c7d%UZGkynd;l2aGeH;h^|w zhndKc6&Y!lX|-BhpU&7 zIjof(a+>B)>NBpD`9ht;3}a1)cUG}Ijq>(oxrkEr&XoQGCZsc%dMy^z)G*Z|dWAER| zhoX-W)=C`rfb6z8-xLgril=sS05 z?%UbL&WD`nlYw;EfXO23)YZo(?$htrf}jI5#)Sm%~RHj-nf;OspB4A6usx}x{zdH6FWaT z&49RMfDu;l6hfv_T{$54fYGD|FD%_)3hPuIt8;_a2!6{EZ$wJEp)t9HjNYh#L(Vz*`s12a@ zg>T$8M>lbI+qS`rPVc;Ir>U5N;(8I;(IF8}a9TNNBd%rr1YS_xVw16E5*o7JG!Y#k z>oebLLb*E<0aP*>c9dbb&<4202P3_kUTal4OJ2I#Tnd^8i*FMW9B(iojXF@ z=neIKi6$9Ifqx*irp)m5lx=DN-&*j3Osq8~pxCmkvaQ>uKYai8LR8Rn10Z^o9_D)( zqezI9wH1@GIIzBp<`NEjEfqsJ1e>{ty}E_zy&Hh)(d-ddVB=J5%SF17FeA8hkHhy8 zg-hX_xTh;q&{O`)cC>+@u(5mmW#^9IKvJiM8@NDGg*Jx~EQG8+r2!=j-2s=2q%cF; zZ)5(o238h&KWW6g+)?@w{31MtW=)-boRpT5-o=PU4&AX9Z|M9i)$&V1vpSn8=hyc#y-%y<`wnMRJQ4z5aDixYLCqmkGh~ znz3vN$U8l^k;+)+#DMg_)V~U?uT%<=mVdB5`N+?-7ovyBQ@AxiLg^7LAX7Wd#YXdi zh8Z`UQB!J)oGqj3P^44C;m7rfpX}GY5Vh9McDK|9P{n#9nDDJx3nVIR5T_G36j4WE zt439}#8$90SAF?a-3vL!44AbhDG4fO3^1Q-rbx%#f(`(`@kmNH$Po*oBuk?mwP$tm ztdrUci3k}CZylu($ZuBxs9%*{_Kq?kws#SAMz7k zjWs7Q4-B>T`8_G4J0GXAiL`g>#l7jG*He6xb zju2iIVsudbO62{tpv6GCG5o|GomZp;CQ~pgYT7VWBn>}u1#BZQtLPO-Atlfk$Y87o zx?i1afl|oEAJw3y+!2pu#+-}jI(%{zFe-w;5VNSh5C0uxgr)c)GQgb~)5@UAVwC2J zH#D}Z`a<0HoMas2P=ofFxK`7Gu4zdD0K3|El(m3;6@~zUr3;esIS2P{>XTe39Ss5x zuSSLsq`-nE!kZ=0vS9h7inyGO=+Owg{#s60L@{n3?ET@+*H?-sD)6&uzv3tn6%lSc z0XfD&9ok)p^%uL5aprL!*v(fs~gVC8?mLfwN76{)|NF z8sRUA_QX^t3-W%f?1p1`0zJ9S(xO!B882;k$!u?IJJXfO>FlCG)&+cflAp5VVNWQ6ps148Lg+VpWf2B zA=^)6L9%*u*G(&nJ(E-3)Pn>kSp@F1T?O4pbM`g9+?HCOEkE$f?u7zDky?Jz=Sro8 zL6D$y1_p47Yx+Ad7OtS9E=)V)2Pu{6-#>Bx&V_tOU;w!l@NPo`pqXERQcP|Emk7>w zbnM;831X&Z2>9E*t`3eop!4xfHVLVrcMxoVBbfRD0OkVphV&+f$v~)EnWWZTp%V20 zDQ|XgaX0Vh993M2HWy5q+{`8%mL_e&_7qY`bdBJy>QyZ(rsDCS%Cc_vj%b9_d^0ry z&j_PEJ9$brpd*l2Ne0jBB{xw>b%Gj+!d+MRIV#mTM(j&c;sl(CgU>W4TuZ3k#KP3M~nlaR0X~hlGV(URl3Ksc+n6FK6NAaCT z*2*1aOT*}B9uUFJ|tQe6s0e&mArB)kpq;!dXrg$3b+m5*=AJ zE4QYwQ@2S{DfTF7ehOl>4@UPttaC@TDIuMp%5}mzF)9679vH$R3uVZPN>pr$m5481 z!Mx^Eq(61y{n1*QxNrg=MAS%+QdGbuDQBUhThr zqI*MXl#l_Y2cbZ`1Wh`|E>IP0T-zSk?&icrBz(j;MUNcpHEzsRzuCc9Xqk+Al{r0n zc4f3LMXJOPjFO|7Wz)$Aw&}bf?IS~MLb}q{h0*_P3i!Nh9rvm}5tGlF?#VP)5QKRzg%vRFS@k*!=T?fRn|!6B^~us}5%J1$aIYwmvjgv!15PktAXI zd>|65BbnEBQOt$&7CO~&+h#|XkMjfk_hPi=M-!8m75f%9mph#R)nV0Gb<_9@#_vD& z^|7~&J$7s`eEjGmqvJ*o8s0cOqr9qoakBF)%Yf%&2;Uym+_<$k_1LO7pCu}A-vo`gipSKsv=w&+undswD!X!Lg zq(zG*Qd#ITviYL97*l~1Z3^SU7R*-l(r|=Zf$IILHr~9?atq0p>B) zsVoCHE>GO$%I<|AGHjrB?WTuLR?qfs$_%efr zW#n{-lL-`|@F7V7;9%yJgcj$gFL+b;j&u|F%@7LE$H;}`FEJyyGQb&z6N1t*wZ70h zw%NtGP(2JD+lLevXfuc1E=7WP8Bu?oOJk`*+*AXUCMsHasTnHv!NDu%I*-Po2lHoH z>%V8=;veChAOvBTxPQGvRj(ErU>b=gk1Ei-{WNY5{$Z?hp-gD;9eBhzsKZ2p#x+Kd z<7#K2PH~T>B#YG%h&lx&h^vF2G@^1IO~U12Mjm7ax+I8%ji{bxS;3m-OD@Z+_N(ft z0~R7A!x+46vHH?0x_1=oAwks(L2@dMqx_g~BZqjy>Rn$TeU$Q&mxGA|JK~JCZ2S9v zv3sGoiOo(ku#mAjHgXj{u1#H)4GqjHuxUx*<#+)kLRrWmtQ>6PKlpIxLcRqi&Nda9 zWiWuqgbK`stY_s#CpN+uhYbVTkgOrnXWC_qvM4{+K-0XVOgB)p(w32AUMlE?;Il&U zoG3be6Wo2~M3;l)wve2wHqeRLvy4$we9CW&niv7>+Gs6k;yNb$I}h9HXI=(aN{R)6Xqt3Ej$%nWKN!xln5B z7>el(<}Tnl>~~?_7qeE9(ClBa+B(2l;C`dax@<)7>fG<%=|a#adBnni-xWqiW7xt; zmbMt=%dsKsnZKL-5Ya~}_Mj$KjNQHI$;)SpmDq+9t4ZL2STF&!Yi4?egvcrund9c7 zJ2UMu)}$Wv%~Y(TFJ-feN%*x*GZ@VpbgCX2c^G@%TBb#b^i{8}Fh%m)=Ny z8fCX{AG`lgx=#k%*POI4ujq0xfJeec_?j6V%+z(vDDVg-ebuTX#vGG({`nw7f(zstbvmUzTEX%vIvrw(Z<_np^a6Nq`wh|gLn zj}27FKvZT-N(hgviOc|3=44JZ+g3fBVf*BCMu;On-3hNwJeb2eF67Vd@ogOX$&H6$PC%6L0T*>TBH#WrS8hO$wUqMRQG+U5JoO zlCfA&LyBb)J@gbvhWkjThFWZ}?>jmdlIYVlE5_y>g85ADo`StsA18E@)*_JI#)IKi zq#1Aq8ADJz$}3*ky-->J<32_PZI!`i6z9%T8G?V;MFA_Y<6FHO*4Bdq@M^tNiW9gtdZdCVsS$jvxeeT{G zvPIJ>!>p3w78po59=RL_2hL^>V}H(3dpK`pPR3PN4|+iNLcXNoKFT2~Mr!sjklear zco=0|L{vf?tmhT^vN$x$BZTH>`|sP0UH7kd29annf+j*;?3WI4EOl=g^_(-9k&iUN zr|zwXxyA*tf}|{oS$^u)M@_rZ9nF<^lVVq9&V#Ml{#-gu>6vpy+%gD1y$b9}2wtAN z%zB3iY`B%#(Kjz{pG_eX!v&}blL3I~`{IxZT4$vfDVb3czyWWWgcR%r1$L6)w@&=# zF`WzHk9fGb#3ES52@1pFOH)DMQ{gGx!ncMrkRZXXiAH4j~wIM5`PRytJ^xzlmJ^jN*ReKq_2*D z_rlJFe0=bj;;mPKG8O6=Zh*U3cD*Q;fLJ#u&B?gpgFzCUcxaC83*)Dp*SU~B7hD0k zD#*qC&{f$bY75OhBg&_@`(|!`YkMK0Vq6xg4gl8kg-3<&O(5=6SdgsvDp^}M!NUN%3SVsFP>{2x zZ~uYH_c6P+T0I+(EJ`M0U&_Qyg0)%4JbIz0{3D7T4CzH%`vgL;)*o>-%}w8Yd;4f& zI|jq9^{pXkhD4E80fa_E+!_T+IR;>2c)}lRHnOFOfNb9DE7M>4m)Gw5tos(l{r)&S zz+CZmGJWx_$-O7Ow&jxQh+Xyj730U61n|w78_L%f zS;gCjhY!c6kC{1n`qIJGgO~K*zUAot6Q}p;PxU_0dr37}e!REeulB+7AyMYFo&pdy5V@Ys4sV=zqAUq`u+TJPvA)??$YMtuV(&4m-NVy<8tUT zo3G`dHjfcg?L&uO*jhcL$-cQzTFulY!E3Q>uiaoG zkx)DK^6#|oh|ABAY&a4vElEX1CVRlFdK6N@8;nJON3BDMFdUXaXh91=FB`*$KfApU zql-E>C_Zyca@RBs0R(-=49JL}gvJ`iLF<_uh@z;^$4SXJHF!jOA=4mD0SJ3+7I-FO zW6N-alqeU}ydc;l8(3i&CAAyL)e4Y;X(8pGex`FF4N1_cnopao3YHTM;-f|i$JPUK zUTWgk%yc!ZCE|ll9iiDowBmGU!G*?r-eC zX1Z6s0746!H;hfD2w0JnvYf?*{4{t7+7>hM>z-HkMqnw1v0n>f^+tK^bmxw+;c>af z>K^$&Coapy9LXNZz&iqNFkDQptl&lnKzliqfj+V@*sU3alsm$vc_ri(*-+@$$04}Z z*&0^We4z7_GYVh=zksrM5Mqi$FAcuX^kcgYYAX2GQjLEbWlil!gCK^+ub?DyZiu0f z5-kihrNR~DAq*b5v4y41lW`3m z%kN*?xsa_v;{ms<>-JT-sgcY@g1pTzlC#(~$!2Nr#VPlG`N-~tyjp=6 z6s4&8uX(8Sf?#yhQl-x*U7IGEyS_ser4fkJOA{@ta~laJFI#jLTEQB7%7g=MGFUH` zWZ@(;s+=WH`WGEV+IT$m!J^72PU{=}8!z5P1=JU^g2KI`R9JxglQ_zK;vD^%ffyt% zG$eY+LkhkaPasAmYZ}&$k9F3y>JC>bJ0hSh+mv2HH-M^z2CxiygV^OIGTa6FL7Zhi zjCix7zt0ysZwLhzLJmEnLyiT|qB5R|slY)fmNVfACm~x|05PnmSA@er7Su4;|I^Ne z+-sU6)w$~Qn0{npn={3r$}ZEYUB)KCUc`EVmbRWiVTrxEaJSBrnQSJ|u%OnMfxqQOpnnbA!Xa(zzkl3W1&`uf4#%=isj#zsVmVMSJQDGQ*u(&_WW{*|kFl zsSbL7d479Ch(FRjgiT8iy@9t?F&gfOpM<`pUj}29G0Y1Rh`46{nSrF=ZF#Bx#g}(3 zL{XI*W$et(u?$Jyy8y2~KBbQr$DbsX1&|{=yiLleqH2AudeR?sE(8+DSL87EiikCc z4J;d|11iBJad-Ga-mKS$k3n$6FT*9cZK-!f!%SGiqEq};`USF6V_HXu2?H`A{af-! zjK!jk9?)>B2SLe00|Sm%yd_TtmU$>Io^>LRo9S*3YHyOR7C_9b43B=d}m2fYGH)JEGU&bx`3 z^m$4Ok0!-N1!Tnp$0QO7)s+!a5N#S!bI=1aj*iP8X&;N1Iju>@_2OFp%onvUJE)j- zK>i@z>Iam#Ex6EU@ze*odf7}W5nc%(5#4hHoHxHXSG{uo&V`VEapI9Pf_X#C88}Md zWKhc?a2(G57ZNWnJ1-E9))qlw7l?b$d+D7nq=G^L=Lkz0Ks|7Q2@QGKxSyE7klUV4p@+j&6r&*5 zMi(E^UMQ1o6#U*XgI;7OgGR`Ync$|KgaQ;!0nCl>S9O_rQLJ!Qf;cmMc=z+m2NV}P zeKJ^F$wBy;$uD8X#jK+Q;6eV9Km9NKIFJg3N~@zcJg9R=Ml9vaYhdL{0zD8Xs)-Ee zi^mNLLB0do9InXwOvmsG1mQ686YqIcd!hIUa$Kk_uq z7^cj1E~FMZxpYZcUQk%HwwVey0*3uA# zsMpZwI?maHB5S2Qxt4H_`&P!VRj5*sp{aqmx%kXSA8gp<(E*;RhnWKhos(Xu)U z^888TU-=O~zbL>QLp1@!r+F<9qv7HxG^*tH!?mZzchnu1>LnN`l@-je@gW{;*5N!Pj$MGiyln zGu4GiB5NslED*Id$dPJs$Mk*fv+J$J+N%*5f9Nf#vzeCD)|g2}HAcduWR|%-jxod_ zI2ncgTDGC{3w$$gd|~H8X>qsOA;dI4Vsq1E5EG~jlY?e5A03P^B*X8}C+@%3(vVVW z>cP!6&K=nU+`GKD2Bg7dX?rwrhKv@@R%%BBv7KOzIR?d@_*G011$gEb`}^$Gxg%Oe z23*JQV)KLPY>s3bsWmlWI(pRplqzm43xgbnvJPd1Kd!EC;7RUCC!_F2l|qQc5e!gd zXsCCBuu`(Z70KBChKV%sD`Udcoe>PiCcf0UBM(P;Wi-TJWS=N14Ym_%<5WhEfR4h2 zI{?D`O|Jsxsdvqe>c8Hzb0J$x7?8cF+tk&tkZ@=iKCeP~Wpk*JS(g0YTEas12B6jt3yV0DG}mgCd>-9ynqO1HngHdgRF*G%vDzE zfoKYsnYUlNtD?v|;)@|@lUG^8(BmRMZO|7(+NQAQpcIvLE)c^q%S8F_X~iiwKk=KL z8xp|5HynT&QJ4n@IA#hmTN@e&5OF7#SY)n{!c+?DBv~~|ZSTzus?5r^tI}SYQP3c5 z4rr44^?x!HsPi+!h~S-47pR9Y>8k2!a|meJ(@#5P7x2!L!9$o_da`$_K$c?D`i|_T zTSn^gxol*^a@F?o6tRwqgHc&upL&1OkeTaHDJ&OKaGHi<9FbRLjoQvHaitZM<5b7H z<)A$*5EV+np3iO_o!e-O^$mHo(uO6&V$a>Dp`1!YBDsl*z!<(Bp@zjUAv)Ntd>CDq&XI+6sJ;#ZTW5SDJ!X~$21CcZYYu| z8Ue7(vcc53s8SC#PQ5T=!V;7=Q3^px>GrY(tT+<&Y<2DJof|UF&Ru67UnT|_00G=` zY)NJr)n#sL67=u&>Fe`@FHw3X;AV{iNBZzbL#{{CJEg& zJRM3yDSv5gV)DOqZV0JClXkn>f-%n6@a))!MWy@n0Av_n8d^>m@vhd=>tYIOzeH`CL`&dd@v!_(w1N7b`)_U0-oAJE3w7?x#1{>wv`qZ^QXz$6=K|Ux1aq-4+ASW?yZp=SWvSYpx zit5CAn6$}}@*YlKB@3VJn7pDPfb*8(Ay(Wd?u0j$9Mqr4W_+BA6}WWNGxQB;3ws== zabLr9^6mD;^776?LW*Q0rDu>z+4iwq!bIJBN*K~tO)#RAbI7Uga1)t^qPSM}t!9)oQ&aWv!Dkw$IJ0?;L~bt#pI{4dc&E#c8#{$1kT^R%KGk_gpr1)G zI5o77$@%d{8*B;g3bF>e2Gn>_k+}$G2tMmWZp@^Fm5G1qM1H$S@3ds=M}&Uv!z3gn zt?dMPy2ZmQv0hP=SdXY2dN& z1y~PAt;Qsw?-dW&fW`hEf6_i$X2xKDPO)#eL}?)*T{%nuIE&1E)1M_ti`q;B znc8J}t(LF(`%W%GTJlVoJeQSYMWU2sjRJ6!I97=LEY1#x09)GPLHisn!qsk4|5{s%Yqw^c`Kkqt2c{B9~EdHnV~oNRt$v25phM zKYV}pLLhJ&ZUUdvWDlUHqo9r$TqNnsjr1j=(|s^N=~AK@XZFe9v}VFcwwgu4R*)_d zSPUs1#aq<~nlY@|faz<9^(ZE7%pG!=_*;+iS{uFXw$2@S1)>W(cZOL-o(Z3l&T9cS z_XyTz;GvS*QV*pkn9Alk)^qr(Cv-0q%8;^dH?YNsI|go`sYFgc$7kVgEqIw07?8|? zB~I~rLeI+Bd*9x@5a@{3wTp6?LikpVfySU<7uD4gPo{{$*m$pWrCUaDR{ULa+sFUp zk2@E#He`O>4B|DN*Ca!?LQFO~fCozeQ9AQ*LE6+mEtD7{kcWq5cH(_at(=#QS3x#< z1(unEi0`6$Pr$mlPql=Kcj;nb4%b++MD%|VxA;cWjtA&(kif!0DLw~ z36O*%QF4dWR`l@~jK1GE6!L6nc=0tym&Rs|SX7}$Cd0AH@;*0a0|K|>GMzjICvuVk z93?ycq3d?}0bD2~VqE{wKjxkrPGV*pB~RqE`%pPjCisra5rXUEIbs-5*vzd?9NzGf zxg!mLAShc*#>3~h`xwv=f7Xfw4VBn;3Rn*#fof#U^ey{2cCqoVKNAn|=%V_@bmi6- zii?V(_vBA)xp>RQmfdGQH*?a={PZo;r%xX|b;s0SO|4DsHu>4fmrl-3+%$1oanZy< z!3jt(6De0bq-b@&^DPdjH|KivYS_8-&xdGEsBj^1w7 zXRDW0bLGwDY2`u1FaGU3z_0w9{nvbR*V-kt3+JfU@b)>N2vH+I0lZ8@Iqx}KJ`*$s zCy<51(%23@EI|dYvR3VJx1#vajhh#0vf2Q|{Q({jI;q5`^d6{h>6~DV&uQL%8f0y?Ls0_mT6G>-pz%M;TB3VijWr-XSwKZk ztxuQ}vodln(>?6f5Us$7+61yuha+7`%qY{@2RypyJ$~=@T2_Pv46gI*!F>KLbAcf? zt|)XD%3p62l1lR9Dy@lRFgG}NcH=SkE2?h`l&{#LBynF96ax-8;!(>IsaiZ$vRLE@ zEw!r;LHSfwAQvTVX&uR|{=dGFwryXL@t;p$t;>f zX8H5>axQuq7+Tt9>{vX5%ai}~@}hd~kK0cPOZYW3!ZagjkmrRUnAt-q8x%Thof$bv zs<7rYzxn%wA|mzjdi7^-D~2y&SbkALoHlf< zwQWfsLJ{MQ`rm(PF*xsz%~vMB`hK)FCmpKV)COc-EQ@Xl00YFZIza+Ug>vY|FykOt z+%Dvpne7J@)pMF7gxpz%s>dqNj^ZA25~tEyR);I31YQ(`oJ{Oy7r!%y9f?#pv}< zZl4lGNos|R(RQ&tMUP=S(GpmjRiGZ|3E71kmxZk_v>v%R!qvj$OMk8CfA~MO7bBb^ zB%u-Yo5!WN1M~tHG=O4G!R;E-UCdQp0h-lY;~Lg-u{d_@8;jnL{-M1XcPxx5e`8OC zVGxJHg=lm^!-}2mM{`RG|EU`SY4i9-8MY(xT4zozqS{X_}FCpJY%^SrWU5* zW*<}c`7jy09f`oaYQiLP3ApjM-7^5UI6pe2EJhD2H#a6P4k#VPn__)y30V{n$6nMoEC`_(lwzMLYnV>m22ji~@ zWaABaGTP(PV)&JYFtWy_o0Q7Zg@u;sYX}f(J#HX9AWj*P8U^|c-SzCU4Yes#Qgo#+ z_m4ch7(H^|%{$BdBJWr&59S$bD0U z!@^jsNNhZ`0st^23D9ok9-D{yJPrGUJDXjquKQsJ*Jmifh5Np-T0K4pNIcx2ZM^xmBJ830)9U~IK zVs&Hq)s><+>-zR$5{TY+M?R>EGDk&DC%&ji;rDoN(sOR-N0RV)-~)P*n1JzFTCI+{ zy6Ao9KerddbO5o+dDC2E5Hl>a0#P6=)D@LW`uj2w(A^St^~4fuGJ;evTUe_8@$h2U z|4Mr?9EL&%-yucw{~KXNw4p@Fp_WJVPK#K2%Di3yk8jiciU>Z+{P3I4D2AUnxV>1s z((*VA;mfIZkR%pG+BzUA;LI&$gaOf57!sEZ=HMH#p~y1hPkm+4TlqzMF_VLHfCAs0 zJ%VWF#o|!Q;1~s?EykkeyGUSKL@}v0@=i~`ap&tZ_d2oY{dNnpGmVq^O*;qPJ(VDE z?z|7xDgH8KMoei;Y@`$r96d&KGHNf`Y<^+t!nYO0p`EV@8v(FlSTKt!A|RFv3gSrB zit=YPU>DKhq2&Vpaax~n32FG8Q~Nj$eY~LyQRreU>Y9xU%|vy;yMj+dEM~X#BH^#? z>Nw+dM)DtLj+K2DPtxk@_&>g-7#!FLVKvDt!g9IkBcT>rkOEESkNQ})5Kkt-O1!a8 zfKwn|gi~fK>y3#jJ~Aq*uk(%WLXFfD$QQWI&i2qT^5$ zFu^Do6#d@(PW>A=M$cqupH_`$ej{(#y#Cq{9-`r6|MJhJHT z*KTy+BhnBm#+GB$(_H6HfM1k~`^7{EBXXPA#9&9*w2gB9kiu?mZt8J=RrJ317ww(d z;6O80K%lVqq*1doy#Mq^slccyibG({juH+Dx1y(%9V5fiS-tMD<(VzT3mN#2okLM`3ed}7RDahFr!Lv_ zTUW+k*|1)@BUM!j1j{G`!j#OSb3(gs4~(jObfAh#CfVcJo%yS&nQRoLe|>zpvrwUZ zm7q>s+?Y`(ifZjb0I?=o(GPp>uxyS}cO})>vT{oHsQ+A88vFLKov%hLL6fjbiBPpf z8fIIn^K~F9@-|o(W2H-T;~=-qAdKB$V}5D$KmM_EA^xa{zJXv2utH1(9FZT*h2kXq z^RQY6S>+lalb7h4pq5`e`X9G+E+l^7%JBely$Q&3==iiI$D7JXrw@dm3Fy*!qAJYb z5XD>&D$co@d0Nivh%Q)ve=0k`8-ql=PWnP^Tx}rQ0n;un+~n*fQkp{1N)fu5F(Rz4 zm6!fe=Z-S-B$g4Ji-iK^hO779&>ZSitzkk7y)T58!rRzB>;($ikIheB&>P-V99Z9w z5P<59Gd<(BWRy@UnNPtsYpfg?<@<1aDoWH8St?jeLU@`s*Lpwd+)#bYokcHr7`{b( z-ig&RNlQTk8HxN93nv$5ToQAQxQGzX@sm?mE!^osJi7p4lyIC7X&??@kQ6baVJfw) z^~|Sl8_CQ$1|TceTG`(J+&_0OB(EANE!AM68R`I9;Sz!tB-3jsIS}zOFJ6A2oq8-r zLOO_Xb1%NKbD{L;Ajj*2nA7&*mXs<&c49o^Oj>%W<@`7SH~R4{H=L@}xG`Mo?%5Ey zlpmM}HAWULe8DEae;Gy zm*O|KZR(!Q$ck(bJfJY)b7UsXPM5ivDlyWEftZy{a7d?z2h8@+VPFrWYh}mA#8WTr zyd$7Teybk?Tc-BI`?BNM=PAwPI=~)=NDHB?z@Va$*3MJLu8sfTuA10>zH5glS`3c~ z?}xw>+*L?$TD>i-FW}Cn)(=ZtOq(sXl6O>TrbB3M`~&mI@@Mb5P&!AHyu5>%5Q7>l=J zD(mUmN_oy6-3z68fqzHgK>W89)PD$1fuGNcNkX@pJ`UWt;~-N6AWu_{B3`!@*Zkg{ zE+iafWQB#Ko~NToh_M!>1~WffMT-5P_|+}2M16yx+^9kOisUfTkPBZ!+*Se` zVoW9Cng~D)66cg9moDuTx0CN{`JA|H;(_z$e35Awf^WH^g8xNeUjk|~UIoVwIerC6%(zY@Oa`gLI~EO^5}?{bX{z@eBGBicN7XW%?gN5 zLDyn|kU$8y5(uan1&`@oLXyxyRdpmF#4`*xeAHf@3kio{4~Ko)u&n_FoHJ~3izD!?_2j&K=oTGKB|M zZ=yIPSl}<$W9Es6ONs<@)4Oa*!6zArBTix$w^!BMx)%bNNGX7ecP%gQB7~%lZ5pFP zGFSKprjg&N;58M91Z1;XpXIzV-o@sE~^<1gNMLO^l**x{qA zN5}6vJuoK(T*DPG-@mPYZvRRBneuOXP7TbNfz`XJrxfS?%98(I|A*}}+q}M)XAzj7 z>og1}CP_H;bn7?>GwhY=+_V?W3hV^$5vZ8#M~}Fmy^xj(>n1e~XaalY_!EE(wq`n{ z!if}_0d8z(SeM24XFY&o+v%&FxnIUxXj z*EqCP-@24)Pt^LB$yW3Uz0R;mE#S9gw4v337$T)_C@~rH?8o`9a0w^{je>%z!AP}o zHb3)>Pq&Yj$xWDOZ3IFHO+f)EwLmMlRn1NQxs69bgAd)D@F`(XL`{=i+%a?Hq3wmp zP*4d#z_o_#BYtyKsG0;5|D4oDyA&ZZmEM|y6VPr5Yc&|)^!Uz_7Z2S9n%gz}xau4G zm2Qq$9SJgMwBSqy1-3IMXJ$A~PFxha`pdhucZ3Z0F``T;284al4FVMhG^+X%YV3H~ z7z{H>(8{Qt$Oui*ac;QnU7OM$;zul$&_HL_GBM2^h80AFe4j}m(Sba-^1rlt6 zWA!ZnJ-hv|b3^QJToiJc9Va&>k9n==K`nXoK$Q*eh$WShS=Tb{kA_US)|=3O+C4fK z!Z?NPp`7azXJfElJOMS4S%L2BtXULM#-Dji@lG#C4w2yhn_n6~u?={!ampYD1^FaG zt^^v$3wQIM^6x^6V2l434jUQ>YDG1|$n2-p{(sZGBVkHz^aSu(4!FTsrh-S7nI$A4 zAU_nJ4%#%>F*!)RqS4k*%}woiOy@#w(FY~JDI?L}aF=Bq&pUt-r(!)`n|Q$>0GZ;Q zG7SUEibNSc<@Y-m3i+pCq|E|X_KG@y%N5@RN5GE;ho}~l-35nu4d7j(2vKrzVQjbQ z?uD>ub`;T9Zt(ka)1oAP2;)v#lfrrM1qT%fvznGTZ=aB_s2l8ld-pH)1B%yuY)ek1%fhZri4WYO-U$}9`so)2IGfnx zBL>B1E&0=QjjHlsj`i88>tEWIOyoLyBA#5835XWrF4rPFt`F%RgGr$47K=J!6aJ@FjoF}XiE7QWfSN+|Ky{!-H zUP#Kpa(cJuND?4u2{J0815pT!Z#CPx3xljoUei*V83{E9)lqYdKdJ zQd2VZF`4^&QVG2_(^JU#Y}1H#)-AqA0a3<{uZA+6kD~5e9sO>1t6B82pLTihGJOj9 zR`HzkIM_}Mhv_b7fYd}J9w5vV2qK)fzcRHp(|JcEJ~nmUEIv@>QF@U=^u}RgSJ{R! zRNBpeEjcOvbG?s}iLQo;>*rfUL$siLW>^(?EQ(@Su+-9`tRa-7L{Z`R69un=Gp8a5 zYdl=)x?Zb$O4I-62+scq<=S~g|DP%Szsi)pt5rAPA2gZlfNNHw=74#k0N3O)BA!Lj zpTSt*Bvj*|D1`&zCFOZMFO$D)&a_YD&-@94lfd#!xHcTiRs|VtR8@?Lj_{vyByDQ? zkMPy=zB8DDl_!1|U z*88vO;u-N!T}7n>cxd=(N$^8(Aok8&D-l?H&FKRiR63uaE-^uksX?e*e0FCwGO9T6 ziGqyCAT_|$el1}w+22j6x1$CqIM^^*4btgG`_Brt9mc)?Ni-comCxPjh9!K$N%dk|DFG2^Q|dB6-h#K`r_kt;RRI=qMdN@J|nmn zT_VLB+Fk#<**nDdG=FSg-g1w>?OcdIApQSI7U(sswAU8Z#|DUws%wTyVc}!(UBlZ- z_p_!URLsnq&+J?%jWe#I_VoRg{BWezWHOe-mT7Y-dn5@3l+2`*mW^o@7S8JSnHM$_ z3xWY~>4Xhp8flCB7%6Cu3LXkmDixqV)m<_QUCx#9w3$jNglC_Pu6%2IM}$(QB?^Mf zgKC#J4AzO?q@KVL$nSa3&CXgQg)kSeDzDQ+A}guKfoN(e< z|37uO4ZaIs$D1Ox06WBR+r&qR8y2?=S|~3xfMpBg&I!z5GG*9Yg7x7~-ru>Sx^Ykv zM*tZ2S_=rVt_v#ZKai9;Cb{PTA)!;D3~yVQ@#Spm-S*w?g@mX0HZ#g0^Zx4=xU}S2 zcwBsFK^mc&Tbu&jq9-fKG2ST5@xQ;Kd!hIxa86P1SQ?PI8Rvu`x17+xaWb=xsWqSy zO`Y2D)IcJZcQAJOdgnrz6%4jXqv9{F%`Zix*M{~~T>_5XM^&clh{>6{q7=^*3+rU; zf>(Aggr)<{^qTSzq|PVc_)_f9&NA~A+?0kVrI|)K;n${%t67<{ZDI7R)=M6bi*ix5 zs;|@U6vDwqzAGz*{WaZS5rEUDlfHWFfGq==>etx1T0OkgyIctO&bk@%m4>_|vCM0* zE4)n{nYu9NyyS%7#A&jj?;#^tHroc*J-K}}e6r`r8Qgv*t-Wmb)I|3v&t$G1%GjhP z^pM<1KZ$oBz4mh2T>pf>>|7`Zr9asms$fs?fmnNXf)J@b zu@{Kdwm&J34xD2>#c2LyMFP1<^icNFM!kuxEB)`yckhU14Aa)0UnqcOp!UBiu1~@*j3DB+ZHwdh(SOIV8{^RoKEKlQz7cOcSEwrO{GUM#W(Ee0`B& zW8(4{o^$+M{f>NAV+(KrE7pCEuJdq8ZRlMo9)iIl5NiDkF=`ojmkr71$N-qAkJ-DK$*)`!!|O>^f}^TU`O4Q# z&GCme4P9jF0k7#^$f}8OXRTpXD4h|G(>ILfBO7oOiMA%8WdkTHX+1#)i&n?B;X`(B z!6|u4JR&I52;gIG2<8Z2gWo38Vb!FWc}IKU#TKXGJq5Ll&3!a@ba%_*>FWttO#IXV zHL*mAYEGY?8TM|@mkwKn_enU2-B7Ez?7cKMb7V)=@Pf^%As9F+z;dpg#u>L8v#;F- zx6|`92{H26+L?%njEZ@U8>P2zM?=u790$I%XJ^3paiH-ixI3N+SwPf~-XMp(X9T5G z;ynW=0{7t3Zp0>{(9~JIB)x0`PlS)a`{x)Woar3UgZD+V>(|STrmZ%^1Glb^Zt5f> zWR~kN4geBtf|<#ekR+5^%NeWAhvWMY%`**(cH{I|<8+J_Hml~SPjtRMiIcHYz7r{k zY+wvVF)zUz%CQ58&76@)&|m`v{uf{5|1!@EY3^~GY zTVd4xO!Xw|RJ(WIk#tBLjZX|I8A}PGNAO10V>{AWrqd7kZWyDPIU3c_!KwswZI)q~;*e|+aBFHPsgO-h2#A6WPRGow?0m0h@ArKk&asY_p3nK?P%5zZ ze%3Sme)oOd*LB_ZFE)B-*ILMS3~JF5({$*25I>B*Q57P2XM2DDyvl|2zKR)`P!kY* zDwBUHv1m>84G@w|hFe0$V}4~8G^{rVtzchv27h)@d7<2h=eJU%QAKJ2w{u8uCjENR z>EF{Df=Cm|(xqvPuJFaXur=TLXk}&V_(FSU`k&F(vE(X;txOr04+ppcymHzG!Bx0a zr9cn{X~itIvebFgcqpT%K+xk&Av_2`%Orj;KDYEl#A_1y!3UyM0<#!dsD{7>=mHq4 z3!~3f@@zOe10pcr7M~&rJ4+YEWQor?fmPhGhdJu0M+k34a?)PLhRp8_U-%D|ca$2+ zW<^=cH@r<6>FsXe1crbhkzz))(XY84X@1^JXiLO0956iO3$f*yItf{i5*1`q;UOP#CUTD=f7qa)Bpv*$7bJi0nMks!ddfM^Qn z5vYAXj!qCWCN>j#2(r^ZUs@9-RPqXg0y6`AOoxDQ6dkzwBo?Fj;<17PbYj9+HlP9V z5N8gHnHxUwzLh(&w?s7Xm?WyQ3R^&T5CStXg*1aGh4gu*7>;Q#v^KUh7Hl+O>xu_f zFJyQC#|M*KaEK;OF()UUaiFApkCh_>+0~fw>`D#A`M=b-o%P-u?^j+(737FDYNOvG zb-{n}Uh!d}G_*STZa`ziY61)yflxw~#M}}~=Vwm1o*&@#wZ?B<-xxivc69xHS`r`l zmox8}IlX(gnID?IZu*y|S4V#{+SA<`4Te__pFTWv>XTEyI`!j&Zw!97`|ZI`5AN9i zVEOA_E#IcC?&c#1CY&6TX=xn)n@VEobn7A_#iFsv?}a z-!ZlNoBw%ytsI6W1g%=t8N-fKGC419dc``IYg}KMtiwP?gcTSxPT=dvds)i0tM6E= zpFB0WmLeoH`MgbPNFT3{WRkux^`MCj^a1{1x*R}b<_Y5`6^fQgjwXpWUp!swzP>%V z7J7%At%F#Zi^M?gX|>Vu3hl7pb7scbEVk>jOiL+AmlGHZBYw}-?|DeA{n0y2u7yS< zj+5g!%FRxcRRT!t6VNuT=;`o)X>`KI_0HMIs;BOQ>36p3Pra$uI`g#2wQvGZU1j$EDXUUWR{#vL zSeYpq-#EFJM{o-~CXj+Qcl4a93@w^ar&&%$ zhd0P1a6pa|GgVob^wPl7jo}B*sx=>W%H#Zr5En9Ps%w%G6r8jSfI+XTs3UJ=9O zkhGS@AZR3<62!|Ly!^|x+E+5dAzd2C52*nx1-1YuRU92f(V{!!z$5`-KlU;xiP13# zo#>uYUp2Wj-20?j?aPmvT#K@;EC5~AWvm%d&2*WtoNzvf#&ORjyqjR-ZA1yraEHPf zWHwb#`_?57pIpltHpNMq2+t@#SxGY)aMLkiSWR6ctdOb4kS;1M?0F0b>7PmKdE=EY ztaaab%;Z{x-gq!AcIsNDU6IYz9q1E&f5H=2LuPtf>kzuEi@UN5kRkZ_{$G5#)_B#a zlWURlD3GyI^M1>n*bcQB_g>J68LPOUG`+@8>VIJ#Uli@3dv0-~*WOpFed4Q=YnhCm zxg~m}B<%FQ$Kc4a6++tQz>xt}9?S-Spu&$T;#9MU+Kt8|ezaD*;6;;bu~H~qy%Y~+ z|8YI#C^!ElXgGxz^?DiBm<|woTa(JlYX$)Y1}xu7JP^pLCcAPIaG50 zTzVNYhYiH}tCaPQ_~umGMh3;iZ~lwMl=aQtQ%|e4Zt0A#C9Eo6fNJHo5TKs=FF)dMozbW>f&1ctCLt5no~?s@G065Ti93w@Nf-*4+d9e zn7x|-pwStqB`Z`Th>w*M4C{v-QEU9dh2#6u9V$2#^mRU#Ekkt#n&KYQ+iCT|@uWgC zF+HgOqyRvns+7dI#yhrZ?c2gi6nlt1k_qtfXRx60R(RYLMaC7zh|B+F$t(&F@ftIz zfE;O~27rjWQ#T)0Yb`!+e66(VZ4g;8KAQNzVU)u_t%~{z7}wsAsSZmZjJGoZ+>HHSS3$riHAZfLLFuI04fYlx5!^aM#LiRWS4P9DMIi&rBrS2`y zsnrktg~_$nDa&b7(;>&=;_NbUQFOJ5l{DUwb_T1~Ty2_+EUcM3H7945hi#v;T5G@S zE|Y7ia(o^y+crZ2kN~)L06Ks^Ey=N27laA>9xC4^z^ZT{D_pjB>OXy3tvfx5(Uw(l zI3StGTQ-PGYnj~$liSR!&(sKA-u9^CD`za0cCB{vPfo6tw7?Vu?eO|W4mAb~U#62lj}fu~viDHf%hcB}0;voI zi1fkOwO%SeF1%@Stu#TSD&UZm?etcUdd*K_D_)(># z20#P@g>dzUh%nrLYqeicBSnWR>ET=f~`V z^vd`zUUT|`HZ9Ve9yj)&NDrv&nBMzm-n-WM{aYs264z~13mVHH?DzE->Hu(L4eJQ@$M8dM%Xz)J1> z`pn_YCv*<${7d_@ou{=gXrI*X)vjypYwhm8sIglA%Jc<;-)TH=bawsH(b4?}*Us<# z?BEBQw@u$zKX~ShnZ5PXntQsxHoUd}v8k2L<)iluUpw8Me)QBY4jS_%kTs`{QcKgc3^8H{EEk4y`6eDH` zdo4~rbz|nwSW9Ru9@_L@DV`{T)b2P_c;2SoaNguPVk%ER?GfGP#?X;&n_Z-+rQ~u^ zB>f0Hg)k|$K+lP3MRowapn2|O-}+K4Zw3|wkV!=;AiWst5KLm8Q*x5AGEy6#rzMHp z05^FBq_5e|-M%@wA0=({6*8tm+rv48At!jsAb2eOYQiE$6nPh+H=UC>R83qt8*+R2 z`0~34#WN&o@h_yB*ykzQlBQ=MkI^k%!0`pDE$*ENP=r169YPFFz3ZIG{fI&7fCuLN zz6@g|ji}w&5r`o|w8c{Ncc_0%3{xa(oScJ{a&~k3>whx2j^=_K<>K?Cmwf3FHliaNzB?4}o1fkfa)2C@ncrCDO&d#8{=|D#J zvpyM-gCJ0k+c!YvTIZ13gP(NeZ__1?? zqhv46j*hw8LtdNOvj-p!X+^FQdAOMC(3y5&@S2@-Fhd(|!wRYA-Y}$A;LVTu_6ptTo^8;_^DOpC;&tAZQ0a4A!Dr5Xbbeo2;px z3R^`23bcn;aXFS6c6fWG*?Q#|NeCuI)JW$8#*E66`2z%(-~|#f`w-j=Wu@vRAaI{V z@xn`C9`5tC@^+vPW?2v_leJQd>4F6-Gs7b7+Ey;wz(?R0=4fFEma6S}kZ!$xuSwcB z??X?5YpDvEybZCEK)oxn0m}>B1}IH4q~edDmRSwTcE6Uk)Ai<4|G2y#eWp51lWr7k ze5HaXlTgO(syfX=@R;eBxei&7aRG9LF2o6fkh$F!t%#;wJ7Y3X>ZCF9 zj$nu>lTYkWuV;0wd%p)wu9KtNayp9cX|*MK${1vH@HyS&NqF7?gg7^N<6v?>f(zBt zZ%@N+ftd8P(q$E9U@%Eg%YZ3t{?>0wuX4oyh;#sc=lA|V#gs5m^Dh%aWj%_O zOcwfp5|NX+K|h2>LV>E@;H8Yz^SGPC``@d)j&}k4Blfr-xT{UXV9sMf%*X>Yoqs_} z&4KEgQX-SMS>n32$x8EpADvt$NA1#xVi{Es+U>#QN;mzg@Q-C883~~-#sDzS5fL*G z>lSO#{HV1uxeihW1+9Wn=2=_rM8fe=b)2UmkWMMiWxT5@Uc`YqC2YAgWBLYP{>AZi zfH&lxi=hc~YM%haJsE-9HV;aZtwmYXq+P)_Zd$b>NTLdZ+PY#w6h(6fku#Z26-?i? zm*M(sd2_#FI!(T%c&25ZD&w}?rW@y`+G)S4vcI$?#rc*=^>7C2LtKW$VNS1{cToVK z7B1@;;JZa7W|n}LiVIq9|Lh-)pG$hfrwMJSic|(^;)x?jxye*T4~#AtGj zaSpSbk*nPYeR*;nB)XUn_f+~6NR zGQJL&6E@J7^tIDit&+~vfjk0+SL>as$d=Pbqym>qfRUV)E(C zz(LAK$76`-%(EMVGw)ko2kga0F-EaBrOQ}noZ)h49t%P0VquX2=sSk%4-pNU&OJ3EB)5QHwE(}$P#4N3?ZLE>GQy7%ejbs+JapraVn!Y4wh ze?6O~rsN>XX`&V*{6OU#Xk)$To(41jA4wm?XOcC_oL&= zJJK|gA=PHah~I{gWObq1mutWJY|NT9pI>6-FpJ9YyboOah;33k3Ft(olFD3S>?Cb%gO_A!GR1J;poNKQZTEml)1Zj zQuhh_1FX7Pdb?jXxsGr`=gvSyKO;a@F4P4%PllMFG>Q03aZKRB$isJ+fj+W^Du~?=E|%p2%v=Mv zsTa?I1Q@ZLBNKNrLN2_6O3YSbMcrv1UVgA_Qua~VTp?^17%_mH)4o+*$w)S<-=p5d@v3L4tU%S`4 zSNAW6Pv~9NKfnKw;cfNP1_xsVW}62!Z<{&1e_d<$bZ@kK>Ur%~_r5vYGq|*UQvKli zrQMef4;p->`^avscK*y6oxM}nOy4;D>gkha_SUWouW)+~ApbOe&$I`-+ZM8RQCghV z)Im@nI7KEkX*Wklq2#-~Aqw>%b0HFL8#fgD#%Bxq`@oD&~tLwErlK@RKV)Ir2XRy9PLmr2pfCJG+*2|z-B?^2;xK^(4 z0MuNO#cj#Mk^Sy-xffJ9j-_JAn=!BP`ljZ1b;af=p0EoXT zQmToH6b%hr?$?CzI)Wy*p~_xa9dG*jYHd&DJ?jW10f;el2DzQPQc=JL&RC}W%9JSn z34*SprNI2q@d`BYo6otuJgMK|ozz&00szQ1#f}9|r$f^}c&SK8`ZABHo0cq7GFlyZ z(A9(GAm2{JwGzJACwVXL9+qc_02er zfOKGou%3ZTJ}~7Y&<1{_+|r5tJmVLXVzcvuJ0Ci^jx?q8AR;LwVKE~#i!mAMcPxfH zCiIwMq54HLdq`s-7!xz(LZfKswMUoN$=NkoBD5r1LYM+jeSHZv&1~umJhyTkR6(`4 zx{(wqMEDCfny)-{avf_t2Y!hc(x&(6gCvt&J+qb2|@~7CE%X$=5se zTi;T-4(=O+7~&K3M#_Tq0yKV8)n=#j@hJpgs0_Y>4BZ*YuQ-dKbBBkO*Fha=>X8c} za!EZ3k3k;dw9fP>G3E}a%e-=xOpv2BZ{{G{ZM<{f$qOgCitZ0%=o#i{L!MMRV7$me*m@&~u`l(L!X90Gd?@j4{+dD=LSWh=JQ$ zCS?I76}p#SNO!OsY(4*D<#n`_D4qoHyhp*NnB5~&^BN+OwAqkWygRQc5{B_mrUc?B z4Yl9so-)A+-Xvw)yeNu_IG2+peROw?t+A*iGORwwrl^gq$P6421QJ!RZSOSh@h_A6 zA$coW(bzH+R4*I~Xo@T7UglAg=Bzp4j~@+J8%hb&I`2J``e2v*GVBEXRxy4XZe)a7}J%5`?LJR z_=et3{vlYah2n?z*)fWXo!3nYmAFQ@J?-{bAIM*+W<++bXK2VSr!a@Z)BU5?1^cx| zNSw?JAW`EH)06u_po@ld{1ohdV0zy&c}i}GPZe?JW)!4Wr*$eW*sVpwA#Q8xp?_Om zhdT(lBAiHGISx0i9agmv6cZJS1-WMDc!M@CvNjcdK~c`F_8;|($#pzGD>iP15Ep-_ zf|+<5s!;Lk^ZQDw58pYo4>C5!4ER_9gxES^f)CU6h5vzh6f1%ir#d)f8Ee6!?q|Z? zYGg051y_=h4;Esie>Y(f;)I457DDQx7o6EnN(oh^2wP0&%lD6g zvRGkJJCz2#Bd;s3gL?2Za1A`EXo`r1I`X-NW!pnE6R0f$?S@J4wyYc^!N8BbegC7p z4%#sOJ^=?z_SK2kjE4>tW!}Je@pH(q&~YIe9Qlg*FI7WF(5`(mliVTfx3e(#UO`1?)JLLb>JIp6nCe+ zli1;|g?IurfWSf}nIKG{s`$i#0MX6%w@CoN)xphonp_8MC=TWr8u24@{vx8Om03{Z zgVQNUjm=BK(%WK;eaXGFM)g$x3;pss8PrCGvYzE-Aiz7pb!TXVA0g+2K~GF$tj{#t zNQbVk)Lou$ys5;QY^%{2Gm;y{k+Tb!ko8^08GtE4Nn}JMhzL+&$B9rtW^Bq%E$FYj zsk|Q?amZ0WM3GH4V5Q_w@_~IVO?%h_T)l7Tg{TqJvjek&kPu3}epz`PA>ElfnFVi- zSjNy>Jyx7{Hy_3FO}Y@`z<6w*uzw+}wfDu9g0tm}zw)p~WCRPL9 zMJ*!+N8=}S=TS1iUmpcE9pPquZTR7zoZL@w278=OR*225T7)eq%$^bj3a>B=P+*Pu zQWxMYkiW&5JW$!{@OK}=4{%(Kdw4K?Qf;YreoZyMZ?t-%HS% zZQd4kp?Of_n#S|$m(J|v9yt7e=KyZU1Eg+DO!1A(IzdIL!0DV@p3E=lm&%}eyH7Cy z$);O~g$WW;jIIpdU*d4-FC8(uh*fh0d%#9|Nc_`xC;U;=)nS0B?Ml1D;$Ru@r()#N z@a-k;&74u9L&`~Jp%jm@ImI={y4V)6V#^|c)-pVvssGqR(y|x6wmG`rM8HUk7W;t> z?}3~g1U(UhK|#RTgp9)Q=u1Vw_XF6BFdv!T#`xew<%Ods-<^J}z+yxpR(O7*VnVrP zpuqOK@q%f+4*N=2rN@g_jOWA`2B_iDdnVTj4Z$NC1}T4p^3JlXx7J?3p17I|gQCvC zuz`hY4=d?r>d)5f)cGae$oO_5m2x0MKWsB4dnD6hP_ef!yJg%q`U&lVRYX+hOl{S} z($>`7-#57*RSMi2$GYI8J%?_G;(&ZO{vaRmI$go8oK13;Sx`OgWQg3m%iRHM|`qES80p`kl@%uY-o=^Rm?V`TZS+kEPDm-t8i=3LPV1VExLbh@WaKID;340W+OG6oZ_MUzm4a$&<3 z@-O7d_9YW1UWk2lPGlE*C~}MJ&dd}pg3uLBCW+S26%|kZ9bSxhmFBJWjr!f+UOpF# zEp;$ubckh8R1n9Fkl=I#s7P(ILJHHW$O<4QSO|F&-dj z0__dLqz47Y@E84j2tJDP63e=|*8JEz%KL#;bB=e;5mZIwq$G)*p&8QCe3|}F zUS~-QA_2AeGU8PXYWr} zuEVG23;SdOkgpIEZ$^i3$Dqbp$}u3KzTR@-EB11AIu1Z1++2P6_o~-Xt1;ogIuH~& zfnu6f6k|s^=kjvpSmr`(HaRyoX=_;mS*>67oboy}#tm<-z+n_6Eq1(-G^%8Lfenj< zL*eHmAx7fUCCBCo0`cVaFaPE8I+^o{kzuzFVWm_7vmtiLSml@zrtD2jRfaiwDQHDY zAP~s%SZMFLcjY=-hRyzudo+kZB9$R>oU}{(Y$$&gC+1ar0BBs8k%uAA5lu_v~?mT^Wc|URcW6r=EjF|Kfcu8T5BN!by zp6nFcP&ztXt(MZrtUc~mgul9YLIE9c3fq5&AfHW_N9yU&6>6_(s zWMq{+Qio>}vl6`>Q4ysH37PXKm{5eT3RHsUC} zq4!E=&v2kZaaQzZXJ|Q7x%xc;CSXAP&x1c0mDiD1d=%`NZ|qwDL-q-0T1E#!=nnG> zNvx5K-r&ReiPn_4VgOa+ZoTq4>PWv!%e0_?hDB3`9mR_4>rn`R7D#_}g=#mw=x9w0 zUwDqS?Z&6d^<(LW4b>A2TVkP6PgaC02) zDfCxc$3D1xF85#(oP6ciygL;xlMphSy-5Edl#(Gzav&subv2O3bOxFNN@ufv_+gdn zq%eg^+5FQ~F2KsX1{tA>{WIvDo|{+)St>EE$V0j(7X^D->*7nx>*P=f=DTz}0Q+{h z4auwGzY-Z|(My5CnfpU=u(G74Ot9jBLxS|Mz_8d#bHqsc3;Y8W(jU|Dp;dexhQ-t#NhiFd{4@-kU0G-KKolqQsINPX@J z-qu)X%y5QFj8=3py#q4bR_*-mZM27tsdrUo5bpiXOu+5`?SVlEe2;7xbf=KpIiLeNH}6a_ zq4@OD$UZq*!t?TFE2&UIcBlNwt4yKjKWC=AkW@p#vRToh5E-H{DMf>`7pInq+Y;fJ zX+#`eY)5HRB@Kf5TPw|DK2W(3X*W|D&6rEinbo8qCCe$GV6&$NW;#yQa)T(myZNp5H=bEuNR)^G%rgZ# zD#qn70ybdd{ez@v54V8qXDfjv0=PqYU^ld>wLf%nd7;ds%SiwQ)j%#+fk+xS_&CDS zKaPg=rZdSBYhb%&pcqIP7ee!AO?Iqail0@>bofL4N@0|9YL!He6%-gTX|M~h9M7w_ zhdRnZFoNIqX8nh+w_`GuE3cdRS*FL@xo>Qf8!(6miLa#u?sH>`Lf8bw5Un)h16jxE zc;3mK#$#|?M;uguF=N0}7La8pooKs{V3|*z;l9`<%o0IDkG!}L8au}0rQW^9Gd^-5 zD*^-|2M;dmdzj9WRb>LZb8L z;tUjEaR5;edoTF=%7xJK>Rd4zgjeGNvzfzS6LU!TK(SQh++30|dPd2eDPk^Va@0!m z(D7uJ;;R`P$7U7PLeNx9Tg9AsxPc6pz}j<{1Z#L8saOZY7P{DRFcwzrbFVA!$OtLj z;6#0EQB~&Sp#Vf_!yYxiuzRIFl1oK2vH);nakb&XEzOPLOMc>!<&`{geu0CB4y3oh z9|YOVIn5Z3v{OgnM}X7oyh*}NY?&M$NzL6~8Xwe@XCs|6)UbBPJIDRcVGoreD=;fk zoRUct${C3Uk>w=Mw4Y`8lE&=b_P5JB(j;nuz*n%ZCd9%=M%Xjb$xXrm@i|FKuqynF zfDe@*kZ_mGuXlHydbXg)Aa z!9Whlt(nrPN`gI23nJNAAM$mMeIO}9ZU&Ih7q;6s99#(_CU@s{;QlB@Bn;m?NgF4N z3Kk(jN^VhwtM7((Df)MfV-OR5x^tf>^u{1j_Zj`mo= zHz?2HV07R5Z1?_Ou3U&0Aly%em8-qA)2n~eyqM-!r3j@ZJc5ttORz*h2r;{$&o@`w zue^8lLK$_DL+pSOSwm*Rr0d%eDvdGYYnFJK#T5JG1fVL78ZL@}QO0egb=9;g zxL(#nXu$O$!I93GkN&5|!)9}#bd3Xy=)f>%c0!Vzzt0?#bfXK~UI?FoB}?5!+G+Hc z-gsG>pFFO7-IzBDXh!bZlqxrNZ}=v^*`1O?2&Uj6Tfa#fiZ*Rv>LAqtB(TxAW;~id zca-OqjS#P4h9O-Vl-uNz;NXwAQIzgHA=%mR1T`a|N5ETbU3*^Tjv}9m4q3+Pw~WhT zeq_>dgApY;n}`e41r&vvs~9F49K?{e)_dakSdQWyWf&mepL&L#i4yXkbb+`*N+&Gg zN7GHCp!!#|4$IS0h!$R-3<)hRL^6}F>?quW7lTXC55-LJx)p~p zS|#R<2Jft7HX$a1SyU%hIEB67vk++odSjtX)RS0@?$9bIIHD3@4ZnGN)T*EnO)r_R zfH39RR%wbwnZSjL=eUWo!~lfl%1hHNWBgfBG)VCl(W-)B_$|UWoY5_{te%DNE}D1S=!?-~Dh`z|Is4 zvLfOLw(--<8m0}aPO-lAqbpm@LYGLixLoO-ru0(5r-_kU z9-aX+^pUZ7Q)UEQxCESB+nze%+RBA|N6r()4aO`nBkh$jQfBy(74Y}lTZi|uGpZ^oqB66NyLWGk7R|KP^FIK@rEsP zjbv)JG(Tu1*WGkfySyWnST+`{shcFO5>5VTmf?z_Q=?C8TkNj2#^s}sEf0U}2!4QrYTY~BFfjD# z=-MT<_Suc8_ED|R8}4#);|r}p^S#a8&7=398ZfhKczkO4sWYdJ7(H#~kO3B8aKYfj zL3{eswOjjF_Mg!|vi`o_O}$rlZtgw0aq(zxfdsTh5`^@hB>gUuh$yo%on*Xlv z|GV4Q{Qvqt9e8h=+(bi*N~fD@o{K|<;<$+nu1L-_6+)N|$=$b=3PHsyYfy23i@Djs z;$@W!#SW4S#wkU82*2PJiXm+2Bt^+U14_}Go`&c6Z|%yoPi=0Fj(JMuLgp3-9HO>Q zPH?wA372SujM21`Or!;1WO_V4rbgNlEhq`;=D5D@O z@GvJ&32`8^MVk4jae{}px6jr#hSTHKo(rYvQeQ<}jG{P4xV|Kex@fIgBz{<4nEk!% z2v{OZ)Wvv#l?}t*v&u({T{lCJtsZzu@ld>SwIptmzX0A8dg2$9;;B<`k!c`U7M|SI zsn4BMUMMP@1jd8}0?@xfNj*GzJRmpxZNa~(l)*pM9#p1MCatPuxEH4m{bJ=pvRD{Q zAV_g#Z$&}P6u7tmQ`P}fC^sRLnGj(t3-KqCJbaObZ2}atK4N_-gVF_w zDI7Ten(Ls9ae!N`bH*b`eKj(OXst>FW|XKfj^dK%m!gktk5}8$x4_~Zz%c@!`o*j| zZ4Xi}u(P`OO9XY|A;rJ+_zu-qFbkIz-iqj?1}W6Q1*n@YKG zaHNAD{~>rT5VXt|qI;(7$&>;zP-JSh_U7gop%fRg719yr@A>J`1+r|WexqsBz-nI4 zW#!~}6bqB10q{TsVdZw(bK}}87eaC%Tp-09{i0mY{ zAYHFqflGtaD=S;Erw2w0x84_IaPATPKxV99LyX9_HfGeQCeq5xWM$}3g7J{`ba#bgLx zOu<-mv#%WtAEM(*no?dfY7OiI6na7HTK(E5iv@ujz*1&%|}; zyrJZ7tPfv0KAOdoWfHuLpr4cc#cZJ|N7!Q?3%^R z#_{*8+>te!jyeSss9>jyr(|h`A-Di`i?YHR)4C8!#HYs*6Xgmu^-lM$cc@&5U>HS| zk1*{NsTxR&CZgnY53K_!M!gn1sb(e#H?FwE5w76n_WE??LScEtNQ}E}kuDQs==^!M zT*@)-HC?8K(7;81MvgTCRIpUAcm`M&M z5;YYkz6537``DiEUNtVfe127C@J{RutXC>^0YI%{Bb!ta!vqdTeOq+I)7&+aPTU8!oRJ7IU+@>k!kbnGv;mQfL>Lt%!yUbW|71t8!+Dht@-Y=$49di zcZ6!mJI;9GP!PtNss6nkTP~f0sn}dDKa3|ADJ5oRycr_1_1y6^{9Gs`noz4y7K7uu z(-jy4Z_0jLvX%m-fH0J?5PC-uclmEn=JSnzNrQ0Ygj|RjK4)EEx6ly?9#O0)wZz!W zV^H(O6)E*7^NFg$1*RE-fHroWTD^{lz&{6}0%Zoq#E^`+k0s7T5)pyF3dGSc zp@tEyHBK!*a(q}w?nfO>l121c0(Oat3n+v0;2-nk>_BTW1NdMDO`n;KBrwHazOvcA z;fl&PGovS6Bnk$Y6+a#uZd%0TdaeLz2+eHmNpZTP>@hG02dttI*1kMGmnV0mqW39t zpfW#$L`##>&J}sxC-aP&j|j*-3GM@pA(yD@kPCq{$BjqW=R#J6?4aU@no-6%mkLoG z50Roz$V)%CrT|lMVw%=NLwrhC7vo|7hbln?wNZ?VHQ_+1Wm$s}#Q`l4WoD-MLqb8^ zxrX$kQF3seQ5G2Gh1K3CudlqLH2aZ?(aaJXo))1_SVcTUm-|gY^$^;7ftHS&|5SiN}kBR~%nn zh`KF==wKu&5Dim_2=NRSfJDr=_6738J_&d)8X7UYe5VS9*})OdQG9)Bf0|`0#(Jlf zQYmBzhju$aFau~}I)}{_V9i{o6ILiI0NTELGDeVO% zcHE`v?KG76MCe9e&d(8ceOwlkjm^RP4y|0sp9dZx7cG9)jm&O{66lkDe!`}o5k;Tr z!XpxkVggYQOG@*LgSWn~ybxg?Po{KHv}n-vsSGR$M%Qh_#p=2-x7la zh;;9Ds}Y%srRT(~_!EG;$hkHGoE0X{*Hev&wE{|pHVak5wb}B~atM=oJQyGh9j0F- z@WWw0jIYoDR(WQx3i4&y@j1nE#EmA%#pS_02K)dQ*E$t8je`q% zomBU!>^m1uf4YBU@22`({aKxpdav$1x_x!d1KfWa;LNU8ul8Ce0-oJGs_})!C5^{5 zhBKGfZma)cr`x?s^?(1)&66_-&lnvxeC67^G4Y$<_pWzz9nwYs(@I? zF%(@%!TQqMp@h?iXCq*+DABefRonkgKVW<~PA=r2nheDPL=do?GvcCz&n_pv2q<7B z8Fd+7s2en6NiZm)0(RfPh?`$i-jRH(I)Nk;DnU=^ROIy;jVDQ$AxTZdB&iu(D-8(8 zg*cuzl)0G)y{mE|Tfp}tBe{!^O__G(yJrfnGTtvH_=)a-3alUhu0AN%U{PxL(KnYD z!W9vsc+pe}iM_7r>>kTmJTkZk4;GAz>5AVC=^%YXFV?g^yE^s9<5QpVj_6&0nI+6m z4L#Di{G&HZVQ{<>kGqP@#n_yI1RzF5WwHTi26^v$LFJB2q_tIw7JNV?=h0Z8X>}rY zLjg9rAx;6z-WF9&EK3O&*V%gi%5nGZeqo!>N=Q}H+PzkHnsnH2a4$d-gNN2C7vi{s2hwcgrsZR|v7vSPty!CFIKPMBiZb&FO^69&E`5VM?CrP3d^Ot{rt8COf* zHNruEFXxqJM2wnYld=Ln0iZQ_kbp%p^nwI}oVJ0R@D?*(ln-XJanXG$ca+ITIV%wz zf}BWik2ga9P+Zfz{X#6IJPB}X7Wm9M4~M9s<*ARlUVA`c<}g}KW&PP_Fh^J9Wu|B6OR-O(W060g}(^sb8@YPUo zAsVoG{I%A)1m&v^5C2-_jv{Vn8k5>wd{*|SM@&ykCcKCsVuu2pPLV_aF0m(o2N`KI zH{1MtWgTtc!ENdEC#Nqb^hySNB5X+dct%w-3zz7k4)Wxgc@o7*f1ymXPT@~f!iq=&aJu38tZ$sWSy=vs zGDEeSW(Uu25zq&>H(FO7S$QsMb|y$}UZzK?~IvoIq8i#)Hq3Cj^fA@;@x&wvT2lLaPA!3SAiXy5dv%7qkO z`Mx4P-2&O}g(0QH3ArE7t%y?%T2SVo*>Q27hM=$l<`>#m-05}~60fZRY=C|eeI(r5 zM#b0!)C2TG`o`3OA_%{0KyT<>erDgPHsO=zzWx+bfPQSE*GPb+uC!f8M2s7NcePHDqQcnj8zQ6w^ond%AXh?yP;v0y`V z#JLWi zT8({p?erjoOoU`12w*(eLPW3V9Q~I)vGQoKae4#5HVJ04Hr`wuK}cCRnl0_iD5W zSAXxEf2!P2MulRJjd}sGd|%5v1NJc${C45&k(L$~{@1J2U5$33hKq&UTa6peDKEs< zn##_hy2yZHlqbInkSTIy-gGABN!(ifl-eBl0kX2Cl}DeOIesjXcrq6Pti42;p5!KI zsHpWiKyZlFVk))tNFT8p6!@ZWB*BER^_}i3D(^a0P3^6a5SoxLEV+g?QQIOBF%yzf z$lGQjxcfz!Lf=*ihI@0n_K9(SOYR7vph8TLfW-wJPlKQY;0p;0)g3dMu&v=gtcmSw zZz@DqmueT?qwnFKw-uObt)v?mn`BH1MZ~rZv#TXZ+LiiwuYxHu1BhX^dFSQI9mPHz+W``qy2&cT z0r`d1|~LkQEvloO%X zHaizRs`6-#1d?4XrcAnI=c4$>ghY|D0L=iAv%x=%d=8Q=rlIqU5!xtS(|=b5HSnb} zm;s7c3|hfjr~EPG7?#lxFTj#WG7!{xv}&4UPjr>ClK1A4MScLC`X~O)V0fFpfEU+> zdurDYpD>;ZP=8~l0+<2t(o6;z?dxCH{mcIOGkg0F$#j7FU3;f@A356Htz|Mm=kVH# z+c&l^Y(J*mZ@ss5PHV3D#pdgpKiRxP{j1Zx#)s3CL=XvKu6m~PV8mAUpr z&73Qf8Mxxh^7iPfU!7dXU>mKACA3Q2PfCT1Y{rrxf2PI>WSx$aVtZ$*e)`g+|(v1AD-YiL{e*dB{(RvcUDKA8xI8W zy)2EgSQ*QGJ8-v{paibTT0CYtFjjkaIH$ZHy)8%sKfy=g zIreop8hIWvM?oQ>q6U|JLYPPrR>paiaJWK#q5l54%5~5#dhOuwjP;Te{N-KI?Qr$9 zUtfXj5rsFE92Ww#>|kk5?%C0W+;ZdnFD$Q<217xL zOGwH9u`y0~hjd4)u|#XZgUJfJQuzp%0A3NVAj&)^G71JUDCp)V8LAmc8K^E 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 Date: Sat, 4 Apr 2026 10:48:42 +0100 Subject: [PATCH 18/21] feat(pathfinder): add pathfinding example and update dependencies --- Cargo.lock | 5 +---- Cargo.toml | 5 +++++ crates/pathfinder/Cargo.toml | 1 - crates/pathfinder/src/fetcher.rs | 36 +++++++++++++++++++++++--------- examples/pathfinder/main.rs | 23 ++++++++++++++++++++ 5 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 examples/pathfinder/main.rs diff --git a/Cargo.lock b/Cargo.lock index 5ce80744..28ea17b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1031,7 +1031,6 @@ dependencies = [ [[package]] name = "dojo-introspect" version = "0.1.0" -source = "git+https://github.com/dojoengine/dojo-introspect?rev=aadc3c9#aadc3c980706596a4a083413813a0a3ab01fded7" dependencies = [ "async-trait", "introspect-rust-macros", @@ -2012,7 +2011,6 @@ dependencies = [ [[package]] name = "introspect-events" version = "0.1.2" -source = "git+https://github.com/cartridge-gg/introspect?rev=34e93c1#34e93c10c867c53c622cce03abb6431c9dae0ef5" dependencies = [ "cainome-cairo-serde", "introspect-types", @@ -2024,7 +2022,6 @@ dependencies = [ [[package]] name = "introspect-rust-macros" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/introspect?rev=34e93c1#34e93c10c867c53c622cce03abb6431c9dae0ef5" dependencies = [ "paste", "proc-macro2", @@ -2036,7 +2033,6 @@ dependencies = [ [[package]] name = "introspect-types" version = "0.1.2" -source = "git+https://github.com/cartridge-gg/introspect?rev=34e93c1#34e93c10c867c53c622cce03abb6431c9dae0ef5" dependencies = [ "blake3", "convert_case", @@ -4874,6 +4870,7 @@ dependencies = [ "torii-introspect", "torii-introspect-postgres-sink", "torii-log-sink", + "torii-pathfinder", "torii-sql-sink", "torii-test-utils", "tower 0.5.3", diff --git a/Cargo.toml b/Cargo.toml index 7043f6e0..4c14aeb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -185,6 +185,10 @@ path = "examples/introspect/simple.rs" name = "introspect_restart" path = "examples/introspect/restart.rs" +[[example]] +name = "pathfinder" +path = "examples/pathfinder/main.rs" + [dependencies] anyhow.workspace = true async-trait.workspace = true @@ -245,6 +249,7 @@ torii-introspect.workspace = true torii-common.workspace = true torii-introspect-postgres-sink.workspace = true torii-test-utils.workspace = true +torii-pathfinder.workspace = true # Example dependencies diff --git a/crates/pathfinder/Cargo.toml b/crates/pathfinder/Cargo.toml index 92bad707..35a1306b 100644 --- a/crates/pathfinder/Cargo.toml +++ b/crates/pathfinder/Cargo.toml @@ -23,5 +23,4 @@ anyhow = { workspace = true, optional = true } workspace = true [features] -default = ["etl"] etl = ["torii", "async-trait", "anyhow", "torii-starknet/starknet"] diff --git a/crates/pathfinder/src/fetcher.rs b/crates/pathfinder/src/fetcher.rs index 8f64f919..2866aa0a 100644 --- a/crates/pathfinder/src/fetcher.rs +++ b/crates/pathfinder/src/fetcher.rs @@ -104,10 +104,18 @@ impl EventFetcher for Connection { for row in self.get_block_events_rows(from_block, to_block)? { let block: BlockEvents = row.try_into()?; - let block_hash = hash_rows - .next() - .map(|r| r.hash) - .ok_or_else(|| PFError::block_hash_missing(block.block_number))?; + let block_hash = loop { + match hash_rows.next() { + Some(hash_row) => { + if hash_row.number == block.block_number { + break hash_row.hash; + } else if hash_row.number > block.block_number { + return Err(PFError::block_hash_missing(block.block_number)); + } + } + None => return Err(PFError::block_hash_missing(block.block_number)), + } + }; for transaction in block.transactions { let transaction_hash = tx_hashes .next() @@ -144,12 +152,20 @@ impl EventFetcher for Connection { for row in self.get_block_events_rows(from_block, to_block)? { let block = BlockEvents::try_from(row)?; - let ctx = ctx_iter - .next() - .ok_or_else(|| PFError::block_context_missing(block.block_number))?; - if ctx.number != block.block_number { - return Err(PFError::block_context_missing(block.block_number)); - } + let ctx = loop { + match ctx_iter.next() { + Some(ctx) => { + if ctx.number == block.block_number { + break ctx; + } else if ctx.number > block.block_number { + return Err(PFError::block_context_missing(block.block_number)); + } else { + contexts.push(ctx.into()); + } + } + None => return Err(PFError::block_context_missing(block.block_number)), + } + }; for transaction in block.transactions { let transaction_hash = tx_hashes .next() diff --git a/examples/pathfinder/main.rs b/examples/pathfinder/main.rs new file mode 100644 index 00000000..57bf5370 --- /dev/null +++ b/examples/pathfinder/main.rs @@ -0,0 +1,23 @@ +use torii_pathfinder::{connect, EventFetcher}; + +const DB_PATH: &str = "/mnt/store/mainnet.sqlite"; + +const BATCH_SIZE: u64 = 10000; + +fn main() { + let conn = connect(DB_PATH).unwrap(); + let mut current_block = 6000000; + for _ in 0..100 { + let (blocks, events) = conn + .get_emitted_events_with_context(current_block, current_block + BATCH_SIZE - 1) + .expect("failed to fetch events with context"); + println!( + "Fetched {} blocks and {} events for blocks {} to {}", + blocks.len(), + events.len(), + current_block, + current_block + BATCH_SIZE - 1 + ); + current_block += BATCH_SIZE; + } +} From 958377f31110cfd96c1a2fd54c8eff47d0e25c33 Mon Sep 17 00:00:00 2001 From: Bengineer Date: Sat, 4 Apr 2026 11:02:57 +0100 Subject: [PATCH 19/21] refactor(fetcher): simplify block context retrieval logic in EventFetcher implementation --- crates/pathfinder/src/fetcher.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/crates/pathfinder/src/fetcher.rs b/crates/pathfinder/src/fetcher.rs index 2866aa0a..e3aebabf 100644 --- a/crates/pathfinder/src/fetcher.rs +++ b/crates/pathfinder/src/fetcher.rs @@ -154,15 +154,13 @@ impl EventFetcher for Connection { let block = BlockEvents::try_from(row)?; let ctx = loop { match ctx_iter.next() { - Some(ctx) => { - if ctx.number == block.block_number { - break ctx; - } else if ctx.number > block.block_number { - return Err(PFError::block_context_missing(block.block_number)); - } else { - contexts.push(ctx.into()); + Some(ctx) => match ctx.number.cmp(&block.block_number) { + std::cmp::Ordering::Equal => break ctx, + std::cmp::Ordering::Less => contexts.push(ctx.into()), + std::cmp::Ordering::Greater => { + return Err(PFError::block_context_missing(block.block_number)) } - } + }, None => return Err(PFError::block_context_missing(block.block_number)), } }; From 0737803abbe4ca93b31e52fc6ce0c6f31a53dda2 Mon Sep 17 00:00:00 2001 From: Bengineer Date: Sat, 4 Apr 2026 11:30:58 +0100 Subject: [PATCH 20/21] refactor: clean up error handling and improve code readability across multiple files --- bins/torii-arcade/src/main.rs | 2 +- crates/dojo/src/decoder.rs | 2 +- crates/dojo/src/event.rs | 3 --- crates/introspect-sql-sink/src/postgres/query.rs | 1 + crates/introspect-sql-sink/src/table.rs | 5 +++-- crates/introspect-sql-sink/src/tables.rs | 3 ++- crates/torii-controllers-sink/src/lib.rs | 3 +++ crates/torii-ecs-sink/src/grpc_service.rs | 15 +++++++-------- 8 files changed, 18 insertions(+), 16 deletions(-) diff --git a/bins/torii-arcade/src/main.rs b/bins/torii-arcade/src/main.rs index 417b5529..c263a6fb 100644 --- a/bins/torii-arcade/src/main.rs +++ b/bins/torii-arcade/src/main.rs @@ -386,7 +386,7 @@ async fn run_indexer(config: Config) -> Result<()> { &erc721_addresses, &erc1155_addresses, &config, - ); + )?; let conn_options = DbConnectionOptions::from_str(&engine_database_url).map_err(anyhow::Error::msg)?; let max_connections = match config.max_db_connections { diff --git a/crates/dojo/src/decoder.rs b/crates/dojo/src/decoder.rs index af140dbd..4db510ae 100644 --- a/crates/dojo/src/decoder.rs +++ b/crates/dojo/src/decoder.rs @@ -191,7 +191,7 @@ where self.tables.write()?.insert(id, table); Ok(CreateTable::from_schema( full_table.into(), - self.append_only.contains(&(owner.clone(), id)), + self.append_only.contains(&(*owner, id)), )) } diff --git a/crates/dojo/src/event.rs b/crates/dojo/src/event.rs index 3ae7b61b..a3034ccf 100644 --- a/crates/dojo/src/event.rs +++ b/crates/dojo/src/event.rs @@ -35,7 +35,6 @@ where raw, ) .await - .map(Into::into) } } @@ -55,7 +54,6 @@ where decoder .register_table(&raw.from_address, &self.namespace, &self.name, schema, raw) .await - .map(Into::into) } } @@ -75,7 +73,6 @@ where decoder .register_table(&raw.from_address, &self.namespace, &self.name, schema, raw) .await - .map(Into::into) } } diff --git a/crates/introspect-sql-sink/src/postgres/query.rs b/crates/introspect-sql-sink/src/postgres/query.rs index bef6ddbb..9a1adc1b 100644 --- a/crates/introspect-sql-sink/src/postgres/query.rs +++ b/crates/introspect-sql-sink/src/postgres/query.rs @@ -641,6 +641,7 @@ where Ok(PgQuery::new(INSERT_COLUMN_QUERY, args)) } +#[allow(clippy::too_many_arguments)] pub fn insert_table_query( schema: &str, id: &Felt, diff --git a/crates/introspect-sql-sink/src/table.rs b/crates/introspect-sql-sink/src/table.rs index 0b5ad632..7d9242ee 100644 --- a/crates/introspect-sql-sink/src/table.rs +++ b/crates/introspect-sql-sink/src/table.rs @@ -76,7 +76,7 @@ impl From<(u128, DeadField)> for DeadFieldDef { impl Table { pub fn column(&self, id: &Felt) -> Result<&ColumnInfo, ColumnNotFoundError> { - self.columns.get(id).ok_or_else(|| ColumnNotFoundError(*id)) + self.columns.get(id).ok_or(ColumnNotFoundError(*id)) } pub fn namespace(&self) -> Rc { @@ -104,6 +104,7 @@ impl Table { self.columns.iter().collect() } + #[allow(clippy::too_many_arguments)] pub fn new( namespace: String, id: Felt, @@ -120,7 +121,7 @@ impl Table { owner, name, primary: primary.into(), - columns: columns.into_iter().cloned().map_into().collect(), + columns: columns.iter().cloned().map_into().collect(), dead: dead.unwrap_or_default().into_iter().collect(), append_only, alive: true, diff --git a/crates/introspect-sql-sink/src/tables.rs b/crates/introspect-sql-sink/src/tables.rs index 2ce18e80..95693cdb 100644 --- a/crates/introspect-sql-sink/src/tables.rs +++ b/crates/introspect-sql-sink/src/tables.rs @@ -22,6 +22,7 @@ impl Deref for Tables { } } +#[allow(clippy::too_many_arguments)] impl Tables { pub fn create_table( &self, @@ -141,7 +142,7 @@ impl Tables { return Ok(()); } DB::insert_record_queries( - &table, + table, &event.columns, &event.records, from_address, diff --git a/crates/torii-controllers-sink/src/lib.rs b/crates/torii-controllers-sink/src/lib.rs index 3a2d6213..f576c90d 100644 --- a/crates/torii-controllers-sink/src/lib.rs +++ b/crates/torii-controllers-sink/src/lib.rs @@ -25,6 +25,9 @@ pub const CONTROLLERS_STATE_TABLE: &str = "torii_controller_sync_state"; const MAX_RETRIES: u32 = 3; const INITIAL_BACKOFF: Duration = Duration::from_secs(2); const CONTROLLERS_TYPE: TypeId = TypeId::new("controllers.sync"); +const CONTROLLER_PROCESSING_BATCH_SIZE: usize = 10_000; +const SQLITE_CONTROLLER_UPSERT_BATCH_SIZE: usize = 199; +const POSTGRES_CONTROLLER_UPSERT_BATCH_SIZE: usize = 10_000; #[derive(Debug, Clone, Deserialize)] struct ControllerAccount { username: String, diff --git a/crates/torii-ecs-sink/src/grpc_service.rs b/crates/torii-ecs-sink/src/grpc_service.rs index 29d70475..64060a60 100644 --- a/crates/torii-ecs-sink/src/grpc_service.rs +++ b/crates/torii-ecs-sink/src/grpc_service.rs @@ -889,6 +889,8 @@ impl EcsService { ] { if let Some(url) = url { let options = SqliteConnectOptions::from_str(url)?; + #[allow(clippy::match_bool)] + #[allow(clippy::single_match_else)] match options.is_in_memory() { true => tracing::info!(schema, "Attaching in-memory ERC database"), false => { @@ -899,9 +901,9 @@ impl EcsService { path = %path.display(), file_exists, "Attaching ERC database" - ) + ); } - }; + } attach_sqlite_database(&mut conn, schema, &options).await?; match sqlx::query(sqlite_master_preview_sql(schema)) .fetch_all(&mut *conn) @@ -4929,7 +4931,9 @@ async fn attach_sqlite_database( if let Some(parent) = path.parent() { fs::create_dir_all(parent)?; } - fs::OpenOptions::new().create(true).write(true).open(path)?; + if !path.exists() { + fs::File::create(path)?; + } // sqlite-dynamic-ok: ATTACH requires the database path and schema identifier in SQL text. let path = path.to_string_lossy().replace('\'', "''"); sqlx::query(&format!("ATTACH DATABASE '{path}' AS {schema}")) @@ -4938,11 +4942,6 @@ async fn attach_sqlite_database( Ok(()) } -fn is_sqlite_memory_url(url: &str) -> bool { - matches!(url, ":memory:" | "sqlite::memory:") - || (url.starts_with("sqlite:file:") && url.contains("mode=memory")) -} - fn sqlite_master_preview_sql(schema: &str) -> &'static str { match schema { "erc20" => "SELECT name FROM erc20.sqlite_master WHERE type='table' LIMIT 5", From 8b1f737990459c3fbd15a369e927b021420aff2c Mon Sep 17 00:00:00 2001 From: Bengineer Date: Tue, 7 Apr 2026 09:41:51 +0100 Subject: [PATCH 21/21] refactor(storage): generalize Erc20Storage to accept a backend type refactor(decoder): improve error handling in event data decoding --- crates/dojo/src/decoder.rs | 10 +++++++--- crates/torii-erc20/src/storage.rs | 14 ++------------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/crates/dojo/src/decoder.rs b/crates/dojo/src/decoder.rs index 4db510ae..9afb1627 100644 --- a/crates/dojo/src/decoder.rs +++ b/crates/dojo/src/decoder.rs @@ -341,10 +341,14 @@ where .err_into(); } - self.decode_event_data(event, selector, keys, &event.data) + match self + .decode_event_data(event, selector, keys, &event.data) .await - .map(|msg| vec![msg.to_body(event).into()]) - .err_into() + { + Ok(msg) => Ok(vec![msg.to_envelope(event)]), + Err(DojoToriiError::UnknownDojoEventSelector(_)) => Ok(Vec::new()), + Err(e) => Err(e.into()), + } } } diff --git a/crates/torii-erc20/src/storage.rs b/crates/torii-erc20/src/storage.rs index 82b0296e..fa8fac88 100644 --- a/crates/torii-erc20/src/storage.rs +++ b/crates/torii-erc20/src/storage.rs @@ -173,18 +173,8 @@ pub enum TransferDirection { } /// Storage for ERC20 transfers and approvals -pub struct Erc20Storage { - backend: StorageBackend, - conn: Arc>, - balance_cache: Arc>, - pg_conns: Option>>>, - pg_rr: AtomicUsize, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum StorageBackend { - Sqlite, - Postgres, +pub struct Erc20Storage { + backend: Backend, } /// Transfer data for batch insertion