From 51eb543be193b40554a37d77fb0eb2517228740c Mon Sep 17 00:00:00 2001 From: laruh Date: Tue, 3 Sep 2024 09:39:42 +0700 Subject: [PATCH] update multi_index in wasm NftTransferHistoryTable and PRIMARY KEY in sql transfer history --- mm2src/coins/nft/nft_tests.rs | 7 ++++- mm2src/coins/nft/storage/db_test_helpers.rs | 8 ++--- mm2src/coins/nft/storage/mod.rs | 3 +- mm2src/coins/nft/storage/sql_storage.rs | 9 +++--- mm2src/coins/nft/storage/wasm/wasm_storage.rs | 29 +++++++++++-------- 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/mm2src/coins/nft/nft_tests.rs b/mm2src/coins/nft/nft_tests.rs index 05f732a9ee..71001d8f21 100644 --- a/mm2src/coins/nft/nft_tests.rs +++ b/mm2src/coins/nft/nft_tests.rs @@ -463,7 +463,12 @@ cross_test!(test_add_get_transfers, { .clone(); assert_eq!(transfer1.block_number, 28056721); let transfer2 = storage - .get_transfer_by_tx_hash_and_log_index(&chain, TX_HASH.to_string(), LOG_INDEX) + .get_transfer_by_tx_hash_log_index_token_id( + &chain, + TX_HASH.to_string(), + LOG_INDEX, + BigUint::from_str("214300047253").unwrap(), + ) .await .unwrap() .unwrap(); diff --git a/mm2src/coins/nft/storage/db_test_helpers.rs b/mm2src/coins/nft/storage/db_test_helpers.rs index d59b845661..2565be8f2e 100644 --- a/mm2src/coins/nft/storage/db_test_helpers.rs +++ b/mm2src/coins/nft/storage/db_test_helpers.rs @@ -258,7 +258,7 @@ pub(crate) fn nft_transfer_history() -> Vec { transaction_index: Some(198), log_index: 495, value: Default::default(), - transaction_type: Some("Single".to_string()), + transaction_type: Some("Batch".to_string()), token_address: Address::from_str("0xfd913a305d70a60aac4faac70c739563738e1f81").unwrap(), from_address: Address::from_str("0x6fad0ec6bb76914b2a2a800686acc22970645820").unwrap(), to_address: Address::from_str("0xf622a6c52c94b500542e2ae6bcad24c53bc5b6a2").unwrap(), @@ -284,15 +284,15 @@ pub(crate) fn nft_transfer_history() -> Vec { confirmations: 0, }; - // Same as transfer1 but with different log_index, meaning that transfer1 and transfer2 are part of one batch/multi token transaction + // Same as transfer1 (identical tx hash and log index) but with different token_id, meaning that transfer1 and transfer2 are part of one batch/multi token transaction let transfer2 = NftTransferHistory { common: NftTransferCommon { block_hash: Some("0x3d68b78391fb3cf8570df27036214f7e9a5a6a45d309197936f51d826041bfe7".to_string()), transaction_hash: "0x1e9f04e9b571b283bde02c98c2a97da39b2bb665b57c1f2b0b733f9b681debbe".to_string(), transaction_index: Some(198), - log_index: 496, + log_index: 495, value: Default::default(), - transaction_type: Some("Single".to_string()), + transaction_type: Some("Batch".to_string()), token_address: Address::from_str("0xfd913a305d70a60aac4faac70c739563738e1f81").unwrap(), from_address: Address::from_str("0x6fad0ec6bb76914b2a2a800686acc22970645820").unwrap(), to_address: Address::from_str("0xf622a6c52c94b500542e2ae6bcad24c53bc5b6a2").unwrap(), diff --git a/mm2src/coins/nft/storage/mod.rs b/mm2src/coins/nft/storage/mod.rs index ad255100c3..2d91193288 100644 --- a/mm2src/coins/nft/storage/mod.rs +++ b/mm2src/coins/nft/storage/mod.rs @@ -156,11 +156,12 @@ pub trait NftTransferHistoryStorageOps { token_id: BigUint, ) -> MmResult, Self::Error>; - async fn get_transfer_by_tx_hash_and_log_index( + async fn get_transfer_by_tx_hash_log_index_token_id( &self, chain: &Chain, transaction_hash: String, log_index: u32, + token_id: BigUint, ) -> MmResult, Self::Error>; /// Updates the metadata for NFT transfers identified by their token address and ID. diff --git a/mm2src/coins/nft/storage/sql_storage.rs b/mm2src/coins/nft/storage/sql_storage.rs index 6844b261d9..21be74c50f 100644 --- a/mm2src/coins/nft/storage/sql_storage.rs +++ b/mm2src/coins/nft/storage/sql_storage.rs @@ -103,7 +103,7 @@ fn create_transfer_history_table_sql(chain: &Chain) -> Result image_domain TEXT, token_name TEXT, details_json TEXT, - PRIMARY KEY (transaction_hash, log_index) + PRIMARY KEY (transaction_hash, log_index, token_id) );", safe_table_name.inner() ); @@ -1121,22 +1121,23 @@ impl NftTransferHistoryStorageOps for AsyncMutexGuard<'_, AsyncConnection> { .map_to_mm(AsyncConnError::from) } - async fn get_transfer_by_tx_hash_and_log_index( + async fn get_transfer_by_tx_hash_log_index_token_id( &self, chain: &Chain, transaction_hash: String, log_index: u32, + token_id: BigUint, ) -> MmResult, Self::Error> { let table_name = chain.transfer_history_table_name()?; let sql = format!( - "SELECT * FROM {} WHERE transaction_hash=?1 AND log_index = ?2", + "SELECT * FROM {} WHERE transaction_hash=?1 AND log_index = ?2 AND token_id = ?3", table_name.inner() ); self.call(move |conn| { let transfer = query_single_row( conn, &sql, - [transaction_hash, log_index.to_string()], + [transaction_hash, log_index.to_string(), token_id.to_string()], transfer_history_from_row, )?; Ok(transfer) diff --git a/mm2src/coins/nft/storage/wasm/wasm_storage.rs b/mm2src/coins/nft/storage/wasm/wasm_storage.rs index e5ea955918..81f5f5c158 100644 --- a/mm2src/coins/nft/storage/wasm/wasm_storage.rs +++ b/mm2src/coins/nft/storage/wasm/wasm_storage.rs @@ -547,18 +547,20 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { .collect() } - async fn get_transfer_by_tx_hash_and_log_index( + async fn get_transfer_by_tx_hash_log_index_token_id( &self, chain: &Chain, transaction_hash: String, log_index: u32, + token_id: BigUint, ) -> MmResult, Self::Error> { let db_transaction = self.get_inner().transaction().await?; let table = db_transaction.table::().await?; - let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_INDEX) + let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX) .with_value(chain.to_string())? .with_value(&transaction_hash)? - .with_value(log_index)?; + .with_value(log_index)? + .with_value(BeBigUint::from(token_id))?; if let Some((_item_id, item)) = table.get_item_by_unique_multi_index(index_keys).await? { Ok(Some(transfer_details_from_item(item)?)) @@ -602,10 +604,11 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { } drop_mutability!(transfer); - let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_INDEX) + let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX) .with_value(&chain_str)? .with_value(&transfer.common.transaction_hash)? - .with_value(transfer.common.log_index)?; + .with_value(transfer.common.log_index)? + .with_value(BeBigUint::from(transfer.token_id.clone()))?; let item = NftTransferHistoryTable::from_transfer_history(&transfer)?; table.replace_item_by_unique_multi_index(index_keys, &item).await?; @@ -691,10 +694,11 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { transfer.common.possible_spam = possible_spam; drop_mutability!(transfer); - let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_INDEX) + let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX) .with_value(&chain_str)? .with_value(&transfer.common.transaction_hash)? - .with_value(transfer.common.log_index)?; + .with_value(transfer.common.log_index)? + .with_value(BeBigUint::from(transfer.token_id.clone()))?; let item = NftTransferHistoryTable::from_transfer_history(&transfer)?; table.replace_item_by_unique_multi_index(index_keys, &item).await?; @@ -777,10 +781,11 @@ async fn update_transfer_phishing_for_index( transfer.possible_phishing = possible_phishing; drop_mutability!(transfer); let transfer_item = NftTransferHistoryTable::from_transfer_history(&transfer)?; - let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_INDEX) + let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX) .with_value(chain)? .with_value(&transfer.common.transaction_hash)? - .with_value(transfer.common.log_index)?; + .with_value(transfer.common.log_index)? + .with_value(BeBigUint::from(transfer.token_id))?; table .replace_item_by_unique_multi_index(index_keys, &transfer_item) .await?; @@ -951,7 +956,7 @@ pub(crate) struct NftTransferHistoryTable { } impl NftTransferHistoryTable { - const CHAIN_TX_HASH_LOG_INDEX_INDEX: &str = "chain_tx_hash_log_index_index"; + const CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX: &str = "chain_tx_hash_log_index_token_idindex"; fn from_transfer_history(transfer: &NftTransferHistory) -> WasmNftCacheResult { let details_json = @@ -992,8 +997,8 @@ impl TableSignature for NftTransferHistoryTable { false, )?; table.create_multi_index( - Self::CHAIN_TX_HASH_LOG_INDEX_INDEX, - &["chain", "transaction_hash", "log_index"], + Self::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX, + &["chain", "transaction_hash", "log_index", "token_id"], true, )?; table.create_multi_index(CHAIN_BLOCK_NUMBER_INDEX, &["chain", "block_number"], false)?;