Skip to content

Commit 16f0855

Browse files
feat: async check transaction (#178)
1 parent 88c2a6e commit 16f0855

File tree

13 files changed

+198
-155
lines changed

13 files changed

+198
-155
lines changed

dash-spv-ffi/include/dash_spv_ffi.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#ifndef DASH_SPV_FFI_H
44
#define DASH_SPV_FFI_H
55

6-
/* Generated with cbindgen:0.29.2 */
6+
/* Generated with cbindgen:0.29.0 */
77

88
/* Warning: This file is auto-generated by cbindgen. Do not modify manually. */
99

@@ -16,6 +16,11 @@
1616
namespace dash_spv_ffi {
1717
#endif // __cplusplus
1818

19+
typedef enum FFIMempoolStrategy {
20+
FetchAll = 0,
21+
BloomFilter = 1,
22+
} FFIMempoolStrategy;
23+
1924
typedef enum FFISyncStage {
2025
Connecting = 0,
2126
QueryingHeight = 1,
@@ -29,11 +34,6 @@ typedef enum FFISyncStage {
2934
Failed = 9,
3035
} FFISyncStage;
3136

32-
typedef enum FFIMempoolStrategy {
33-
FetchAll = 0,
34-
BloomFilter = 1,
35-
} FFIMempoolStrategy;
36-
3737
typedef enum DashSpvValidationMode {
3838
None = 0,
3939
Basic = 1,

key-wallet-ffi/src/transaction.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,11 @@ pub unsafe extern "C" fn wallet_check_transaction(
564564
return false;
565565
}
566566
};
567-
let check_result =
568-
managed_info.check_transaction(&tx, network_rust, context, wallet_mut, update_state);
567+
568+
// Block on the async check_transaction call
569+
let check_result = tokio::runtime::Handle::current().block_on(
570+
managed_info.check_transaction(&tx, network_rust, context, wallet_mut, update_state),
571+
);
569572

570573
// If we updated state, we need to update the wallet's managed info
571574
// Note: This would require storing ManagedWalletInfo in FFIWallet

key-wallet-ffi/src/transaction_checking.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,11 @@ pub unsafe extern "C" fn managed_wallet_check_transaction(
208208
return false;
209209
}
210210
};
211-
let check_result =
212-
managed_wallet.check_transaction(&tx, network_rust, context, wallet_mut, update_state);
211+
212+
// Block on the async check_transaction call
213+
let check_result = tokio::runtime::Handle::current().block_on(
214+
managed_wallet.check_transaction(&tx, network_rust, context, wallet_mut, update_state),
215+
);
213216

214217
// Convert the result to FFI format
215218
let affected_accounts = if check_result.affected_accounts.is_empty() {

key-wallet-ffi/src/wallet_manager.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,9 @@ pub unsafe extern "C" fn wallet_manager_process_transaction(
791791
// Process the transaction using async runtime
792792
let relevant_wallets = manager_ref.runtime.block_on(async {
793793
let mut manager_guard = manager_ref.manager.write().await;
794-
manager_guard.check_transaction_in_all_wallets(&tx, network, context, update_state_if_found)
794+
manager_guard
795+
.check_transaction_in_all_wallets(&tx, network, context, update_state_if_found)
796+
.await
795797
});
796798

797799
FFIError::set_success(error);

key-wallet-manager/src/wallet_manager/mod.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ impl<T: WalletInfoInterface> WalletManager<T> {
502502
}
503503

504504
/// Check a transaction against all wallets and update their states if relevant
505-
pub fn check_transaction_in_all_wallets(
505+
pub async fn check_transaction_in_all_wallets(
506506
&mut self,
507507
tx: &Transaction,
508508
network: Network,
@@ -521,13 +521,9 @@ impl<T: WalletInfoInterface> WalletManager<T> {
521521
let wallet_info_opt = self.wallet_infos.get_mut(&wallet_id);
522522

523523
if let (Some(wallet), Some(wallet_info)) = (wallet_opt, wallet_info_opt) {
524-
let result = wallet_info.check_transaction(
525-
tx,
526-
network,
527-
context,
528-
wallet,
529-
update_state_if_found,
530-
);
524+
let result = wallet_info
525+
.check_transaction(tx, network, context, wallet, update_state_if_found)
526+
.await;
531527

532528
// If the transaction is relevant
533529
if result.is_relevant {

key-wallet-manager/src/wallet_manager/process_block.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ impl<T: WalletInfoInterface + Send + Sync + 'static> WalletInterface for WalletM
3131
timestamp: Some(timestamp),
3232
};
3333

34-
let affected_wallets = self.check_transaction_in_all_wallets(
35-
tx, network, context, true, // update state
36-
);
34+
let affected_wallets = self
35+
.check_transaction_in_all_wallets(
36+
tx, network, context, true, // update state
37+
)
38+
.await;
3739

3840
if !affected_wallets.is_empty() {
3941
relevant_txids.push(tx.txid());
@@ -54,7 +56,8 @@ impl<T: WalletInfoInterface + Send + Sync + 'static> WalletInterface for WalletM
5456
// Check transaction against all wallets
5557
self.check_transaction_in_all_wallets(
5658
tx, network, context, true, // update state
57-
);
59+
)
60+
.await;
5861
}
5962

6063
async fn handle_reorg(

key-wallet/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ hex = { version = "0.4"}
4343
hkdf = { version = "0.12", default-features = false }
4444
zeroize = { version = "1.8", features = ["derive"] }
4545
tracing = "0.1"
46+
async-trait = "0.1"
4647

4748
[dev-dependencies]
4849
hex = "0.4"
4950
key-wallet = { path = ".", features = ["bip38", "serde", "bincode", "eddsa", "bls"] }
51+
tokio = { version = "1", features = ["macros", "rt"] }

key-wallet/src/transaction_checking/transaction_router/tests/asset_unlock.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ fn test_asset_unlock_classification() {
6767
assert!(accounts.contains(&AccountTypeToCheck::StandardBIP32));
6868
}
6969

70-
#[test]
71-
fn test_asset_unlock_transaction_routing() {
70+
#[tokio::test]
71+
async fn test_asset_unlock_transaction_routing() {
7272
let network = Network::Testnet;
7373
let mut wallet = Wallet::new_random(&[network], WalletAccountCreationOptions::Default)
7474
.expect("Failed to create wallet with default options");
@@ -134,7 +134,8 @@ fn test_asset_unlock_transaction_routing() {
134134
timestamp: Some(1234567890),
135135
};
136136

137-
let result = managed_wallet_info.check_transaction(&tx, network, context, &mut wallet, true);
137+
let result =
138+
managed_wallet_info.check_transaction(&tx, network, context, &mut wallet, true).await;
138139

139140
// The transaction should be recognized as relevant
140141
assert!(result.is_relevant, "Asset unlock transaction should be recognized as relevant");
@@ -155,8 +156,8 @@ fn test_asset_unlock_transaction_routing() {
155156
);
156157
}
157158

158-
#[test]
159-
fn test_asset_unlock_routing_to_bip32_account() {
159+
#[tokio::test]
160+
async fn test_asset_unlock_routing_to_bip32_account() {
160161
// Test AssetUnlock routing to BIP32 accounts
161162
let network = Network::Testnet;
162163

@@ -214,7 +215,8 @@ fn test_asset_unlock_routing_to_bip32_account() {
214215
timestamp: Some(1234567890),
215216
};
216217

217-
let result = managed_wallet_info.check_transaction(&tx, network, context, &mut wallet, true);
218+
let result =
219+
managed_wallet_info.check_transaction(&tx, network, context, &mut wallet, true).await;
218220

219221
// Should be recognized as relevant
220222
assert!(result.is_relevant, "Asset unlock transaction to BIP32 account should be relevant");

key-wallet/src/transaction_checking/transaction_router/tests/coinbase.rs

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ fn create_basic_transaction() -> Transaction {
6060
}
6161
}
6262

63-
#[test]
64-
fn test_coinbase_transaction_routing_to_bip44_receive_address() {
63+
#[tokio::test]
64+
async fn test_coinbase_transaction_routing_to_bip44_receive_address() {
6565
let network = Network::Testnet;
6666

6767
// Create a wallet with a BIP44 account
@@ -109,13 +109,15 @@ fn test_coinbase_transaction_routing_to_bip44_receive_address() {
109109
};
110110

111111
// Check the coinbase transaction
112-
let result = managed_wallet_info.check_transaction(
113-
&coinbase_tx,
114-
network,
115-
context,
116-
&mut wallet,
117-
true, // update state
118-
);
112+
let result = managed_wallet_info
113+
.check_transaction(
114+
&coinbase_tx,
115+
network,
116+
context,
117+
&mut wallet,
118+
true, // update state
119+
)
120+
.await;
119121

120122
// The coinbase transaction should be recognized as relevant
121123
assert!(result.is_relevant, "Coinbase transaction to BIP44 receive address should be relevant");
@@ -136,8 +138,8 @@ fn test_coinbase_transaction_routing_to_bip44_receive_address() {
136138
);
137139
}
138140

139-
#[test]
140-
fn test_coinbase_transaction_routing_to_bip44_change_address() {
141+
#[tokio::test]
142+
async fn test_coinbase_transaction_routing_to_bip44_change_address() {
141143
let network = Network::Testnet;
142144

143145
// Create a wallet with a BIP44 account
@@ -185,13 +187,15 @@ fn test_coinbase_transaction_routing_to_bip44_change_address() {
185187
};
186188

187189
// Check the coinbase transaction
188-
let result = managed_wallet_info.check_transaction(
189-
&coinbase_tx,
190-
network,
191-
context,
192-
&mut wallet,
193-
true, // update state
194-
);
190+
let result = managed_wallet_info
191+
.check_transaction(
192+
&coinbase_tx,
193+
network,
194+
context,
195+
&mut wallet,
196+
true, // update state
197+
)
198+
.await;
195199

196200
// The coinbase transaction should be recognized as relevant even to change address
197201
assert!(result.is_relevant, "Coinbase transaction to BIP44 change address should be relevant");
@@ -212,8 +216,8 @@ fn test_coinbase_transaction_routing_to_bip44_change_address() {
212216
);
213217
}
214218

215-
#[test]
216-
fn test_update_state_flag_behavior() {
219+
#[tokio::test]
220+
async fn test_update_state_flag_behavior() {
217221
let network = Network::Testnet;
218222

219223
let mut wallet = Wallet::new_random(&[network], WalletAccountCreationOptions::Default)
@@ -257,7 +261,8 @@ fn test_update_state_flag_behavior() {
257261
};
258262

259263
// First check with update_state = false
260-
let result1 = managed_wallet_info.check_transaction(&tx, network, context, &mut wallet, false);
264+
let result1 =
265+
managed_wallet_info.check_transaction(&tx, network, context, &mut wallet, false).await;
261266

262267
assert!(result1.is_relevant);
263268

@@ -278,13 +283,15 @@ fn test_update_state_flag_behavior() {
278283
}
279284

280285
// Now check with update_state = true
281-
let result2 = managed_wallet_info.check_transaction(
282-
&tx,
283-
network,
284-
context,
285-
&mut wallet,
286-
true, // update state
287-
);
286+
let result2 = managed_wallet_info
287+
.check_transaction(
288+
&tx,
289+
network,
290+
context,
291+
&mut wallet,
292+
true, // update state
293+
)
294+
.await;
288295

289296
assert!(result2.is_relevant);
290297
assert_eq!(
@@ -346,8 +353,8 @@ fn test_coinbase_routing() {
346353
assert!(!accounts.contains(&AccountTypeToCheck::ProviderOwnerKeys));
347354
}
348355

349-
#[test]
350-
fn test_coinbase_transaction_with_payload_routing() {
356+
#[tokio::test]
357+
async fn test_coinbase_transaction_with_payload_routing() {
351358
// Test coinbase with special payload routing to BIP44 account
352359
let network = Network::Testnet;
353360
let mut wallet = Wallet::new_random(&[network], WalletAccountCreationOptions::Default)
@@ -402,8 +409,9 @@ fn test_coinbase_transaction_with_payload_routing() {
402409
timestamp: Some(1234567890),
403410
};
404411

405-
let result =
406-
managed_wallet_info.check_transaction(&coinbase_tx, network, context, &mut wallet, true);
412+
let result = managed_wallet_info
413+
.check_transaction(&coinbase_tx, network, context, &mut wallet, true)
414+
.await;
407415

408416
assert!(result.is_relevant, "Coinbase with payload should be relevant");
409417
assert_eq!(result.total_received, 5000000000, "Should have received block reward");

key-wallet/src/transaction_checking/transaction_router/tests/identity_transactions.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ fn test_identity_registration() {
5353
assert!(accounts.contains(&AccountTypeToCheck::IdentityTopUp));
5454
}
5555

56-
#[test]
57-
fn test_identity_registration_account_routing() {
56+
#[tokio::test]
57+
async fn test_identity_registration_account_routing() {
5858
let network = Network::Testnet;
5959

6060
let mut wallet = Wallet::new_random(&[network], WalletAccountCreationOptions::None)
@@ -144,7 +144,8 @@ fn test_identity_registration_account_routing() {
144144
};
145145

146146
// First check without updating state
147-
let result = managed_wallet_info.check_transaction(&tx, network, context, &mut wallet, true);
147+
let result =
148+
managed_wallet_info.check_transaction(&tx, network, context, &mut wallet, true).await;
148149

149150
println!(
150151
"Identity registration transaction result: is_relevant={}, received={}, credit_conversion={}",
@@ -174,8 +175,8 @@ fn test_identity_registration_account_routing() {
174175
);
175176
}
176177

177-
#[test]
178-
fn test_normal_payment_to_identity_address_not_detected() {
178+
#[tokio::test]
179+
async fn test_normal_payment_to_identity_address_not_detected() {
179180
let network = Network::Testnet;
180181

181182
let mut wallet = Wallet::new_random(&[network], WalletAccountCreationOptions::Default)
@@ -219,13 +220,15 @@ fn test_normal_payment_to_identity_address_not_detected() {
219220
timestamp: Some(1234567890),
220221
};
221222

222-
let result = managed_wallet_info.check_transaction(
223-
&normal_tx,
224-
network,
225-
context,
226-
&mut wallet,
227-
true, // update state
228-
);
223+
let result = managed_wallet_info
224+
.check_transaction(
225+
&normal_tx,
226+
network,
227+
context,
228+
&mut wallet,
229+
true, // update state
230+
)
231+
.await;
229232

230233
// A normal transaction to an identity registration address should NOT be detected
231234
// Identity addresses are only for special transactions (AssetLock)

0 commit comments

Comments
 (0)