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

Add signature to dispute result and various other improvements #4543

Merged
merged 42 commits into from Sep 25, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4f1cbbd
Add check for refund agent if donation address is valid
chimp1984 Sep 11, 2020
2b04338
Dont allow opening refudn agent dispute if delayed payout tx is invalid.
chimp1984 Sep 11, 2020
c48abbf
Improve address validation code
chimp1984 Sep 11, 2020
d82631f
Fix some issues found during testing
chimp1984 Sep 12, 2020
677211b
Allow close dispute for refund agent without payout
chimp1984 Sep 12, 2020
08fb596
Call validatePayoutTx only after trades are initialized
chimp1984 Sep 12, 2020
05e1039
Call validatePayoutTx only after trades are initialized
chimp1984 Sep 12, 2020
7ac6e71
Dispute agent sign summary. Add tool for verification
chimp1984 Sep 12, 2020
559028e
Remove unused var
chimp1984 Sep 12, 2020
48066ae
Remove setting of pubKey as it is not needed
chimp1984 Sep 12, 2020
0c46e7d
Add more data to summary msg
chimp1984 Sep 12, 2020
de4fb17
Improve summary notes
chimp1984 Sep 13, 2020
966b22a
Fix line breaks
chimp1984 Sep 13, 2020
29f3a7c
Merge branch 'master_upstream' into allow-refund-agent-close-without-…
chimp1984 Sep 17, 2020
b0b4334
Merge branch 'master_upstream' into dispute-agents-sign-summary
chimp1984 Sep 17, 2020
1c0bef7
Merge branch 'master_upstream' into verify-donation-address-for-refun…
chimp1984 Sep 17, 2020
1c41db4
Fix wrong handling of mainnet RECIPIENT_BTC_ADDRESSes
chimp1984 Sep 17, 2020
3d4427c
Add result of filter match. Add more filter data (tx ids, json)
chimp1984 Sep 17, 2020
45cee2a
Add check for disputes with duplicated trade ID or payout tx ids
chimp1984 Sep 18, 2020
f46a991
Merge branch 'dispute-agents-sign-summary' into dispute-agent-branch
chimp1984 Sep 18, 2020
b2a9262
Merge branch 'verify-donation-address-for-refund-agent' into dispute-…
chimp1984 Sep 18, 2020
c1850cb
Merge branch 'master_upstream' into dispute-agent-branch
chimp1984 Sep 20, 2020
3293047
Set agentsUid to new uuid in case it is null from persisted data
chimp1984 Sep 20, 2020
d31deff
Remove dev log
chimp1984 Sep 20, 2020
25bc616
Add check for multiple deposit txs
chimp1984 Sep 20, 2020
4878a10
Optimize testIfDisputeTriesReplay methods to avoid that maps get crea…
chimp1984 Sep 20, 2020
c6778d6
Add copy to csv data button to report screen
chimp1984 Sep 21, 2020
72dca0b
Add cylce index
chimp1984 Sep 21, 2020
2943316
Remove agentsUid from protobuf, rename to uid
chimp1984 Sep 21, 2020
30e9add
Refactor: rename DelayedPayoutTxValidation to TradeDataValidation
chimp1984 Sep 21, 2020
3206c62
Refactor: Move RegexValidator from bisq.desktop.util.validation to bi…
chimp1984 Sep 21, 2020
987bf49
Add node address validation
chimp1984 Sep 21, 2020
baa915f
Add validateNodeAddress at onOpenNewDisputeMessage
chimp1984 Sep 21, 2020
d52199e
Merge branch 'refactor-regexvalidator' into dispute-agent-branch
chimp1984 Sep 21, 2020
c7a3f95
Rename filterString to filterTerm
chimp1984 Sep 21, 2020
76c8263
Ignore onion address validation for localhost
chimp1984 Sep 21, 2020
a9f1062
Move validation after adding dispute to list
chimp1984 Sep 21, 2020
81bea14
Show popup to peer who accepted mediators suggestion once locktime is…
chimp1984 Sep 21, 2020
f37446b
Change log level
chimp1984 Sep 25, 2020
8ac468d
Commit to trigger travis as it got stuck...
chimp1984 Sep 25, 2020
25c4b4d
Merge branch 'master_upstream' into dispute-agent-branch
chimp1984 Sep 25, 2020
423cc71
Add changes from merge conflict (class was renamed)
chimp1984 Sep 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions core/src/main/resources/i18n/displayStrings.properties
Expand Up @@ -894,6 +894,12 @@ portfolio.pending.mediationResult.popup.info=The mediator has suggested the foll
(or if the other peer is unresponsive).\n\n\
More details about the new arbitration model:\n\
https://docs.bisq.network/trading-rules.html#arbitration
portfolio.pending.mediationResult.popup.selfAccepted.lockTimeOver=You have accepted the mediator''s suggested payout \
but it seems that your trading peer has not accepted it.\n\n\
The lock time is since {0} (block {1}) over and you can open a second-round dispute with an arbitrator who will \
investigate the case again and do a payout based on their findings.\n\n\
You can find more details about the arbitration model at:\n\
https://docs.bisq.network/trading-rules.html#arbitration
portfolio.pending.mediationResult.popup.openArbitration=Reject and request arbitration
portfolio.pending.mediationResult.popup.alreadyAccepted=You've already accepted

