Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re activate confirm buttons again #4602

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@ public interface Listener {
@Getter
private boolean isInConflictWithSeedNode;
@Getter
private ObservableList<UtxoMismatch> utxoMismatches = FXCollections.observableArrayList();
private final ObservableList<UtxoMismatch> utxoMismatches = FXCollections.observableArrayList();

private List<Checkpoint> checkpoints = Arrays.asList(
private final List<Checkpoint> checkpoints = Arrays.asList(
new Checkpoint(586920, Utilities.decodeFromHex("523aaad4e760f6ac6196fec1b3ec9a2f42e5b272"))
);
private boolean checkpointFailed;
private boolean ignoreDevMsg;
private final boolean ignoreDevMsg;
private int numCalls;
private long accumulatedDuration;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ public void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) {
Trade trade = tradeOptional.get();
if (trade.getDisputeState() == Trade.DisputeState.MEDIATION_REQUESTED ||
trade.getDisputeState() == Trade.DisputeState.MEDIATION_STARTED_BY_PEER) {
trade.getProcessModel().setBuyerPayoutAmountFromMediation(disputeResult.getBuyerPayoutAmount().value);
trade.getProcessModel().setSellerPayoutAmountFromMediation(disputeResult.getSellerPayoutAmount().value);
tradeManager.requestPersistence();

trade.setDisputeState(Trade.DisputeState.MEDIATION_CLOSED);
}
} else {
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/bisq/core/trade/BuyerTrade.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,8 @@ public Coin getPayoutAmount() {
return checkNotNull(getOffer()).getBuyerSecurityDeposit().add(getTradeAmount());
}

@Override
public boolean confirmPermitted() {
return !getDisputeState().isArbitrated();
}
}
30 changes: 30 additions & 0 deletions core/src/main/java/bisq/core/trade/SellerTrade.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package bisq.core.trade;

import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.locale.CurrencyUtil;
import bisq.core.offer.Offer;
import bisq.core.trade.protocol.ProcessModel;

Expand Down Expand Up @@ -83,5 +84,34 @@ public abstract class SellerTrade extends Trade {
public Coin getPayoutAmount() {
return checkNotNull(getOffer()).getSellerSecurityDeposit();
}

@Override
public boolean confirmPermitted() {
// For altcoin there is no reason to delay BTC release as no chargeback risk
if (CurrencyUtil.isCryptoCurrency(getOffer().getCurrencyCode())) {
return true;
}

switch (getDisputeState()) {
case NO_DISPUTE:
return true;

case DISPUTE_REQUESTED:
case DISPUTE_STARTED_BY_PEER:
case DISPUTE_CLOSED:
case MEDIATION_REQUESTED:
case MEDIATION_STARTED_BY_PEER:
return false;

case MEDIATION_CLOSED:
return !mediationResultAppliedPenaltyToSeller();

case REFUND_REQUESTED:
case REFUND_REQUEST_STARTED_BY_PEER:
case REFUND_REQUEST_CLOSED:
default:
return false;
}
}
}

29 changes: 29 additions & 0 deletions core/src/main/java/bisq/core/trade/Trade.java
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,25 @@ public static Trade.DisputeState fromProto(protobuf.Trade.DisputeState disputeSt
public static protobuf.Trade.DisputeState toProtoMessage(Trade.DisputeState disputeState) {
return protobuf.Trade.DisputeState.valueOf(disputeState.name());
}

public boolean isNotDisputed() {
return this == Trade.DisputeState.NO_DISPUTE;
}

public boolean isMediated() {
return this == Trade.DisputeState.MEDIATION_REQUESTED ||
this == Trade.DisputeState.MEDIATION_STARTED_BY_PEER ||
this == Trade.DisputeState.MEDIATION_CLOSED;
}

public boolean isArbitrated() {
return this == Trade.DisputeState.DISPUTE_REQUESTED ||
this == Trade.DisputeState.DISPUTE_STARTED_BY_PEER ||
this == Trade.DisputeState.DISPUTE_CLOSED ||
this == Trade.DisputeState.REFUND_REQUESTED ||
this == Trade.DisputeState.REFUND_REQUEST_STARTED_BY_PEER ||
this == Trade.DisputeState.REFUND_REQUEST_CLOSED;
}
}

public enum TradePeriodState {
Expand Down Expand Up @@ -687,6 +706,15 @@ public void appendErrorMessage(String msg) {
errorMessage = errorMessage == null ? msg : errorMessage + "\n" + msg;
}

public boolean mediationResultAppliedPenaltyToSeller() {
// If mediated payout is same or more then normal payout we enable otherwise a penalty was applied
// by mediators and we keep the confirm disabled to avoid that the seller can complete the trade
// without the penalty.
long payoutAmountFromMediation = processModel.getSellerPayoutAmountFromMediation();
long normalPayoutAmount = offer.getSellerSecurityDeposit().value;
return payoutAmountFromMediation < normalPayoutAmount;
}


///////////////////////////////////////////////////////////////////////////////////////////
// Model implementation
Expand All @@ -703,6 +731,7 @@ public void onComplete() {

public abstract Coin getPayoutAmount();

public abstract boolean confirmPermitted();

///////////////////////////////////////////////////////////////////////////////////////////
// Setters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler er
BuyerEvent event = BuyerEvent.PAYMENT_SENT;
expect(phase(Trade.Phase.DEPOSIT_CONFIRMED)
.with(event)
.preCondition(notDisputed()))
.preCondition(trade.confirmPermitted()))
.setup(tasks(ApplyFilter.class,
getVerifyPeersFeePaymentClass(),
BuyerSignPayoutTx.class,
Expand Down Expand Up @@ -188,5 +188,4 @@ protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
}

abstract protected Class<? extends TradeTask> getVerifyPeersFeePaymentClass();

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ public DisputeProtocol(Trade trade) {
super(trade);
}

protected boolean notDisputed() {
return trade.getDisputeState() == Trade.DisputeState.NO_DISPUTE;
}


///////////////////////////////////////////////////////////////////////////////////////////
// User interaction: Trader accepts mediation result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public void onPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler e
SellerEvent event = SellerEvent.PAYMENT_RECEIVED;
expect(anyPhase(Trade.Phase.FIAT_SENT, Trade.Phase.PAYOUT_PUBLISHED)
.with(event)
.preCondition(notDisputed()))
.preCondition(trade.confirmPermitted()))
.setup(tasks(
ApplyFilter.class,
getVerifyPeersFeePaymentClass(),
Expand Down Expand Up @@ -159,4 +159,5 @@ protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
}

abstract protected Class<? extends TradeTask> getVerifyPeersFeePaymentClass();

}
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ protected String getPeriodOverWarnText() {
protected void applyOnDisputeOpened() {
}

private void updateDisputeState(Trade.DisputeState disputeState) {
protected void updateDisputeState(Trade.DisputeState disputeState) {
Optional<Dispute> ownDispute;
switch (disputeState) {
case NO_DISPUTE:
Expand Down Expand Up @@ -513,8 +513,6 @@ private void updateDisputeState(Trade.DisputeState disputeState) {
default:
break;
}

updateConfirmButtonDisableState(isDisputed());
}

private void updateMediationResultState(boolean blockOpeningOfResultAcceptedPopup) {
Expand Down Expand Up @@ -674,10 +672,6 @@ private void openMediationResultPopup(String headLine) {
acceptMediationResultPopup.show();
}

protected void updateConfirmButtonDisableState(boolean isDisabled) {
// By default do nothing. Only overwritten in certain trade steps
}

protected String getCurrencyName(Trade trade) {
return CurrencyUtil.getNameByCode(getCurrencyCode(trade));
}
Expand Down Expand Up @@ -722,10 +716,6 @@ private void updateTradePeriodState(Trade.TradePeriodState tradePeriodState) {
}
}

protected boolean isDisputed() {
return trade.getDisputeState() != Trade.DisputeState.NO_DISPUTE;
}

private void checkIfLockTimeIsOver() {
if (trade.getDisputeState() == Trade.DisputeState.MEDIATION_CLOSED) {
Transaction delayedPayoutTx = trade.getDelayedPayoutTx();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,10 @@ public void activate() {
case BUYER_CONFIRMED_IN_UI_FIAT_PAYMENT_INITIATED:
case BUYER_SENT_FIAT_PAYMENT_INITIATED_MSG:
busyAnimation.play();
// confirmButton.setDisable(true);
statusLabel.setText(Res.get("shared.sendingConfirmation"));
model.setMessageStateProperty(MessageState.SENT);
timeoutTimer = UserThread.runAfter(() -> {
busyAnimation.stop();
// confirmButton.setDisable(false);
statusLabel.setText(Res.get("shared.sendingConfirmationAgain"));
}, 10);
break;
Expand All @@ -156,27 +154,22 @@ public void activate() {
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("");
model.setMessageStateProperty(MessageState.FAILED);
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 {
log.warn("confirmButton gets disabled because trade contains error message {}", trade.getErrorMessage());
// confirmButton.setDisable(true);
log.warn("Trade contains error message {}", trade.getErrorMessage());
statusLabel.setText("");
}
}
});
}

confirmButton.setDisable(isDisputed());
}

@Override
Expand Down Expand Up @@ -372,15 +365,19 @@ protected String getPeriodOverWarnText() {
protected void applyOnDisputeOpened() {
}

@Override
protected void updateDisputeState(Trade.DisputeState disputeState) {
super.updateDisputeState(disputeState);

confirmButton.setDisable(!trade.confirmPermitted());
}


///////////////////////////////////////////////////////////////////////////////////////////
// UI Handlers
///////////////////////////////////////////////////////////////////////////////////////////

private void onPaymentStarted() {
if (isDisputed()) {
return;
}

if (!model.dataModel.isBootstrappedOrShowPopup()) {
return;
}
Expand Down Expand Up @@ -633,9 +630,4 @@ private void validatePayoutTx() {
}
}
}

@Override
protected void updateConfirmButtonDisableState(boolean isDisabled) {
confirmButton.setDisable(isDisabled);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import bisq.core.payment.payload.USPostalMoneyOrderAccountPayload;
import bisq.core.payment.payload.WesternUnionAccountPayload;
import bisq.core.trade.Contract;
import bisq.core.trade.Trade;
import bisq.core.trade.txproof.AssetTxProofResult;
import bisq.core.user.DontShowAgainLookup;

Expand Down Expand Up @@ -119,12 +120,10 @@ public void activate() {
case SELLER_PUBLISHED_PAYOUT_TX:
case SELLER_SENT_PAYOUT_TX_PUBLISHED_MSG:
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;
Expand All @@ -139,19 +138,16 @@ public void activate() {
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 {
log.warn("confirmButton gets disabled because trade contains error message {}", trade.getErrorMessage());
// confirmButton.setDisable(true);
log.warn("Trade contains error message {}", trade.getErrorMessage());
statusLabel.setText("");
}
}
Expand Down Expand Up @@ -308,11 +304,6 @@ protected void addContent() {
statusLabel = tuple.third;
}

@Override
protected void updateConfirmButtonDisableState(boolean isDisabled) {
confirmButton.setDisable(isDisabled);
}


///////////////////////////////////////////////////////////////////////////////////////////
// Info
Expand Down Expand Up @@ -355,15 +346,19 @@ protected String getPeriodOverWarnText() {
protected void applyOnDisputeOpened() {
}

@Override
protected void updateDisputeState(Trade.DisputeState disputeState) {
super.updateDisputeState(disputeState);

confirmButton.setDisable(!trade.confirmPermitted());
}


////////////////////////////////////////////////////////////////////////////////////////
// UI Handlers
///////////////////////////////////////////////////////////////////////////////////////////

private void onPaymentReceived() {
if (isDisputed()) {
return;
}

// The confirmPaymentReceived call will trigger the trade protocol to do the payout tx. We want to be sure that we
// are well connected to the Bitcoin network before triggering the broadcast.
if (model.dataModel.isReadyForTxBroadcast()) {
Expand Down Expand Up @@ -459,13 +454,7 @@ private void confirmPaymentReceived() {
statusLabel.setText(Res.get("shared.sendingConfirmation"));

model.dataModel.onFiatPaymentReceived(() -> {
// 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.
//TODO check for support. in case of a dispute we dont want to hide the button
//if (notificationGroup != null)
// notificationGroup.setButtonVisible(false);
}, errorMessage -> {
// confirmButton.setDisable(false);
busyAnimation.stop();
new Popup().warning(Res.get("popup.warning.sendMsgFailed")).show();
});
Expand Down