mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-22 19:49:32 +00:00
Handle arbitrator giving all payout to one trader
This commit is contained in:
parent
1f7daac389
commit
c7cc810d47
1 changed files with 35 additions and 27 deletions
|
@ -65,6 +65,7 @@ import com.google.common.base.Preconditions;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -618,12 +619,10 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
||||||
|
|
||||||
// TODO (woodser): include arbitration fee
|
// TODO (woodser): include arbitration fee
|
||||||
//System.out.println("Creating feeEstimateTx!");
|
//System.out.println("Creating feeEstimateTx!");
|
||||||
MoneroTxWallet feeEstimateTx = multisigWallet.createTx(new MoneroTxConfig()
|
MoneroTxConfig txConfig = new MoneroTxConfig().setAccountIndex(0).setRelay(false);
|
||||||
.setAccountIndex(0)
|
if (buyerPayoutAmount.compareTo(BigInteger.ZERO) == 1) txConfig.addDestination(buyerPayoutAddress, buyerPayoutAmount.multiply(BigInteger.valueOf(4)).divide(BigInteger.valueOf(5))); // reduce payment amount to compute fee of similar tx
|
||||||
.addDestination(buyerPayoutAddress, buyerPayoutAmount.multiply(BigInteger.valueOf(4)).divide(BigInteger.valueOf(5))) // reduce payment amount to compute fee of similar tx
|
if (sellerPayoutAmount.compareTo(BigInteger.ZERO) == 1) txConfig.addDestination(sellerPayoutAddress, sellerPayoutAmount.multiply(BigInteger.valueOf(4)).divide(BigInteger.valueOf(5)));
|
||||||
.addDestination(sellerPayoutAddress, sellerPayoutAmount.multiply(BigInteger.valueOf(4)).divide(BigInteger.valueOf(5)))
|
MoneroTxWallet feeEstimateTx = multisigWallet.createTx(txConfig);
|
||||||
.setRelay(false)
|
|
||||||
);
|
|
||||||
|
|
||||||
System.out.println("Created fee estimate tx!");
|
System.out.println("Created fee estimate tx!");
|
||||||
System.out.println(feeEstimateTx);
|
System.out.println(feeEstimateTx);
|
||||||
|
@ -632,16 +631,21 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
||||||
// attempt to create payout tx by increasing estimated fee until successful
|
// attempt to create payout tx by increasing estimated fee until successful
|
||||||
MoneroTxWallet payoutTx = null;
|
MoneroTxWallet payoutTx = null;
|
||||||
int numAttempts = 0;
|
int numAttempts = 0;
|
||||||
|
int feeDivisor = 0; // adjust fee divisor based on number of payout destinations
|
||||||
|
if (buyerPayoutAmount.compareTo(BigInteger.ZERO) == 1) feeDivisor += 1;
|
||||||
|
if (sellerPayoutAmount.compareTo(BigInteger.ZERO) == 1) feeDivisor += 1;
|
||||||
|
|
||||||
while (payoutTx == null && numAttempts < 50) {
|
while (payoutTx == null && numAttempts < 50) {
|
||||||
BigInteger feeEstimate = feeEstimateTx.getFee().add(feeEstimateTx.getFee().multiply(BigInteger.valueOf(numAttempts)).divide(BigInteger.valueOf(10))); // add 1/10 of fee until tx is successful
|
BigInteger feeEstimate = feeEstimateTx.getFee().add(feeEstimateTx.getFee().multiply(BigInteger.valueOf(numAttempts)).divide(BigInteger.valueOf(10))); // add 1/10 of fee until tx is successful
|
||||||
|
txConfig = new MoneroTxConfig().setAccountIndex(0).setRelay(false);
|
||||||
|
if (buyerPayoutAmount.compareTo(BigInteger.ZERO) == 1) txConfig.addDestination(buyerPayoutAddress, buyerPayoutAmount.subtract(feeEstimate.divide(BigInteger.valueOf(feeDivisor)))); // split fee subtracted from each payout amount
|
||||||
|
if (sellerPayoutAmount.compareTo(BigInteger.ZERO) == 1) txConfig.addDestination(sellerPayoutAddress, sellerPayoutAmount.subtract(feeEstimate.divide(BigInteger.valueOf(feeDivisor))));
|
||||||
try {
|
try {
|
||||||
numAttempts++;
|
numAttempts++;
|
||||||
payoutTx = multisigWallet.createTx(new MoneroTxConfig()
|
payoutTx = multisigWallet.createTx(txConfig);
|
||||||
.setAccountIndex(0)
|
|
||||||
.addDestination(buyerPayoutAddress, buyerPayoutAmount.subtract(feeEstimate.divide(BigInteger.valueOf(2)))) // split fee subtracted from each payout amount
|
|
||||||
.addDestination(sellerPayoutAddress, sellerPayoutAmount.subtract(feeEstimate.divide(BigInteger.valueOf(2))))
|
|
||||||
.setRelay(false));
|
|
||||||
} catch (MoneroError e) {
|
} catch (MoneroError e) {
|
||||||
|
System.out.println(e.toString());
|
||||||
|
System.out.println(e.getStackTrace());
|
||||||
// exception expected // TODO: better way of estimating fee?
|
// exception expected // TODO: better way of estimating fee?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -677,32 +681,36 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
||||||
MoneroTxWallet arbitratorSignedPayoutTx = parsedTxSet.getTxs().get(0);
|
MoneroTxWallet arbitratorSignedPayoutTx = parsedTxSet.getTxs().get(0);
|
||||||
System.out.println("Parsed arbitrator-signed payout tx:\n" + arbitratorSignedPayoutTx);
|
System.out.println("Parsed arbitrator-signed payout tx:\n" + arbitratorSignedPayoutTx);
|
||||||
|
|
||||||
// verify payout tx has exactly 2 destinations
|
// verify payout tx has 1 or 2 destinations
|
||||||
if (arbitratorSignedPayoutTx.getOutgoingTransfer() == null || arbitratorSignedPayoutTx.getOutgoingTransfer().getDestinations() == null || arbitratorSignedPayoutTx.getOutgoingTransfer().getDestinations().size() != 2) throw new RuntimeException("Buyer-signed payout tx does not have exactly two destinations");
|
int numDestinations = arbitratorSignedPayoutTx.getOutgoingTransfer() == null || arbitratorSignedPayoutTx.getOutgoingTransfer().getDestinations() == null ? 0 : arbitratorSignedPayoutTx.getOutgoingTransfer().getDestinations().size();
|
||||||
|
if (numDestinations != 1 && numDestinations != 2) throw new RuntimeException("Buyer-signed payout tx does not have 1 or 2 destinations");
|
||||||
|
|
||||||
// get buyer and seller destinations (order not preserved)
|
// get buyer and seller destinations (order not preserved)
|
||||||
boolean buyerFirst = arbitratorSignedPayoutTx.getOutgoingTransfer().getDestinations().get(0).getAddress().equals(contract.getBuyerPayoutAddressString());
|
List<MoneroDestination> destinations = arbitratorSignedPayoutTx.getOutgoingTransfer().getDestinations();
|
||||||
MoneroDestination buyerPayoutDestination = arbitratorSignedPayoutTx.getOutgoingTransfer().getDestinations().get(buyerFirst ? 0 : 1);
|
boolean buyerFirst = destinations.get(0).getAddress().equals(contract.getBuyerPayoutAddressString());
|
||||||
MoneroDestination sellerPayoutDestination = arbitratorSignedPayoutTx.getOutgoingTransfer().getDestinations().get(buyerFirst ? 1 : 0);
|
MoneroDestination buyerPayoutDestination = buyerFirst ? destinations.get(0) : numDestinations == 2 ? destinations.get(1) : null;
|
||||||
|
MoneroDestination sellerPayoutDestination = buyerFirst ? (numDestinations == 2 ? destinations.get(1) : null) : destinations.get(0);
|
||||||
|
|
||||||
// verify payout addresses
|
// verify payout addresses
|
||||||
if (!buyerPayoutDestination.getAddress().equals(contract.getBuyerPayoutAddressString())) throw new RuntimeException("Buyer payout address does not match contract");
|
if (buyerPayoutDestination != null && !buyerPayoutDestination.getAddress().equals(contract.getBuyerPayoutAddressString())) throw new RuntimeException("Buyer payout address does not match contract");
|
||||||
if (!sellerPayoutDestination.getAddress().equals(contract.getSellerPayoutAddressString())) throw new RuntimeException("Seller payout address does not match contract");
|
if (sellerPayoutDestination != null && !sellerPayoutDestination.getAddress().equals(contract.getSellerPayoutAddressString())) throw new RuntimeException("Seller payout address does not match contract");
|
||||||
|
|
||||||
// verify change address is multisig's primary address
|
// verify change address is multisig's primary address
|
||||||
if (!arbitratorSignedPayoutTx.getChangeAddress().equals(multisigWallet.getPrimaryAddress())) throw new RuntimeException("Change address is not multisig wallet's primary address");
|
if (!arbitratorSignedPayoutTx.getChangeAddress().equals(multisigWallet.getPrimaryAddress())) throw new RuntimeException("Change address is not multisig wallet's primary address");
|
||||||
|
|
||||||
// verify sum of outputs = destination amounts + change amount
|
// verify sum of outputs = destination amounts + change amount
|
||||||
if (!arbitratorSignedPayoutTx.getOutputSum().equals(buyerPayoutDestination.getAmount().add(sellerPayoutDestination.getAmount()).add(arbitratorSignedPayoutTx.getChangeAmount()))) throw new RuntimeException("Sum of outputs != destination amounts + change amount");
|
BigInteger destinationSum = (buyerPayoutDestination == null ? BigInteger.ZERO : buyerPayoutDestination.getAmount()).add(sellerPayoutDestination == null ? BigInteger.ZERO : sellerPayoutDestination.getAmount());
|
||||||
|
if (!arbitratorSignedPayoutTx.getOutputSum().equals(destinationSum.add(arbitratorSignedPayoutTx.getChangeAmount()))) throw new RuntimeException("Sum of outputs != destination amounts + change amount");
|
||||||
|
|
||||||
// verify buyer destination amount is payout amount - 1/2 tx costs
|
// verify buyer destination amount is payout amount - 1/2 tx costs
|
||||||
|
if (buyerPayoutDestination != null) {
|
||||||
BigInteger txCost = arbitratorSignedPayoutTx.getFee().add(arbitratorSignedPayoutTx.getChangeAmount());
|
BigInteger txCost = arbitratorSignedPayoutTx.getFee().add(arbitratorSignedPayoutTx.getChangeAmount());
|
||||||
BigInteger expectedBuyerPayout = buyerPayoutAmount.subtract(txCost.divide(BigInteger.valueOf(2)));
|
BigInteger expectedBuyerPayout = buyerPayoutAmount.subtract(txCost.divide(BigInteger.valueOf(2)));
|
||||||
|
|
||||||
System.out.println("Dispute buyer payout amount: " + buyerPayoutAmount);
|
System.out.println("Dispute buyer payout amount: " + buyerPayoutAmount);
|
||||||
System.out.println("Tx cost: " + txCost);
|
System.out.println("Tx cost: " + txCost);
|
||||||
System.out.println("Buyer destination payout amount: " + buyerPayoutDestination.getAmount());
|
System.out.println("Buyer destination payout amount: " + buyerPayoutDestination.getAmount());
|
||||||
|
}
|
||||||
|
|
||||||
// payout amount is dispute payout amount - 1/2 tx cost - deposit tx fee
|
// payout amount is dispute payout amount - 1/2 tx cost - deposit tx fee
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue