mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 15:00:30 +01:00
Add timeout and resend support for p2p messages in trade process
This commit is contained in:
parent
443f871b58
commit
728dead33c
8 changed files with 85 additions and 22 deletions
|
@ -105,6 +105,7 @@ shared.TheBTCBuyer=The BTC buyer
|
|||
shared.You=You
|
||||
shared.reasonForPayment=Reason for payment
|
||||
shared.sendingConfirmation=Sending confirmation...
|
||||
shared.sendingConfirmationAgain=Please send confirmation again
|
||||
shared.exportCSV=Export to csv
|
||||
shared.noDateAvailable=No date available
|
||||
shared.arbitratorsFee=Arbitrator's fee
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.google.common.util.concurrent.Futures;
|
|||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.Message;
|
||||
import io.bisq.common.app.DevEnv;
|
||||
import io.bisq.common.app.Log;
|
||||
import io.bisq.common.crypto.KeyRing;
|
||||
import io.bisq.common.crypto.PubKeyRing;
|
||||
|
@ -584,24 +583,22 @@ public abstract class Trade implements Tradable, Model {
|
|||
|
||||
public void setState(State state) {
|
||||
log.info("Set new state at {} (id={}): {}", this.getClass().getSimpleName(), getShortId(), state);
|
||||
if (state.getPhase().ordinal() >= this.state.getPhase().ordinal()) {
|
||||
boolean changed = this.state != state;
|
||||
this.state = state;
|
||||
stateProperty.set(state);
|
||||
statePhaseProperty.set(state.getPhase());
|
||||
|
||||
if (state == State.WITHDRAW_COMPLETED && tradeProtocol != null)
|
||||
tradeProtocol.completed();
|
||||
|
||||
if (changed)
|
||||
persist();
|
||||
} else {
|
||||
final String message = "we got a state change to a previous phase. that is likely a bug.\n" +
|
||||
"old state is: " + this.state + ". New state is: " + state;
|
||||
log.error(message);
|
||||
if (DevEnv.DEV_MODE)
|
||||
throw new RuntimeException(message);
|
||||
if (state.getPhase().ordinal() < this.state.getPhase().ordinal()) {
|
||||
final String message = "We got a state change to a previous phase.\n" +
|
||||
"Old state is: " + this.state + ". New state is: " + state;
|
||||
log.warn(message);
|
||||
}
|
||||
|
||||
boolean changed = this.state != state;
|
||||
this.state = state;
|
||||
stateProperty.set(state);
|
||||
statePhaseProperty.set(state.getPhase());
|
||||
|
||||
if (state == State.WITHDRAW_COMPLETED && tradeProtocol != null)
|
||||
tradeProtocol.completed();
|
||||
|
||||
if (changed)
|
||||
persist();
|
||||
}
|
||||
|
||||
public void setDisputeState(DisputeState disputeState) {
|
||||
|
|
|
@ -39,6 +39,7 @@ public class BuyerSendCounterCurrencyTransferStartedMessage extends TradeTask {
|
|||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
|
||||
BtcWalletService walletService = processModel.getBtcWalletService();
|
||||
final String id = processModel.getOfferId();
|
||||
AddressEntry payoutAddressEntry = walletService.getOrCreateAddressEntry(id,
|
||||
|
|
|
@ -27,7 +27,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
// TODO remove
|
||||
public class SellerSendPayoutTxPublishedMessage extends TradeTask {
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public SellerSendPayoutTxPublishedMessage(TaskRunner taskHandler, Trade trade) {
|
||||
|
|
|
@ -88,6 +88,7 @@ public class SellerSignAndFinalizePayoutTx extends TradeTask {
|
|||
);
|
||||
|
||||
trade.setPayoutTx(transaction);
|
||||
|
||||
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.MULTI_SIG);
|
||||
|
||||
complete();
|
||||
|
|
|
@ -168,7 +168,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
amountLabel = amountTuple.first;
|
||||
amountTextField = amountTuple.second;
|
||||
if (DevEnv.DEV_MODE)
|
||||
amountTextField.setText("1000");
|
||||
amountTextField.setText("10");
|
||||
|
||||
titledGroupBg.setVisible(false);
|
||||
titledGroupBg.setManaged(false);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package io.bisq.gui.main.portfolio.pendingtrades.steps.buyer;
|
||||
|
||||
import io.bisq.common.Timer;
|
||||
import io.bisq.common.UserThread;
|
||||
import io.bisq.common.app.DevEnv;
|
||||
import io.bisq.common.locale.CurrencyUtil;
|
||||
import io.bisq.common.locale.Res;
|
||||
|
@ -46,6 +48,7 @@ public class BuyerStep2View extends TradeStepView {
|
|||
private Label statusLabel;
|
||||
private BusyAnimation busyAnimation;
|
||||
private Subscription tradeStatePropertySubscription;
|
||||
private Timer timeoutTimer;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -59,13 +62,19 @@ public class BuyerStep2View extends TradeStepView {
|
|||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
if (timeoutTimer != null)
|
||||
timeoutTimer.stop();
|
||||
|
||||
//TODO we get called twice, check why
|
||||
if (tradeStatePropertySubscription == null) {
|
||||
tradeStatePropertySubscription = EasyBind.subscribe(trade.stateProperty(), state -> {
|
||||
if (timeoutTimer != null)
|
||||
timeoutTimer.stop();
|
||||
|
||||
if (trade.isDepositConfirmed() && !trade.isFiatSent()) {
|
||||
showPopup();
|
||||
} else if (state.ordinal() <= Trade.State.BUYER_SEND_FAILED_FIAT_PAYMENT_INITIATED_MSG.ordinal()) {
|
||||
busyAnimation.stop();
|
||||
if (!trade.hasFailed()) {
|
||||
switch (state) {
|
||||
case BUYER_CONFIRMED_IN_UI_FIAT_PAYMENT_INITIATED:
|
||||
|
@ -73,18 +82,33 @@ public class BuyerStep2View extends TradeStepView {
|
|||
busyAnimation.play();
|
||||
confirmButton.setDisable(true);
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmation"));
|
||||
|
||||
timeoutTimer = UserThread.runAfter(() -> {
|
||||
busyAnimation.stop();
|
||||
confirmButton.setDisable(false);
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmationAgain"));
|
||||
}, 10);
|
||||
break;
|
||||
case BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageArrived"));
|
||||
break;
|
||||
case BUYER_STORED_IN_MAILBOX_FIAT_PAYMENT_INITIATED_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageStoredInMailbox"));
|
||||
break;
|
||||
case BUYER_SEND_FAILED_FIAT_PAYMENT_INITIATED_MSG:
|
||||
// We get a popup and the trade closed, so we dont need to show anything here
|
||||
busyAnimation.stop();
|
||||
confirmButton.setDisable(false);
|
||||
statusLabel.setText("");
|
||||
break;
|
||||
default:
|
||||
log.warn("Unexpected case: State={}, tradeId={} " + state.name(), trade.getId());
|
||||
busyAnimation.stop();
|
||||
confirmButton.setDisable(false);
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmationAgain"));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
confirmButton.setDisable(true);
|
||||
|
@ -101,6 +125,9 @@ public class BuyerStep2View extends TradeStepView {
|
|||
|
||||
busyAnimation.stop();
|
||||
|
||||
if (timeoutTimer != null)
|
||||
timeoutTimer.stop();
|
||||
|
||||
if (tradeStatePropertySubscription != null) {
|
||||
tradeStatePropertySubscription.unsubscribe();
|
||||
tradeStatePropertySubscription = null;
|
||||
|
@ -276,6 +303,11 @@ public class BuyerStep2View extends TradeStepView {
|
|||
|
||||
private void confirmPaymentStarted() {
|
||||
confirmButton.setDisable(true);
|
||||
busyAnimation.play();
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmation"));
|
||||
if (trade.isFiatSent())
|
||||
trade.setState(Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN);
|
||||
|
||||
model.dataModel.onPaymentStarted(() -> {
|
||||
// In case the first send failed we got the support button displayed.
|
||||
// If it succeeds at a second try we remove the support button again.
|
||||
|
|
|
@ -17,12 +17,15 @@
|
|||
|
||||
package io.bisq.gui.main.portfolio.pendingtrades.steps.seller;
|
||||
|
||||
import io.bisq.common.Timer;
|
||||
import io.bisq.common.UserThread;
|
||||
import io.bisq.common.app.DevEnv;
|
||||
import io.bisq.common.locale.CurrencyUtil;
|
||||
import io.bisq.common.locale.Res;
|
||||
import io.bisq.common.util.Tuple3;
|
||||
import io.bisq.core.payment.payload.*;
|
||||
import io.bisq.core.trade.Contract;
|
||||
import io.bisq.core.trade.Trade;
|
||||
import io.bisq.core.user.DontShowAgainLookup;
|
||||
import io.bisq.gui.components.BusyAnimation;
|
||||
import io.bisq.gui.components.TextFieldWithCopyIcon;
|
||||
|
@ -48,6 +51,7 @@ public class SellerStep3View extends TradeStepView {
|
|||
private Label statusLabel;
|
||||
private BusyAnimation busyAnimation;
|
||||
private Subscription tradeStatePropertySubscription;
|
||||
private Timer timeoutTimer;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -62,11 +66,16 @@ public class SellerStep3View extends TradeStepView {
|
|||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
if (timeoutTimer != null)
|
||||
timeoutTimer.stop();
|
||||
|
||||
tradeStatePropertySubscription = EasyBind.subscribe(trade.stateProperty(), state -> {
|
||||
if (timeoutTimer != null)
|
||||
timeoutTimer.stop();
|
||||
|
||||
if (trade.isFiatSent() && !trade.isFiatReceived()) {
|
||||
showPopup();
|
||||
} else if (trade.isFiatReceived()) {
|
||||
busyAnimation.stop();
|
||||
if (!trade.hasFailed()) {
|
||||
switch (state) {
|
||||
case SELLER_CONFIRMED_IN_UI_FIAT_PAYMENT_RECEIPT:
|
||||
|
@ -75,18 +84,33 @@ public class SellerStep3View extends TradeStepView {
|
|||
busyAnimation.play();
|
||||
confirmButton.setDisable(true);
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmation"));
|
||||
|
||||
timeoutTimer = UserThread.runAfter(() -> {
|
||||
busyAnimation.stop();
|
||||
confirmButton.setDisable(false);
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmationAgain"));
|
||||
}, 10);
|
||||
break;
|
||||
case SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageArrived"));
|
||||
break;
|
||||
case SELLER_STORED_IN_MAILBOX_PAYOUT_TX_PUBLISHED_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageStoredInMailbox"));
|
||||
break;
|
||||
case SELLER_SEND_FAILED_PAYOUT_TX_PUBLISHED_MSG:
|
||||
// We get a popup and the trade closed, so we dont need to show anything here
|
||||
busyAnimation.stop();
|
||||
confirmButton.setDisable(false);
|
||||
statusLabel.setText("");
|
||||
break;
|
||||
default:
|
||||
log.warn("Unexpected case: State={}, tradeId={} " + state.name(), trade.getId());
|
||||
busyAnimation.stop();
|
||||
confirmButton.setDisable(false);
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmationAgain"));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
confirmButton.setDisable(true);
|
||||
|
@ -104,7 +128,11 @@ public class SellerStep3View extends TradeStepView {
|
|||
tradeStatePropertySubscription.unsubscribe();
|
||||
tradeStatePropertySubscription = null;
|
||||
}
|
||||
|
||||
busyAnimation.stop();
|
||||
|
||||
if (timeoutTimer != null)
|
||||
timeoutTimer.stop();
|
||||
}
|
||||
|
||||
|
||||
|
@ -295,6 +323,10 @@ public class SellerStep3View extends TradeStepView {
|
|||
|
||||
private void confirmPaymentReceived() {
|
||||
confirmButton.setDisable(true);
|
||||
busyAnimation.play();
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmation"));
|
||||
if (trade.isPayoutPublished())
|
||||
trade.setState(Trade.State.SELLER_CONFIRMED_IN_UI_FIAT_PAYMENT_RECEIPT);
|
||||
|
||||
model.dataModel.onFiatPaymentReceived(() -> {
|
||||
// In case the first send failed we got the support button displayed.
|
||||
|
|
Loading…
Add table
Reference in a new issue