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/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 779f4e6b17..21be74c50f 100644 --- a/mm2src/coins/nft/storage/sql_storage.rs +++ b/mm2src/coins/nft/storage/sql_storage.rs @@ -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 1e635b4a21..d116c294d5 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(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(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(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,7 +997,7 @@ impl TableSignature for NftTransferHistoryTable { false, )?; table.create_multi_index( - Self::CHAIN_TX_HASH_LOG_INDEX_INDEX, + Self::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX, &["chain", "transaction_hash", "log_index", "token_id"], true, )?;