From c442b428e615c9f77c419d7f61ee04407aecb646 Mon Sep 17 00:00:00 2001
From: Renee Tso <8248583+rtso@users.noreply.github.com>
Date: Fri, 6 Dec 2024 13:41:41 -0800
Subject: [PATCH] fix token claims (#627)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Description
When a token gets claimed, processor needs to know the previous owner for token_activities_v2. Currently the processor gets it from PendingClaimsResource but in this case the resource wasn't found in the transaction and breaks the processor. This PR tries to get it previous owner from the TokenClaim event instead of the table metadata.
## Testing
---
rust/Cargo.lock | 6 +--
rust/Cargo.toml | 2 +-
.../collections_v2.json | 1 +
.../current_collections_v2.json | 1 +
.../current_token_datas_v2.json | 1 +
.../current_token_ownerships_v2.json | 17 ++++++++
.../current_token_pending_claims.json | 18 ++++++++
.../current_token_v2_metadata.json | 1 +
.../token_activities_v2.json | 36 ++++++++++++++++
.../token_datas_v2.json | 1 +
.../token_ownerships_v2.json | 18 ++++++++
.../src/sdk_tests/token_v2_processor_tests.rs | 10 +++++
.../models/token_models/token_claims.rs | 34 ++++++++++++---
.../token_v2_models/v2_token_activities.rs | 43 +++++++++++++------
.../src/processors/token_v2_processor.rs | 8 +++-
15 files changed, 173 insertions(+), 24 deletions(-)
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/collections_v2.json
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_collections_v2.json
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_datas_v2.json
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_ownerships_v2.json
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_pending_claims.json
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_v2_metadata.json
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_activities_v2.json
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_datas_v2.json
create mode 100644 rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_ownerships_v2.json
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index 5cd4f6081..4ff913872 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -198,9 +198,9 @@ dependencies = [
[[package]]
name = "aptos-indexer-test-transactions"
version = "1.0.0"
-source = "git+https://github.com/aptos-labs/aptos-core.git?rev=60ee0c686c15480b2cbba224c205e03f479bcdbd#60ee0c686c15480b2cbba224c205e03f479bcdbd"
+source = "git+https://github.com/aptos-labs/aptos-core.git?rev=8bb628129ff48241c650178caf1ff8bf53a44e5e#8bb628129ff48241c650178caf1ff8bf53a44e5e"
dependencies = [
- "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=60ee0c686c15480b2cbba224c205e03f479bcdbd)",
+ "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=8bb628129ff48241c650178caf1ff8bf53a44e5e)",
"serde_json",
]
@@ -309,7 +309,7 @@ dependencies = [
[[package]]
name = "aptos-protos"
version = "1.3.1"
-source = "git+https://github.com/aptos-labs/aptos-core.git?rev=60ee0c686c15480b2cbba224c205e03f479bcdbd#60ee0c686c15480b2cbba224c205e03f479bcdbd"
+source = "git+https://github.com/aptos-labs/aptos-core.git?rev=8bb628129ff48241c650178caf1ff8bf53a44e5e#8bb628129ff48241c650178caf1ff8bf53a44e5e"
dependencies = [
"futures-core",
"pbjson",
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 763af2006..72c748f9c 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -34,7 +34,7 @@ aptos-indexer-processor-sdk = { git = "https://github.com/aptos-labs/aptos-index
aptos-indexer-processor-sdk-server-framework = { git = "https://github.com/aptos-labs/aptos-indexer-processor-sdk.git", rev = "e6867c50a2c30ef16ad6f82e02313b2ba5ce361a" }
aptos-protos = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "5c48aee129b5a141be2792ffa3d9bd0a1a61c9cb" }
aptos-system-utils = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "202bdccff2b2d333a385ae86a4fcf23e89da9f62" }
-aptos-indexer-test-transactions = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "60ee0c686c15480b2cbba224c205e03f479bcdbd" }
+aptos-indexer-test-transactions = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "8bb628129ff48241c650178caf1ff8bf53a44e5e" }
aptos-indexer-testing-framework = { git = "https://github.com/aptos-labs/aptos-indexer-processor-sdk.git", rev = "e6867c50a2c30ef16ad6f82e02313b2ba5ce361a" }
async-trait = "0.1.53"
backtrace = "0.3.58"
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/collections_v2.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/collections_v2.json
new file mode 100644
index 000000000..0637a088a
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/collections_v2.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_collections_v2.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_collections_v2.json
new file mode 100644
index 000000000..0637a088a
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_collections_v2.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_datas_v2.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_datas_v2.json
new file mode 100644
index 000000000..0637a088a
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_datas_v2.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_ownerships_v2.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_ownerships_v2.json
new file mode 100644
index 000000000..eeac22ab3
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_ownerships_v2.json
@@ -0,0 +1,17 @@
+[
+ {
+ "token_data_id": "0x2877fd783c3c7957b50941cce1b3b729dae16b5928e0ba0606cd282df2b085c8",
+ "property_version_v1": "0",
+ "owner_address": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a",
+ "storage_id": "0xa5e6f84af35d356027c1513b37248bae3968c20720af6fc2d5c58b7c90ffda55",
+ "amount": "1",
+ "table_type_v1": "0x3::token::TokenStore",
+ "token_properties_mutated_v1": {},
+ "is_soulbound_v2": null,
+ "token_standard": "v1",
+ "is_fungible_v2": null,
+ "last_transaction_version": 19922017,
+ "last_transaction_timestamp": "2024-11-28T23:53:41.291148",
+ "non_transferrable_by_owner": null
+ }
+]
\ No newline at end of file
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_pending_claims.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_pending_claims.json
new file mode 100644
index 000000000..46b9c5590
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_pending_claims.json
@@ -0,0 +1,18 @@
+[
+ {
+ "token_data_id_hash": "2877fd783c3c7957b50941cce1b3b729dae16b5928e0ba0606cd282df2b085c8",
+ "property_version": "0",
+ "from_address": "0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e",
+ "to_address": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a",
+ "collection_data_id_hash": "84b2198ac10fdbb64bc3474ed0cf184b7bdcd5bc5f098a8858f2e48f379c5fcc",
+ "creator_address": "0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e",
+ "collection_name": "Alice's",
+ "name": "Alice's first token",
+ "amount": "0",
+ "table_handle": "0xc4b3a532f522e5cc021427b4d729938073a6d34949bd397490d4bbf96a4703f1",
+ "last_transaction_version": 19922017,
+ "collection_id": "0x84b2198ac10fdbb64bc3474ed0cf184b7bdcd5bc5f098a8858f2e48f379c5fcc",
+ "last_transaction_timestamp": "2024-11-28T23:53:41.291148",
+ "token_data_id": "0x2877fd783c3c7957b50941cce1b3b729dae16b5928e0ba0606cd282df2b085c8"
+ }
+]
\ No newline at end of file
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_v2_metadata.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_v2_metadata.json
new file mode 100644
index 000000000..0637a088a
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/current_token_v2_metadata.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_activities_v2.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_activities_v2.json
new file mode 100644
index 000000000..8e23ed7ef
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_activities_v2.json
@@ -0,0 +1,36 @@
+[
+ {
+ "transaction_version": 19922017,
+ "event_index": 0,
+ "event_account_address": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "token_data_id": "0x2877fd783c3c7957b50941cce1b3b729dae16b5928e0ba0606cd282df2b085c8",
+ "property_version_v1": "0",
+ "type_": "0x3::token::TokenDeposit",
+ "from_address": null,
+ "to_address": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a",
+ "token_amount": "1",
+ "before_value": null,
+ "after_value": null,
+ "entry_function_id_str": "0x3::token_transfers::claim_script",
+ "token_standard": "v1",
+ "is_fungible_v2": null,
+ "transaction_timestamp": "2024-11-28T23:53:41.291148"
+ },
+ {
+ "transaction_version": 19922017,
+ "event_index": 1,
+ "event_account_address": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "token_data_id": "0x2877fd783c3c7957b50941cce1b3b729dae16b5928e0ba0606cd282df2b085c8",
+ "property_version_v1": "0",
+ "type_": "0x3::token_transfers::Claim",
+ "from_address": "0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e",
+ "to_address": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a",
+ "token_amount": "1",
+ "before_value": null,
+ "after_value": null,
+ "entry_function_id_str": "0x3::token_transfers::claim_script",
+ "token_standard": "v1",
+ "is_fungible_v2": null,
+ "transaction_timestamp": "2024-11-28T23:53:41.291148"
+ }
+]
\ No newline at end of file
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_datas_v2.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_datas_v2.json
new file mode 100644
index 000000000..0637a088a
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_datas_v2.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_ownerships_v2.json b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_ownerships_v2.json
new file mode 100644
index 000000000..10b251571
--- /dev/null
+++ b/rust/integration-tests/sdk_expected_db_output_files/token_v2_processor/test_token_v1_offer_claim_no_table_metadata/token_ownerships_v2.json
@@ -0,0 +1,18 @@
+[
+ {
+ "transaction_version": 19922017,
+ "write_set_change_index": 4,
+ "token_data_id": "0x2877fd783c3c7957b50941cce1b3b729dae16b5928e0ba0606cd282df2b085c8",
+ "property_version_v1": "0",
+ "owner_address": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a",
+ "storage_id": "0xa5e6f84af35d356027c1513b37248bae3968c20720af6fc2d5c58b7c90ffda55",
+ "amount": "1",
+ "table_type_v1": "0x3::token::TokenStore",
+ "token_properties_mutated_v1": {},
+ "is_soulbound_v2": null,
+ "token_standard": "v1",
+ "is_fungible_v2": null,
+ "transaction_timestamp": "2024-11-28T23:53:41.291148",
+ "non_transferrable_by_owner": null
+ }
+]
\ No newline at end of file
diff --git a/rust/integration-tests/src/sdk_tests/token_v2_processor_tests.rs b/rust/integration-tests/src/sdk_tests/token_v2_processor_tests.rs
index 3bbc2ba18..5b8e8f369 100644
--- a/rust/integration-tests/src/sdk_tests/token_v2_processor_tests.rs
+++ b/rust/integration-tests/src/sdk_tests/token_v2_processor_tests.rs
@@ -58,6 +58,7 @@ mod sdk_token_v2_processor_tests {
},
};
use aptos_indexer_test_transactions::{
+ IMPORTED_DEVNET_TXNS_19922017_TOKEN_V1_OFFER_CLAIM,
IMPORTED_DEVNET_TXNS_78753831_TOKEN_V1_MINT_TRANSFER_WITH_V2_EVENTS,
IMPORTED_DEVNET_TXNS_78753832_TOKEN_V2_MINT_TRANSFER_WITH_V2_EVENTS,
IMPORTED_MAINNET_TXNS_1058723093_TOKEN_V1_MINT_WITHDRAW_DEPOSIT_EVENTS,
@@ -314,6 +315,15 @@ mod sdk_token_v2_processor_tests {
.await;
}
+ #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
+ async fn test_token_v1_offer_claim_no_table_metadata() {
+ process_single_transaction(
+ IMPORTED_DEVNET_TXNS_19922017_TOKEN_V1_OFFER_CLAIM,
+ Some("test_token_v1_offer_claim_no_table_metadata".to_string()),
+ )
+ .await;
+ }
+
/**
* This test includes processing for the following:
* - Resources
diff --git a/rust/processor/src/db/postgres/models/token_models/token_claims.rs b/rust/processor/src/db/postgres/models/token_models/token_claims.rs
index f418aede5..90b709cd5 100644
--- a/rust/processor/src/db/postgres/models/token_models/token_claims.rs
+++ b/rust/processor/src/db/postgres/models/token_models/token_claims.rs
@@ -6,12 +6,20 @@
#![allow(clippy::unused_unit)]
use super::{token_utils::TokenWriteSet, tokens::TableHandleToOwner};
-use crate::{schema::current_token_pending_claims, utils::util::standardize_address};
+use crate::{
+ db::postgres::models::token_v2_models::v2_token_activities::TokenActivityHelperV1,
+ schema::current_token_pending_claims, utils::util::standardize_address,
+};
+use ahash::AHashMap;
use aptos_protos::transaction::v1::{DeleteTableItem, WriteTableItem};
use bigdecimal::{BigDecimal, Zero};
use field_count::FieldCount;
use serde::{Deserialize, Serialize};
+// Map to keep track of the metadata of token offers that were claimed. The key is the token data id of the offer.
+// Potentially it'd also be useful to keep track of offers that were canceled.
+pub type TokenV1Claimed = AHashMap;
+
#[derive(
Clone, Debug, Deserialize, Eq, FieldCount, Identifiable, Insertable, PartialEq, Serialize,
)]
@@ -136,6 +144,7 @@ impl CurrentTokenPendingClaim {
txn_version: i64,
txn_timestamp: chrono::NaiveDateTime,
table_handle_to_owner: &TableHandleToOwner,
+ tokens_claimed: &TokenV1Claimed,
) -> anyhow::Result