mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-22 03:29:28 +00:00
allow scheduling funds from split output tx
This commit is contained in:
parent
542441d9d2
commit
7340ca9c21
1 changed files with 29 additions and 29 deletions
|
@ -115,7 +115,6 @@ import lombok.Getter;
|
||||||
import monero.common.MoneroRpcConnection;
|
import monero.common.MoneroRpcConnection;
|
||||||
import monero.daemon.model.MoneroKeyImageSpentStatus;
|
import monero.daemon.model.MoneroKeyImageSpentStatus;
|
||||||
import monero.daemon.model.MoneroTx;
|
import monero.daemon.model.MoneroTx;
|
||||||
import monero.wallet.model.MoneroIncomingTransfer;
|
|
||||||
import monero.wallet.model.MoneroOutputQuery;
|
import monero.wallet.model.MoneroOutputQuery;
|
||||||
import monero.wallet.model.MoneroOutputWallet;
|
import monero.wallet.model.MoneroOutputWallet;
|
||||||
import monero.wallet.model.MoneroTransferQuery;
|
import monero.wallet.model.MoneroTransferQuery;
|
||||||
|
@ -1159,23 +1158,17 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
|
|
||||||
private void scheduleWithEarliestTxs(List<OpenOffer> openOffers, OpenOffer openOffer) {
|
private void scheduleWithEarliestTxs(List<OpenOffer> openOffers, OpenOffer openOffer) {
|
||||||
|
|
||||||
// check for sufficient balance - scheduled offers amount
|
|
||||||
BigInteger offerReserveAmount = openOffer.getOffer().getAmountNeeded();
|
|
||||||
if (xmrWalletService.getBalance().subtract(getScheduledAmount(openOffers)).compareTo(offerReserveAmount) < 0) {
|
|
||||||
throw new RuntimeException("Not enough money in Haveno wallet");
|
|
||||||
}
|
|
||||||
|
|
||||||
// get earliest available or pending txs with sufficient spendable amount
|
// get earliest available or pending txs with sufficient spendable amount
|
||||||
|
BigInteger offerReserveAmount = openOffer.getOffer().getAmountNeeded();
|
||||||
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()) {
|
||||||
|
|
||||||
// get spendable amount
|
// get unscheduled spendable amount
|
||||||
BigInteger spendableAmount = getSpendableAmount(tx);
|
BigInteger spendableAmount = getUnscheduledSpendableAmount(tx, openOffers);
|
||||||
|
|
||||||
// skip if no spendable amount or already scheduled
|
// skip if no spendable amount
|
||||||
if (spendableAmount.equals(BigInteger.ZERO)) continue;
|
if (spendableAmount.equals(BigInteger.ZERO)) continue;
|
||||||
if (isTxScheduledByOtherOffer(openOffers, openOffer, tx.getHash())) continue;
|
|
||||||
|
|
||||||
// schedule tx
|
// schedule tx
|
||||||
scheduledAmount = scheduledAmount.add(spendableAmount);
|
scheduledAmount = scheduledAmount.add(spendableAmount);
|
||||||
|
@ -1184,7 +1177,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
// break if sufficient funds
|
// break if sufficient funds
|
||||||
if (scheduledAmount.compareTo(offerReserveAmount) >= 0) break;
|
if (scheduledAmount.compareTo(offerReserveAmount) >= 0) break;
|
||||||
}
|
}
|
||||||
if (scheduledAmount.compareTo(offerReserveAmount) < 0) throw new RuntimeException("Not enough funds to schedule offer");
|
if (scheduledAmount.compareTo(offerReserveAmount) < 0) throw new RuntimeException("Not enough funds to create offer");
|
||||||
|
|
||||||
// schedule txs
|
// schedule txs
|
||||||
openOffer.setScheduledTxHashes(scheduledTxs.stream().map(tx -> tx.getHash()).collect(Collectors.toList()));
|
openOffer.setScheduledTxHashes(scheduledTxs.stream().map(tx -> tx.getHash()).collect(Collectors.toList()));
|
||||||
|
@ -1192,6 +1185,30 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
openOffer.setState(OpenOffer.State.PENDING);
|
openOffer.setState(OpenOffer.State.PENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BigInteger getUnscheduledSpendableAmount(MoneroTxWallet tx, List<OpenOffer> openOffers) {
|
||||||
|
if (isScheduledWithUnknownAmount(tx, openOffers)) return BigInteger.ZERO;
|
||||||
|
return getSpendableAmount(tx).subtract(getSplitAmount(tx, openOffers)).max(BigInteger.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isScheduledWithUnknownAmount(MoneroTxWallet tx, List<OpenOffer> openOffers) {
|
||||||
|
for (OpenOffer openOffer : openOffers) {
|
||||||
|
if (openOffer.getScheduledTxHashes() == null) continue;
|
||||||
|
if (openOffer.getScheduledTxHashes().contains(tx.getHash()) && !tx.getHash().equals(openOffer.getSplitOutputTxHash())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigInteger getSplitAmount(MoneroTxWallet tx, List<OpenOffer> openOffers) {
|
||||||
|
for (OpenOffer openOffer : openOffers) {
|
||||||
|
if (openOffer.getSplitOutputTxHash() == null) continue;
|
||||||
|
if (!openOffer.getSplitOutputTxHash().equals(tx.getHash())) continue;
|
||||||
|
return openOffer.getOffer().getAmountNeeded();
|
||||||
|
}
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
private BigInteger getSpendableAmount(MoneroTxWallet tx) {
|
private BigInteger getSpendableAmount(MoneroTxWallet tx) {
|
||||||
|
|
||||||
// compute spendable amount from outputs if confirmed
|
// compute spendable amount from outputs if confirmed
|
||||||
|
@ -1220,23 +1237,6 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
return getSpendableAmount(tx).compareTo(BigInteger.ZERO) > 0;
|
return getSpendableAmount(tx).compareTo(BigInteger.ZERO) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigInteger getScheduledAmount(List<OpenOffer> openOffers) {
|
|
||||||
BigInteger scheduledAmount = BigInteger.ZERO;
|
|
||||||
for (OpenOffer openOffer : openOffers) {
|
|
||||||
if (openOffer.getState() != OpenOffer.State.PENDING) continue;
|
|
||||||
if (openOffer.getScheduledTxHashes() == null) continue;
|
|
||||||
List<MoneroTxWallet> fundingTxs = xmrWalletService.getTxs(openOffer.getScheduledTxHashes());
|
|
||||||
for (MoneroTxWallet fundingTx : fundingTxs) {
|
|
||||||
if (fundingTx.getIncomingTransfers() != null) {
|
|
||||||
for (MoneroIncomingTransfer transfer : fundingTx.getIncomingTransfers()) {
|
|
||||||
if (transfer.getAccountIndex() == 0) scheduledAmount = scheduledAmount.add(transfer.getAmount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return scheduledAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isTxScheduledByOtherOffer(List<OpenOffer> openOffers, OpenOffer openOffer, String txHash) {
|
private boolean isTxScheduledByOtherOffer(List<OpenOffer> openOffers, OpenOffer openOffer, String txHash) {
|
||||||
for (OpenOffer otherOffer : openOffers) {
|
for (OpenOffer otherOffer : openOffers) {
|
||||||
if (otherOffer == openOffer) continue;
|
if (otherOffer == openOffer) continue;
|
||||||
|
|
Loading…
Reference in a new issue