Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(torii): add erc20 patch for eth mainnet token #2733

Merged
merged 2 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions crates/torii/core/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,17 @@
None,
}

impl FetchDataResult {
pub fn block_id(&self) -> Option<BlockId> {
match self {
FetchDataResult::Range(range) => Some(BlockId::Number(range.latest_block_number)),
FetchDataResult::Pending(_pending) => Some(BlockId::Tag(BlockTag::Pending)),

Check warning on line 177 in crates/torii/core/src/engine.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/engine.rs#L174-L177

Added lines #L174 - L177 were not covered by tests
// we dont require block_id when result is none, we return None
FetchDataResult::None => None,

Check warning on line 179 in crates/torii/core/src/engine.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/engine.rs#L179

Added line #L179 was not covered by tests
}
}

Check warning on line 181 in crates/torii/core/src/engine.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/engine.rs#L181

Added line #L181 was not covered by tests
}

#[derive(Debug)]
pub struct FetchRangeResult {
// (block_number, transaction_hash) -> events
Expand Down Expand Up @@ -269,11 +280,16 @@
info!(target: LOG_TARGET, "Syncing reestablished.");
}

let block_id = fetch_result.block_id();
match self.process(fetch_result).await {
Ok(_) => {
self.db.flush().await?;
self.db.apply_cache_diff().await?;
self.db.execute().await?;
// Its only `None` when `FetchDataResult::None` in which case
// we don't need to flush or apply cache diff
if let Some(block_id) = block_id {
self.db.flush().await?;
self.db.apply_cache_diff(block_id).await?;
self.db.execute().await?;
}
},
Err(e) => {
error!(target: LOG_TARGET, error = %e, "Processing fetched data.");
Expand Down
39 changes: 37 additions & 2 deletions crates/torii/core/src/executor/erc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use super::{ApplyBalanceDiffQuery, Executor};
use crate::constants::{IPFS_CLIENT_MAX_RETRY, SQL_FELT_DELIMITER, TOKEN_BALANCE_TABLE};
use crate::executor::LOG_TARGET;
use crate::sql::utils::{felt_to_sql_string, sql_string_to_u256, u256_to_sql_string, I256};
use crate::types::ContractType;
use crate::utils::fetch_content_from_ipfs;
Expand Down Expand Up @@ -46,6 +47,7 @@
pub async fn apply_balance_diff(
&mut self,
apply_balance_diff: ApplyBalanceDiffQuery,
provider: Arc<P>,

Check warning on line 50 in crates/torii/core/src/executor/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/erc.rs#L50

Added line #L50 was not covered by tests
) -> Result<()> {
let erc_cache = apply_balance_diff.erc_cache;
for ((contract_type, id_str), balance) in erc_cache.iter() {
Expand All @@ -66,6 +68,8 @@
contract_address,
token_id,
balance,
Arc::clone(&provider),
apply_balance_diff.block_id,

Check warning on line 72 in crates/torii/core/src/executor/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/erc.rs#L71-L72

Added lines #L71 - L72 were not covered by tests
)
.await
.with_context(|| "Failed to apply balance diff in apply_cache_diff")?;
Expand All @@ -83,6 +87,8 @@
contract_address,
token_id,
balance,
Arc::clone(&provider),
apply_balance_diff.block_id,

Check warning on line 91 in crates/torii/core/src/executor/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/erc.rs#L90-L91

Added lines #L90 - L91 were not covered by tests
)
.await
.with_context(|| "Failed to apply balance diff in apply_cache_diff")?;
Expand All @@ -93,13 +99,16 @@
Ok(())
}

#[allow(clippy::too_many_arguments)]
pub async fn apply_balance_diff_helper(
&mut self,
id: &str,
account_address: &str,
contract_address: &str,
token_id: &str,
balance_diff: &I256,
provider: Arc<P>,
block_id: BlockId,

Check warning on line 111 in crates/torii/core/src/executor/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/erc.rs#L110-L111

Added lines #L110 - L111 were not covered by tests
) -> Result<()> {
let tx = &mut self.transaction;
let balance: Option<(String,)> =
Expand All @@ -116,9 +125,35 @@

if balance_diff.is_negative {
if balance < balance_diff.value {
dbg!(&balance_diff, balance, id);
// HACK: ideally we should never hit this case. But ETH on starknet mainnet didn't
// emit transfer events properly so they are broken. For those cases
// we manually fetch the balance of the address using RPC

let current_balance = provider
.call(
FunctionCall {
contract_address: Felt::from_str(contract_address).unwrap(),
entry_point_selector: get_selector_from_name("balanceOf").unwrap(),
calldata: vec![Felt::from_str(account_address).unwrap()],
},
block_id,
)
.await
.with_context(|| format!("Failed to fetch balance for id: {}", id))?;

Check warning on line 142 in crates/torii/core/src/executor/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/erc.rs#L132-L142

Added lines #L132 - L142 were not covered by tests

let current_balance =
cainome::cairo_serde::U256::cairo_deserialize(&current_balance, 0).unwrap();

warn!(

Check warning on line 147 in crates/torii/core/src/executor/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/erc.rs#L144-L147

Added lines #L144 - L147 were not covered by tests
target: LOG_TARGET,
id = id,
"Invalid transfer event detected, overriding balance by querying RPC directly"

Check warning on line 150 in crates/torii/core/src/executor/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/erc.rs#L150

Added line #L150 was not covered by tests
);
// override the balance from onchain data
balance = U256::from_words(current_balance.low, current_balance.high);
} else {
balance -= balance_diff.value;

Check warning on line 155 in crates/torii/core/src/executor/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/erc.rs#L153-L155

Added lines #L153 - L155 were not covered by tests
}
balance -= balance_diff.value;
} else {
balance += balance_diff.value;
}
Expand Down
5 changes: 4 additions & 1 deletion crates/torii/core/src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#[derive(Debug, Clone)]
pub struct ApplyBalanceDiffQuery {
pub erc_cache: HashMap<(ContractType, String), I256>,
pub block_id: BlockId,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -606,7 +607,7 @@
QueryType::ApplyBalanceDiff(apply_balance_diff) => {
debug!(target: LOG_TARGET, "Applying balance diff.");
let instant = Instant::now();
self.apply_balance_diff(apply_balance_diff).await?;
self.apply_balance_diff(apply_balance_diff, self.provider.clone()).await?;

Check warning on line 610 in crates/torii/core/src/executor/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/mod.rs#L610

Added line #L610 was not covered by tests
debug!(target: LOG_TARGET, duration = ?instant.elapsed(), "Applied balance diff.");
}
QueryType::RegisterErc721Token(register_erc721_token) => {
Expand Down Expand Up @@ -678,6 +679,8 @@

self.register_tasks.spawn(async move {
let permit = semaphore.acquire().await.unwrap();
let span = tracing::span!(tracing::Level::INFO, "contract_address_span", contract_address = %register_erc721_token.contract_address);
let _enter = span.enter();

Check warning on line 683 in crates/torii/core/src/executor/mod.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/executor/mod.rs#L682-L683

Added lines #L682 - L683 were not covered by tests

let result = Self::process_register_erc721_token_query(
register_erc721_token,
Expand Down
3 changes: 2 additions & 1 deletion crates/torii/core/src/processors/erc20_legacy_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
&self,
world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_number: u64,
block_timestamp: u64,
event_id: &str,
event: &Event,
Expand All @@ -59,6 +59,7 @@
world.provider(),
block_timestamp,
event_id,
block_number,

Check warning on line 62 in crates/torii/core/src/processors/erc20_legacy_transfer.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/erc20_legacy_transfer.rs#L62

Added line #L62 was not covered by tests
)
.await?;
debug!(target: LOG_TARGET,from = ?from, to = ?to, value = ?value, "Legacy ERC20 Transfer");
Expand Down
3 changes: 2 additions & 1 deletion crates/torii/core/src/processors/erc20_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
&self,
world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_number: u64,
block_timestamp: u64,
event_id: &str,
event: &Event,
Expand All @@ -59,6 +59,7 @@
world.provider(),
block_timestamp,
event_id,
block_number,

Check warning on line 62 in crates/torii/core/src/processors/erc20_transfer.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/erc20_transfer.rs#L62

Added line #L62 was not covered by tests
)
.await?;
debug!(target: LOG_TARGET,from = ?from, to = ?to, value = ?value, "ERC20 Transfer");
Expand Down
14 changes: 11 additions & 3 deletions crates/torii/core/src/processors/erc721_legacy_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
&self,
_world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_number: u64,
block_timestamp: u64,
event_id: &str,
event: &Event,
Expand All @@ -51,8 +51,16 @@
let token_id = U256Cainome::cairo_deserialize(&event.data, 2)?;
let token_id = U256::from_words(token_id.low, token_id.high);

db.handle_erc721_transfer(token_address, from, to, token_id, block_timestamp, event_id)
.await?;
db.handle_erc721_transfer(
token_address,
from,
to,
token_id,
block_timestamp,
event_id,
block_number,
)
.await?;

Check warning on line 63 in crates/torii/core/src/processors/erc721_legacy_transfer.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/erc721_legacy_transfer.rs#L54-L63

Added lines #L54 - L63 were not covered by tests
debug!(target: LOG_TARGET, from = ?from, to = ?to, token_id = ?token_id, "ERC721 Transfer");

Ok(())
Expand Down
14 changes: 11 additions & 3 deletions crates/torii/core/src/processors/erc721_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
&self,
_world: &WorldContractReader<P>,
db: &mut Sql,
_block_number: u64,
block_number: u64,
block_timestamp: u64,
event_id: &str,
event: &Event,
Expand All @@ -51,8 +51,16 @@
let token_id = U256Cainome::cairo_deserialize(&event.keys, 3)?;
let token_id = U256::from_words(token_id.low, token_id.high);

db.handle_erc721_transfer(token_address, from, to, token_id, block_timestamp, event_id)
.await?;
db.handle_erc721_transfer(
token_address,
from,
to,
token_id,
block_timestamp,
event_id,
block_number,
)
.await?;

Check warning on line 63 in crates/torii/core/src/processors/erc721_transfer.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/erc721_transfer.rs#L54-L63

Added lines #L54 - L63 were not covered by tests
debug!(target: LOG_TARGET, from = ?from, to = ?to, token_id = ?token_id, "ERC721 Transfer");

Ok(())
Expand Down
11 changes: 8 additions & 3 deletions crates/torii/core/src/sql/erc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
provider: &P,
block_timestamp: u64,
event_id: &str,
block_number: u64,

Check warning on line 32 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L32

Added line #L32 was not covered by tests
) -> Result<()> {
// contract_address
let token_id = felt_to_sql_string(&contract_address);
Expand Down Expand Up @@ -66,10 +67,11 @@
self.local_cache.erc_cache.entry((ContractType::ERC20, to_balance_id)).or_default();
*to_balance += I256::from(amount);
}
let block_id = BlockId::Number(block_number);

Check warning on line 70 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L70

Added line #L70 was not covered by tests

if self.local_cache.erc_cache.len() >= 100000 {
self.flush().await.with_context(|| "Failed to flush in handle_erc20_transfer")?;
self.apply_cache_diff().await?;
self.apply_cache_diff(block_id).await?;

Check warning on line 74 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L74

Added line #L74 was not covered by tests
}

Ok(())
Expand All @@ -84,6 +86,7 @@
token_id: U256,
block_timestamp: u64,
event_id: &str,
block_number: u64,

Check warning on line 89 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L89

Added line #L89 was not covered by tests
) -> Result<()> {
// contract_address:id
let actual_token_id = token_id;
Expand Down Expand Up @@ -127,10 +130,11 @@
.or_default();
*to_balance += I256::from(1u8);
}
let block_id = BlockId::Number(block_number);

Check warning on line 133 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L133

Added line #L133 was not covered by tests

if self.local_cache.erc_cache.len() >= 100000 {
self.flush().await.with_context(|| "Failed to flush in handle_erc721_transfer")?;
self.apply_cache_diff().await?;
self.apply_cache_diff(block_id).await?;

Check warning on line 137 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L137

Added line #L137 was not covered by tests
}

Ok(())
Expand Down Expand Up @@ -272,7 +276,7 @@
Ok(())
}

pub async fn apply_cache_diff(&mut self) -> Result<()> {
pub async fn apply_cache_diff(&mut self, block_id: BlockId) -> Result<()> {

Check warning on line 279 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L279

Added line #L279 was not covered by tests
if !self.local_cache.erc_cache.is_empty() {
self.executor.send(QueryMessage::new(
"".to_string(),
Expand All @@ -282,6 +286,7 @@
&mut self.local_cache.erc_cache,
HashMap::with_capacity(64),
),
block_id,

Check warning on line 289 in crates/torii/core/src/sql/erc.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql/erc.rs#L289

Added line #L289 was not covered by tests
}),
))?;
}
Expand Down
12 changes: 6 additions & 6 deletions crates/torii/graphql/src/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ lazy_static! {
),
]);
pub static ref PAGE_INFO_TYPE_MAPPING: TypeMapping = TypeMapping::from([
(Name::new("hasPreviousPage"), TypeData::Simple(TypeRef::named(TypeRef::BOOLEAN))),
(Name::new("hasNextPage"), TypeData::Simple(TypeRef::named(TypeRef::BOOLEAN))),
(Name::new("hasPreviousPage"), TypeData::Simple(TypeRef::named_nn(TypeRef::BOOLEAN))),
(Name::new("hasNextPage"), TypeData::Simple(TypeRef::named_nn(TypeRef::BOOLEAN))),
(
Name::new("startCursor"),
TypeData::Simple(TypeRef::named(GraphqlType::Cursor.to_string())),
Expand Down Expand Up @@ -160,7 +160,7 @@ lazy_static! {
pub static ref ERC20_TOKEN_TYPE_MAPPING: TypeMapping = IndexMap::from([
(Name::new("name"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("symbol"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("decimals"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("decimals"), TypeData::Simple(TypeRef::named_nn(TypeRef::INT))),
(Name::new("contractAddress"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("amount"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
]);
Expand All @@ -171,9 +171,9 @@ lazy_static! {
(Name::new("tokenId"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("contractAddress"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("metadata"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("metadataName"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("metadataDescription"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("metadataAttributes"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
(Name::new("metadataName"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
(Name::new("metadataDescription"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
(Name::new("metadataAttributes"), TypeData::Simple(TypeRef::named(TypeRef::STRING))),
(Name::new("imagePath"), TypeData::Simple(TypeRef::named_nn(TypeRef::STRING))),
]);

Expand Down
12 changes: 9 additions & 3 deletions crates/torii/graphql/src/object/erc/token_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,14 @@ fn token_balances_connection_output<'a>(
let token_id = row.token_id.split(':').collect::<Vec<&str>>();
assert!(token_id.len() == 2);

// skip the token if metadata is null
if row.metadata.is_none() {
continue;
}
let metadata_str = row.metadata.as_ref().unwrap();

let metadata: serde_json::Value =
serde_json::from_str(&row.metadata).expect("metadata is always json");
serde_json::from_str(metadata_str).expect("metadata is always json");
let metadata_name =
metadata.get("name").map(|v| v.to_string().trim_matches('"').to_string());
let metadata_description = metadata
Expand All @@ -248,7 +254,7 @@ fn token_balances_connection_output<'a>(

let token_metadata = Erc721Token {
name: row.name,
metadata: row.metadata,
metadata: metadata_str.to_owned(),
contract_address: row.contract_address,
symbol: row.symbol,
token_id: token_id[1].to_string(),
Expand Down Expand Up @@ -295,5 +301,5 @@ struct BalanceQueryResultRaw {
pub token_id: String,
pub balance: String,
pub contract_type: String,
pub metadata: String,
pub metadata: Option<String>,
}
Loading
Loading