mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-20 07:46:05 -04:00
add support for lost deposit tx
This commit is contained in:
parent
7ab6cfed60
commit
582999844f
@ -19,10 +19,7 @@ package io.bitsquare.gui.main.disputes.arbitrator;
|
||||
|
||||
import io.bitsquare.arbitration.Dispute;
|
||||
import io.bitsquare.arbitration.DisputeManager;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.main.disputes.trader.DisputeSummaryPopup;
|
||||
import io.bitsquare.gui.main.disputes.trader.TraderDisputeView;
|
||||
@ -40,10 +37,10 @@ import javax.inject.Inject;
|
||||
public class ArbitratorDisputeView extends TraderDisputeView {
|
||||
|
||||
@Inject
|
||||
public ArbitratorDisputeView(DisputeManager disputeManager, KeyRing keyRing, TradeWalletService tradeWalletService, WalletService walletService,
|
||||
TradeManager tradeManager, Stage stage, BSFormatter formatter, Navigation navigation,
|
||||
DisputeSummaryPopup disputeSummaryPopup, ContractPopup contractPopup, TradeDetailsPopup tradeDetailsPopup) {
|
||||
super(disputeManager, keyRing, tradeWalletService, walletService, tradeManager, stage, formatter, navigation,
|
||||
public ArbitratorDisputeView(DisputeManager disputeManager, KeyRing keyRing, TradeManager tradeManager, Stage stage,
|
||||
BSFormatter formatter, DisputeSummaryPopup disputeSummaryPopup,
|
||||
ContractPopup contractPopup, TradeDetailsPopup tradeDetailsPopup) {
|
||||
super(disputeManager, keyRing, tradeManager, stage, formatter,
|
||||
disputeSummaryPopup, contractPopup, tradeDetailsPopup);
|
||||
}
|
||||
|
||||
|
@ -381,7 +381,7 @@ public class DisputeSummaryPopup extends Popup {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
log.warn("dispute.getDepositTxOptional is empty");
|
||||
log.warn("dispute.getDepositTxSerialized is null");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
package io.bitsquare.gui.main.portfolio.pendingtrades;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.arbitration.Dispute;
|
||||
import io.bitsquare.arbitration.DisputeManager;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
@ -32,6 +33,7 @@ import io.bitsquare.gui.main.disputes.DisputesView;
|
||||
import io.bitsquare.gui.main.portfolio.PortfolioView;
|
||||
import io.bitsquare.gui.main.portfolio.closedtrades.ClosedTradesView;
|
||||
import io.bitsquare.gui.popups.Popup;
|
||||
import io.bitsquare.gui.popups.SelectDepositTxPopup;
|
||||
import io.bitsquare.gui.popups.WalletPasswordPopup;
|
||||
import io.bitsquare.payment.PaymentAccountContractData;
|
||||
import io.bitsquare.trade.*;
|
||||
@ -45,8 +47,11 @@ import javafx.collections.ObservableList;
|
||||
import org.bitcoinj.core.BlockChainListener;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionOutput;
|
||||
import org.spongycastle.crypto.params.KeyParameter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -182,57 +187,94 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||
}
|
||||
|
||||
public void onOpenDispute() {
|
||||
doOpenDispute(false);
|
||||
tryOpenDispute(false);
|
||||
}
|
||||
|
||||
public void onOpenSupportTicket() {
|
||||
doOpenDispute(true);
|
||||
tryOpenDispute(true);
|
||||
}
|
||||
|
||||
private void doOpenDispute(boolean isSupportTicket) {
|
||||
private void tryOpenDispute(boolean isSupportTicket) {
|
||||
if (trade != null) {
|
||||
Transaction depositTx = trade.getDepositTx();
|
||||
log.debug("trade.getDepositTx() " + depositTx);
|
||||
byte[] depositTxSerialized = null;
|
||||
byte[] payoutTxSerialized = null;
|
||||
String depositTxHashAsString = null;
|
||||
String payoutTxHashAsString = null;
|
||||
if (depositTx != null) {
|
||||
depositTxSerialized = depositTx.bitcoinSerialize();
|
||||
depositTxHashAsString = depositTx.getHashAsString();
|
||||
}
|
||||
Transaction payoutTx = trade.getPayoutTx();
|
||||
if (payoutTx != null) {
|
||||
payoutTxSerialized = payoutTx.bitcoinSerialize();
|
||||
payoutTxHashAsString = payoutTx.getHashAsString();
|
||||
}
|
||||
doOpenDispute(isSupportTicket, trade.getDepositTx());
|
||||
} else {
|
||||
log.warn("Trade.depositTx is null. We try to find the tx in our wallet.");
|
||||
List<Transaction> candidates = new ArrayList<>();
|
||||
List<Transaction> transactions = walletService.getWallet().getRecentTransactions(100, true);
|
||||
transactions.stream().forEach(transaction -> {
|
||||
Coin valueSentFromMe = transaction.getValueSentFromMe(walletService.getWallet());
|
||||
if (!valueSentFromMe.isZero()) {
|
||||
// spending tx
|
||||
for (TransactionOutput transactionOutput : transaction.getOutputs()) {
|
||||
if (!transactionOutput.isMine(walletService.getWallet())) {
|
||||
if (transactionOutput.getScriptPubKey().isPayToScriptHash()) {
|
||||
// MS tx
|
||||
candidates.add(transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Dispute dispute = new Dispute(disputeManager.getDisputeStorage(),
|
||||
trade.getId(),
|
||||
keyRing.getPubKeyRing().hashCode(), // traderId
|
||||
trade.getOffer().getDirection() == Offer.Direction.BUY ? isOfferer : !isOfferer,
|
||||
isOfferer,
|
||||
keyRing.getPubKeyRing(),
|
||||
trade.getDate(),
|
||||
trade.getContract(),
|
||||
trade.getContractHash(),
|
||||
depositTxSerialized,
|
||||
payoutTxSerialized,
|
||||
depositTxHashAsString,
|
||||
payoutTxHashAsString,
|
||||
trade.getContractAsJson(),
|
||||
trade.getOffererContractSignature(),
|
||||
trade.getTakerContractSignature(),
|
||||
user.getAcceptedArbitratorByAddress(trade.getArbitratorAddress()).getPubKeyRing(),
|
||||
isSupportTicket
|
||||
);
|
||||
|
||||
trade.setDisputeState(Trade.DisputeState.DISPUTE_REQUESTED);
|
||||
disputeManager.sendOpenNewDisputeMessage(dispute);
|
||||
navigation.navigateTo(MainView.class, DisputesView.class);
|
||||
if (candidates.size() == 1)
|
||||
doOpenDispute(isSupportTicket, candidates.get(0));
|
||||
else if (candidates.size() > 1)
|
||||
new SelectDepositTxPopup().transactions(candidates).onSelect(transaction -> {
|
||||
doOpenDispute(isSupportTicket, transaction);
|
||||
}).show();
|
||||
else
|
||||
log.error("Trade.depositTx is null and we did not find any MultiSig transaction.");
|
||||
}
|
||||
} else {
|
||||
log.error("Trade is null");
|
||||
}
|
||||
}
|
||||
|
||||
private void doOpenDispute(boolean isSupportTicket, Transaction depositTx) {
|
||||
Log.traceCall("depositTx=" + depositTx);
|
||||
byte[] depositTxSerialized = null;
|
||||
byte[] payoutTxSerialized = null;
|
||||
String depositTxHashAsString = null;
|
||||
String payoutTxHashAsString = null;
|
||||
if (depositTx != null) {
|
||||
depositTxSerialized = depositTx.bitcoinSerialize();
|
||||
depositTxHashAsString = depositTx.getHashAsString();
|
||||
} else {
|
||||
log.warn("depositTx is null");
|
||||
}
|
||||
Transaction payoutTx = trade.getPayoutTx();
|
||||
if (payoutTx != null) {
|
||||
payoutTxSerialized = payoutTx.bitcoinSerialize();
|
||||
payoutTxHashAsString = payoutTx.getHashAsString();
|
||||
}
|
||||
|
||||
Dispute dispute = new Dispute(disputeManager.getDisputeStorage(),
|
||||
trade.getId(),
|
||||
keyRing.getPubKeyRing().hashCode(), // traderId
|
||||
trade.getOffer().getDirection() == Offer.Direction.BUY ? isOfferer : !isOfferer,
|
||||
isOfferer,
|
||||
keyRing.getPubKeyRing(),
|
||||
trade.getDate(),
|
||||
trade.getContract(),
|
||||
trade.getContractHash(),
|
||||
depositTxSerialized,
|
||||
payoutTxSerialized,
|
||||
depositTxHashAsString,
|
||||
payoutTxHashAsString,
|
||||
trade.getContractAsJson(),
|
||||
trade.getOffererContractSignature(),
|
||||
trade.getTakerContractSignature(),
|
||||
user.getAcceptedArbitratorByAddress(trade.getArbitratorAddress()).getPubKeyRing(),
|
||||
isSupportTicket
|
||||
);
|
||||
|
||||
trade.setDisputeState(Trade.DisputeState.DISPUTE_REQUESTED);
|
||||
disputeManager.sendOpenNewDisputeMessage(dispute);
|
||||
navigation.navigateTo(MainView.class, DisputesView.class);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.popups;
|
||||
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.util.StringConverter;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static io.bitsquare.gui.util.FormBuilder.addLabelComboBox;
|
||||
import static io.bitsquare.gui.util.FormBuilder.addMultilineLabel;
|
||||
|
||||
public class SelectDepositTxPopup extends Popup {
|
||||
private static final Logger log = LoggerFactory.getLogger(SelectDepositTxPopup.class);
|
||||
private Button emptyWalletButton;
|
||||
private ComboBox<Transaction> transactionsComboBox;
|
||||
private List<Transaction> transaction;
|
||||
private Optional<Consumer<Transaction>> selectHandlerOptional;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public SelectDepositTxPopup() {
|
||||
}
|
||||
|
||||
public SelectDepositTxPopup show() {
|
||||
if (headLine == null)
|
||||
headLine = "Select deposit transaction for dispute";
|
||||
|
||||
width = 700;
|
||||
createGridPane();
|
||||
addHeadLine();
|
||||
addContent();
|
||||
createPopup();
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectDepositTxPopup onSelect(Consumer<Transaction> selectHandler) {
|
||||
this.selectHandlerOptional = Optional.of(selectHandler);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectDepositTxPopup transactions(List<Transaction> transaction) {
|
||||
this.transaction = transaction;
|
||||
return this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void addContent() {
|
||||
addMultilineLabel(gridPane, ++rowIndex,
|
||||
"The deposit transaction was not stored in the trade.\n" +
|
||||
"Please select one of the existing MultiSig transactions from your wallet which was the " +
|
||||
"deposit transaction used in the failed trade.",
|
||||
10);
|
||||
|
||||
Tuple2<Label, ComboBox> tuple = addLabelComboBox(gridPane, ++rowIndex);
|
||||
transactionsComboBox = tuple.second;
|
||||
transactionsComboBox.setConverter(new StringConverter<Transaction>() {
|
||||
@Override
|
||||
public String toString(Transaction transaction) {
|
||||
return transaction.getHashAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction fromString(String string) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
transactionsComboBox.setItems(FXCollections.observableArrayList(transaction));
|
||||
transactionsComboBox.setOnAction(event -> {
|
||||
selectHandlerOptional.get().accept(transactionsComboBox.getSelectionModel().getSelectedItem());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user