From 0b4ee5e17ecbfff2c29ef1ed097f9cd6fa4e4a73 Mon Sep 17 00:00:00 2001 From: bowenyang007 Date: Wed, 20 Mar 2024 16:02:52 -0700 Subject: [PATCH 1/4] handle burn properly for partial burns --- .../token_v2_models/v2_token_ownerships.rs | 48 ++++++++++++++++--- .../src/processors/token_v2_processor.rs | 3 ++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs b/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs index f0a3c926d..9d58dcf9d 100644 --- a/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs +++ b/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs @@ -226,12 +226,14 @@ impl TokenOwnershipV2 { } /// This handles the case where token is burned but objectCore is still there - pub fn get_burned_nft_v2_from_write_resource( + pub async fn get_burned_nft_v2_from_write_resource( write_resource: &WriteResource, txn_version: i64, write_set_change_index: i64, txn_timestamp: chrono::NaiveDateTime, + prior_nft_ownership: &AHashMap, tokens_burned: &TokenV2Burned, + conn: &mut PgPoolConnection<'_>, ) -> anyhow::Result> { let token_data_id = standardize_address(&write_resource.address.to_string()); if tokens_burned @@ -279,6 +281,17 @@ impl TokenOwnershipV2 { non_transferrable_by_owner: Some(is_soulbound), }, ))); + } else { + return Self::get_burned_nft_v2_helper( + &token_data_id, + txn_version, + write_set_change_index, + txn_timestamp, + prior_nft_ownership, + tokens_burned, + conn, + ) + .await; } } Ok(None) @@ -286,7 +299,7 @@ impl TokenOwnershipV2 { /// This handles the case where token is burned and objectCore is deleted pub async fn get_burned_nft_v2_from_delete_resource( - write_resource: &DeleteResource, + delete_resource: &DeleteResource, txn_version: i64, write_set_change_index: i64, txn_timestamp: chrono::NaiveDateTime, @@ -296,15 +309,36 @@ impl TokenOwnershipV2 { query_retries: u32, query_retry_delay_ms: u64, ) -> anyhow::Result> { - let token_address = standardize_address(&write_resource.address.to_string()); - if let Some(burn_event) = tokens_burned.get(&token_address) { + let token_address = standardize_address(&delete_resource.address.to_string()); + Self::get_burned_nft_v2_helper( + &token_address, + txn_version, + write_set_change_index, + txn_timestamp, + prior_nft_ownership, + tokens_burned, + conn, + ) + .await + } + + async fn get_burned_nft_v2_helper( + token_address: &str, + txn_version: i64, + write_set_change_index: i64, + txn_timestamp: chrono::NaiveDateTime, + prior_nft_ownership: &AHashMap, + tokens_burned: &TokenV2Burned, + conn: &mut PgPoolConnection<'_>, + ) -> anyhow::Result> { + if let Some(burn_event) = tokens_burned.get(token_address) { // 1. Try to lookup token address in burn event mapping let previous_owner = if let Some(burn_event) = burn_event { burn_event.get_previous_owner_address() } else { // 2. If it doesn't exist in burn event mapping, then it must be an old burn event that doesn't contain previous_owner. // Do a lookup to get previous owner. This is necessary because preivous owner is part of current token ownerships primary key. - match prior_nft_ownership.get(&token_address) { + match prior_nft_ownership.get(token_address) { Some(inner) => inner.owner_address.clone(), None => { match CurrentTokenOwnershipV2Query::get_latest_owned_nft_by_token_data_id( @@ -319,7 +353,7 @@ impl TokenOwnershipV2 { Err(_) => { tracing::error!( transaction_version = txn_version, - lookup_key = &token_address, + lookup_key = token_address, "Failed to find current_token_ownership_v2 for burned token. You probably should backfill db." ); DEFAULT_OWNER_ADDRESS.to_string() @@ -329,7 +363,7 @@ impl TokenOwnershipV2 { } }; - let token_data_id = token_address.clone(); + let token_data_id = token_address.to_string(); let storage_id = token_data_id.clone(); return Ok(Some(( diff --git a/rust/processor/src/processors/token_v2_processor.rs b/rust/processor/src/processors/token_v2_processor.rs index 7975f24a9..bf3a8b3f9 100644 --- a/rust/processor/src/processors/token_v2_processor.rs +++ b/rust/processor/src/processors/token_v2_processor.rs @@ -925,8 +925,11 @@ async fn parse_v2_token( txn_version, wsc_index, txn_timestamp, + &prior_nft_ownership, &tokens_burned, + conn, ) + .await .unwrap() { token_ownerships_v2.push(nft_ownership); From 301ba32b02261360b245beff7f8a655f0c978076 Mon Sep 17 00:00:00 2001 From: bowenyang007 Date: Wed, 20 Mar 2024 20:11:39 -0700 Subject: [PATCH 2/4] rebase --- .../src/models/token_v2_models/v2_token_ownerships.rs | 8 ++++++++ rust/processor/src/processors/token_v2_processor.rs | 2 ++ 2 files changed, 10 insertions(+) diff --git a/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs b/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs index 9d58dcf9d..77e522df2 100644 --- a/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs +++ b/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs @@ -234,6 +234,8 @@ impl TokenOwnershipV2 { prior_nft_ownership: &AHashMap, tokens_burned: &TokenV2Burned, conn: &mut PgPoolConnection<'_>, + query_retries: u32, + query_retry_delay_ms: u64, ) -> anyhow::Result> { let token_data_id = standardize_address(&write_resource.address.to_string()); if tokens_burned @@ -290,6 +292,8 @@ impl TokenOwnershipV2 { prior_nft_ownership, tokens_burned, conn, + query_retries, + query_retry_delay_ms, ) .await; } @@ -318,6 +322,8 @@ impl TokenOwnershipV2 { prior_nft_ownership, tokens_burned, conn, + query_retries, + query_retry_delay_ms, ) .await } @@ -330,6 +336,8 @@ impl TokenOwnershipV2 { prior_nft_ownership: &AHashMap, tokens_burned: &TokenV2Burned, conn: &mut PgPoolConnection<'_>, + query_retries: u32, + query_retry_delay_ms: u64, ) -> anyhow::Result> { if let Some(burn_event) = tokens_burned.get(token_address) { // 1. Try to lookup token address in burn event mapping diff --git a/rust/processor/src/processors/token_v2_processor.rs b/rust/processor/src/processors/token_v2_processor.rs index bf3a8b3f9..f53d134ed 100644 --- a/rust/processor/src/processors/token_v2_processor.rs +++ b/rust/processor/src/processors/token_v2_processor.rs @@ -928,6 +928,8 @@ async fn parse_v2_token( &prior_nft_ownership, &tokens_burned, conn, + query_retries, + query_retry_delay_ms, ) .await .unwrap() From a780d8c3918a9b64e080670a1df9942309ce7657 Mon Sep 17 00:00:00 2001 From: bowenyang007 Date: Wed, 20 Mar 2024 20:18:30 -0700 Subject: [PATCH 3/4] lint --- .../processor/src/models/token_v2_models/v2_token_ownerships.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs b/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs index 77e522df2..28fb9aa20 100644 --- a/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs +++ b/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs @@ -351,7 +351,7 @@ impl TokenOwnershipV2 { None => { match CurrentTokenOwnershipV2Query::get_latest_owned_nft_by_token_data_id( conn, - &token_address, + token_address, query_retries, query_retry_delay_ms, ) From addc4a5acdd30ff9e76fdbd09603597519552ea1 Mon Sep 17 00:00:00 2001 From: bowenyang007 Date: Thu, 21 Mar 2024 12:34:23 -0700 Subject: [PATCH 4/4] comment --- .../src/models/token_v2_models/v2_token_ownerships.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs b/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs index 28fb9aa20..6edc4b80f 100644 --- a/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs +++ b/rust/processor/src/models/token_v2_models/v2_token_ownerships.rs @@ -339,19 +339,20 @@ impl TokenOwnershipV2 { query_retries: u32, query_retry_delay_ms: u64, ) -> anyhow::Result> { - if let Some(burn_event) = tokens_burned.get(token_address) { + let token_address = standardize_address(token_address); + if let Some(burn_event) = tokens_burned.get(&token_address) { // 1. Try to lookup token address in burn event mapping let previous_owner = if let Some(burn_event) = burn_event { burn_event.get_previous_owner_address() } else { // 2. If it doesn't exist in burn event mapping, then it must be an old burn event that doesn't contain previous_owner. // Do a lookup to get previous owner. This is necessary because preivous owner is part of current token ownerships primary key. - match prior_nft_ownership.get(token_address) { + match prior_nft_ownership.get(&token_address) { Some(inner) => inner.owner_address.clone(), None => { match CurrentTokenOwnershipV2Query::get_latest_owned_nft_by_token_data_id( conn, - token_address, + &token_address, query_retries, query_retry_delay_ms, ) @@ -361,7 +362,7 @@ impl TokenOwnershipV2 { Err(_) => { tracing::error!( transaction_version = txn_version, - lookup_key = token_address, + lookup_key = &token_address, "Failed to find current_token_ownership_v2 for burned token. You probably should backfill db." ); DEFAULT_OWNER_ADDRESS.to_string() @@ -371,7 +372,7 @@ impl TokenOwnershipV2 { } }; - let token_data_id = token_address.to_string(); + let token_data_id = token_address.clone(); let storage_id = token_data_id.clone(); return Ok(Some((