Skip to content

Commit 184b299

Browse files
committed
fix race condition when removing tx
1 parent f4dcad1 commit 184b299

File tree

2 files changed

+13
-12
lines changed

2 files changed

+13
-12
lines changed

BRPeerManager.c

+12-11
Original file line numberDiff line numberDiff line change
@@ -494,29 +494,30 @@ static void _requestUnrelayedTxGetdataDone(void *info, int success)
494494
// don't remove transactions until we're connected to maxConnectCount peers, and all peers have finished
495495
// relaying their mempools
496496
if (count >= manager->maxConnectCount) {
497+
UInt256 hash;
497498
size_t txCount = BRWalletTxUnconfirmedBefore(manager->wallet, NULL, 0, TX_UNCONFIRMED);
498-
BRTransaction *tx[(txCount < 10000) ? txCount : 10000];
499+
BRTransaction *tx[(txCount*sizeof(BRTransaction *) <= 0x1000) ? txCount : 0x1000/sizeof(BRTransaction *)];
499500

500501
txCount = BRWalletTxUnconfirmedBefore(manager->wallet, tx, sizeof(tx)/sizeof(*tx), TX_UNCONFIRMED);
501502

502-
for (size_t i = 0; i < txCount; i++) {
503+
for (size_t i = txCount; i > 0; i--) {
504+
hash = tx[i - 1]->txHash;
503505
isPublishing = 0;
504506

505507
for (size_t j = array_count(manager->publishedTx); ! isPublishing && j > 0; j--) {
506-
if (BRTransactionEq(manager->publishedTx[j - 1].tx, tx[i]) &&
508+
if (BRTransactionEq(manager->publishedTx[j - 1].tx, tx[i - 1]) &&
507509
manager->publishedTx[j - 1].callback != NULL) isPublishing = 1;
508510
}
509511

510-
if (! isPublishing && _BRTxPeerListCount(manager->txRelays, tx[i]->txHash) == 0 &&
511-
_BRTxPeerListCount(manager->txRequests, tx[i]->txHash) == 0) {
512-
peer_log(peer, "removing tx unconfirmed at height: %d, txHash: %s", manager->lastBlock->height,
513-
u256hex(tx[i]->txHash));
514-
assert(tx[i]->blockHeight == TX_UNCONFIRMED);
515-
BRWalletRemoveTransaction(manager->wallet, tx[i]->txHash);
512+
if (! isPublishing && _BRTxPeerListCount(manager->txRelays, hash) == 0 &&
513+
_BRTxPeerListCount(manager->txRequests, hash) == 0) {
514+
peer_log(peer, "removing tx unconfirmed at: %d, txHash: %s", manager->lastBlock->height, u256hex(hash));
515+
assert(tx[i - 1]->blockHeight == TX_UNCONFIRMED);
516+
BRWalletRemoveTransaction(manager->wallet, hash);
516517
}
517-
else if (! isPublishing && _BRTxPeerListCount(manager->txRelays, tx[i]->txHash) < manager->maxConnectCount){
518+
else if (! isPublishing && _BRTxPeerListCount(manager->txRelays, hash) < manager->maxConnectCount) {
518519
// set timestamp 0 to mark as unverified
519-
_BRPeerManagerUpdateTx(manager, &tx[i]->txHash, 1, TX_UNCONFIRMED, 0);
520+
_BRPeerManagerUpdateTx(manager, &hash, 1, TX_UNCONFIRMED, 0);
520521
}
521522
}
522523
}

BRWallet.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -813,9 +813,9 @@ void BRWalletRemoveTransaction(BRWallet *wallet, UInt256 txHash)
813813
}
814814
}
815815

816-
BRTransactionFree(tx);
817816
if (wallet->balanceChanged) wallet->balanceChanged(wallet->callbackInfo, wallet->balance);
818817
if (wallet->txDeleted) wallet->txDeleted(wallet->callbackInfo, txHash, notifyUser, recommendRescan);
818+
BRTransactionFree(tx);
819819
}
820820

821821
array_free(hashes);

0 commit comments

Comments
 (0)