Separate security deposit for buyer and seller. Remove arbitrator amount and address at dispute result. Remove Payout policy. Add bank as reason.

This commit is contained in:
Manfred Karrer 2017-03-15 17:06:44 -05:00
parent a4b15f5906
commit 5afd2bde11
15 changed files with 153 additions and 357 deletions

View file

@ -17,5 +17,5 @@ public class DevEnv {
// If set to true we ignore several UI behavior like confirmation popups as well dummy accounts are created and
// offers are filled with default values. Intended to make dev testing faster.
public static final boolean DEV_MODE = STRESS_TEST_MODE || false;
public static final boolean DEV_MODE = STRESS_TEST_MODE || true;
}

View file

@ -385,16 +385,9 @@ message DisputeResultMessage {
// payload
message DisputeResult {
enum DisputeFeePolicy {
LOSER = 0;
SPLIT = 1;
WAIVE = 2;
}
enum Winner {
BUYER = 0;
SELLER = 1;
STALE_MATE = 2;
}
// only append new values as we use the ordinal value
@ -405,27 +398,25 @@ message DisputeResult {
SCAM = 3;
PROTOCOL_VIOLATION = 4;
NO_REPLY = 5;
BANK_PROBLEMS = 6;
}
string trade_id = 1;
int32 trader_id = 2;
DisputeFeePolicy dispute_fee_policy = 3;
Winner winner = 4;
int32 reason_ordinal = 5;
Winner winner = 3;
int32 reason_ordinal = 4;
bool tamper_proof_evidence = 6;
bool id_verification = 7;
bool screen_cast = 8;
string summary_notes = 9;
DisputeCommunicationMessage dispute_communication_message = 10;
bytes arbitrator_signature = 11;
int64 buyer_payout_amount = 12;
int64 seller_payout_amount = 13;
int64 arbitrator_payout_amount = 14;
string arbitrator_address_as_string = 15;
bytes arbitrator_pub_key = 16;
int64 close_date = 17;
bool is_loser_publisher = 18;
bool tamper_proof_evidence = 5;
bool id_verification = 6;
bool screen_cast = 7;
string summary_notes = 8;
DisputeCommunicationMessage dispute_communication_message = 9;
bytes arbitrator_signature = 10;
int64 buyer_payout_amount = 11;
int64 seller_payout_amount = 12;
bytes arbitrator_pub_key = 13;
int64 close_date = 14;
bool is_loser_publisher = 15;
}
message OpenNewDisputeMessage {
Dispute dispute = 1;

View file

@ -976,19 +976,13 @@ disputeSummaryWindow.evidence.tamperProof=Tamper proof evidence
disputeSummaryWindow.evidence.id=ID Verification
disputeSummaryWindow.evidence.video=Video/Screencast
disputeSummaryWindow.payout=Trade amount payout:
disputeSummaryWindow.payout.buyerWinner=BTC buyer gets trade amount payout
disputeSummaryWindow.payout.sellerWinner=BTC seller gets trade amount payout
disputeSummaryWindow.payout.both=Both gets half trade amount payout
disputeSummaryWindow.payout.getsTradeAmount=BTC {0} gets trade amount payout
disputeSummaryWindow.payout.getsAll=BTC {0} gets all
disputeSummaryWindow.payout.custom=Custom payout
disputeSummaryWindow.payout.adjustAmount=Amount entered exceeds available amount of {0}.\n\
We adjust this input field to the max possible value.
disputeSummaryWindow.arbitrationFee=Arbitration fee:
disputeSummaryWindow.arbitrationFee.looserPay=Loser pays arbitration fee
disputeSummaryWindow.split=Split arbitration fee
disputeSummaryWindow.arbitrationFee.waive=Waive arbitration fee
disputeSummaryWindow.payoutAmount.buyer=Buyer's payout amount:
disputeSummaryWindow.payoutAmount.seller=Seller's payout amount:
disputeSummaryWindow.payoutAmount.arbitrator=Arbitrator's payout amount:
disputeSummaryWindow.payoutAmount.invert=Use loser as publisher:
disputeSummaryWindow.reason=Reason of dispute:
disputeSummaryWindow.reason.bug=Bug
@ -997,6 +991,7 @@ disputeSummaryWindow.reason.protocolViolation=Protocol violation
disputeSummaryWindow.reason.noReply=No reply
disputeSummaryWindow.reason.scam=Scam
disputeSummaryWindow.reason.other=Other
disputeSummaryWindow.reason.bank=Bank
disputeSummaryWindow.summaryNotes=Summary notes:
disputeSummaryWindow.addSummaryNotes=Add summary notes
disputeSummaryWindow.close.button=Close ticket
@ -1006,9 +1001,8 @@ Summary:\n\
{3} did ID verification: {4}\n\
{5} did screencast or video: {6}\n\
Payout amount for BTC buyer: {7}\n\
Payout amount for BTC seller: {8}\n\
Arbitrator''s dispute fee: {9}\n\n\
Summary notes:\n{10}
Payout amount for BTC seller: {8}\n\n\
Summary notes:\n{9}
disputeSummaryWindow.close.closePeer=You need to close also the trading peers ticket!
emptyWalletWindow.headline=Emergency wallet tool

View file

@ -976,19 +976,13 @@ disputeSummaryWindow.evidence.tamperProof=Tamper proof evidence
disputeSummaryWindow.evidence.id=ID Verification
disputeSummaryWindow.evidence.video=Video/Screencast
disputeSummaryWindow.payout=Trade amount payout:
disputeSummaryWindow.payout.buyerWinner=BTC buyer gets trade amount payout
disputeSummaryWindow.payout.sellerWinner=BTC seller gets trade amount payout
disputeSummaryWindow.payout.both=Both gets half trade amount payout
disputeSummaryWindow.payout.getsTradeAmount=BTC {0} gets trade amount payout
disputeSummaryWindow.payout.getsAll=BTC {0} gets all
disputeSummaryWindow.payout.custom=Custom payout
disputeSummaryWindow.payout.adjustAmount=Amount entered exceeds available amount of {0}.\n\
We adjust this input field to the max possible value.
disputeSummaryWindow.arbitrationFee=Arbitration fee:
disputeSummaryWindow.arbitrationFee.looserPay=Loser pays arbitration fee
disputeSummaryWindow.split=Split arbitration fee
disputeSummaryWindow.arbitrationFee.waive=Waive arbitration fee
disputeSummaryWindow.payoutAmount.buyer=Buyer's payout amount:
disputeSummaryWindow.payoutAmount.seller=Seller's payout amount:
disputeSummaryWindow.payoutAmount.arbitrator=Arbitrator's payout amount:
disputeSummaryWindow.payoutAmount.invert=Use loser as publisher:
disputeSummaryWindow.reason=Reason of dispute:
disputeSummaryWindow.reason.bug=Bug
@ -1006,9 +1000,8 @@ Summary:\n\
{3} did ID verification: {4}\n\
{5} did screencast or video: {6}\n\
Payout amount for BTC buyer: {7}\n\
Payout amount for BTC seller: {8}\n\
Arbitrator''s dispute fee: {9}\n\n\
Summary notes:\n{10}
Payout amount for BTC seller: {8}\n\n\
Summary notes:\n{9}
disputeSummaryWindow.close.closePeer=You need to close also the trading peers ticket!
emptyWalletWindow.headline=Emergency wallet tool

View file

@ -59,10 +59,7 @@ import org.slf4j.LoggerFactory;
import javax.inject.Named;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -580,8 +577,7 @@ public class DisputeManager {
}
if ((isBuyer && publisher == DisputeResult.Winner.BUYER)
|| (!isBuyer && publisher == DisputeResult.Winner.SELLER)
|| (isBuyer && publisher == DisputeResult.Winner.STALE_MATE)) {
|| (!isBuyer && publisher == DisputeResult.Winner.SELLER)) {
final Optional<Trade> tradeOptional = tradeManager.getTradeById(tradeId);
Transaction payoutTx = null;
@ -605,10 +601,8 @@ public class DisputeManager {
disputeResult.getArbitratorSignature(),
disputeResult.getBuyerPayoutAmount(),
disputeResult.getSellerPayoutAmount(),
disputeResult.getArbitratorPayoutAmount(),
contract.getBuyerPayoutAddressString(),
contract.getSellerPayoutAddressString(),
disputeResult.getArbitratorAddressAsString(),
multiSigKeyPair,
contract.getBuyerMultiSigPubKey(),
contract.getSellerMultiSigPubKey(),
@ -727,7 +721,8 @@ public class DisputeManager {
}
private boolean isArbitrator(DisputeResult disputeResult) {
return disputeResult.getArbitratorAddressAsString().equals(walletService.getOrCreateAddressEntry(AddressEntry.Context.ARBITRATOR).getAddressString());
return Arrays.equals(disputeResult.getArbitratorPubKey(),
walletService.getOrCreateAddressEntry(AddressEntry.Context.ARBITRATOR).getPubKey());
}
public String getNrOfDisputes(boolean isBuyer, Contract contract) {

View file

@ -685,10 +685,8 @@ public class TradeWalletService {
* @param depositTxSerialized Serialized deposit tx
* @param buyerPayoutAmount The payout amount of the buyer.
* @param sellerPayoutAmount The payout amount of the seller.
* @param arbitratorPayoutAmount The payout amount of the arbitrator.
* @param buyerAddressString The address of the buyer.
* @param sellerAddressString The address of the seller.
* @param arbitratorAddressString The address of the arbitrator.
* @param arbitratorKeyPair The keypair of the arbitrator.
* @param buyerPubKey The public key of the buyer.
* @param sellerPubKey The public key of the seller.
@ -700,10 +698,8 @@ public class TradeWalletService {
public byte[] arbitratorSignsDisputedPayoutTx(byte[] depositTxSerialized,
Coin buyerPayoutAmount,
Coin sellerPayoutAmount,
Coin arbitratorPayoutAmount,
String buyerAddressString,
String sellerAddressString,
String arbitratorAddressString,
DeterministicKey arbitratorKeyPair,
byte[] buyerPubKey,
byte[] sellerPubKey,
@ -714,10 +710,8 @@ public class TradeWalletService {
log.trace("depositTx " + depositTx.toString());
log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString());
log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString());
log.trace("arbitratorPayoutAmount " + arbitratorPayoutAmount.toFriendlyString());
log.trace("buyerAddressString " + buyerAddressString);
log.trace("sellerAddressString " + sellerAddressString);
log.trace("arbitratorAddressString " + arbitratorAddressString);
log.trace("arbitratorKeyPair (not displayed for security reasons)");
log.info("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString());
log.info("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString());
@ -731,8 +725,6 @@ public class TradeWalletService {
preparedPayoutTx.addOutput(buyerPayoutAmount, new Address(params, buyerAddressString));
if (sellerPayoutAmount.isGreaterThan(Coin.ZERO))
preparedPayoutTx.addOutput(sellerPayoutAmount, new Address(params, sellerAddressString));
if (arbitratorPayoutAmount.isGreaterThan(Coin.ZERO) && arbitratorAddressString != null)
preparedPayoutTx.addOutput(arbitratorPayoutAmount, new Address(params, arbitratorAddressString));
// take care of sorting!
Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey);
@ -757,10 +749,8 @@ public class TradeWalletService {
* @param arbitratorSignature DER encoded canonical signature of arbitrator
* @param buyerPayoutAmount Payout amount of the buyer
* @param sellerPayoutAmount Payout amount of the seller
* @param arbitratorPayoutAmount Payout amount for arbitrator
* @param buyerAddressString The address of the buyer.
* @param sellerAddressString The address of the seller.
* @param arbitratorAddressString The address of the arbitrator.
* @param tradersMultiSigKeyPair The keypair for the MultiSig of the trader who calls that method
* @param buyerPubKey The public key of the buyer.
* @param sellerPubKey The public key of the seller.
@ -774,10 +764,8 @@ public class TradeWalletService {
byte[] arbitratorSignature,
Coin buyerPayoutAmount,
Coin sellerPayoutAmount,
Coin arbitratorPayoutAmount,
String buyerAddressString,
String sellerAddressString,
String arbitratorAddressString,
DeterministicKey tradersMultiSigKeyPair,
byte[] buyerPubKey,
byte[] sellerPubKey,
@ -791,10 +779,8 @@ public class TradeWalletService {
log.trace("arbitratorSignature s " + ECKey.ECDSASignature.decodeFromDER(arbitratorSignature).s.toString());
log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString());
log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString());
log.trace("arbitratorPayoutAmount " + arbitratorPayoutAmount.toFriendlyString());
log.trace("buyerAddressString " + buyerAddressString);
log.trace("sellerAddressString " + sellerAddressString);
log.trace("arbitratorAddressString " + arbitratorAddressString);
log.trace("tradersMultiSigKeyPair (not displayed for security reasons)");
log.info("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString());
log.info("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString());
@ -808,8 +794,6 @@ public class TradeWalletService {
payoutTx.addOutput(buyerPayoutAmount, new Address(params, buyerAddressString));
if (sellerPayoutAmount.isGreaterThan(Coin.ZERO))
payoutTx.addOutput(sellerPayoutAmount, new Address(params, sellerAddressString));
if (arbitratorPayoutAmount.isGreaterThan(Coin.ZERO))
payoutTx.addOutput(arbitratorPayoutAmount, new Address(params, arbitratorAddressString));
// take care of sorting!
Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey);
@ -843,6 +827,7 @@ public class TradeWalletService {
// Emergency payout tool. Used only in cased when the payput from the arbitrator does not work because some data
// in the trade/dispute are messed up.
// We keep here arbitratorPayoutAmount just in case (requires cooperation from peer anyway)
public Transaction emergencySignAndPublishPayoutTx(String depositTxHex,
Coin buyerPayoutAmount,
Coin sellerPayoutAmount,

View file

@ -121,7 +121,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
ProcessPublishDepositTxRequest.class,
VerifyOffererAccount.class,
VerifyAndSignContract.class,
TakerSignAndPublishDepositTxAsBuyer.class,
SignAndPublishDepositTxAsBuyer.class,
SendDepositTxPublishedMessage.class,
PublishTradeStatistics.class
);

View file

@ -69,7 +69,7 @@ public class OffererCreatesAndSignsDepositTxAsBuyer extends TradeTask {
Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
checkArgument(addressEntryOptional.isPresent(), "addressEntryOptional must be present");
AddressEntry buyerMultiSigAddressEntry = addressEntryOptional.get();
buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInputAmount.subtract(trade.getTxFee()));
buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInputAmount);
walletService.saveAddressEntryList();
Address offererAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
Address offererChangeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();

View file

@ -68,7 +68,7 @@ public class OffererCreatesAndSignsDepositTxAsSeller extends TradeTask {
Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
checkArgument(addressEntryOptional.isPresent(), "addressEntry must be set here.");
AddressEntry sellerMultiSigAddressEntry = addressEntryOptional.get();
sellerMultiSigAddressEntry.setCoinLockedInMultiSig(sellerInputAmount.subtract(trade.getTxFee()));
sellerMultiSigAddressEntry.setCoinLockedInMultiSig(sellerInputAmount);
byte[] sellerMultiSigPubKey = processModel.getMyMultiSigPubKey();
checkArgument(Arrays.equals(sellerMultiSigPubKey,
sellerMultiSigAddressEntry.getPubKey()),

View file

@ -15,7 +15,7 @@
* along with bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bisq.trade.protocol.trade.tasks.buyer;
package io.bisq.trade.protocol.trade.tasks.taker;
import com.google.common.util.concurrent.FutureCallback;
import io.bisq.btc.AddressEntry;
@ -38,11 +38,11 @@ import java.util.Optional;
import static com.google.common.base.Preconditions.checkArgument;
public class TakerSignAndPublishDepositTxAsBuyer extends TradeTask {
private static final Logger log = LoggerFactory.getLogger(TakerSignAndPublishDepositTxAsBuyer.class);
public class SignAndPublishDepositTxAsBuyer extends TradeTask {
private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTxAsBuyer.class);
@SuppressWarnings({"WeakerAccess", "unused"})
public TakerSignAndPublishDepositTxAsBuyer(TaskRunner taskHandler, Trade trade) {
public SignAndPublishDepositTxAsBuyer(TaskRunner taskHandler, Trade trade) {
super(taskHandler, trade);
}
@ -67,7 +67,7 @@ public class TakerSignAndPublishDepositTxAsBuyer extends TradeTask {
checkArgument(addressEntryOptional.isPresent(), "addressEntryOptional must be present");
AddressEntry buyerMultiSigAddressEntry = addressEntryOptional.get();
Coin buyerInput = Coin.valueOf(buyerInputs.stream().mapToLong(input -> input.value).sum());
buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInput.subtract(trade.getTxFee()));
buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInput.subtract(trade.getTxFee().multiply(2)));
TradingPeer tradingPeer = processModel.tradingPeer;
byte[] buyerMultiSigPubKey = processModel.getMyMultiSigPubKey();
checkArgument(Arrays.equals(buyerMultiSigPubKey, buyerMultiSigAddressEntry.getPubKey()),

View file

@ -15,7 +15,7 @@
* along with bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bisq.trade.protocol.trade.tasks.seller;
package io.bisq.trade.protocol.trade.tasks.taker;
import com.google.common.util.concurrent.FutureCallback;
import io.bisq.btc.AddressEntry;
@ -71,7 +71,7 @@ public class SignAndPublishDepositTxAsSeller extends TradeTask {
"sellerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
Coin sellerInput = Coin.valueOf(sellerInputs.stream().mapToLong(input -> input.value).sum());
sellerMultiSigAddressEntry.setCoinLockedInMultiSig(sellerInput.subtract(trade.getTxFee()));
sellerMultiSigAddressEntry.setCoinLockedInMultiSig(sellerInput.subtract(trade.getTxFee().multiply(2)));
TradingPeer tradingPeer = processModel.tradingPeer;
Transaction depositTx = processModel.getTradeWalletService().takerSignsAndPublishesDepositTx(
true,

View file

@ -36,7 +36,6 @@ import io.bisq.messages.arbitration.DisputeResult;
import io.bisq.messages.trade.offer.payload.Offer;
import io.bisq.messages.trade.payload.Contract;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
@ -69,25 +68,23 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
private final TradeWalletService tradeWalletService;
private Dispute dispute;
private Optional<Runnable> finalizeDisputeHandlerOptional = Optional.empty();
private ToggleGroup tradeAmountToggleGroup;
private ToggleGroup tradeAmountToggleGroup, reasonToggleGroup;
private DisputeResult disputeResult;
private RadioButton buyerIsWinnerRadioButton, sellerIsWinnerRadioButton, shareRadioButton, customRadioButton, loserPaysFeeRadioButton, splitFeeRadioButton,
waiveFeeRadioButton, reasonWasBugRadioButton, reasonWasUsabilityIssueRadioButton, reasonProtocolViolationRadioButton, reasonNoReplyRadioButton, reasonWasScamRadioButton, reasonWasOtherRadioButton;
private RadioButton buyerGetsTradeAmountRadioButton, sellerGetsTradeAmountRadioButton,
buyerGetsAllRadioButton, sellerGetsAllRadioButton, customRadioButton;
private RadioButton reasonWasBugRadioButton, reasonWasUsabilityIssueRadioButton,
reasonProtocolViolationRadioButton, reasonNoReplyRadioButton, reasonWasScamRadioButton,
reasonWasOtherRadioButton, reasonWasBankRadioButton;
private Optional<Dispute> peersDisputeOptional;
private Coin arbitratorPayoutAmount, winnerPayoutAmount, loserPayoutAmount, stalematePayoutAmount;
private ToggleGroup feeToggleGroup, reasonToggleGroup;
private String role;
private TextArea summaryNotesTextArea;
// keep a reference to not get GCed
private ObjectBinding<Tuple2<DisputeResult.DisputeFeePolicy, Toggle>> feePaymentPolicyChanged;
private ChangeListener<Tuple2<DisputeResult.DisputeFeePolicy, Toggle>> feePaymentPolicyListener;
private ChangeListener<Boolean> shareRadioButtonSelectedListener, customRadioButtonSelectedListener;
private ChangeListener<Toggle> feeToggleSelectionListener, reasonToggleSelectionListener;
private InputTextField buyerPayoutAmountInputTextField, sellerPayoutAmountInputTextField, arbitratorPayoutAmountInputTextField;
private ChangeListener<String> buyerPayoutAmountListener, sellerPayoutAmountListener, arbitratorPayoutAmountListener;
private ChangeListener<Boolean> customRadioButtonSelectedListener;
private ChangeListener<Toggle> reasonToggleSelectionListener;
private InputTextField buyerPayoutAmountInputTextField, sellerPayoutAmountInputTextField;
private ChangeListener<String> buyerPayoutAmountListener, sellerPayoutAmountListener;
private CheckBox isLoserPublisherCheckBox;
private ChangeListener<Toggle> tradeAmountToggleGroupListener;
///////////////////////////////////////////////////////////////////////////////////////////
@ -108,7 +105,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
this.dispute = dispute;
rowIndex = -1;
width = 850;
width = 1050;
createGridPane();
addContent();
display();
@ -126,21 +123,15 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
@Override
protected void cleanup() {
if (feePaymentPolicyChanged != null)
feePaymentPolicyChanged.removeListener(feePaymentPolicyListener);
if (shareRadioButton != null)
shareRadioButton.selectedProperty().removeListener(shareRadioButtonSelectedListener);
if (feeToggleGroup != null)
feeToggleGroup.selectedToggleProperty().removeListener(feeToggleSelectionListener);
if (reasonToggleGroup != null)
reasonToggleGroup.selectedToggleProperty().removeListener(reasonToggleSelectionListener);
if (customRadioButton != null)
customRadioButton.selectedProperty().removeListener(customRadioButtonSelectedListener);
if (tradeAmountToggleGroup != null)
tradeAmountToggleGroup.selectedToggleProperty().removeListener(tradeAmountToggleGroupListener);
removePayoutAmountListeners();
}
@ -183,7 +174,6 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
addCheckboxes();
addTradeAmountPayoutControls();
addFeeControls();
addPayoutAmountTextFields();
addReasonControls();
@ -193,8 +183,6 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
DisputeResult peersDisputeResult = peersDisputeOptional.get().disputeResultProperty().get();
disputeResult.setBuyerPayoutAmount(peersDisputeResult.getBuyerPayoutAmount());
disputeResult.setSellerPayoutAmount(peersDisputeResult.getSellerPayoutAmount());
disputeResult.setArbitratorPayoutAmount(peersDisputeResult.getArbitratorPayoutAmount());
disputeResult.setDisputeFeePolicy(peersDisputeResult.getDisputeFeePolicy());
disputeResult.setWinner(peersDisputeResult.getWinner());
disputeResult.setLoserIsPublisher(peersDisputeResult.isLoserPublisher());
disputeResult.setReason(peersDisputeResult.getReason());
@ -203,23 +191,18 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
if (disputeResult.getBuyerPayoutAmount() != null) {
log.debug("buyerPayoutAmount " + disputeResult.getBuyerPayoutAmount().toFriendlyString());
log.debug("sellerPayoutAmount " + disputeResult.getSellerPayoutAmount().toFriendlyString());
log.debug("arbitratorPayoutAmount " + disputeResult.getArbitratorPayoutAmount().toFriendlyString());
}
buyerIsWinnerRadioButton.setDisable(true);
sellerIsWinnerRadioButton.setDisable(true);
shareRadioButton.setDisable(true);
buyerGetsTradeAmountRadioButton.setDisable(true);
buyerGetsAllRadioButton.setDisable(true);
sellerGetsTradeAmountRadioButton.setDisable(true);
sellerGetsAllRadioButton.setDisable(true);
customRadioButton.setDisable(true);
loserPaysFeeRadioButton.setDisable(true);
splitFeeRadioButton.setDisable(true);
waiveFeeRadioButton.setDisable(true);
buyerPayoutAmountInputTextField.setDisable(true);
sellerPayoutAmountInputTextField.setDisable(true);
arbitratorPayoutAmountInputTextField.setDisable(true);
buyerPayoutAmountInputTextField.setEditable(false);
sellerPayoutAmountInputTextField.setEditable(false);
arbitratorPayoutAmountInputTextField.setEditable(false);
reasonWasBugRadioButton.setDisable(true);
reasonWasUsabilityIssueRadioButton.setDisable(true);
@ -227,25 +210,17 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
reasonNoReplyRadioButton.setDisable(true);
reasonWasScamRadioButton.setDisable(true);
reasonWasOtherRadioButton.setDisable(true);
reasonWasBankRadioButton.setDisable(true);
isLoserPublisherCheckBox.setDisable(true);
isLoserPublisherCheckBox.setSelected(peersDisputeResult.isLoserPublisher());
calculatePayoutAmounts(disputeResult.getDisputeFeePolicy());
applyPayoutAmounts(tradeAmountToggleGroup.selectedToggleProperty().get());
applyTradeAmountRadioButtonStates();
} else {
applyPayoutAmounts(disputeResult.disputeFeePolicyProperty().get(), tradeAmountToggleGroup.selectedToggleProperty().get());
feePaymentPolicyChanged = Bindings.createObjectBinding(
() -> new Tuple2<>(disputeResult.disputeFeePolicyProperty().get(), tradeAmountToggleGroup.selectedToggleProperty().get()),
disputeResult.disputeFeePolicyProperty(),
tradeAmountToggleGroup.selectedToggleProperty());
feePaymentPolicyListener = (observable, oldValue, newValue) -> applyPayoutAmounts(newValue.first, newValue.second);
feePaymentPolicyChanged.addListener(feePaymentPolicyListener);
isLoserPublisherCheckBox.setSelected(false);
}
setFeeRadioButtonState();
setReasonRadioButtonState();
addSummaryNotes();
@ -299,55 +274,46 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
Label distributionLabel = addLabel(gridPane, ++rowIndex, Res.get("disputeSummaryWindow.payout"), 10);
GridPane.setValignment(distributionLabel, VPos.TOP);
buyerIsWinnerRadioButton = new RadioButton(Res.get("disputeSummaryWindow.payout.buyerWinner"));
sellerIsWinnerRadioButton = new RadioButton(Res.get("disputeSummaryWindow.payout.sellerWinner"));
shareRadioButton = new RadioButton(Res.get("disputeSummaryWindow.payout.both"));
buyerGetsTradeAmountRadioButton = new RadioButton(Res.get("disputeSummaryWindow.payout.getsTradeAmount",
Res.get("shared.buyer")));
buyerGetsAllRadioButton = new RadioButton(Res.get("disputeSummaryWindow.payout.getsAll",
Res.get("shared.buyer")));
sellerGetsTradeAmountRadioButton = new RadioButton(Res.get("disputeSummaryWindow.payout.getsTradeAmount",
Res.get("shared.seller")));
sellerGetsAllRadioButton = new RadioButton(Res.get("disputeSummaryWindow.payout.getsAll",
Res.get("shared.seller")));
customRadioButton = new RadioButton(Res.get("disputeSummaryWindow.payout.custom"));
VBox radioButtonPane = new VBox();
radioButtonPane.setSpacing(10);
radioButtonPane.getChildren().addAll(buyerIsWinnerRadioButton, sellerIsWinnerRadioButton, shareRadioButton, customRadioButton);
radioButtonPane.getChildren().addAll(buyerGetsTradeAmountRadioButton, buyerGetsAllRadioButton,
sellerGetsTradeAmountRadioButton, sellerGetsAllRadioButton,
customRadioButton);
GridPane.setRowIndex(radioButtonPane, rowIndex);
GridPane.setColumnIndex(radioButtonPane, 1);
GridPane.setMargin(radioButtonPane, new Insets(10, 0, 0, 0));
gridPane.getChildren().add(radioButtonPane);
tradeAmountToggleGroup = new ToggleGroup();
buyerIsWinnerRadioButton.setToggleGroup(tradeAmountToggleGroup);
sellerIsWinnerRadioButton.setToggleGroup(tradeAmountToggleGroup);
shareRadioButton.setToggleGroup(tradeAmountToggleGroup);
buyerGetsTradeAmountRadioButton.setToggleGroup(tradeAmountToggleGroup);
buyerGetsAllRadioButton.setToggleGroup(tradeAmountToggleGroup);
sellerGetsTradeAmountRadioButton.setToggleGroup(tradeAmountToggleGroup);
sellerGetsAllRadioButton.setToggleGroup(tradeAmountToggleGroup);
customRadioButton.setToggleGroup(tradeAmountToggleGroup);
shareRadioButtonSelectedListener = (observable, oldValue, newValue) -> {
if (newValue) {
loserPaysFeeRadioButton.setSelected(false);
if (splitFeeRadioButton != null && !dispute.isSupportTicket())
splitFeeRadioButton.setSelected(true);
if (waiveFeeRadioButton != null && dispute.isSupportTicket())
waiveFeeRadioButton.setSelected(true);
}
loserPaysFeeRadioButton.setDisable(newValue);
};
shareRadioButton.selectedProperty().addListener(shareRadioButtonSelectedListener);
tradeAmountToggleGroupListener = (observable, oldValue, newValue) -> applyPayoutAmounts(newValue);
tradeAmountToggleGroup.selectedToggleProperty().addListener(tradeAmountToggleGroupListener);
buyerPayoutAmountListener = (observable1, oldValue1, newValue1) -> applyCustomAmounts(buyerPayoutAmountInputTextField);
sellerPayoutAmountListener = (observable1, oldValue1, newValue1) -> applyCustomAmounts(sellerPayoutAmountInputTextField);
arbitratorPayoutAmountListener = (observable1, oldValue1, newValue1) -> applyCustomAmounts(arbitratorPayoutAmountInputTextField);
customRadioButtonSelectedListener = (observable, oldValue, newValue) -> {
buyerPayoutAmountInputTextField.setEditable(newValue);
sellerPayoutAmountInputTextField.setEditable(newValue);
arbitratorPayoutAmountInputTextField.setEditable(newValue);
loserPaysFeeRadioButton.setDisable(newValue);
splitFeeRadioButton.setDisable(newValue);
waiveFeeRadioButton.setDisable(newValue);
if (newValue) {
buyerPayoutAmountInputTextField.textProperty().addListener(buyerPayoutAmountListener);
sellerPayoutAmountInputTextField.textProperty().addListener(sellerPayoutAmountListener);
arbitratorPayoutAmountInputTextField.textProperty().addListener(arbitratorPayoutAmountListener);
} else {
removePayoutAmountListeners();
}
@ -362,21 +328,18 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
if (sellerPayoutAmountInputTextField != null && sellerPayoutAmountListener != null)
sellerPayoutAmountInputTextField.textProperty().removeListener(sellerPayoutAmountListener);
if (arbitratorPayoutAmountInputTextField != null && arbitratorPayoutAmountListener != null)
arbitratorPayoutAmountInputTextField.textProperty().removeListener(arbitratorPayoutAmountListener);
}
private boolean isPayoutAmountValid() {
Coin buyerAmount = formatter.parseToCoin(buyerPayoutAmountInputTextField.getText());
Coin sellerAmount = formatter.parseToCoin(sellerPayoutAmountInputTextField.getText());
Coin arbitratorAmount = formatter.parseToCoin(arbitratorPayoutAmountInputTextField.getText());
Contract contract = dispute.getContract();
Coin tradeAmount = contract.getTradeAmount();
Offer offer = contract.offer;
Coin available = tradeAmount
.add(offer.getBuyerSecurityDeposit())
.add(offer.getSellerSecurityDeposit());
Coin totalAmount = buyerAmount.add(sellerAmount).add(arbitratorAmount);
Coin totalAmount = buyerAmount.add(sellerAmount);
return (totalAmount.compareTo(available) == 0);
}
@ -384,75 +347,34 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
Contract contract = dispute.getContract();
Coin buyerAmount = formatter.parseToCoin(buyerPayoutAmountInputTextField.getText());
Coin sellerAmount = formatter.parseToCoin(sellerPayoutAmountInputTextField.getText());
Coin arbitratorAmount = formatter.parseToCoin(arbitratorPayoutAmountInputTextField.getText());
Offer offer = contract.offer;
Coin available = contract.getTradeAmount().
add(offer.getBuyerSecurityDeposit())
.add(offer.getSellerSecurityDeposit());
Coin totalAmount = buyerAmount.add(sellerAmount).add(arbitratorAmount);
Coin totalAmount = buyerAmount.add(sellerAmount);
if (totalAmount.compareTo(available) > 0) {
new Popup<>().warning(Res.get("disputeSummaryWindow.payout.adjustAmount", available.toFriendlyString()))
.show();
if (inputTextField == buyerPayoutAmountInputTextField) {
buyerAmount = available.subtract(sellerAmount).subtract(arbitratorAmount);
buyerAmount = available.subtract(sellerAmount);
inputTextField.setText(formatter.formatCoin(buyerAmount));
} else if (inputTextField == sellerPayoutAmountInputTextField) {
sellerAmount = available.subtract(buyerAmount).subtract(arbitratorAmount);
sellerAmount = available.subtract(buyerAmount);
inputTextField.setText(formatter.formatCoin(sellerAmount));
} else if (inputTextField == arbitratorPayoutAmountInputTextField) {
arbitratorAmount = available.subtract(sellerAmount).subtract(buyerAmount);
inputTextField.setText(formatter.formatCoin(arbitratorAmount));
}
}
disputeResult.setBuyerPayoutAmount(buyerAmount);
disputeResult.setSellerPayoutAmount(sellerAmount);
disputeResult.setArbitratorPayoutAmount(arbitratorAmount);
if (buyerAmount.compareTo(sellerAmount) == 0)
disputeResult.setWinner(DisputeResult.Winner.STALE_MATE);
else if (buyerAmount.compareTo(sellerAmount) > 0)
if (buyerAmount.compareTo(sellerAmount) > 0)
disputeResult.setWinner(DisputeResult.Winner.BUYER);
else
disputeResult.setWinner(DisputeResult.Winner.SELLER);
}
private void addFeeControls() {
Label splitFeeLabel = addLabel(gridPane, ++rowIndex, Res.get("disputeSummaryWindow.arbitrationFee"), 10);
GridPane.setValignment(splitFeeLabel, VPos.TOP);
loserPaysFeeRadioButton = new RadioButton(Res.get("disputeSummaryWindow.arbitrationFee.looserPay"));
splitFeeRadioButton = new RadioButton(Res.get("disputeSummaryWindow.split"));
waiveFeeRadioButton = new RadioButton(Res.get("disputeSummaryWindow.arbitrationFee.waive"));
HBox feeRadioButtonPane = new HBox();
feeRadioButtonPane.setSpacing(20);
feeRadioButtonPane.getChildren().addAll(loserPaysFeeRadioButton, splitFeeRadioButton, waiveFeeRadioButton);
GridPane.setRowIndex(feeRadioButtonPane, rowIndex);
GridPane.setColumnIndex(feeRadioButtonPane, 1);
GridPane.setMargin(feeRadioButtonPane, new Insets(10, 0, 10, 0));
gridPane.getChildren().add(feeRadioButtonPane);
feeToggleGroup = new ToggleGroup();
loserPaysFeeRadioButton.setToggleGroup(feeToggleGroup);
splitFeeRadioButton.setToggleGroup(feeToggleGroup);
waiveFeeRadioButton.setToggleGroup(feeToggleGroup);
feeToggleSelectionListener = (observable, oldValue, newValue) -> {
if (newValue == loserPaysFeeRadioButton)
disputeResult.setDisputeFeePolicy(DisputeResult.DisputeFeePolicy.LOSER);
else if (newValue == splitFeeRadioButton)
disputeResult.setDisputeFeePolicy(DisputeResult.DisputeFeePolicy.SPLIT);
else if (newValue == waiveFeeRadioButton)
disputeResult.setDisputeFeePolicy(DisputeResult.DisputeFeePolicy.WAIVE);
};
feeToggleGroup.selectedToggleProperty().addListener(feeToggleSelectionListener);
if (dispute.isSupportTicket())
feeToggleGroup.selectToggle(waiveFeeRadioButton);
}
private void addPayoutAmountTextFields() {
buyerPayoutAmountInputTextField = addLabelInputTextField(gridPane, ++rowIndex,
Res.get("disputeSummaryWindow.payoutAmount.buyer")).second;
@ -462,28 +384,10 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
Res.get("disputeSummaryWindow.payoutAmount.seller")).second;
sellerPayoutAmountInputTextField.setEditable(false);
arbitratorPayoutAmountInputTextField = addLabelInputTextField(gridPane, ++rowIndex,
Res.get("disputeSummaryWindow.payoutAmount.arbitrator")).second;
arbitratorPayoutAmountInputTextField.setEditable(false);
isLoserPublisherCheckBox = addLabelCheckBox(gridPane, ++rowIndex,
Res.get("disputeSummaryWindow.payoutAmount.invert")).second;
}
private void setFeeRadioButtonState() {
switch (disputeResult.getDisputeFeePolicy()) {
case LOSER:
feeToggleGroup.selectToggle(loserPaysFeeRadioButton);
break;
case SPLIT:
feeToggleGroup.selectToggle(splitFeeRadioButton);
break;
case WAIVE:
feeToggleGroup.selectToggle(waiveFeeRadioButton);
break;
}
}
private void addReasonControls() {
Label label = addLabel(gridPane, ++rowIndex, Res.get("disputeSummaryWindow.reason"), 10);
GridPane.setValignment(label, VPos.TOP);
@ -492,6 +396,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
reasonProtocolViolationRadioButton = new RadioButton(Res.get("disputeSummaryWindow.reason.protocolViolation"));
reasonNoReplyRadioButton = new RadioButton(Res.get("disputeSummaryWindow.reason.noReply"));
reasonWasScamRadioButton = new RadioButton(Res.get("disputeSummaryWindow.reason.scam"));
reasonWasBankRadioButton = new RadioButton(Res.get("disputeSummaryWindow.reason.bank"));
reasonWasOtherRadioButton = new RadioButton(Res.get("disputeSummaryWindow.reason.other"));
//TODO add banks as reason
@ -499,7 +404,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
feeRadioButtonPane.setSpacing(20);
feeRadioButtonPane.getChildren().addAll(reasonWasBugRadioButton, reasonWasUsabilityIssueRadioButton,
reasonProtocolViolationRadioButton, reasonNoReplyRadioButton,
reasonWasScamRadioButton, reasonWasOtherRadioButton);
reasonWasBankRadioButton, reasonWasScamRadioButton, reasonWasOtherRadioButton);
GridPane.setRowIndex(feeRadioButtonPane, rowIndex);
GridPane.setColumnIndex(feeRadioButtonPane, 1);
GridPane.setMargin(feeRadioButtonPane, new Insets(10, 0, 10, 0));
@ -512,6 +417,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
reasonNoReplyRadioButton.setToggleGroup(reasonToggleGroup);
reasonWasScamRadioButton.setToggleGroup(reasonToggleGroup);
reasonWasOtherRadioButton.setToggleGroup(reasonToggleGroup);
reasonWasBankRadioButton.setToggleGroup(reasonToggleGroup);
reasonToggleSelectionListener = (observable, oldValue, newValue) -> {
if (newValue == reasonWasBugRadioButton)
@ -524,6 +430,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
disputeResult.setReason(DisputeResult.Reason.NO_REPLY);
else if (newValue == reasonWasScamRadioButton)
disputeResult.setReason(DisputeResult.Reason.SCAM);
else if (newValue == reasonWasBankRadioButton)
disputeResult.setReason(DisputeResult.Reason.BANK_PROBLEMS);
else if (newValue == reasonWasOtherRadioButton)
disputeResult.setReason(DisputeResult.Reason.OTHER);
};
@ -548,6 +456,9 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
case SCAM:
reasonToggleGroup.selectToggle(reasonWasScamRadioButton);
break;
case BANK_PROBLEMS:
reasonToggleGroup.selectToggle(reasonWasBankRadioButton);
break;
case OTHER:
reasonToggleGroup.selectToggle(reasonWasOtherRadioButton);
break;
@ -582,8 +493,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
tradeAmountToggleGroup.selectedToggleProperty(),
summaryNotesTextArea.textProperty(),
buyerPayoutAmountInputTextField.textProperty(),
sellerPayoutAmountInputTextField.textProperty(),
arbitratorPayoutAmountInputTextField.textProperty()));
sellerPayoutAmountInputTextField.textProperty()));
Button cancelButton = tuple.second;
@ -592,8 +502,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
if (dispute.getDepositTxSerialized() != null) {
try {
AddressEntry arbitratorAddressEntry = walletService.getOrCreateAddressEntry(AddressEntry.Context.ARBITRATOR);
disputeResult.setArbitratorAddressAsString(arbitratorAddressEntry.getAddressString());
disputeResult.setArbitratorPubKey(arbitratorAddressEntry.getPubKey());
disputeResult.setArbitratorPubKey(walletService.getOrCreateAddressEntry(AddressEntry.Context.ARBITRATOR).getPubKey());
/* byte[] depositTxSerialized,
Coin buyerPayoutAmount,
@ -610,10 +519,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
dispute.getDepositTxSerialized(),
disputeResult.getBuyerPayoutAmount(),
disputeResult.getSellerPayoutAmount(),
disputeResult.getArbitratorPayoutAmount(),
contract.getBuyerPayoutAddressString(),
contract.getSellerPayoutAddressString(),
arbitratorAddressEntry.getAddressString(),
arbitratorAddressEntry.getKeyPair(),
contract.getBuyerMultiSigPubKey(),
contract.getSellerMultiSigPubKey(),
@ -636,7 +543,6 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
formatter.booleanToYesNo(disputeResult.screenCastProperty().get()),
formatter.formatCoinWithCode(disputeResult.getBuyerPayoutAmount()),
formatter.formatCoinWithCode(disputeResult.getSellerPayoutAmount()),
formatter.formatCoinWithCode(disputeResult.getArbitratorPayoutAmount()),
disputeResult.summaryNotesProperty().get());
dispute.setIsClosed(true);
@ -669,88 +575,68 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
// Controller
///////////////////////////////////////////////////////////////////////////////////////////
private void applyPayoutAmounts(DisputeResult.DisputeFeePolicy feePayment, Toggle selectedTradeAmountToggle) {
if (selectedTradeAmountToggle != customRadioButton) {
calculatePayoutAmounts(feePayment);
if (selectedTradeAmountToggle != null) {
private void applyPayoutAmounts(Toggle selectedTradeAmountToggle) {
if (selectedTradeAmountToggle != customRadioButton && selectedTradeAmountToggle != null) {
applyPayoutAmountsToDisputeResult(selectedTradeAmountToggle);
applyTradeAmountRadioButtonStates();
}
}
}
//TODO
private void calculatePayoutAmounts(DisputeResult.DisputeFeePolicy feePayment) {
private void applyPayoutAmountsToDisputeResult(Toggle selectedTradeAmountToggle) {
Contract contract = dispute.getContract();
Coin buyerSecurityDeposit = contract.offer.getBuyerSecurityDeposit();
Coin sellerSecurityDeposit = contract.offer.getSellerSecurityDeposit();
Coin winnerRefund;
Coin loserRefund;
switch (feePayment) {
case SPLIT:
winnerRefund = buyerSecurityDeposit.divide(2L);
loserRefund = winnerRefund;
arbitratorPayoutAmount = buyerSecurityDeposit;
break;
case WAIVE:
winnerRefund = buyerSecurityDeposit;
loserRefund = buyerSecurityDeposit;
arbitratorPayoutAmount = Coin.ZERO;
break;
case LOSER:
default:
winnerRefund = buyerSecurityDeposit;
loserRefund = Coin.ZERO;
arbitratorPayoutAmount = buyerSecurityDeposit;
break;
}
winnerPayoutAmount = contract.getTradeAmount().add(winnerRefund);
loserPayoutAmount = loserRefund;
stalematePayoutAmount = contract.getTradeAmount().divide(2L).add(winnerRefund);
}
private void applyPayoutAmountsToDisputeResult(Toggle selectedTradeAmountToggle) {
if (selectedTradeAmountToggle == buyerIsWinnerRadioButton) {
disputeResult.setBuyerPayoutAmount(winnerPayoutAmount);
disputeResult.setSellerPayoutAmount(loserPayoutAmount);
Coin tradeAmount = contract.getTradeAmount();
if (selectedTradeAmountToggle == buyerGetsTradeAmountRadioButton) {
disputeResult.setBuyerPayoutAmount(tradeAmount.add(buyerSecurityDeposit));
disputeResult.setSellerPayoutAmount(sellerSecurityDeposit);
disputeResult.setWinner(DisputeResult.Winner.BUYER);
buyerPayoutAmountInputTextField.setText(formatter.formatCoin(winnerPayoutAmount));
sellerPayoutAmountInputTextField.setText(formatter.formatCoin(loserPayoutAmount));
} else if (selectedTradeAmountToggle == sellerIsWinnerRadioButton) {
disputeResult.setBuyerPayoutAmount(loserPayoutAmount);
disputeResult.setSellerPayoutAmount(winnerPayoutAmount);
} else if (selectedTradeAmountToggle == buyerGetsAllRadioButton) {
disputeResult.setBuyerPayoutAmount(tradeAmount
.add(buyerSecurityDeposit)
.add(sellerSecurityDeposit));
disputeResult.setSellerPayoutAmount(Coin.ZERO);
disputeResult.setWinner(DisputeResult.Winner.BUYER);
} else if (selectedTradeAmountToggle == sellerGetsTradeAmountRadioButton) {
disputeResult.setBuyerPayoutAmount(buyerSecurityDeposit);
disputeResult.setSellerPayoutAmount(tradeAmount.add(sellerSecurityDeposit));
disputeResult.setWinner(DisputeResult.Winner.SELLER);
} else if (selectedTradeAmountToggle == sellerGetsAllRadioButton) {
disputeResult.setBuyerPayoutAmount(Coin.ZERO);
disputeResult.setSellerPayoutAmount(tradeAmount
.add(sellerSecurityDeposit)
.add(buyerSecurityDeposit));
disputeResult.setWinner(DisputeResult.Winner.SELLER);
buyerPayoutAmountInputTextField.setText(formatter.formatCoin(loserPayoutAmount));
sellerPayoutAmountInputTextField.setText(formatter.formatCoin(winnerPayoutAmount));
} else if (selectedTradeAmountToggle == shareRadioButton) {
disputeResult.setBuyerPayoutAmount(stalematePayoutAmount);
disputeResult.setSellerPayoutAmount(stalematePayoutAmount);
disputeResult.setWinner(DisputeResult.Winner.STALE_MATE);
buyerPayoutAmountInputTextField.setText(formatter.formatCoin(stalematePayoutAmount));
sellerPayoutAmountInputTextField.setText(formatter.formatCoin(stalematePayoutAmount));
}
disputeResult.setArbitratorPayoutAmount(arbitratorPayoutAmount);
arbitratorPayoutAmountInputTextField.setText(formatter.formatCoin(arbitratorPayoutAmount));
buyerPayoutAmountInputTextField.setText(formatter.formatCoin(disputeResult.getBuyerPayoutAmount()));
sellerPayoutAmountInputTextField.setText(formatter.formatCoin(disputeResult.getSellerPayoutAmount()));
}
private void applyTradeAmountRadioButtonStates() {
Contract contract = dispute.getContract();
Coin buyerSecurityDeposit = contract.offer.getBuyerSecurityDeposit();
Coin sellerSecurityDeposit = contract.offer.getSellerSecurityDeposit();
Coin tradeAmount = contract.getTradeAmount();
Coin buyerPayoutAmount = disputeResult.getBuyerPayoutAmount();
Coin sellerPayoutAmount = disputeResult.getSellerPayoutAmount();
buyerPayoutAmountInputTextField.setText(formatter.formatCoin(buyerPayoutAmount));
sellerPayoutAmountInputTextField.setText(formatter.formatCoin(sellerPayoutAmount));
arbitratorPayoutAmountInputTextField.setText(formatter.formatCoin(disputeResult.getArbitratorPayoutAmount()));
if (buyerPayoutAmount.equals(winnerPayoutAmount) && sellerPayoutAmount.equals(loserPayoutAmount)) {
buyerIsWinnerRadioButton.setSelected(true);
} else if (sellerPayoutAmount.equals(winnerPayoutAmount) && buyerPayoutAmount.equals(loserPayoutAmount)) {
sellerIsWinnerRadioButton.setSelected(true);
} else if (sellerPayoutAmount.equals(buyerPayoutAmount)) {
shareRadioButton.setSelected(true);
if (buyerPayoutAmount.equals(tradeAmount.add(buyerSecurityDeposit)) &&
sellerPayoutAmount.equals(sellerSecurityDeposit)) {
buyerGetsTradeAmountRadioButton.setSelected(true);
} else if (buyerPayoutAmount.equals(tradeAmount.add(buyerSecurityDeposit).add(sellerSecurityDeposit)) &&
sellerPayoutAmount.equals(Coin.ZERO)) {
buyerGetsAllRadioButton.setSelected(true);
} else if (sellerPayoutAmount.equals(tradeAmount.add(sellerSecurityDeposit))
&& buyerPayoutAmount.equals(buyerSecurityDeposit)) {
sellerGetsTradeAmountRadioButton.setSelected(true);
} else if (sellerPayoutAmount.equals(tradeAmount.add(buyerSecurityDeposit).add(sellerSecurityDeposit))
&& buyerPayoutAmount.equals(Coin.ZERO)) {
sellerGetsAllRadioButton.setSelected(true);
} else {
customRadioButton.setSelected(true);
}

View file

@ -21,7 +21,10 @@ import com.google.protobuf.ByteString;
import io.bisq.app.Version;
import io.bisq.common.wire.Payload;
import io.bisq.common.wire.proto.Messages;
import javafx.beans.property.*;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import lombok.EqualsAndHashCode;
import org.bitcoinj.core.Coin;
import org.slf4j.Logger;
@ -37,31 +40,25 @@ public final class DisputeResult implements Payload {
private static final long serialVersionUID = Version.P2P_NETWORK_VERSION;
private static final Logger log = LoggerFactory.getLogger(DisputeResult.class);
public enum DisputeFeePolicy {
LOSER,
SPLIT,
WAIVE
}
public enum Winner {
BUYER,
SELLER,
STALE_MATE
SELLER
}
// only append new values as we use the ordinal value
// bank problems, no reply, buyer not sent
public enum Reason {
OTHER,
BUG,
USABILITY,
SCAM,
PROTOCOL_VIOLATION,
NO_REPLY
NO_REPLY,
BANK_PROBLEMS
}
public final String tradeId;
public final int traderId;
private DisputeFeePolicy disputeFeePolicy;
private Winner winner;
private int reasonOrdinal = Reason.OTHER.ordinal();
@ -74,8 +71,6 @@ public final class DisputeResult implements Payload {
private byte[] arbitratorSignature;
private long buyerPayoutAmount;
private long sellerPayoutAmount;
private long arbitratorPayoutAmount;
private String arbitratorAddressAsString;
private byte[] arbitratorPubKey;
private long closeDate;
private boolean isLoserPublisher;
@ -83,25 +78,22 @@ public final class DisputeResult implements Payload {
transient private BooleanProperty tamperProofEvidenceProperty = new SimpleBooleanProperty();
transient private BooleanProperty idVerificationProperty = new SimpleBooleanProperty();
transient private BooleanProperty screenCastProperty = new SimpleBooleanProperty();
transient private ObjectProperty<DisputeFeePolicy> feePaymentPolicyProperty = new SimpleObjectProperty<>();
transient private StringProperty summaryNotesProperty = new SimpleStringProperty();
public DisputeResult(String tradeId, int traderId) {
this.tradeId = tradeId;
this.traderId = traderId;
this.disputeFeePolicy = DisputeFeePolicy.LOSER;
init();
}
public DisputeResult(String tradeId, int traderId, DisputeFeePolicy disputeFeePolicy, Winner winner,
public DisputeResult(String tradeId, int traderId, Winner winner,
int reasonOrdinal, boolean tamperProofEvidence, boolean idVerification, boolean screenCast,
String summaryNotes, DisputeCommunicationMessage disputeCommunicationMessage,
byte[] arbitratorSignature, long buyerPayoutAmount, long sellerPayoutAmount,
long arbitratorPayoutAmount, String arbitratorAddressAsString, byte[] arbitratorPubKey,
byte[] arbitratorPubKey,
long closeDate, boolean isLoserPublisher) {
this.tradeId = tradeId;
this.traderId = traderId;
this.disputeFeePolicy = disputeFeePolicy;
this.winner = winner;
this.reasonOrdinal = reasonOrdinal;
this.tamperProofEvidence = tamperProofEvidence;
@ -112,8 +104,6 @@ public final class DisputeResult implements Payload {
this.arbitratorSignature = arbitratorSignature;
this.buyerPayoutAmount = buyerPayoutAmount;
this.sellerPayoutAmount = sellerPayoutAmount;
this.arbitratorPayoutAmount = arbitratorPayoutAmount;
this.arbitratorAddressAsString = arbitratorAddressAsString;
this.arbitratorPubKey = arbitratorPubKey;
this.closeDate = closeDate;
this.isLoserPublisher = isLoserPublisher;
@ -133,7 +123,6 @@ public final class DisputeResult implements Payload {
tamperProofEvidenceProperty = new SimpleBooleanProperty(tamperProofEvidence);
idVerificationProperty = new SimpleBooleanProperty(idVerification);
screenCastProperty = new SimpleBooleanProperty(screenCast);
feePaymentPolicyProperty = new SimpleObjectProperty<>(disputeFeePolicy);
summaryNotesProperty = new SimpleStringProperty(summaryNotes);
tamperProofEvidenceProperty.addListener((observable, oldValue, newValue) -> {
@ -145,9 +134,6 @@ public final class DisputeResult implements Payload {
screenCastProperty.addListener((observable, oldValue, newValue) -> {
screenCast = newValue;
});
feePaymentPolicyProperty.addListener((observable, oldValue, newValue) -> {
disputeFeePolicy = newValue;
});
summaryNotesProperty.addListener((observable, oldValue, newValue) -> {
summaryNotes = newValue;
});
@ -165,19 +151,6 @@ public final class DisputeResult implements Payload {
return screenCastProperty;
}
public void setDisputeFeePolicy(DisputeFeePolicy disputeFeePolicy) {
this.disputeFeePolicy = disputeFeePolicy;
feePaymentPolicyProperty.set(disputeFeePolicy);
}
public ReadOnlyObjectProperty<DisputeFeePolicy> disputeFeePolicyProperty() {
return feePaymentPolicyProperty;
}
public DisputeFeePolicy getDisputeFeePolicy() {
return disputeFeePolicy;
}
public void setReason(Reason reason) {
this.reasonOrdinal = reason.ordinal();
}
@ -229,22 +202,6 @@ public final class DisputeResult implements Payload {
return Coin.valueOf(sellerPayoutAmount);
}
public void setArbitratorPayoutAmount(Coin arbitratorPayoutAmount) {
this.arbitratorPayoutAmount = arbitratorPayoutAmount.value;
}
public Coin getArbitratorPayoutAmount() {
return Coin.valueOf(arbitratorPayoutAmount);
}
public void setArbitratorAddressAsString(String arbitratorAddressAsString) {
this.arbitratorAddressAsString = arbitratorAddressAsString;
}
public String getArbitratorAddressAsString() {
return arbitratorAddressAsString;
}
public void setArbitratorPubKey(byte[] arbitratorPubKey) {
this.arbitratorPubKey = arbitratorPubKey;
}
@ -282,7 +239,6 @@ public final class DisputeResult implements Payload {
return Messages.DisputeResult.newBuilder()
.setTradeId(tradeId)
.setTraderId(traderId)
.setDisputeFeePolicy(Messages.DisputeResult.DisputeFeePolicy.forNumber(disputeFeePolicy.ordinal()))
.setWinner(Messages.DisputeResult.Winner.forNumber(winner.ordinal()))
.setReasonOrdinal(reasonOrdinal)
.setTamperProofEvidence(tamperProofEvidence)
@ -293,8 +249,6 @@ public final class DisputeResult implements Payload {
.setArbitratorSignature(ByteString.copyFrom(arbitratorSignature))
.setBuyerPayoutAmount(buyerPayoutAmount)
.setSellerPayoutAmount(sellerPayoutAmount)
.setArbitratorPayoutAmount(arbitratorPayoutAmount)
.setArbitratorAddressAsString(arbitratorAddressAsString)
.setArbitratorPubKey(ByteString.copyFrom(arbitratorPubKey))
.setCloseDate(closeDate)
.setIsLoserPublisher(isLoserPublisher).build();

View file

@ -250,17 +250,15 @@ public class ProtoBufferUtilities {
Messages.DisputeResult disputeResultproto = disputeResultMessage.getDisputeResult();
DisputeResult disputeResult = new DisputeResult(disputeResultproto.getTradeId(),
disputeResultproto.getTraderId(), DisputeResult.DisputeFeePolicy.valueOf(disputeResultproto.getDisputeFeePolicy().name()),
disputeResultproto.getTraderId(),
DisputeResult.Winner.valueOf(disputeResultproto.getWinner().name()), disputeResultproto.getReasonOrdinal(),
disputeResultproto.getTamperProofEvidence(), disputeResultproto.getIdVerification(), disputeResultproto.getScreenCast(),
disputeResultproto.getSummaryNotes(),
(DisputeCommunicationMessage) getDisputeCommunicationMessage(disputeResultproto.getDisputeCommunicationMessage()),
disputeResultproto.getArbitratorSignature().toByteArray(), disputeResultproto.getBuyerPayoutAmount(),
disputeResultproto.getSellerPayoutAmount(), disputeResultproto.getArbitratorPayoutAmount(),
disputeResultproto.getArbitratorAddressAsString(),
disputeResultproto.getSellerPayoutAmount(),
disputeResultproto.getArbitratorPubKey().toByteArray(), disputeResultproto.getCloseDate(),
disputeResultproto.getIsLoserPublisher());
disputeResult.setArbitratorAddressAsString(disputeResultproto.getArbitratorAddressAsString());
return new DisputeResultMessage(disputeResult, getNodeAddress(disputeResultMessage.getMyNodeAddress()));
}