Skip to content

Commit

Permalink
Various fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
DOBEN committed Dec 19, 2024
1 parent 484ec61 commit 07af40c
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 68 deletions.
2 changes: 0 additions & 2 deletions backend-rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions backend-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ tokio-util = "0.7"
prometheus-client = "0.22"
tonic = { version = "0.10.2", features = ["tls-roots", "tls"]}
tower-http = { version = "0.6", features = ["cors"] }
num-bigint = "0.4.6"
bs58 = { version = "0.5.1", features = ["check"] }
leb128 = "0.2.5"
num-traits = "0.2.19"
bigdecimal = "0.4.7"

# Recommended by SQLx to speed up incremental builds
Expand Down
5 changes: 4 additions & 1 deletion backend-rust/src/graphql_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ enum ApiError {
InvalidVersionedModuleSchema(#[from] VersionedSchemaError),
#[error("Invalid token ID: {0}")]
InvalidTokenID(Arc<ParseTokenIdVecError>),
#[error("Invalid token address: {0}")]
InvalidTokenAddress(Arc<anyhow::Error>),
}

impl From<sqlx::Error> for ApiError {
Expand Down Expand Up @@ -889,7 +891,8 @@ LIMIT 30", // WHERE slot_time > (LOCALTIMESTAMP - $1::interval)
contract_address_index.0,
contract_address_sub_index.0,
&TokenId::from_str(&token_id).map_err(|e| ApiError::InvalidTokenID(e.into()))?,
);
)
.map_err(|e| ApiError::InvalidTokenAddress(Arc::new(e)))?;

