Skip to content

Commit

Permalink
Refactor torii indexer system calls to transactions (#1068)
Browse files Browse the repository at this point in the history
* Refactor torii indexer system calls to transactions

* fix fmt
  • Loading branch information
broody authored Oct 25, 2023
1 parent a8b7903 commit 1018840
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 242 deletions.
69 changes: 46 additions & 23 deletions crates/torii/core/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::time::Duration;
use anyhow::Result;
use dojo_world::contracts::world::WorldContractReader;
use starknet::core::types::{
BlockId, BlockWithTxs, Event, InvokeTransaction, InvokeTransactionReceipt,
BlockId, BlockWithTxs, Event, InvokeTransaction, InvokeTransactionReceipt, InvokeTransactionV1,
MaybePendingBlockWithTxs, MaybePendingTransactionReceipt, Transaction, TransactionReceipt,
};
use starknet::core::utils::get_selector_from_name;
Expand Down Expand Up @@ -147,36 +147,48 @@ where
_ => continue,
};

let receipt = match self
let receipt = self
.provider
.get_transaction_receipt(invoke_transaction.transaction_hash)
.await
{
Ok(receipt) => receipt,
.ok()
.and_then(|receipt| match receipt {
MaybePendingTransactionReceipt::Receipt(TransactionReceipt::Invoke(
receipt,
)) => Some(receipt),
_ => None,
});

let invoke_receipt = match receipt {
Some(receipt) => receipt,
_ => continue,
};

let receipt = match receipt {
MaybePendingTransactionReceipt::Receipt(receipt) => receipt,
_ => continue,
};

if let TransactionReceipt::Invoke(invoke_receipt) = receipt.clone() {
for (event_idx, event) in invoke_receipt.events.iter().enumerate() {
if event.from_address != self.world.address() {
continue;
}
let mut world_event = false;
for (event_idx, event) in invoke_receipt.events.iter().enumerate() {
if event.from_address != self.world.address() {
continue;
}

let event_id = format!(
"0x{:064x}:0x{:04x}:0x{:04x}",
block.block_number, tx_idx, event_idx
);
world_event = true;
let event_id =
format!("0x{:064x}:0x{:04x}:0x{:04x}", block.block_number, tx_idx, event_idx);

Self::process_event(self, &block, &invoke_receipt, &event_id, event).await?;
}
Self::process_event(self, &block, &invoke_receipt, &event_id, event).await?;
}

Self::process_transaction(self, &block, &receipt).await?;
if world_event {
let transaction_id = format!("0x{:064x}:0x{:04x}", block.block_number, tx_idx);

Self::process_transaction(
self,
&block,
&invoke_receipt,
&transaction_id,
invoke_transaction,
)
.await?;
}
}

info!("processed block: {}", block.block_number);
Expand All @@ -194,10 +206,21 @@ where
async fn process_transaction(
&mut self,
block: &BlockWithTxs,
receipt: &TransactionReceipt,
invoke_receipt: &InvokeTransactionReceipt,
transaction_id: &str,
transaction: &InvokeTransactionV1,
) -> Result<()> {
for processor in &self.processors.transaction {
processor.process(self.db, self.provider.as_ref(), block, receipt).await?
processor
.process(
self.db,
self.provider.as_ref(),
block,
invoke_receipt,
transaction,
transaction_id,
)
.await?
}

Ok(())
Expand Down
7 changes: 5 additions & 2 deletions crates/torii/core/src/processors/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use anyhow::{Error, Result};
use async_trait::async_trait;
use dojo_world::contracts::world::WorldContractReader;
use starknet::core::types::{BlockWithTxs, Event, InvokeTransactionReceipt, TransactionReceipt};
use starknet::core::types::{BlockWithTxs, Event, InvokeTransactionReceipt, InvokeTransactionV1};
use starknet::providers::Provider;

use crate::sql::Sql;

pub mod metadata_update;
pub mod register_model;
pub mod store_set_record;
pub mod store_transaction;

#[async_trait]
pub trait EventProcessor<P>
Expand Down Expand Up @@ -42,6 +43,8 @@ pub trait TransactionProcessor<P: Provider + Sync> {
db: &mut Sql,
provider: &P,
block: &BlockWithTxs,
transaction_receipt: &TransactionReceipt,
invoke_receipt: &InvokeTransactionReceipt,
transaction: &InvokeTransactionV1,
transaction_id: &str,
) -> Result<(), Error>;
}
56 changes: 0 additions & 56 deletions crates/torii/core/src/processors/store_system_call.rs

This file was deleted.

27 changes: 27 additions & 0 deletions crates/torii/core/src/processors/store_transaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use anyhow::{Error, Ok, Result};
use async_trait::async_trait;
use starknet::core::types::{BlockWithTxs, InvokeTransactionReceipt, InvokeTransactionV1};
use starknet::providers::Provider;

use super::TransactionProcessor;
use crate::sql::Sql;

#[derive(Default)]
pub struct StoreTransactionProcessor;

#[async_trait]
impl<P: Provider + Sync> TransactionProcessor<P> for StoreTransactionProcessor {
async fn process(
&self,
db: &mut Sql,
_provider: &P,
_block: &BlockWithTxs,
_receipt: &InvokeTransactionReceipt,
transaction: &InvokeTransactionV1,
transaction_id: &str,
) -> Result<(), Error> {
db.store_transaction(transaction, transaction_id);

Ok(())
}
}
29 changes: 15 additions & 14 deletions crates/torii/core/src/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use dojo_types::schema::Ty;
use sqlx::pool::PoolConnection;
use sqlx::sqlite::SqliteRow;
use sqlx::{Executor, Pool, Row, Sqlite};
use starknet::core::types::{Event, FieldElement};
use starknet::core::types::{Event, FieldElement, InvokeTransactionV1};
use starknet_crypto::poseidon_hash_many;

use super::World;
Expand Down Expand Up @@ -200,20 +200,21 @@ impl Sql {
Ok(rows.drain(..).map(|row| serde_json::from_str(&row.2).unwrap()).collect())
}

pub fn store_system_call(
&mut self,
system: String,
transaction_hash: FieldElement,
calldata: &[FieldElement],
) {
let query = format!(
"INSERT OR IGNORE INTO system_calls (data, transaction_hash, system_id) VALUES ('{}', \
'{:#x}', '{}')",
calldata.iter().map(|c| format!("{:#x}", c)).collect::<Vec<String>>().join(","),
transaction_hash,
system
pub fn store_transaction(&mut self, transaction: &InvokeTransactionV1, transaction_id: &str) {
let txn_query = format!(
"INSERT OR IGNORE INTO transactions (id, transaction_hash, sender_address, calldata, \
max_fee, signature, nonce) VALUES
('{}', '{:#x}', '{}', '{}', '{:#x}', '{}', '{:#x}')",
transaction_id,
transaction.transaction_hash,
transaction.sender_address,
felts_sql_string(&transaction.calldata),
transaction.max_fee,
felts_sql_string(&transaction.signature),
transaction.nonce
);
self.query_queue.push(query);

self.query_queue.push(txn_query);
}

pub fn store_event(&mut self, event_id: &str, event: &Event, transaction_hash: FieldElement) {
Expand Down
33 changes: 19 additions & 14 deletions crates/torii/graphql/src/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,31 @@ lazy_static! {
TypeData::Simple(TypeRef::named(GraphqlType::DateTime.to_string())),
),
]);
pub static ref SYSTEM_CALL_TYPE_MAPPING: TypeMapping = IndexMap::from([
pub static ref TRANSACTION_MAPPING: TypeMapping = IndexMap::from([
(Name::new("id"), TypeData::Simple(TypeRef::named(TypeRef::ID))),
(Name::new("transaction_hash"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
(Name::new("data"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
(Name::new("system_id"), TypeData::Simple(TypeRef::named(TypeRef::ID))),
(
Name::new("created_at"),
TypeData::Simple(TypeRef::named(GraphqlType::DateTime.to_string())),
Name::new("transaction_hash"),
TypeData::Simple(TypeRef::named(Primitive::Felt252(None).to_string()))
),
]);
pub static ref SYSTEM_TYPE_MAPPING: TypeMapping = IndexMap::from([
(Name::new("id"), TypeData::Simple(TypeRef::named(TypeRef::ID))),
(Name::new("name"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
(
Name::new("class_hash"),
TypeData::Simple(TypeRef::named(Primitive::Felt252(None).to_string())),
Name::new("sender_address"),
TypeData::Simple(TypeRef::named(Primitive::Felt252(None).to_string()))
),
(
Name::new("transaction_hash"),
TypeData::Simple(TypeRef::named(Primitive::Felt252(None).to_string())),
Name::new("calldata"),
TypeData::Simple(TypeRef::named_list(Primitive::Felt252(None).to_string()))
),
(
Name::new("max_fee"),
TypeData::Simple(TypeRef::named(Primitive::Felt252(None).to_string()))
),
(
Name::new("signature"),
TypeData::Simple(TypeRef::named_list(Primitive::Felt252(None).to_string()))
),
(
Name::new("nonce"),
TypeData::Simple(TypeRef::named(Primitive::Felt252(None).to_string()))
),
(
Name::new("created_at"),
Expand Down
24 changes: 3 additions & 21 deletions crates/torii/graphql/src/object/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ use sqlx::{Pool, Sqlite};

use super::connection::{connection_arguments, connection_output, parse_connection_arguments};
use super::inputs::keys_input::{keys_argument, parse_keys_argument};
use super::{ObjectTrait, TypeMapping, ValueMapping};
use crate::mapping::{EVENT_TYPE_MAPPING, SYSTEM_CALL_TYPE_MAPPING};
use super::{ObjectTrait, TypeMapping};
use crate::mapping::EVENT_TYPE_MAPPING;
use crate::query::constants::{EVENT_TABLE, ID_COLUMN};
use crate::query::data::{count_rows, fetch_multiple_rows, fetch_single_row};
use crate::query::value_mapping_from_row;
use crate::utils::extract;
use crate::query::data::{count_rows, fetch_multiple_rows};

pub struct EventObject;

Expand Down Expand Up @@ -73,20 +71,4 @@ impl ObjectTrait for EventObject {

Some(field)
}

fn related_fields(&self) -> Option<Vec<Field>> {
Some(vec![Field::new("systemCall", TypeRef::named_nn("SystemCall"), |ctx| {
FieldFuture::new(async move {
let mut conn = ctx.data::<Pool<Sqlite>>()?.acquire().await?;
let event_values = ctx.parent_value.try_downcast_ref::<ValueMapping>()?;
let syscall_id = extract::<u64>(event_values, "system_call_id")?;
let data =
fetch_single_row(&mut conn, "system_calls", "id", &syscall_id.to_string())
.await?;
let system_call = value_mapping_from_row(&data, &SYSTEM_CALL_TYPE_MAPPING, false)?;

Ok(Some(Value::Object(system_call)))
})
})])
}
}
3 changes: 1 addition & 2 deletions crates/torii/graphql/src/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ pub mod inputs;
pub mod metadata;
pub mod model;
pub mod model_data;
pub mod system;
pub mod system_call;
pub mod transaction;

use async_graphql::dynamic::{
Enum, Field, FieldFuture, InputObject, InputValue, Object, SubscriptionField, TypeRef,
Expand Down
46 changes: 0 additions & 46 deletions crates/torii/graphql/src/object/system.rs

This file was deleted.

Loading

0 comments on commit 1018840

Please sign in to comment.