mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-22 19:49:32 +00:00
resend payment sent msg until ack, payment received msg if not published
improve payment confirmation states in ui
This commit is contained in:
parent
aea831bafd
commit
7e8e145c85
4 changed files with 83 additions and 44 deletions
|
@ -53,9 +53,9 @@ public class BuyerProtocol extends DisputeProtocol {
|
|||
protected void onInitialized() {
|
||||
super.onInitialized();
|
||||
|
||||
// re-send payment sent message if not arrived
|
||||
// re-send payment sent message if not acked
|
||||
synchronized (trade) {
|
||||
if (trade.getState().ordinal() >= Trade.State.BUYER_SENT_PAYMENT_SENT_MSG.ordinal() && trade.getState().ordinal() <= Trade.State.BUYER_SEND_FAILED_PAYMENT_SENT_MSG.ordinal()) {
|
||||
if (trade.getState().ordinal() >= Trade.State.BUYER_SENT_PAYMENT_SENT_MSG.ordinal() && trade.getState().ordinal() < Trade.State.SELLER_RECEIVED_PAYMENT_SENT_MSG.ordinal()) {
|
||||
latchTrade();
|
||||
given(anyPhase(Trade.Phase.PAYMENT_SENT)
|
||||
.with(BuyerEvent.STARTUP))
|
||||
|
|
|
@ -49,9 +49,9 @@ public class SellerProtocol extends DisputeProtocol {
|
|||
protected void onInitialized() {
|
||||
super.onInitialized();
|
||||
|
||||
// re-send payment received message if not arrived
|
||||
// re-send payment received message if payout not published
|
||||
synchronized (trade) {
|
||||
if (trade.getState().ordinal() >= Trade.State.SELLER_SENT_PAYMENT_RECEIVED_MSG.ordinal() && trade.getState().ordinal() <= Trade.State.SELLER_SEND_FAILED_PAYMENT_RECEIVED_MSG.ordinal()) {
|
||||
if (trade.getState().ordinal() >= Trade.State.SELLER_SENT_PAYMENT_RECEIVED_MSG.ordinal() && !trade.isPayoutPublished()) {
|
||||
latchTrade();
|
||||
given(anyPhase(Trade.Phase.PAYMENT_RECEIVED)
|
||||
.with(SellerEvent.STARTUP))
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
|
||||
package haveno.core.trade.protocol.tasks;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import haveno.common.Timer;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.network.MessageState;
|
||||
|
@ -45,6 +48,9 @@ import lombok.extern.slf4j.Slf4j;
|
|||
public abstract class BuyerSendPaymentSentMessage extends SendMailboxMessageTask {
|
||||
private ChangeListener<MessageState> listener;
|
||||
private Timer timer;
|
||||
private static final int MAX_RESEND_ATTEMPTS = 10;
|
||||
private int delayInMin = 10;
|
||||
private int resendCounter = 0;
|
||||
|
||||
public BuyerSendPaymentSentMessage(TaskRunner<Trade> taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
|
@ -61,8 +67,6 @@ public abstract class BuyerSendPaymentSentMessage extends SendMailboxMessageTask
|
|||
super.run();
|
||||
} catch (Throwable t) {
|
||||
failed(t);
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,22 +109,21 @@ public abstract class BuyerSendPaymentSentMessage extends SendMailboxMessageTask
|
|||
|
||||
@Override
|
||||
protected void setStateSent() {
|
||||
if (trade.getState().ordinal() < Trade.State.BUYER_SENT_PAYMENT_SENT_MSG.ordinal()) {
|
||||
trade.setStateIfValidTransitionTo(Trade.State.BUYER_SENT_PAYMENT_SENT_MSG);
|
||||
}
|
||||
if (trade.getState().ordinal() < Trade.State.BUYER_SENT_PAYMENT_SENT_MSG.ordinal()) trade.setStateIfValidTransitionTo(Trade.State.BUYER_SENT_PAYMENT_SENT_MSG);
|
||||
tryToSendAgainLater();
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setStateArrived() {
|
||||
trade.setStateIfValidTransitionTo(Trade.State.BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG);
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setStateStoredInMailbox() {
|
||||
trade.setStateIfValidTransitionTo(Trade.State.BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG);
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
// TODO: schedule repeat sending like haveno?
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -137,4 +140,40 @@ public abstract class BuyerSendPaymentSentMessage extends SendMailboxMessageTask
|
|||
processModel.getPaymentSentMessageStateProperty().removeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryToSendAgainLater() {
|
||||
|
||||
// skip if already acked
|
||||
if (trade.getState().ordinal() >= Trade.State.SELLER_RECEIVED_PAYMENT_SENT_MSG.ordinal()) return;
|
||||
|
||||
if (resendCounter >= MAX_RESEND_ATTEMPTS) {
|
||||
cleanup();
|
||||
log.warn("We never received an ACK message when sending the PaymentSentMessage to the peer. We stop trying to send the message.");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("We will send the message again to the peer after a delay of {} min.", delayInMin);
|
||||
if (timer != null) {
|
||||
timer.stop();
|
||||
}
|
||||
|
||||
timer = UserThread.runAfter(this::run, delayInMin, TimeUnit.MINUTES);
|
||||
|
||||
if (resendCounter == 0) {
|
||||
listener = (observable, oldValue, newValue) -> onMessageStateChange(newValue);
|
||||
processModel.getPaymentSentMessageStateProperty().addListener(listener);
|
||||
onMessageStateChange(processModel.getPaymentSentMessageStateProperty().get());
|
||||
}
|
||||
|
||||
delayInMin = delayInMin * 2;
|
||||
resendCounter++;
|
||||
}
|
||||
|
||||
private void onMessageStateChange(MessageState newValue) {
|
||||
if (newValue == MessageState.ACKNOWLEDGED) {
|
||||
trade.setStateIfValidTransitionTo(Trade.State.SELLER_RECEIVED_PAYMENT_SENT_MSG);
|
||||
processModel.getTradeManager().requestPersistence();
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,43 +149,43 @@ public class BuyerStep2View extends TradeStepView {
|
|||
|
||||
if (trade.isDepositsUnlocked() && !trade.isPaymentSent()) {
|
||||
showPopup();
|
||||
} else if (state.ordinal() <= Trade.State.BUYER_SEND_FAILED_PAYMENT_SENT_MSG.ordinal()) {
|
||||
} else if (state.ordinal() <= Trade.State.SELLER_RECEIVED_PAYMENT_SENT_MSG.ordinal()) {
|
||||
switch (state) {
|
||||
case BUYER_CONFIRMED_IN_UI_PAYMENT_SENT:
|
||||
busyAnimation.play();
|
||||
statusLabel.setText(Res.get("shared.preparingConfirmation"));
|
||||
break;
|
||||
case BUYER_SENT_PAYMENT_SENT_MSG:
|
||||
busyAnimation.play();
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmation"));
|
||||
model.setMessageStateProperty(MessageState.SENT);
|
||||
timeoutTimer = UserThread.runAfter(() -> {
|
||||
case BUYER_CONFIRMED_IN_UI_PAYMENT_SENT:
|
||||
busyAnimation.play();
|
||||
statusLabel.setText(Res.get("shared.preparingConfirmation"));
|
||||
break;
|
||||
case BUYER_SENT_PAYMENT_SENT_MSG:
|
||||
busyAnimation.play();
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmation"));
|
||||
model.setMessageStateProperty(MessageState.SENT);
|
||||
timeoutTimer = UserThread.runAfter(() -> {
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmationAgain"));
|
||||
}, 10);
|
||||
break;
|
||||
case BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageStoredInMailbox"));
|
||||
model.setMessageStateProperty(MessageState.STORED_IN_MAILBOX);
|
||||
break;
|
||||
case SELLER_RECEIVED_PAYMENT_SENT_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageArrived"));
|
||||
model.setMessageStateProperty(MessageState.ARRIVED);
|
||||
break;
|
||||
case BUYER_SEND_FAILED_PAYMENT_SENT_MSG:
|
||||
// We get a popup and the trade closed, so we dont need to show anything here
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText("");
|
||||
model.setMessageStateProperty(MessageState.FAILED);
|
||||
break;
|
||||
default:
|
||||
log.warn("Unexpected case: State={}, tradeId={} ", state.name(), trade.getId());
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmationAgain"));
|
||||
}, 10);
|
||||
break;
|
||||
case BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageArrived"));
|
||||
model.setMessageStateProperty(MessageState.ARRIVED);
|
||||
break;
|
||||
case BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG:
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.messageStoredInMailbox"));
|
||||
model.setMessageStateProperty(MessageState.STORED_IN_MAILBOX);
|
||||
break;
|
||||
case BUYER_SEND_FAILED_PAYMENT_SENT_MSG:
|
||||
// We get a popup and the trade closed, so we dont need to show anything here
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText("");
|
||||
model.setMessageStateProperty(MessageState.FAILED);
|
||||
break;
|
||||
default:
|
||||
log.warn("Unexpected case: State={}, tradeId={} ", state.name(), trade.getId());
|
||||
busyAnimation.stop();
|
||||
statusLabel.setText(Res.get("shared.sendingConfirmationAgain"));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue