mirror of
https://github.com/boldsuck/haveno.git
synced 2024-12-22 20:19:21 +00:00
fix scheduling offers by computing spendable amount from txs
Some checks failed
CI / build (macos-13) (push) Has been cancelled
CI / build (ubuntu-22.04) (push) Has been cancelled
CI / build (windows-latest) (push) Has been cancelled
Codacy Coverage Reporter / Publish coverage (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
Some checks failed
CI / build (macos-13) (push) Has been cancelled
CI / build (ubuntu-22.04) (push) Has been cancelled
CI / build (windows-latest) (push) Has been cancelled
Codacy Coverage Reporter / Publish coverage (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
This commit is contained in:
parent
544d69827a
commit
7e29dc188d
2 changed files with 38 additions and 29 deletions
|
@ -127,7 +127,6 @@ public class CreateOfferService {
|
||||||
isPrivateOffer,
|
isPrivateOffer,
|
||||||
buyerAsTakerWithoutDeposit);
|
buyerAsTakerWithoutDeposit);
|
||||||
|
|
||||||
|
|
||||||
// verify buyer as taker security deposit
|
// verify buyer as taker security deposit
|
||||||
boolean isBuyerMaker = offerUtil.isBuyOffer(direction);
|
boolean isBuyerMaker = offerUtil.isBuyOffer(direction);
|
||||||
if (!isBuyerMaker && !isPrivateOffer && buyerAsTakerWithoutDeposit) {
|
if (!isBuyerMaker && !isPrivateOffer && buyerAsTakerWithoutDeposit) {
|
||||||
|
|
|
@ -948,7 +948,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
if (openOffer.getScheduledTxHashes() != null) {
|
if (openOffer.getScheduledTxHashes() != null) {
|
||||||
boolean scheduledTxsAvailable = true;
|
boolean scheduledTxsAvailable = true;
|
||||||
for (MoneroTxWallet tx : xmrWalletService.getTxs(openOffer.getScheduledTxHashes())) {
|
for (MoneroTxWallet tx : xmrWalletService.getTxs(openOffer.getScheduledTxHashes())) {
|
||||||
if (!tx.isLocked() && !isOutputsAvailable(tx)) {
|
if (!tx.isLocked() && !hasSpendableAmount(tx)) {
|
||||||
scheduledTxsAvailable = false;
|
scheduledTxsAvailable = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1165,31 +1165,21 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
throw new RuntimeException("Not enough money in Haveno wallet");
|
throw new RuntimeException("Not enough money in Haveno wallet");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get earliest available or pending txs with sufficient incoming amount
|
// get earliest available or pending txs with sufficient spendable amount
|
||||||
BigInteger scheduledAmount = BigInteger.ZERO;
|
BigInteger scheduledAmount = BigInteger.ZERO;
|
||||||
Set<MoneroTxWallet> scheduledTxs = new HashSet<MoneroTxWallet>();
|
Set<MoneroTxWallet> scheduledTxs = new HashSet<MoneroTxWallet>();
|
||||||
for (MoneroTxWallet tx : xmrWalletService.getTxs()) {
|
for (MoneroTxWallet tx : xmrWalletService.getTxs()) {
|
||||||
|
|
||||||
// skip if no funds available
|
// get spendable amount
|
||||||
BigInteger sentToSelfAmount = xmrWalletService.getAmountSentToSelf(tx); // amount sent to self always shows 0, so compute from destinations manually
|
BigInteger spendableAmount = getSpendableAmount(tx);
|
||||||
if (sentToSelfAmount.equals(BigInteger.ZERO) && (tx.getIncomingTransfers() == null || tx.getIncomingTransfers().isEmpty())) continue;
|
|
||||||
if (!isOutputsAvailable(tx)) continue;
|
// skip if no spendable amount or already scheduled
|
||||||
|
if (spendableAmount.equals(BigInteger.ZERO)) continue;
|
||||||
if (isTxScheduledByOtherOffer(openOffers, openOffer, tx.getHash())) continue;
|
if (isTxScheduledByOtherOffer(openOffers, openOffer, tx.getHash())) continue;
|
||||||
|
|
||||||
// schedule transaction if funds sent to self, because they are not included in incoming transfers // TODO: fix in libraries?
|
// schedule tx
|
||||||
if (sentToSelfAmount.compareTo(BigInteger.ZERO) > 0) {
|
scheduledAmount = scheduledAmount.add(spendableAmount);
|
||||||
scheduledAmount = scheduledAmount.add(sentToSelfAmount);
|
|
||||||
scheduledTxs.add(tx);
|
scheduledTxs.add(tx);
|
||||||
} else if (tx.getIncomingTransfers() != null) {
|
|
||||||
|
|
||||||
// schedule transaction if incoming tranfers to account 0
|
|
||||||
for (MoneroIncomingTransfer transfer : tx.getIncomingTransfers()) {
|
|
||||||
if (transfer.getAccountIndex() == 0) {
|
|
||||||
scheduledAmount = scheduledAmount.add(transfer.getAmount());
|
|
||||||
scheduledTxs.add(tx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// break if sufficient funds
|
// break if sufficient funds
|
||||||
if (scheduledAmount.compareTo(offerReserveAmount) >= 0) break;
|
if (scheduledAmount.compareTo(offerReserveAmount) >= 0) break;
|
||||||
|
@ -1202,6 +1192,34 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
openOffer.setState(OpenOffer.State.PENDING);
|
openOffer.setState(OpenOffer.State.PENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BigInteger getSpendableAmount(MoneroTxWallet tx) {
|
||||||
|
|
||||||
|
// compute spendable amount from outputs if confirmed
|
||||||
|
if (tx.isConfirmed()) {
|
||||||
|
BigInteger spendableAmount = BigInteger.ZERO;
|
||||||
|
if (tx.getOutputsWallet() != null) {
|
||||||
|
for (MoneroOutputWallet output : tx.getOutputsWallet()) {
|
||||||
|
if (!output.isSpent() && !output.isFrozen() && output.getAccountIndex() == 0) {
|
||||||
|
spendableAmount = spendableAmount.add(output.getAmount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return spendableAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// funds sent to self always show 0 incoming amount, so compute from destinations manually
|
||||||
|
// TODO: this excludes change output, so change is missing from spendable amount until confirmed
|
||||||
|
BigInteger sentToSelfAmount = xmrWalletService.getAmountSentToSelf(tx);
|
||||||
|
if (sentToSelfAmount.compareTo(BigInteger.ZERO) > 0) return sentToSelfAmount;
|
||||||
|
|
||||||
|
// if not confirmed and not sent to self, return incoming amount
|
||||||
|
return tx.getIncomingAmount() == null ? BigInteger.ZERO : tx.getIncomingAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasSpendableAmount(MoneroTxWallet tx) {
|
||||||
|
return getSpendableAmount(tx).compareTo(BigInteger.ZERO) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
private BigInteger getScheduledAmount(List<OpenOffer> openOffers) {
|
private BigInteger getScheduledAmount(List<OpenOffer> openOffers) {
|
||||||
BigInteger scheduledAmount = BigInteger.ZERO;
|
BigInteger scheduledAmount = BigInteger.ZERO;
|
||||||
for (OpenOffer openOffer : openOffers) {
|
for (OpenOffer openOffer : openOffers) {
|
||||||
|
@ -1233,14 +1251,6 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOutputsAvailable(MoneroTxWallet tx) {
|
|
||||||
if (tx.getOutputsWallet() == null) return false;
|
|
||||||
for (MoneroOutputWallet output : tx.getOutputsWallet()) {
|
|
||||||
if (output.isSpent() || output.isFrozen()) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void signAndPostOffer(OpenOffer openOffer,
|
private void signAndPostOffer(OpenOffer openOffer,
|
||||||
boolean useSavingsWallet, // TODO: remove this?
|
boolean useSavingsWallet, // TODO: remove this?
|
||||||
TransactionResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
TransactionResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||||
|
|
Loading…
Reference in a new issue