Expand Down
Expand Up @@ -30,6 +30,7 @@
import bisq.core.locale.Res;
import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeResult;
import bisq.core.support.dispute.mediation.MediationResultState;
import bisq.core.trade.Contract;
import bisq.core.trade.Trade;
import bisq.core.user.Preferences;
Expand All @@ -41,6 +42,9 @@
import bisq.common.UserThread;
import bisq.common.util.Tuple3;

import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.listeners.NewBestBlockListener;

import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;

Expand All @@ -62,6 +66,7 @@
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;

import javafx.beans.property.BooleanProperty;
import javafx.beans.value.ChangeListener;

import java.util.Optional;
Expand Down Expand Up @@ -97,6 +102,8 @@ public abstract class TradeStepView extends AnchorPane {
private Popup acceptMediationResultPopup;
private BootstrapListener bootstrapListener;
private TradeSubView.ChatCallback chatCallback;
private final NewBestBlockListener newBestBlockListener;
private ChangeListener<Boolean> pendingTradesInitializedListener;


///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -158,6 +165,10 @@ public void onMinuteTick() {
updateTimeLeft();
}
};

newBestBlockListener = block -> {
checkIfLockTimeIsOver();
};
}

public void activate() {
Expand Down Expand Up @@ -200,14 +211,34 @@ public void onUpdatedDataReceived() {
}

tradePeriodStateSubscription = EasyBind.subscribe(trade.tradePeriodStateProperty(), newValue -> {
if (newValue != null)
if (newValue != null) {
updateTradePeriodState(newValue);
}
});

model.clockWatcher.addListener(clockListener);

if (infoLabel != null)
if (infoLabel != null) {
infoLabel.setText(getInfoText());
}

BooleanProperty pendingTradesInitialized = model.dataModel.tradeManager.getPendingTradesInitialized();
if (pendingTradesInitialized.get()) {
onPendingTradesInitialized();
} else {
pendingTradesInitializedListener = (observable, oldValue, newValue) -> {
if (newValue) {
onPendingTradesInitialized();
UserThread.execute(() -> pendingTradesInitialized.removeListener(pendingTradesInitializedListener));
}
};
pendingTradesInitialized.addListener(pendingTradesInitializedListener);
}
}

protected void onPendingTradesInitialized() {
model.dataModel.btcWalletService.addNewBestBlockListener(newBestBlockListener);
checkIfLockTimeIsOver();
}

