mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-10-01 01:35:48 -04:00
handle errors initializing trade after deposits requested
offer remains valid until trade initialized delete maker and taker trades on error after deposits requested schedule trade deletion if unfunded after timeout or startup DepositResponse supports error message to confirm failure show deposit tx ids in trade details window
This commit is contained in:
parent
646380bc7a
commit
308f6e8077
@ -22,14 +22,11 @@ import bisq.core.locale.Res;
|
|||||||
import bisq.core.monetary.Altcoin;
|
import bisq.core.monetary.Altcoin;
|
||||||
import bisq.core.monetary.Volume;
|
import bisq.core.monetary.Volume;
|
||||||
import bisq.core.offer.OpenOffer;
|
import bisq.core.offer.OpenOffer;
|
||||||
import bisq.core.trade.Tradable;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.util.FormattingUtils;
|
import bisq.core.util.FormattingUtils;
|
||||||
import bisq.core.util.coin.CoinFormatter;
|
import bisq.core.util.coin.CoinFormatter;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.core.Monetary;
|
import org.bitcoinj.core.Monetary;
|
||||||
import org.bitcoinj.core.TransactionConfidence;
|
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -635,7 +635,7 @@ public abstract class Trade implements Tradable, Model {
|
|||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
|
|
||||||
// start listening to trade wallet
|
// start listening to trade wallet
|
||||||
if (isDepositPublished()) {
|
if (isDepositRequested()) {
|
||||||
updateSyncing();
|
updateSyncing();
|
||||||
|
|
||||||
// allow state notifications to process before returning
|
// allow state notifications to process before returning
|
||||||
@ -1462,9 +1462,14 @@ public abstract class Trade implements Tradable, Model {
|
|||||||
if (isDepositUnlocked()) getWallet().rescanSpent();
|
if (isDepositUnlocked()) getWallet().rescanSpent();
|
||||||
|
|
||||||
// get txs with outputs
|
// get txs with outputs
|
||||||
List<MoneroTxWallet> txs = getWallet().getTxs(new MoneroTxQuery()
|
List<MoneroTxWallet> txs;
|
||||||
.setHashes(Arrays.asList(processModel.getMaker().getDepositTxHash(), processModel.getTaker().getDepositTxHash()))
|
try {
|
||||||
.setIncludeOutputs(true));
|
txs = getWallet().getTxs(new MoneroTxQuery()
|
||||||
|
.setHashes(Arrays.asList(processModel.getMaker().getDepositTxHash(), processModel.getTaker().getDepositTxHash()))
|
||||||
|
.setIncludeOutputs(true));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check deposit txs
|
// check deposit txs
|
||||||
if (!isDepositUnlocked()) {
|
if (!isDepositUnlocked()) {
|
||||||
|
@ -63,6 +63,7 @@ import bisq.network.p2p.P2PService;
|
|||||||
import bisq.network.p2p.network.TorNetworkNode;
|
import bisq.network.p2p.network.TorNetworkNode;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import bisq.common.ClockWatcher;
|
import bisq.common.ClockWatcher;
|
||||||
|
import bisq.common.UserThread;
|
||||||
import bisq.common.crypto.KeyRing;
|
import bisq.common.crypto.KeyRing;
|
||||||
import bisq.common.handlers.ErrorMessageHandler;
|
import bisq.common.handlers.ErrorMessageHandler;
|
||||||
import bisq.common.handlers.FaultHandler;
|
import bisq.common.handlers.FaultHandler;
|
||||||
@ -382,6 +383,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
if (isShutDown) return;
|
if (isShutDown) return;
|
||||||
initTradeAndProtocol(trade, getTradeProtocol(trade));
|
initTradeAndProtocol(trade, getTradeProtocol(trade));
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
|
scheduleDeletionIfUnfunded(trade);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initTradeAndProtocol(Trade trade, TradeProtocol tradeProtocol) {
|
private void initTradeAndProtocol(Trade trade, TradeProtocol tradeProtocol) {
|
||||||
@ -1063,24 +1065,50 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
synchronized(tradableList) {
|
synchronized(tradableList) {
|
||||||
if (!tradableList.contains(trade)) return;
|
if (!tradableList.contains(trade)) return;
|
||||||
|
|
||||||
// unreserve key images
|
// unreserve taker key images
|
||||||
if (trade instanceof TakerTrade && trade.getSelf().getReserveTxKeyImages() != null) {
|
if (trade instanceof TakerTrade && trade.getSelf().getReserveTxKeyImages() != null) {
|
||||||
xmrWalletService.thawOutputs(trade.getSelf().getReserveTxKeyImages());
|
xmrWalletService.thawOutputs(trade.getSelf().getReserveTxKeyImages());
|
||||||
xmrWalletService.saveMainWallet();
|
xmrWalletService.saveMainWallet();
|
||||||
trade.getSelf().setReserveTxKeyImages(null);
|
trade.getSelf().setReserveTxKeyImages(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop if trade wallet possibly funded
|
// remove trade if wallet deleted
|
||||||
if (xmrWalletService.multisigWalletExists(trade.getId()) && trade.isDepositRequested()) {
|
if (!xmrWalletService.multisigWalletExists(trade.getId())) {
|
||||||
log.warn("Refusing to delete {} {} because trade wallet could be funded", trade.getClass().getSimpleName(), trade.getId());
|
removeTrade(trade);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete trade wallet if exists
|
// remove trade and wallet unless timeout after deposit requested
|
||||||
if (xmrWalletService.multisigWalletExists(trade.getId())) trade.deleteWallet();
|
boolean isTimeoutError = TradeProtocol.isTimeoutError(trade.getErrorMessage());
|
||||||
|
if (!trade.isDepositRequested() || !isTimeoutError) {
|
||||||
|
removeTrade(trade);
|
||||||
|
if (xmrWalletService.multisigWalletExists(trade.getId())) trade.deleteWallet();
|
||||||
|
} else {
|
||||||
|
scheduleDeletionIfUnfunded(trade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// remove trade
|
private void scheduleDeletionIfUnfunded(Trade trade) {
|
||||||
removeTrade(trade);
|
if (trade.isDepositRequested() && !trade.isDepositPublished()) {
|
||||||
|
log.warn("Scheduling to delete trade if unfunded for {} {}", trade.getClass().getSimpleName(), trade.getId());
|
||||||
|
UserThread.runAfter(() -> {
|
||||||
|
if (isShutDown) return;
|
||||||
|
|
||||||
|
// get trade's deposit txs from daemon
|
||||||
|
MoneroTx makerDepositTx = xmrWalletService.getDaemon().getTx(trade.getMaker().getDepositTxHash());
|
||||||
|
MoneroTx takerDepositTx = xmrWalletService.getDaemon().getTx(trade.getTaker().getDepositTxHash());
|
||||||
|
|
||||||
|
// delete multisig trade wallet if neither deposit tx published
|
||||||
|
if ((makerDepositTx != null && makerDepositTx.isRelayed()) || (takerDepositTx != null && takerDepositTx.isRelayed())) {
|
||||||
|
log.warn("Refusing to delete {} {} after protocol timeout because its wallet might be funded", trade.getClass().getSimpleName(), trade.getId());
|
||||||
|
} else {
|
||||||
|
log.warn("Deleting {} {} after protocol timeout", trade.getClass().getSimpleName(), trade.getId());
|
||||||
|
removeTrade(trade);
|
||||||
|
failedTradesManager.removeTrade(trade);
|
||||||
|
if (xmrWalletService.multisigWalletExists(trade.getId())) trade.deleteWallet();
|
||||||
|
}
|
||||||
|
}, 60);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,11 @@ import bisq.core.proto.CoreProtoResolver;
|
|||||||
|
|
||||||
import bisq.network.p2p.DirectMessage;
|
import bisq.network.p2p.DirectMessage;
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
import bisq.common.crypto.PubKeyRing;
|
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import bisq.common.crypto.PubKeyRing;
|
||||||
|
import bisq.common.proto.ProtoUtil;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
@ -32,17 +35,20 @@ public final class DepositResponse extends TradeMessage implements DirectMessage
|
|||||||
private final NodeAddress senderNodeAddress;
|
private final NodeAddress senderNodeAddress;
|
||||||
private final PubKeyRing pubKeyRing;
|
private final PubKeyRing pubKeyRing;
|
||||||
private final long currentDate;
|
private final long currentDate;
|
||||||
|
private final String errorMessage;
|
||||||
|
|
||||||
public DepositResponse(String tradeId,
|
public DepositResponse(String tradeId,
|
||||||
NodeAddress senderNodeAddress,
|
NodeAddress senderNodeAddress,
|
||||||
PubKeyRing pubKeyRing,
|
PubKeyRing pubKeyRing,
|
||||||
String uid,
|
String uid,
|
||||||
String messageVersion,
|
String messageVersion,
|
||||||
long currentDate) {
|
long currentDate,
|
||||||
|
String errorMessage) {
|
||||||
super(messageVersion, tradeId, uid);
|
super(messageVersion, tradeId, uid);
|
||||||
this.senderNodeAddress = senderNodeAddress;
|
this.senderNodeAddress = senderNodeAddress;
|
||||||
this.pubKeyRing = pubKeyRing;
|
this.pubKeyRing = pubKeyRing;
|
||||||
this.currentDate = currentDate;
|
this.currentDate = currentDate;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -58,6 +64,7 @@ public final class DepositResponse extends TradeMessage implements DirectMessage
|
|||||||
.setPubKeyRing(pubKeyRing.toProtoMessage())
|
.setPubKeyRing(pubKeyRing.toProtoMessage())
|
||||||
.setUid(uid);
|
.setUid(uid);
|
||||||
builder.setCurrentDate(currentDate);
|
builder.setCurrentDate(currentDate);
|
||||||
|
Optional.ofNullable(errorMessage).ifPresent(e -> builder.setErrorMessage(errorMessage));
|
||||||
|
|
||||||
return getNetworkEnvelopeBuilder().setDepositResponse(builder).build();
|
return getNetworkEnvelopeBuilder().setDepositResponse(builder).build();
|
||||||
}
|
}
|
||||||
@ -70,7 +77,8 @@ public final class DepositResponse extends TradeMessage implements DirectMessage
|
|||||||
PubKeyRing.fromProto(proto.getPubKeyRing()),
|
PubKeyRing.fromProto(proto.getPubKeyRing()),
|
||||||
proto.getUid(),
|
proto.getUid(),
|
||||||
messageVersion,
|
messageVersion,
|
||||||
proto.getCurrentDate());
|
proto.getCurrentDate(),
|
||||||
|
ProtoUtil.stringOrNullFromProto(proto.getErrorMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -79,6 +87,7 @@ public final class DepositResponse extends TradeMessage implements DirectMessage
|
|||||||
"\n senderNodeAddress=" + senderNodeAddress +
|
"\n senderNodeAddress=" + senderNodeAddress +
|
||||||
",\n pubKeyRing=" + pubKeyRing +
|
",\n pubKeyRing=" + pubKeyRing +
|
||||||
",\n currentDate=" + currentDate +
|
",\n currentDate=" + currentDate +
|
||||||
|
",\n errorMessage=" + errorMessage +
|
||||||
"\n} " + super.toString();
|
"\n} " + super.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ import javax.annotation.Nullable;
|
|||||||
public abstract class TradeProtocol implements DecryptedDirectMessageListener, DecryptedMailboxListener {
|
public abstract class TradeProtocol implements DecryptedDirectMessageListener, DecryptedMailboxListener {
|
||||||
|
|
||||||
public static final int TRADE_TIMEOUT = 60;
|
public static final int TRADE_TIMEOUT = 60;
|
||||||
|
private static final String TIMEOUT_REACHED = "Timeout reached.";
|
||||||
|
|
||||||
protected final ProcessModel processModel;
|
protected final ProcessModel processModel;
|
||||||
protected final Trade trade;
|
protected final Trade trade;
|
||||||
@ -331,8 +332,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
|||||||
.from(sender))
|
.from(sender))
|
||||||
.setup(tasks(
|
.setup(tasks(
|
||||||
// TODO (woodser): validate request
|
// TODO (woodser): validate request
|
||||||
ProcessSignContractResponse.class,
|
ProcessSignContractResponse.class)
|
||||||
RemoveOffer.class)
|
|
||||||
.using(new TradeTaskRunner(trade,
|
.using(new TradeTaskRunner(trade,
|
||||||
() -> {
|
() -> {
|
||||||
startTimeout(TRADE_TIMEOUT);
|
startTimeout(TRADE_TIMEOUT);
|
||||||
@ -364,7 +364,8 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
|||||||
.from(sender)) // TODO (woodser): ensure this asserts sender == response.getSenderNodeAddress()
|
.from(sender)) // TODO (woodser): ensure this asserts sender == response.getSenderNodeAddress()
|
||||||
.setup(tasks(
|
.setup(tasks(
|
||||||
// TODO (woodser): validate request
|
// TODO (woodser): validate request
|
||||||
ProcessDepositResponse.class)
|
ProcessDepositResponse.class,
|
||||||
|
RemoveOffer.class)
|
||||||
.using(new TradeTaskRunner(trade,
|
.using(new TradeTaskRunner(trade,
|
||||||
() -> {
|
() -> {
|
||||||
stopTimeout();
|
stopTimeout();
|
||||||
@ -548,8 +549,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
|||||||
String err = "Received AckMessage with error state for " + ackMessage.getSourceMsgClassName() +
|
String err = "Received AckMessage with error state for " + ackMessage.getSourceMsgClassName() +
|
||||||
" from "+ peer + " with tradeId " + trade.getId() + " and errorMessage=" + ackMessage.getErrorMessage();
|
" from "+ peer + " with tradeId " + trade.getId() + " and errorMessage=" + ackMessage.getErrorMessage();
|
||||||
log.warn(err);
|
log.warn(err);
|
||||||
stopTimeout();
|
handleError(err);
|
||||||
if (errorMessageHandler != null) errorMessageHandler.handleErrorMessage(err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +608,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
|||||||
synchronized (timeoutTimerLock) {
|
synchronized (timeoutTimerLock) {
|
||||||
stopTimeout();
|
stopTimeout();
|
||||||
timeoutTimer = UserThread.runAfter(() -> {
|
timeoutTimer = UserThread.runAfter(() -> {
|
||||||
handleError("Timeout reached. Protocol did not complete in " + timeoutSec + " sec. TradeID=" + trade.getId() + ", state=" + trade.stateProperty().get());
|
handleError(TIMEOUT_REACHED + " Protocol did not complete in " + timeoutSec + " sec. TradeID=" + trade.getId() + ", state=" + trade.stateProperty().get());
|
||||||
}, timeoutSec);
|
}, timeoutSec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,6 +622,9 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isTimeoutError(String errorMessage) {
|
||||||
|
return errorMessage != null && errorMessage.contains(TIMEOUT_REACHED);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Task runner
|
// Task runner
|
||||||
|
@ -23,7 +23,6 @@ import bisq.common.crypto.PubKeyRing;
|
|||||||
import bisq.common.crypto.Sig;
|
import bisq.common.crypto.Sig;
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
import bisq.core.offer.Offer;
|
import bisq.core.offer.Offer;
|
||||||
import bisq.core.offer.OfferDirection;
|
|
||||||
import bisq.core.trade.HavenoUtils;
|
import bisq.core.trade.HavenoUtils;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.DepositRequest;
|
import bisq.core.trade.messages.DepositRequest;
|
||||||
@ -47,6 +46,8 @@ import monero.daemon.model.MoneroSubmitTxResult;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class ArbitratorProcessDepositRequest extends TradeTask {
|
public class ArbitratorProcessDepositRequest extends TradeTask {
|
||||||
|
|
||||||
|
private boolean depositTxsRelayed = false;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public ArbitratorProcessDepositRequest(TaskRunner taskHandler, Trade trade) {
|
public ArbitratorProcessDepositRequest(TaskRunner taskHandler, Trade trade) {
|
||||||
super(taskHandler, trade);
|
super(taskHandler, trade);
|
||||||
@ -54,6 +55,7 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() {
|
protected void run() {
|
||||||
|
MoneroDaemon daemon = trade.getXmrWalletService().getDaemon();
|
||||||
try {
|
try {
|
||||||
runInterceptHook();
|
runInterceptHook();
|
||||||
|
|
||||||
@ -108,12 +110,12 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
|
|||||||
if (processModel.getMaker().getDepositTxHex() != null && processModel.getTaker().getDepositTxHex() != null) {
|
if (processModel.getMaker().getDepositTxHex() != null && processModel.getTaker().getDepositTxHex() != null) {
|
||||||
|
|
||||||
// relay txs
|
// relay txs
|
||||||
MoneroDaemon daemon = trade.getXmrWalletService().getDaemon();
|
|
||||||
MoneroSubmitTxResult makerResult = daemon.submitTxHex(processModel.getMaker().getDepositTxHex(), true);
|
MoneroSubmitTxResult makerResult = daemon.submitTxHex(processModel.getMaker().getDepositTxHex(), true);
|
||||||
MoneroSubmitTxResult takerResult = daemon.submitTxHex(processModel.getTaker().getDepositTxHex(), true);
|
MoneroSubmitTxResult takerResult = daemon.submitTxHex(processModel.getTaker().getDepositTxHex(), true);
|
||||||
if (!makerResult.isGood()) throw new RuntimeException("Error submitting maker deposit tx: " + JsonUtils.serialize(makerResult));
|
if (!makerResult.isGood()) throw new RuntimeException("Error submitting maker deposit tx: " + JsonUtils.serialize(makerResult));
|
||||||
if (!takerResult.isGood()) throw new RuntimeException("Error submitting taker deposit tx: " + JsonUtils.serialize(takerResult));
|
if (!takerResult.isGood()) throw new RuntimeException("Error submitting taker deposit tx: " + JsonUtils.serialize(takerResult));
|
||||||
daemon.relayTxsByHash(Arrays.asList(processModel.getMaker().getDepositTxHash(), processModel.getTaker().getDepositTxHash()));
|
daemon.relayTxsByHash(Arrays.asList(processModel.getMaker().getDepositTxHash(), processModel.getTaker().getDepositTxHash()));
|
||||||
|
depositTxsRelayed = true;
|
||||||
|
|
||||||
// update trade state
|
// update trade state
|
||||||
log.info("Arbitrator submitted deposit txs for trade " + trade.getId());
|
log.info("Arbitrator submitted deposit txs for trade " + trade.getId());
|
||||||
@ -126,7 +128,8 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
|
|||||||
processModel.getPubKeyRing(),
|
processModel.getPubKeyRing(),
|
||||||
UUID.randomUUID().toString(),
|
UUID.randomUUID().toString(),
|
||||||
Version.getP2PMessageVersion(),
|
Version.getP2PMessageVersion(),
|
||||||
new Date().getTime());
|
new Date().getTime(),
|
||||||
|
null);
|
||||||
|
|
||||||
// send deposit response to maker and taker
|
// send deposit response to maker and taker
|
||||||
sendDepositResponse(trade.getMaker().getNodeAddress(), trade.getMaker().getPubKeyRing(), response);
|
sendDepositResponse(trade.getMaker().getNodeAddress(), trade.getMaker().getPubKeyRing(), response);
|
||||||
@ -139,7 +142,30 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
|
|||||||
// TODO (woodser): request persistence?
|
// TODO (woodser): request persistence?
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
failed(t);
|
|
||||||
|
// handle error before deposits relayed
|
||||||
|
if (!depositTxsRelayed) {
|
||||||
|
try {
|
||||||
|
daemon.flushTxPool(processModel.getMaker().getDepositTxHash(), processModel.getTaker().getDepositTxHash());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// create deposit response with error
|
||||||
|
DepositResponse response = new DepositResponse(
|
||||||
|
trade.getOffer().getId(),
|
||||||
|
processModel.getMyNodeAddress(),
|
||||||
|
processModel.getPubKeyRing(),
|
||||||
|
UUID.randomUUID().toString(),
|
||||||
|
Version.getP2PMessageVersion(),
|
||||||
|
new Date().getTime(),
|
||||||
|
t.getMessage());
|
||||||
|
|
||||||
|
// send deposit response to maker and taker
|
||||||
|
sendDepositResponse(trade.getMaker().getNodeAddress(), trade.getMaker().getPubKeyRing(), response);
|
||||||
|
sendDepositResponse(trade.getTaker().getNodeAddress(), trade.getTaker().getPubKeyRing(), response);
|
||||||
|
}
|
||||||
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ package bisq.core.trade.protocol.tasks;
|
|||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -34,6 +35,14 @@ public class ProcessDepositResponse extends TradeTask {
|
|||||||
protected void run() {
|
protected void run() {
|
||||||
try {
|
try {
|
||||||
runInterceptHook();
|
runInterceptHook();
|
||||||
|
|
||||||
|
// throw if error
|
||||||
|
DepositResponse message = (DepositResponse) processModel.getTradeMessage();
|
||||||
|
if (message.getErrorMessage() != null) {
|
||||||
|
throw new RuntimeException(message.getErrorMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// set success state
|
||||||
trade.setStateIfValidTransitionTo(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
trade.setStateIfValidTransitionTo(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
|
@ -2036,7 +2036,7 @@ The above error message will be copied to the clipboard when you click either of
|
|||||||
It will make debugging easier if you include the haveno.log file by pressing "Open log file", saving a copy, and attaching it to your bug report.
|
It will make debugging easier if you include the haveno.log file by pressing "Open log file", saving a copy, and attaching it to your bug report.
|
||||||
|
|
||||||
popup.error.tryRestart=Please try to restart your application and check your network connection to see if you can resolve the issue.
|
popup.error.tryRestart=Please try to restart your application and check your network connection to see if you can resolve the issue.
|
||||||
popup.error.takeOfferRequestFailed=An error occurred when someone tried to take one of your offers:\n{0}
|
popup.error.takeOfferRequestFailed=An error occurred while taking an offer:\n{0}
|
||||||
|
|
||||||
error.spvFileCorrupted=An error occurred when reading the SPV chain file.\nIt might be that the SPV chain file is corrupted.\n\nError message: {0}\n\nDo you want to delete it and start a resync?
|
error.spvFileCorrupted=An error occurred when reading the SPV chain file.\nIt might be that the SPV chain file is corrupted.\n\nError message: {0}\n\nDo you want to delete it and start a resync?
|
||||||
error.deleteAddressEntryListFailed=Could not delete AddressEntryList file.\nError: {0}
|
error.deleteAddressEntryListFailed=Could not delete AddressEntryList file.\nError: {0}
|
||||||
|
@ -269,12 +269,12 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||||||
Res.get(contract.getPaymentMethodId()));
|
Res.get(contract.getPaymentMethodId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trade.getMakerDepositTx() != null)
|
if (trade.getMaker().getDepositTxHash() != null)
|
||||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.makerDepositTransactionId"),
|
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.makerDepositTransactionId"),
|
||||||
trade.getMakerDepositTx().getHash());
|
trade.getMaker().getDepositTxHash());
|
||||||
if (trade.getTakerDepositTx() != null)
|
if (trade.getTaker().getDepositTxHash() != null)
|
||||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.takerDepositTransactionId"),
|
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.takerDepositTransactionId"),
|
||||||
trade.getTakerDepositTx().getHash());
|
trade.getTaker().getDepositTxHash());
|
||||||
|
|
||||||
if (trade.getPayoutTxId() != null && !trade.getPayoutTxId().isBlank())
|
if (trade.getPayoutTxId() != null && !trade.getPayoutTxId().isBlank())
|
||||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.payoutTxId"),
|
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.payoutTxId"),
|
||||||
|
@ -344,6 +344,7 @@ message DepositResponse {
|
|||||||
PubKeyRing pub_key_ring = 3;
|
PubKeyRing pub_key_ring = 3;
|
||||||
string uid = 4;
|
string uid = 4;
|
||||||
int64 current_date = 5;
|
int64 current_date = 5;
|
||||||
|
string error_message = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DepositsConfirmedMessage {
|
message DepositsConfirmedMessage {
|
||||||
|
Loading…
Reference in New Issue
Block a user