mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-22 11:39:29 +00:00
improve performance by pre-fetching txs for subaddress queries
This commit is contained in:
parent
4fb62d8669
commit
d9f2ce425f
3 changed files with 33 additions and 27 deletions
|
@ -37,9 +37,6 @@ import java.util.Map;
|
|||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
|
@ -57,6 +54,7 @@ import monero.wallet.MoneroWallet;
|
|||
import monero.wallet.MoneroWalletRpc;
|
||||
import monero.wallet.model.MoneroCheckTx;
|
||||
import monero.wallet.model.MoneroDestination;
|
||||
import monero.wallet.model.MoneroOutputQuery;
|
||||
import monero.wallet.model.MoneroOutputWallet;
|
||||
import monero.wallet.model.MoneroSubaddress;
|
||||
import monero.wallet.model.MoneroTransferQuery;
|
||||
|
@ -784,8 +782,9 @@ public class XmrWalletService {
|
|||
return addressEntry.get();
|
||||
} else {
|
||||
// We try to use available and not yet used entries
|
||||
List<MoneroTxWallet> incomingTxs = getIncomingTxs(null); // pre-fetch all incoming txs to avoid query per subaddress
|
||||
Optional<XmrAddressEntry> emptyAvailableAddressEntry = getAddressEntryListAsImmutableList().stream().filter(e -> XmrAddressEntry.Context.AVAILABLE == e.getContext())
|
||||
.filter(e -> isSubaddressUnused(e.getSubaddressIndex())).findAny();
|
||||
.filter(e -> isSubaddressUnused(e.getSubaddressIndex(), incomingTxs)).findAny();
|
||||
if (emptyAvailableAddressEntry.isPresent()) {
|
||||
return xmrAddressEntryList.swapAvailableToAddressEntryWithOfferId(emptyAvailableAddressEntry.get(), context, offerId);
|
||||
} else {
|
||||
|
@ -890,7 +889,33 @@ public class XmrWalletService {
|
|||
}
|
||||
|
||||
public boolean isSubaddressUnused(int subaddressIndex) {
|
||||
return getNumTxOutputsForSubaddress(subaddressIndex) == 0;
|
||||
return isSubaddressUnused(subaddressIndex, null);
|
||||
}
|
||||
|
||||
private boolean isSubaddressUnused(int subaddressIndex, List<MoneroTxWallet> incomingTxs) {
|
||||
return getNumTxOutputsForSubaddress(subaddressIndex, incomingTxs) == 0;
|
||||
}
|
||||
|
||||
public int getNumTxOutputsForSubaddress(int subaddressIndex) {
|
||||
return getNumTxOutputsForSubaddress(subaddressIndex, null);
|
||||
}
|
||||
|
||||
private int getNumTxOutputsForSubaddress(int subaddressIndex, List<MoneroTxWallet> incomingTxs) {
|
||||
if (incomingTxs == null) incomingTxs = getIncomingTxs(subaddressIndex);
|
||||
int numUnspentOutputs = 0;
|
||||
for (MoneroTxWallet tx : incomingTxs) {
|
||||
numUnspentOutputs += tx.isConfirmed() ? tx.getOutputsWallet(new MoneroOutputQuery().setSubaddressIndex(subaddressIndex)).size() : 1; // TODO: monero-project does not provide outputs for unconfirmed txs
|
||||
}
|
||||
return numUnspentOutputs;
|
||||
}
|
||||
|
||||
private List<MoneroTxWallet> getIncomingTxs(Integer subaddressIndex) {
|
||||
return wallet.getTxs(new MoneroTxQuery()
|
||||
.setTransferQuery((new MoneroTransferQuery()
|
||||
.setAccountIndex(0)
|
||||
.setSubaddressIndex(subaddressIndex)
|
||||
.setIsIncoming(true)))
|
||||
.setIncludeOutputs(true));
|
||||
}
|
||||
|
||||
public Coin getBalanceForAddress(String address) {
|
||||
|
@ -917,24 +942,6 @@ public class XmrWalletService {
|
|||
return Coin.valueOf(balance.longValueExact());
|
||||
}
|
||||
|
||||
public int getNumTxOutputsForSubaddress(int subaddressIndex) {
|
||||
|
||||
// get txs with transfers to the subaddress
|
||||
List<MoneroTxWallet> txs = wallet.getTxs(new MoneroTxQuery()
|
||||
.setTransferQuery((new MoneroTransferQuery()
|
||||
.setAccountIndex(0)
|
||||
.setSubaddressIndex(subaddressIndex)
|
||||
.setIsIncoming(true)))
|
||||
.setIncludeOutputs(true));
|
||||
|
||||
// count num outputs
|
||||
int numUnspentOutputs = 0;
|
||||
for (MoneroTxWallet tx : txs) {
|
||||
numUnspentOutputs += tx.isConfirmed() ? tx.getOutputs().size() : 1; // TODO: monero-project does not provide outputs for unconfirmed txs
|
||||
}
|
||||
return numUnspentOutputs;
|
||||
}
|
||||
|
||||
public Coin getAvailableConfirmedBalance() {
|
||||
return wallet != null ? Coin.valueOf(wallet.getUnlockedBalance(0).longValueExact()) : Coin.ZERO;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ public class ArbitratorProtocol extends DisputeProtocol {
|
|||
ArbitratorProcessDepositRequest.class)
|
||||
.using(new TradeTaskRunner(trade,
|
||||
() -> {
|
||||
if (trade.getState() == Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS) {
|
||||
if (trade.getState().ordinal() >= Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS.ordinal()) {
|
||||
stopTimeout();
|
||||
this.errorMessageHandler = null;
|
||||
}
|
||||
|
|
|
@ -424,7 +424,6 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
|||
handleTaskRunnerSuccess(peer, message);
|
||||
},
|
||||
(errorMessage) -> {
|
||||
stopTimeout();
|
||||
handleTaskRunnerFault(peer, message, errorMessage);
|
||||
})))
|
||||
.executeTasks(true);
|
||||
|
@ -589,14 +588,14 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
|||
// Timeout
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected void startTimeout(long timeoutSec) {
|
||||
protected synchronized void startTimeout(long timeoutSec) {
|
||||
stopTimeout();
|
||||
timeoutTimer = UserThread.runAfter(() -> {
|
||||
handleError("Timeout reached. Protocol did not complete in " + timeoutSec + " sec. TradeID=" + trade.getId() + ", state=" + trade.stateProperty().get());
|
||||
}, timeoutSec);
|
||||
}
|
||||
|
||||
protected void stopTimeout() {
|
||||
protected synchronized void stopTimeout() {
|
||||
if (timeoutTimer != null) {
|
||||
timeoutTimer.stop();
|
||||
timeoutTimer = null;
|
||||
|
|
Loading…
Reference in a new issue