let row = sqlx::query_as!(
TokenRow,
Expand Down
126 changes: 63 additions & 63 deletions backend-rust/src/indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1862,33 +1862,29 @@ impl PreparedContractInitialized {
let potential_cis2_events =
event.events.iter().filter_map(|log| log.try_into().ok()).collect::<Vec<_>>();

// Fetch the smart contract name for the given contract.
let row = sqlx::query!(
"
SELECT name FROM contracts WHERE index = $1 AND sub_index = $2
",
index,
sub_index,
)
.fetch_one(pool)
.await?;

let supports_cis2 = cis0::supports(
node_client,
&BlockIdentifier::AbsoluteHeight(data.block_info.block_height),
contract_address,
ContractName::new_unchecked(&row.name),
cis0::StandardIdentifier::CIS2,
)
.await?;

let supports_cis2 = supports_cis2.response.is_support();
let cis2_events = if supports_cis2 {
potential_cis2_events
} else {
// If contract does not support `CIS2`, don't consider the events as CIS2
// events.
// If potential CIS2 events are parsed, we verify if the smart contract
// supports the CIS2 standard before accepting the events as valid.
let cis2_events = if potential_cis2_events.is_empty() {
vec![]
} else {
let supports_cis2 = cis0::supports(
node_client,
&BlockIdentifier::AbsoluteHeight(data.block_info.block_height),
contract_address,
ContractName::new_unchecked(&name),
cis0::StandardIdentifier::CIS2,
)
.await?
.response
.is_support();

if supports_cis2 {
potential_cis2_events
} else {
// If contract does not support `CIS2`, don't consider the events as CIS2
// events.
vec![]
}
};

Ok(Self {
Expand Down Expand Up @@ -1948,13 +1944,13 @@ pub fn get_token_address(
contract_index: u64,
contract_subindex: u64,
token_id: &TokenId,
) -> String {
) -> Result<String, anyhow::Error> {
// Encode the contract index and subindex as unsigned LEB128.
let mut contract_index_bytes = Vec::new();
encode_leb128(&mut contract_index_bytes, contract_index).unwrap();
encode_leb128(&mut contract_index_bytes, contract_index)?;

let mut contract_subindex_bytes = Vec::new();
encode_leb128(&mut contract_subindex_bytes, contract_subindex).unwrap();
encode_leb128(&mut contract_subindex_bytes, contract_subindex)?;

let token_id_bytes = token_id.as_ref();

Expand All @@ -1969,7 +1965,7 @@ pub fn get_token_address(
bytes.extend_from_slice(token_id_bytes);

// Base58 check encoding of the bytes.
bs58::encode(bytes).with_check().into_string()
Ok(bs58::encode(bytes).with_check().into_string())
}

struct PreparedContractUpdate {
Expand Down Expand Up @@ -2040,33 +2036,37 @@ impl PreparedContractUpdate {
} => vec![],
};

// Fetch the smart contract name for the given contract.
let row = sqlx::query!(
"
SELECT name FROM contracts WHERE index = $1 AND sub_index = $2
",
index,
sub_index,
)
.fetch_one(pool)
.await?;

let supports_cis2 = cis0::supports(
node_client,
&BlockIdentifier::AbsoluteHeight(data.block_info.block_height),
contract_address,
ContractName::new_unchecked(&row.name),
cis0::StandardIdentifier::CIS2,
)
.await?;

let supports_cis2 = supports_cis2.response.is_support();
let cis2_events = if supports_cis2 {
potential_cis2_events
} else {
// If contract does not support `CIS2`, don't consider the events as CIS2
// events.
// If potential CIS2 events are parsed, we verify if the smart contract
// supports the CIS2 standard before accepting the events as valid.
let cis2_events = if potential_cis2_events.is_empty() {
vec![]
} else {
let contract_info = node_client
.get_instance_info(
contract_address,
&BlockIdentifier::AbsoluteHeight(data.block_info.block_height),
)
.await?;
let contract_name = contract_info.response.name().as_contract_name();

let supports_cis2 = cis0::supports(
node_client,
&BlockIdentifier::AbsoluteHeight(data.block_info.block_height),
contract_address,
contract_name,
cis0::StandardIdentifier::CIS2,
)
.await?
.response
.is_support();

if supports_cis2 {
potential_cis2_events
} else {
// If contract does not support `CIS2`, don't consider the events as CIS2
// events.
vec![]
}
};

Ok(Self {
Expand Down Expand Up @@ -2137,7 +2137,7 @@ async fn process_cis2_events(
} = log
{
let token_address =
get_token_address(contract_index as u64, contract_sub_index as u64, token_id);
get_token_address(contract_index as u64, contract_sub_index as u64, token_id)?;

// Fetch the current `total_supply` for the given `token_address`.
let row = sqlx::query!(
Expand All @@ -2156,9 +2156,9 @@ async fn process_cis2_events(
let new_total_supply = if let Some(row) = row {
let current_total_supply: BigDecimal = row.total_supply;

current_total_supply + BigDecimal::from_str(&amount.0.to_string()).unwrap()
current_total_supply + BigDecimal::from_str(&amount.0.to_string())?
} else {
BigDecimal::from_str(&amount.0.to_string()).unwrap()
BigDecimal::from_str(&amount.0.to_string())?
};

// If the `token_address` does not exist, insert the new token with its
Expand Down Expand Up @@ -2195,7 +2195,7 @@ async fn process_cis2_events(
} = log
{
let token_address =
get_token_address(contract_index as u64, contract_sub_index as u64, token_id);
get_token_address(contract_index as u64, contract_sub_index as u64, token_id)?;
// Fetch the current `total_supply` for the given `token_address`.
let row = sqlx::query!(
"
Expand All @@ -2215,12 +2215,12 @@ async fn process_cis2_events(
let current_total_supply = row.total_supply;

// Subtract the `amount` from the `current_total_supply`.
current_total_supply - BigDecimal::from_str(&amount.0.to_string()).unwrap()
current_total_supply - BigDecimal::from_str(&amount.0.to_string())?
} else {
// Note: Some `buggy` CIS2 token contracts might burn more tokens than they have
// initially minted. The `total_supply` will be set to 0 (default value) in that
// case (rather than underflowing the value).
-BigDecimal::from_str(&amount.0.to_string()).unwrap()
-BigDecimal::from_str(&amount.0.to_string())?
};

// If the `token_address` does not exist (likely a `buggy` CIS2 token contract),
Expand Down Expand Up @@ -2254,7 +2254,7 @@ async fn process_cis2_events(
} = log
{
let token_address =
get_token_address(contract_index as u64, contract_sub_index as u64, token_id);
get_token_address(contract_index as u64, contract_sub_index as u64, token_id)?;

// If the `token_address` does not exist, insert the new token.
// If the `token_address` exists, update the `metadata_url` value in the
Expand Down

0 comments on commit 07af40c

Please sign in to comment.