private void registerSubscriptions() {
Expand Down Expand Up @@ -262,6 +293,15 @@ public void deactivate() {

if (tradeStepInfo != null)
tradeStepInfo.setOnAction(null);

if (newBestBlockListener != null) {
model.dataModel.btcWalletService.removeNewBestBlockListener(newBestBlockListener);
}

if (acceptMediationResultPopup != null) {
acceptMediationResultPopup.hide();
acceptMediationResultPopup = null;
}
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -445,6 +485,11 @@ private void updateDisputeState(Trade.DisputeState disputeState) {
tradeStepInfo.setState(TradeStepInfo.State.IN_REFUND_REQUEST_SELF_REQUESTED);
});

if (acceptMediationResultPopup != null) {
acceptMediationResultPopup.hide();
acceptMediationResultPopup = null;
}

break;
case REFUND_REQUEST_STARTED_BY_PEER:
if (tradeStepInfo != null) {
Expand All @@ -457,6 +502,11 @@ private void updateDisputeState(Trade.DisputeState disputeState) {
if (tradeStepInfo != null)
tradeStepInfo.setState(TradeStepInfo.State.IN_REFUND_REQUEST_PEER_REQUESTED);
});

if (acceptMediationResultPopup != null) {
acceptMediationResultPopup.hide();
acceptMediationResultPopup = null;
}
break;
case REFUND_REQUEST_CLOSED:
break;
Expand Down Expand Up @@ -563,13 +613,34 @@ private void openMediationResultPopup(String headLine) {
String actionButtonText = hasSelfAccepted() ?
Res.get("portfolio.pending.mediationResult.popup.alreadyAccepted") : Res.get("shared.accept");

acceptMediationResultPopup = new Popup().width(900)
.headLine(headLine)
.instruction(Res.get("portfolio.pending.mediationResult.popup.info",
String message;
MediationResultState mediationResultState = checkNotNull(trade).getMediationResultState();
if (mediationResultState == null) {
return;
}

switch (mediationResultState) {
case MEDIATION_RESULT_ACCEPTED:
case SIG_MSG_SENT:
case SIG_MSG_ARRIVED:
case SIG_MSG_IN_MAILBOX:
case SIG_MSG_SEND_FAILED:
message = Res.get("portfolio.pending.mediationResult.popup.selfAccepted.lockTimeOver",
FormattingUtils.getDateFromBlockHeight(remaining),
lockTime);
break;
default:
message = Res.get("portfolio.pending.mediationResult.popup.info",
myPayoutAmount,
peersPayoutAmount,
FormattingUtils.getDateFromBlockHeight(remaining),
lockTime))
lockTime);
break;
}

acceptMediationResultPopup = new Popup().width(900)
.headLine(headLine)
.instruction(message)
.actionButtonText(actionButtonText)
.onAction(() -> {
model.dataModel.mediationManager.acceptMediationResult(trade,
Expand Down Expand Up @@ -656,6 +727,18 @@ protected boolean isDisputed() {
return trade.getDisputeState() != Trade.DisputeState.NO_DISPUTE;
}

private void checkIfLockTimeIsOver() {
Transaction delayedPayoutTx = trade.getDelayedPayoutTx();
if (delayedPayoutTx != null) {
long lockTime = delayedPayoutTx.getLockTime();
int bestChainHeight = model.dataModel.btcWalletService.getBestChainHeight();
long remaining = lockTime - bestChainHeight;
if (remaining <= 0) {
openMediationResultPopup(Res.get("portfolio.pending.mediationResult.popup.headline", trade.getShortId()));
}
}
}


///////////////////////////////////////////////////////////////////////////////////////////
// TradeDurationLimitInfo
Expand Down
Expand Up @@ -24,13 +24,7 @@
import bisq.core.locale.Res;
import bisq.core.trade.TradeDataValidation;

import bisq.common.UserThread;

import javafx.beans.property.BooleanProperty;
import javafx.beans.value.ChangeListener;

public class BuyerStep1View extends TradeStepView {
private ChangeListener<Boolean> pendingTradesInitializedListener;

///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, Initialisation
Expand All @@ -41,22 +35,9 @@ public BuyerStep1View(PendingTradesViewModel model) {
}

@Override
public void activate() {
super.activate();

// We need to have the trades initialized before we can call validatePayoutTx.
BooleanProperty pendingTradesInitialized = model.dataModel.tradeManager.getPendingTradesInitialized();
if (pendingTradesInitialized.get()) {
validatePayoutTx();
} else {
pendingTradesInitializedListener = (observable, oldValue, newValue) -> {
if (newValue) {
validatePayoutTx();
UserThread.execute(() -> pendingTradesInitialized.removeListener(pendingTradesInitializedListener));
}
};
pendingTradesInitialized.addListener(pendingTradesInitializedListener);
}
protected void onPendingTradesInitialized() {
super.onPendingTradesInitialized();
validatePayoutTx();
}


Expand Down
Expand Up @@ -88,9 +88,6 @@
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;

import javafx.beans.property.BooleanProperty;
import javafx.beans.value.ChangeListener;

import java.util.List;
import java.util.concurrent.TimeUnit;

Expand All @@ -107,7 +104,6 @@ public class BuyerStep2View extends TradeStepView {
private BusyAnimation busyAnimation;
private Subscription tradeStatePropertySubscription;
private Timer timeoutTimer;
private ChangeListener<Boolean> pendingTradesInitializedListener;

///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, Initialisation
Expand All @@ -121,20 +117,6 @@ public BuyerStep2View(PendingTradesViewModel model) {
public void activate() {
super.activate();

// We need to have the trades initialized before we can call validatePayoutTx.
BooleanProperty pendingTradesInitialized = model.dataModel.tradeManager.getPendingTradesInitialized();
if (pendingTradesInitialized.get()) {
validatePayoutTx();
} else {
pendingTradesInitializedListener = (observable, oldValue, newValue) -> {
if (newValue) {
validatePayoutTx();
UserThread.execute(() -> pendingTradesInitialized.removeListener(pendingTradesInitializedListener));
}
};
pendingTradesInitialized.addListener(pendingTradesInitializedListener);
}

if (timeoutTimer != null)
timeoutTimer.stop();

Expand Down Expand Up @@ -212,6 +194,13 @@ public void deactivate() {
}
}

@Override
protected void onPendingTradesInitialized() {
super.onPendingTradesInitialized();
validatePayoutTx();
}


///////////////////////////////////////////////////////////////////////////////////////////
// Content
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down