diff --git a/crates/torii/core/src/processors/store_set_record.rs b/crates/torii/core/src/processors/store_set_record.rs index 38e8e67415..fa1351b156 100644 --- a/crates/torii/core/src/processors/store_set_record.rs +++ b/crates/torii/core/src/processors/store_set_record.rs @@ -8,7 +8,7 @@ use tracing::info; use super::EventProcessor; use crate::processors::{ENTITY_ID_INDEX, MODEL_INDEX, NUM_KEYS_INDEX}; -use crate::sql::utils::felts_sql_string; +use crate::sql::utils::felts_to_sql_string; use crate::sql::Sql; pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_set_record"; @@ -61,7 +61,7 @@ where let keys_end: usize = keys_start + event.data[NUM_KEYS_INDEX].to_usize().context("invalid usize")?; let keys = event.data[keys_start..keys_end].to_vec(); - let keys_str = felts_sql_string(&keys); + let keys_str = felts_to_sql_string(&keys); // keys_end is already the length of the values array. diff --git a/crates/torii/core/src/sql/erc.rs b/crates/torii/core/src/sql/erc.rs index de26b2300d..507e629b81 100644 --- a/crates/torii/core/src/sql/erc.rs +++ b/crates/torii/core/src/sql/erc.rs @@ -1,29 +1,29 @@ +use std::ops::{Add, Sub}; + use anyhow::Result; -use cainome::cairo_serde::ByteArray; -use cainome::cairo_serde::CairoSerde; -use starknet::core::types::{BlockId, BlockTag, FunctionCall, U256}; +use cainome::cairo_serde::{ByteArray, CairoSerde}; +use starknet::core::types::{BlockId, BlockTag, Felt, FunctionCall, U256}; use starknet::core::utils::{get_selector_from_name, parse_cairo_short_string}; -use starknet::{core::types::Felt, providers::Provider}; -use std::ops::{Add, Sub}; +use starknet::providers::Provider; use super::query_queue::{Argument, QueryQueue, QueryType}; use super::utils::{sql_string_to_u256, u256_to_sql_string}; +use super::{Sql, FELT_DELIMITER}; +use crate::sql::utils::{felt_and_u256_to_sql_string, felt_to_sql_string, felts_to_sql_string}; use crate::utils::utc_dt_string_from_timestamp; -use super::Sql; - impl Sql { pub async fn handle_erc20_transfer( &mut self, contract_address: Felt, - from: Felt, - to: Felt, + from_address: Felt, + to_address: Felt, amount: U256, provider: &P, block_timestamp: u64, ) -> Result<()> { // unique token identifier in DB - let token_id = format!("{:#x}", contract_address); + let token_id = felt_to_sql_string(&contract_address); let token_exists: bool = sqlx::query_scalar("SELECT EXISTS(SELECT 1 FROM tokens WHERE id = ?)") @@ -43,8 +43,8 @@ impl Sql { register_erc_transfer_event( contract_address, - from, - to, + from_address, + to_address, amount, &token_id, block_timestamp, @@ -63,9 +63,9 @@ impl Sql { "SELECT account_address, balance FROM balances WHERE contract_address = ? AND \ account_address IN (?, ?)", ) - .bind(format!("{:#x}", contract_address)) - .bind(format!("{:#x}", from)) - .bind(format!("{:#x}", to)); + .bind(felt_to_sql_string(&contract_address)) + .bind(felt_to_sql_string(&from_address)) + .bind(felt_to_sql_string(&to_address)); // (address, balance) let balances: Vec<(String, String)> = query.fetch_all(&self.pool).await?; @@ -75,22 +75,23 @@ impl Sql { let from_balance = balances .iter() - .find(|(address, _)| address == &format!("{:#x}", from)) + .find(|(address, _)| address == &felt_to_sql_string(&from_address)) .map(|(_, balance)| balance.clone()) - .unwrap_or_else(|| format!("{:#64x}", crypto_bigint::U256::ZERO)); + .unwrap_or_else(|| u256_to_sql_string(&U256::from(0u8))); let to_balance = balances .iter() - .find(|(address, _)| address == &format!("{:#x}", to)) + .find(|(address, _)| address == &felt_to_sql_string(&to_address)) .map(|(_, balance)| balance.clone()) - .unwrap_or_else(|| format!("{:#64x}", crypto_bigint::U256::ZERO)); + .unwrap_or_else(|| u256_to_sql_string(&U256::from(0u8))); let from_balance = sql_string_to_u256(&from_balance); let to_balance = sql_string_to_u256(&to_balance); let new_from_balance = - if from != Felt::ZERO { from_balance.sub(amount) } else { from_balance }; - let new_to_balance = if to != Felt::ZERO { to_balance.add(amount) } else { to_balance }; + if from_address != Felt::ZERO { from_balance.sub(amount) } else { from_balance }; + let new_to_balance = + if to_address != Felt::ZERO { to_balance.add(amount) } else { to_balance }; let update_query = " INSERT INTO balances (id, balance, account_address, contract_address, token_id) @@ -98,13 +99,13 @@ impl Sql { ON CONFLICT (id) DO UPDATE SET balance = excluded.balance"; - if from != Felt::ZERO { + if from_address != Felt::ZERO { self.query_queue.enqueue( update_query, vec![ - Argument::String(format!("{:#x}:{:#x}", from, contract_address)), + Argument::String(felts_to_sql_string(&[from_address, contract_address])), Argument::String(u256_to_sql_string(&new_from_balance)), - Argument::FieldElement(from), + Argument::FieldElement(from_address), Argument::FieldElement(contract_address), Argument::String(token_id.clone()), ], @@ -112,13 +113,13 @@ impl Sql { ); } - if to != Felt::ZERO { + if to_address != Felt::ZERO { self.query_queue.enqueue( update_query, vec![ - Argument::String(format!("{:#x}:{:#x}", to, contract_address)), + Argument::String(felts_to_sql_string(&[to_address, contract_address])), Argument::String(u256_to_sql_string(&new_to_balance)), - Argument::FieldElement(to), + Argument::FieldElement(to_address), Argument::FieldElement(contract_address), Argument::String(token_id.clone()), ], @@ -134,13 +135,13 @@ impl Sql { pub async fn handle_erc721_transfer( &mut self, contract_address: Felt, - from: Felt, - to: Felt, + from_address: Felt, + to_address: Felt, token_id: U256, provider: &P, block_timestamp: u64, ) -> Result<()> { - let token_id = format!("{:#x}:{}", contract_address, u256_to_sql_string(&token_id)); + let token_id = felt_and_u256_to_sql_string(&contract_address, &token_id); let token_exists: bool = sqlx::query_scalar("SELECT EXISTS(SELECT 1 FROM tokens WHERE id = ?)") .bind(token_id.clone()) @@ -159,8 +160,8 @@ impl Sql { register_erc_transfer_event( contract_address, - from, - to, + from_address, + to_address, U256::from(1u8), &token_id, block_timestamp, @@ -175,7 +176,7 @@ impl Sql { ON CONFLICT (id) DO UPDATE SET balance = excluded.balance"; - if from != Felt::ZERO { + if from_address != Felt::ZERO { self.query_queue.enqueue( update_query, vec![ @@ -193,7 +194,7 @@ impl Sql { ); } - if to != Felt::ZERO { + if to_address != Felt::ZERO { self.query_queue.enqueue( update_query, vec![ diff --git a/crates/torii/core/src/sql/mod.rs b/crates/torii/core/src/sql/mod.rs index 15ea37bc39..54c576e622 100644 --- a/crates/torii/core/src/sql/mod.rs +++ b/crates/torii/core/src/sql/mod.rs @@ -16,7 +16,7 @@ use sqlx::{Pool, Sqlite}; use starknet::core::types::{Event, Felt, InvokeTransaction, Transaction}; use starknet_crypto::poseidon_hash_many; use tracing::{debug, warn}; -use utils::felts_sql_string; +use utils::felts_to_sql_string; use crate::cache::{Model, ModelCache}; use crate::types::{ @@ -420,7 +420,7 @@ impl Sql { QueryType::Other, ); - let keys_str = felts_sql_string(&keys); + let keys_str = felts_to_sql_string(&keys); let insert_entities = "INSERT INTO event_messages (id, keys, event_id, executed_at) \ VALUES (?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET \ updated_at=CURRENT_TIMESTAMP, executed_at=EXCLUDED.executed_at, \ @@ -561,15 +561,15 @@ impl Sql { Transaction::Invoke(InvokeTransaction::V1(invoke_v1_transaction)) => ( Argument::FieldElement(invoke_v1_transaction.transaction_hash), Argument::FieldElement(invoke_v1_transaction.sender_address), - Argument::String(felts_sql_string(&invoke_v1_transaction.calldata)), + Argument::String(felts_to_sql_string(&invoke_v1_transaction.calldata)), Argument::FieldElement(invoke_v1_transaction.max_fee), - Argument::String(felts_sql_string(&invoke_v1_transaction.signature)), + Argument::String(felts_to_sql_string(&invoke_v1_transaction.signature)), Argument::FieldElement(invoke_v1_transaction.nonce), ), Transaction::L1Handler(l1_handler_transaction) => ( Argument::FieldElement(l1_handler_transaction.transaction_hash), Argument::FieldElement(l1_handler_transaction.contract_address), - Argument::String(felts_sql_string(&l1_handler_transaction.calldata)), + Argument::String(felts_to_sql_string(&l1_handler_transaction.calldata)), Argument::FieldElement(Felt::ZERO), // has no max_fee Argument::String("".to_string()), // has no signature Argument::FieldElement((l1_handler_transaction.nonce).into()), @@ -604,8 +604,8 @@ impl Sql { block_timestamp: u64, ) { let id = Argument::String(event_id.to_string()); - let keys = Argument::String(felts_sql_string(&event.keys)); - let data = Argument::String(felts_sql_string(&event.data)); + let keys = Argument::String(felts_to_sql_string(&event.keys)); + let data = Argument::String(felts_to_sql_string(&event.data)); let hash = Argument::FieldElement(transaction_hash); let executed_at = Argument::String(utc_dt_string_from_timestamp(block_timestamp)); @@ -618,8 +618,8 @@ impl Sql { let emitted = EventEmitted { id: event_id.to_string(), - keys: felts_sql_string(&event.keys), - data: felts_sql_string(&event.data), + keys: felts_to_sql_string(&event.keys), + data: felts_to_sql_string(&event.data), transaction_hash: format!("{:#x}", transaction_hash), created_at: Utc::now(), executed_at: must_utc_datetime_from_timestamp(block_timestamp), diff --git a/crates/torii/core/src/sql/query_queue.rs b/crates/torii/core/src/sql/query_queue.rs index ba3af4ba22..2691102c24 100644 --- a/crates/torii/core/src/sql/query_queue.rs +++ b/crates/torii/core/src/sql/query_queue.rs @@ -83,7 +83,7 @@ impl QueryQueue { Argument::Int(integer) => query.bind(integer), Argument::Bool(bool) => query.bind(bool), Argument::String(string) => query.bind(string), - Argument::FieldElement(felt) => query.bind(format!("{:#x}", felt)), + Argument::FieldElement(felt) => query.bind(felt_to_sql_string(felt)), } } diff --git a/crates/torii/core/src/sql/utils.rs b/crates/torii/core/src/sql/utils.rs index d9cbf1fab9..5a6b97b860 100644 --- a/crates/torii/core/src/sql/utils.rs +++ b/crates/torii/core/src/sql/utils.rs @@ -3,11 +3,19 @@ use starknet_crypto::Felt; use super::FELT_DELIMITER; -pub fn felts_sql_string(felts: &[Felt]) -> String { +pub fn felts_to_sql_string(felts: &[Felt]) -> String { felts.iter().map(|k| format!("{:#x}", k)).collect::>().join(FELT_DELIMITER) + FELT_DELIMITER } +pub(crate) fn felt_to_sql_string(felt: &Felt) -> String { + format!("{:#x}", felt) +} + +pub(crate) fn felt_and_u256_to_sql_string(felt: &Felt, u256: &U256) -> String { + format!("{}:{}", felt_to_sql_string(felt), u256_to_sql_string(u256)) +} + pub(crate) fn u256_to_sql_string(u256: &U256) -> String { format!("{:#064x}", u256) } diff --git a/crates/torii/graphql/src/tests/subscription_test.rs b/crates/torii/graphql/src/tests/subscription_test.rs index 3f753572b5..ccb7dbf114 100644 --- a/crates/torii/graphql/src/tests/subscription_test.rs +++ b/crates/torii/graphql/src/tests/subscription_test.rs @@ -14,7 +14,8 @@ mod tests { use starknet::core::types::Event; use starknet_crypto::{poseidon_hash_many, Felt}; use tokio::sync::mpsc; - use torii_core::sql::{felts_sql_string, Sql}; + use torii_core::sql::utils::felts_to_sql_string; + use torii_core::sql::Sql; use crate::tests::{model_fixtures, run_graphql_subscription}; use crate::utils; @@ -105,7 +106,7 @@ mod tests { ], }); let keys = keys_from_ty(&ty).unwrap(); - let keys_str = felts_sql_string(&keys); + let keys_str = felts_to_sql_string(&keys); let entity_id = poseidon_hash_many(&keys); let model_id = model_id_from_ty(&ty); @@ -223,7 +224,7 @@ mod tests { }); let keys = keys_from_ty(&ty).unwrap(); - let keys_str = felts_sql_string(&keys); + let keys_str = felts_to_sql_string(&keys); let entity_id = poseidon_hash_many(&keys); let model_id = model_id_from_ty(&ty); diff --git a/crates/torii/libp2p/src/server/mod.rs b/crates/torii/libp2p/src/server/mod.rs index 3046a2758f..aebf341a59 100644 --- a/crates/torii/libp2p/src/server/mod.rs +++ b/crates/torii/libp2p/src/server/mod.rs @@ -246,7 +246,7 @@ impl Relay

{ continue; } }; - let keys_str = felts_sql_string(&keys); + let keys_str = felts_to_sql_string(&keys); let entity_id = poseidon_hash_many(&keys); let model_id = ty_model_id(&ty).unwrap();