use of io.bitsquare.btc.AddressEntry in project bitsquare by bitsquare.
the class DisputeSummaryWindow method addButtons.
private void addButtons(Contract contract) {
Tuple2<Button, Button> tuple = add2ButtonsAfterGroup(gridPane, ++rowIndex, "Close ticket", "Cancel");
Button closeTicketButton = tuple.first;
closeTicketButton.disableProperty().bind(Bindings.createBooleanBinding(() -> tradeAmountToggleGroup.getSelectedToggle() == null || summaryNotesTextArea.getText() == null || summaryNotesTextArea.getText().length() == 0 || !isPayoutAmountValid(), tradeAmountToggleGroup.selectedToggleProperty(), summaryNotesTextArea.textProperty(), buyerPayoutAmountInputTextField.textProperty(), sellerPayoutAmountInputTextField.textProperty(), arbitratorPayoutAmountInputTextField.textProperty()));
Button cancelButton = tuple.second;
final Dispute finalPeersDispute = peersDisputeOptional.get();
closeTicketButton.setOnAction(e -> {
if (dispute.getDepositTxSerialized() != null) {
try {
AddressEntry arbitratorAddressEntry = walletService.getOrCreateAddressEntry(AddressEntry.Context.ARBITRATOR);
disputeResult.setArbitratorAddressAsString(arbitratorAddressEntry.getAddressString());
disputeResult.setArbitratorPubKey(arbitratorAddressEntry.getPubKey());
byte[] arbitratorSignature = tradeWalletService.arbitratorSignsDisputedPayoutTx(dispute.getDepositTxSerialized(), disputeResult.getBuyerPayoutAmount(), disputeResult.getSellerPayoutAmount(), disputeResult.getArbitratorPayoutAmount(), contract.getBuyerPayoutAddressString(), contract.getSellerPayoutAddressString(), arbitratorAddressEntry.getAddressString(), arbitratorAddressEntry.getKeyPair(), contract.getBuyerMultiSigPubKey(), contract.getSellerMultiSigPubKey(), arbitratorAddressEntry.getPubKey());
disputeResult.setArbitratorSignature(arbitratorSignature);
closeTicketButton.disableProperty().unbind();
dispute.setDisputeResult(disputeResult);
disputeResult.setLoserIsPublisher(isLoserPublisherCheckBox.isSelected());
disputeResult.setCloseDate(new Date());
String text = "Ticket closed on " + formatter.formatDateTime(disputeResult.getCloseDate()) + "\n\nSummary:" + "\n" + role + " delivered tamper proof evidence: " + formatter.booleanToYesNo(disputeResult.tamperProofEvidenceProperty().get()) + "\n" + role + " did ID verification: " + formatter.booleanToYesNo(disputeResult.idVerificationProperty().get()) + "\n" + role + " did screencast or video: " + formatter.booleanToYesNo(disputeResult.screenCastProperty().get()) + "\nPayout amount for BTC buyer: " + formatter.formatCoinWithCode(disputeResult.getBuyerPayoutAmount()) + "\nPayout amount for BTC seller: " + formatter.formatCoinWithCode(disputeResult.getSellerPayoutAmount()) + "\nArbitrator's dispute fee: " + formatter.formatCoinWithCode(disputeResult.getArbitratorPayoutAmount()) + "\n\nSummary notes:\n" + disputeResult.summaryNotesProperty().get();
dispute.setIsClosed(true);
disputeManager.sendDisputeResultMessage(disputeResult, dispute, text);
if (!finalPeersDispute.isClosed())
UserThread.runAfter(() -> new Popup().attention("You need to close also the trading peers ticket!").show(), Transitions.DEFAULT_DURATION, TimeUnit.MILLISECONDS);
hide();
finalizeDisputeHandlerOptional.ifPresent(finalizeDisputeHandler -> finalizeDisputeHandler.run());
} catch (AddressFormatException | TransactionVerificationException e2) {
e2.printStackTrace();
}
} else {
log.warn("dispute.getDepositTxSerialized is null");
}
});
cancelButton.setOnAction(e -> {
dispute.setDisputeResult(disputeResult);
hide();
});
}
use of io.bitsquare.btc.AddressEntry in project bitsquare by bitsquare.
the class DisputeManager method onDisputeResultMessage.
// We get that message at both peers. The dispute object is in context of the trader
private void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) {
DisputeResult disputeResult = disputeResultMessage.disputeResult;
if (!isArbitrator(disputeResult)) {
final String tradeId = disputeResult.tradeId;
Optional<Dispute> disputeOptional = findDispute(tradeId, disputeResult.traderId);
final String uid = disputeResultMessage.getUID();
if (disputeOptional.isPresent()) {
cleanupRetryMap(uid);
Dispute dispute = disputeOptional.get();
DisputeCommunicationMessage disputeCommunicationMessage = disputeResult.getDisputeCommunicationMessage();
if (!dispute.getDisputeCommunicationMessagesAsObservableList().contains(disputeCommunicationMessage))
dispute.addDisputeMessage(disputeCommunicationMessage);
else
log.warn("We got a dispute mail msg what we have already stored. TradeId = " + disputeCommunicationMessage.getTradeId());
dispute.setIsClosed(true);
if (dispute.disputeResultProperty().get() != null)
log.warn("We got already a dispute result. That should only happen if a dispute needs to be closed " + "again because the first close did not succeed. TradeId = " + tradeId);
dispute.setDisputeResult(disputeResult);
// We need to avoid publishing the tx from both traders as it would create problems with zero confirmation withdrawals
// There would be different transactions if both sign and publish (signers: once buyer+arb, once seller+arb)
// The tx publisher is the winner or in case both get 50% the buyer, as the buyer has more inventive to publish the tx as he receives
// more BTC as he has deposited
final Contract contract = dispute.getContract();
boolean isBuyer = keyRing.getPubKeyRing().equals(contract.getBuyerPubKeyRing());
DisputeResult.Winner publisher = disputeResult.getWinner();
// Default isLoserPublisher is set to false
if (disputeResult.isLoserPublisher()) {
// we invert the logic
if (publisher == DisputeResult.Winner.BUYER)
publisher = DisputeResult.Winner.SELLER;
else if (publisher == DisputeResult.Winner.SELLER)
publisher = DisputeResult.Winner.BUYER;
}
if ((isBuyer && publisher == DisputeResult.Winner.BUYER) || (!isBuyer && publisher == DisputeResult.Winner.SELLER) || (isBuyer && publisher == DisputeResult.Winner.STALE_MATE)) {
final Optional<Trade> tradeOptional = tradeManager.getTradeById(tradeId);
Transaction payoutTx = null;
if (tradeOptional.isPresent()) {
payoutTx = tradeOptional.get().getPayoutTx();
} else {
final Optional<Tradable> tradableOptional = closedTradableManager.getTradableById(tradeId);
if (tradableOptional.isPresent() && tradableOptional.get() instanceof Trade) {
payoutTx = ((Trade) tradableOptional.get()).getPayoutTx();
}
}
if (payoutTx == null) {
if (dispute.getDepositTxSerialized() != null) {
try {
log.debug("do payout Transaction ");
AddressEntry multiSigAddressEntry = walletService.getOrCreateAddressEntry(dispute.getTradeId(), AddressEntry.Context.MULTI_SIG);
Transaction signedDisputedPayoutTx = tradeWalletService.traderSignAndFinalizeDisputedPayoutTx(dispute.getDepositTxSerialized(), disputeResult.getArbitratorSignature(), disputeResult.getBuyerPayoutAmount(), disputeResult.getSellerPayoutAmount(), disputeResult.getArbitratorPayoutAmount(), contract.getBuyerPayoutAddressString(), contract.getSellerPayoutAddressString(), disputeResult.getArbitratorAddressAsString(), multiSigAddressEntry.getKeyPair(), contract.getBuyerMultiSigPubKey(), contract.getSellerMultiSigPubKey(), disputeResult.getArbitratorPubKey());
Transaction committedDisputedPayoutTx = tradeWalletService.addTransactionToWallet(signedDisputedPayoutTx);
log.debug("broadcast committedDisputedPayoutTx");
tradeWalletService.broadcastTx(committedDisputedPayoutTx, new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {
log.debug("BroadcastTx succeeded. Transaction:" + transaction);
// after successful publish we send peer the tx
dispute.setDisputePayoutTxId(transaction.getHashAsString());
sendPeerPublishedPayoutTxMessage(transaction, dispute, contract);
// set state after payout as we call swapTradeEntryToAvailableEntry
if (tradeManager.getTradeById(dispute.getTradeId()).isPresent())
tradeManager.closeDisputedTrade(dispute.getTradeId());
else {
Optional<OpenOffer> openOfferOptional = openOfferManager.getOpenOfferById(dispute.getTradeId());
if (openOfferOptional.isPresent())
openOfferManager.closeOpenOffer(openOfferOptional.get().getOffer());
}
}
@Override
public void onFailure(@NotNull Throwable t) {
log.error(t.getMessage());
}
});
} catch (AddressFormatException | WalletException | TransactionVerificationException e) {
e.printStackTrace();
log.error("Error at traderSignAndFinalizeDisputedPayoutTx " + e.getMessage());
}
} else {
log.warn("DepositTx is null. TradeId = " + tradeId);
}
} else {
log.warn("We got already a payout tx. That might be the case if the other peer did not get the " + "payout tx and opened a dispute. TradeId = " + tradeId);
dispute.setDisputePayoutTxId(payoutTx.getHashAsString());
sendPeerPublishedPayoutTxMessage(payoutTx, dispute, contract);
}
} else {
log.trace("We don't publish the tx as we are not the winning party.");
// Clean up tangling trades
if (dispute.disputeResultProperty().get() != null && dispute.isClosed() && tradeManager.getTradeById(dispute.getTradeId()).isPresent())
tradeManager.closeDisputedTrade(dispute.getTradeId());
}
} else {
log.debug("We got a dispute result msg but we don't have a matching dispute. " + "That might happen when we get the disputeResultMessage before the dispute was created. " + "We try again after 2 sec. to apply the disputeResultMessage. TradeId = " + tradeId);
if (!delayMsgMap.containsKey(uid)) {
// We delay2 sec. to be sure the comm. msg gets added first
Timer timer = UserThread.runAfter(() -> onDisputeResultMessage(disputeResultMessage), 2);
delayMsgMap.put(uid, timer);
} else {
log.warn("We got a dispute result msg after we already repeated to apply the message after a delay. " + "That should never happen. TradeId = " + tradeId);
}
}
} else {
log.error("Arbitrator received disputeResultMessage. That must never happen.");
}
}
use of io.bitsquare.btc.AddressEntry in project bitsquare by bitsquare.
the class OffererCreatesAndSignsDepositTxAsBuyer method run.
@Override
protected void run() {
try {
runInterceptHook();
checkNotNull(trade.getTradeAmount(), "trade.getTradeAmount() must not be null");
Offer offer = trade.getOffer();
Coin securityDeposit = FeePolicy.getSecurityDeposit(offer);
Coin buyerInputAmount = securityDeposit.add(FeePolicy.getFixedTxFeeForTrades(offer));
Coin msOutputAmount = buyerInputAmount.add(securityDeposit).add(trade.getTradeAmount());
log.debug("\n\n------------------------------------------------------------\n" + "Contract as json\n" + trade.getContractAsJson() + "\n------------------------------------------------------------\n");
byte[] contractHash = Hash.getHash(trade.getContractAsJson());
trade.setContractHash(contractHash);
WalletService walletService = processModel.getWalletService();
String id = processModel.getOffer().getId();
AddressEntry offererAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE);
AddressEntry buyerMultiSigAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG);
buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInputAmount.subtract(FeePolicy.getFixedTxFeeForTrades(offer)));
Address changeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();
PreparedDepositTxAndOffererInputs result = processModel.getTradeWalletService().offererCreatesAndSignsDepositTx(true, contractHash, buyerInputAmount, msOutputAmount, processModel.tradingPeer.getRawTransactionInputs(), processModel.tradingPeer.getChangeOutputValue(), processModel.tradingPeer.getChangeOutputAddress(), offererAddressEntry.getAddress(), changeAddress, buyerMultiSigAddressEntry.getPubKey(), processModel.tradingPeer.getMultiSigPubKey(), trade.getArbitratorPubKey());
processModel.setPreparedDepositTx(result.depositTransaction);
processModel.setRawTransactionInputs(result.rawOffererInputs);
complete();
} catch (Throwable t) {
failed(t);
}
}
use of io.bitsquare.btc.AddressEntry in project bitsquare by bitsquare.
the class SendFiatTransferStartedMessage method run.
@Override
protected void run() {
try {
runInterceptHook();
WalletService walletService = processModel.getWalletService();
AddressEntry payoutAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT);
processModel.getP2PService().sendEncryptedMailboxMessage(trade.getTradingPeerNodeAddress(), processModel.tradingPeer.getPubKeyRing(), new FiatTransferStartedMessage(processModel.getId(), payoutAddressEntry.getAddressString(), processModel.getMyNodeAddress()), new SendMailboxMessageListener() {
@Override
public void onArrived() {
log.debug("Message arrived at peer.");
trade.setState(Trade.State.BUYER_SENT_FIAT_PAYMENT_INITIATED_MSG);
complete();
}
@Override
public void onStoredInMailbox() {
log.debug("Message stored in mailbox.");
trade.setState(Trade.State.BUYER_SENT_FIAT_PAYMENT_INITIATED_MSG);
complete();
}
@Override
public void onFault(String errorMessage) {
appendToErrorMessage("FiatTransferStartedMessage sending failed");
failed(errorMessage);
}
});
} catch (Throwable t) {
failed(t);
}
}
use of io.bitsquare.btc.AddressEntry in project bitsquare by bitsquare.
the class SignAndPublishDepositTxAsBuyer method run.
@Override
protected void run() {
try {
runInterceptHook();
log.debug("\n\n------------------------------------------------------------\n" + "Contract as json\n" + trade.getContractAsJson() + "\n------------------------------------------------------------\n");
byte[] contractHash = Hash.getHash(trade.getContractAsJson());
trade.setContractHash(contractHash);
ArrayList<RawTransactionInput> buyerInputs = processModel.getRawTransactionInputs();
WalletService walletService = processModel.getWalletService();
AddressEntry buyerMultiSigAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG);
Coin buyerInput = Coin.valueOf(buyerInputs.stream().mapToLong(input -> input.value).sum());
buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInput.subtract(FeePolicy.getFixedTxFeeForTrades(trade.getOffer())));
TradingPeer tradingPeer = processModel.tradingPeer;
Transaction depositTx = processModel.getTradeWalletService().takerSignsAndPublishesDepositTx(false, contractHash, processModel.getPreparedDepositTx(), buyerInputs, tradingPeer.getRawTransactionInputs(), buyerMultiSigAddressEntry.getPubKey(), tradingPeer.getMultiSigPubKey(), trade.getArbitratorPubKey(), new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {
log.trace("takerSignAndPublishTx succeeded " + transaction);
trade.setDepositTx(transaction);
trade.setState(Trade.State.TAKER_PUBLISHED_DEPOSIT_TX);
complete();
}
@Override
public void onFailure(@NotNull Throwable t) {
failed(t);
}
});
trade.setDepositTx(depositTx);
} catch (Throwable t) {
failed(t);
}
}
Aggregations