diff --git a/common/src/main/java/bisq/common/app/Version.java b/common/src/main/java/bisq/common/app/Version.java
index 24f61ed2b83..a7b810cb939 100644
--- a/common/src/main/java/bisq/common/app/Version.java
+++ b/common/src/main/java/bisq/common/app/Version.java
@@ -17,9 +17,13 @@
package bisq.common.app;
+import bisq.common.util.Utilities;
+
import java.net.URL;
import java.util.Arrays;
+import java.util.Date;
+import java.util.GregorianCalendar;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -107,7 +111,18 @@ private static int getSubVersion(String version, int index) {
// Version 1.2.2 -> TRADE_PROTOCOL_VERSION = 2
// Version 1.5.0 -> TRADE_PROTOCOL_VERSION = 3
// Version 1.7.0 -> TRADE_PROTOCOL_VERSION = 4
- public static final int TRADE_PROTOCOL_VERSION = 4;
+ // Version 1.9.13 and after activation date -> TRADE_PROTOCOL_VERSION = 5
+
+ public static final Date PROTOCOL_5_ACTIVATION_DATE = Utilities.getUTCDate(2023, GregorianCalendar.OCTOBER, 1);
+
+ public static boolean isTradeProtocolVersion5Activated() {
+ return new Date().after(PROTOCOL_5_ACTIVATION_DATE);
+ }
+
+ public static int getTradeProtocolVersion() {
+ return isTradeProtocolVersion5Activated() ? 5 : 4;
+ }
+
private static int p2pMessageVersion;
public static final String BSQ_TX_VERSION = "1";
@@ -136,7 +151,7 @@ public static void printVersion() {
"VERSION=" + VERSION +
", P2P_NETWORK_VERSION=" + P2P_NETWORK_VERSION +
", LOCAL_DB_VERSION=" + LOCAL_DB_VERSION +
- ", TRADE_PROTOCOL_VERSION=" + TRADE_PROTOCOL_VERSION +
+ ", TRADE_PROTOCOL_VERSION=" + getTradeProtocolVersion() +
", BASE_CURRENCY_NETWORK=" + BASE_CURRENCY_NETWORK +
", getP2PNetworkId()=" + getP2PMessageVersion() +
'}');
diff --git a/core/src/main/java/bisq/core/api/CoreTradesService.java b/core/src/main/java/bisq/core/api/CoreTradesService.java
index 17f10803565..1b3949e2102 100644
--- a/core/src/main/java/bisq/core/api/CoreTradesService.java
+++ b/core/src/main/java/bisq/core/api/CoreTradesService.java
@@ -38,8 +38,8 @@
import bisq.core.trade.model.TradeModel;
import bisq.core.trade.model.bisq_v1.Trade;
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
-import bisq.core.trade.protocol.bisq_v1.BuyerProtocol;
-import bisq.core.trade.protocol.bisq_v1.SellerProtocol;
+import bisq.core.trade.protocol.BuyerProtocol;
+import bisq.core.trade.protocol.SellerProtocol;
import bisq.core.user.User;
import bisq.core.util.validation.BtcAddressValidator;
diff --git a/core/src/main/java/bisq/core/offer/OfferFilterService.java b/core/src/main/java/bisq/core/offer/OfferFilterService.java
index 11a8877fe62..7f7cfb8017a 100644
--- a/core/src/main/java/bisq/core/offer/OfferFilterService.java
+++ b/core/src/main/java/bisq/core/offer/OfferFilterService.java
@@ -138,7 +138,7 @@ public boolean isAnyPaymentAccountValidForOffer(Offer offer) {
}
public boolean hasSameProtocolVersion(Offer offer) {
- return offer.getProtocolVersion() == Version.TRADE_PROTOCOL_VERSION;
+ return offer.getProtocolVersion() == Version.getTradeProtocolVersion();
}
public boolean isIgnored(Offer offer) {
diff --git a/core/src/main/java/bisq/core/offer/OpenOfferManager.java b/core/src/main/java/bisq/core/offer/OpenOfferManager.java
index 7ea84ff0b3b..0799e9b4ff9 100644
--- a/core/src/main/java/bisq/core/offer/OpenOfferManager.java
+++ b/core/src/main/java/bisq/core/offer/OpenOfferManager.java
@@ -934,7 +934,7 @@ private void maybeUpdatePersistedOffers() {
// Capability.REFUND_AGENT in v1.2.0 and want to rewrite a
// persisted offer after the user has updated to 1.2.0 so their offer will be accepted by the network.
- if (original.getProtocolVersion() < Version.TRADE_PROTOCOL_VERSION ||
+ if (original.getProtocolVersion() < Version.getTradeProtocolVersion() ||
!OfferRestrictions.hasOfferMandatoryCapability(originalOffer, Capability.MEDIATION) ||
!OfferRestrictions.hasOfferMandatoryCapability(originalOffer, Capability.REFUND_AGENT) ||
!original.getOwnerNodeAddress().equals(p2PService.getAddress())) {
@@ -960,9 +960,9 @@ private void maybeUpdatePersistedOffers() {
// - Protocol version changed?
int protocolVersion = original.getProtocolVersion();
- if (protocolVersion < Version.TRADE_PROTOCOL_VERSION) {
+ if (protocolVersion < Version.getTradeProtocolVersion()) {
// We update the trade protocol version
- protocolVersion = Version.TRADE_PROTOCOL_VERSION;
+ protocolVersion = Version.getTradeProtocolVersion();
log.info("Updated the protocol version of offer id={}", originalOffer.getId());
}
diff --git a/core/src/main/java/bisq/core/offer/bisq_v1/CreateOfferService.java b/core/src/main/java/bisq/core/offer/bisq_v1/CreateOfferService.java
index f984dd9ddff..c9bb0467f7f 100644
--- a/core/src/main/java/bisq/core/offer/bisq_v1/CreateOfferService.java
+++ b/core/src/main/java/bisq/core/offer/bisq_v1/CreateOfferService.java
@@ -216,7 +216,7 @@ public Offer createAndGetOffer(String offerId,
isPrivateOffer,
hashOfChallenge,
extraDataMap,
- Version.TRADE_PROTOCOL_VERSION);
+ Version.getTradeProtocolVersion());
Offer offer = new Offer(offerPayload);
offer.setPriceFeedService(priceFeedService);
return offer;
diff --git a/core/src/main/java/bisq/core/offer/bsq_swap/OpenBsqSwapOfferService.java b/core/src/main/java/bisq/core/offer/bsq_swap/OpenBsqSwapOfferService.java
index 70735a57064..cd41276bddc 100644
--- a/core/src/main/java/bisq/core/offer/bsq_swap/OpenBsqSwapOfferService.java
+++ b/core/src/main/java/bisq/core/offer/bsq_swap/OpenBsqSwapOfferService.java
@@ -220,7 +220,7 @@ public void requestNewOffer(String offerId,
proofOfWork,
null,
Version.VERSION,
- Version.TRADE_PROTOCOL_VERSION);
+ Version.getTradeProtocolVersion());
resultHandler.accept(new Offer(bsqSwapOfferPayload));
});
});
diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java
index 507e1934e88..1af3398b8a7 100644
--- a/core/src/main/java/bisq/core/trade/TradeManager.java
+++ b/core/src/main/java/bisq/core/trade/TradeManager.java
@@ -52,11 +52,11 @@
import bisq.core.trade.model.bsq_swap.BsqSwapSellerAsMakerTrade;
import bisq.core.trade.model.bsq_swap.BsqSwapSellerAsTakerTrade;
import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
+import bisq.core.trade.protocol.MakerProtocol;
import bisq.core.trade.protocol.Provider;
+import bisq.core.trade.protocol.TakerProtocol;
import bisq.core.trade.protocol.TradeProtocol;
import bisq.core.trade.protocol.TradeProtocolFactory;
-import bisq.core.trade.protocol.bisq_v1.MakerProtocol;
-import bisq.core.trade.protocol.bisq_v1.TakerProtocol;
import bisq.core.trade.protocol.bisq_v1.messages.InputsForDepositTxRequest;
import bisq.core.trade.protocol.bisq_v1.model.ProcessModel;
import bisq.core.trade.protocol.bsq_swap.BsqSwapMakerProtocol;
diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerProtocol.java
new file mode 100644
index 00000000000..c7f474e973e
--- /dev/null
+++ b/core/src/main/java/bisq/core/trade/protocol/BuyerProtocol.java
@@ -0,0 +1,25 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.trade.protocol;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.handlers.ResultHandler;
+
+public interface BuyerProtocol {
+ void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler);
+}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/MakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/MakerProtocol.java
similarity index 96%
rename from core/src/main/java/bisq/core/trade/protocol/bisq_v1/MakerProtocol.java
rename to core/src/main/java/bisq/core/trade/protocol/MakerProtocol.java
index 7c1b3299d77..204244a7eb9 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/MakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/MakerProtocol.java
@@ -15,7 +15,7 @@
* along with Bisq. If not, see .
*/
-package bisq.core.trade.protocol.bisq_v1;
+package bisq.core.trade.protocol;
import bisq.core.trade.protocol.bisq_v1.messages.InputsForDepositTxRequest;
diff --git a/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java
new file mode 100644
index 00000000000..c5064f9b9ca
--- /dev/null
+++ b/core/src/main/java/bisq/core/trade/protocol/SellerProtocol.java
@@ -0,0 +1,26 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.trade.protocol;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.handlers.ResultHandler;
+
+public interface SellerProtocol {
+
+ void onPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler);
+}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/TakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/TakerProtocol.java
similarity index 90%
rename from core/src/main/java/bisq/core/trade/protocol/bisq_v1/TakerProtocol.java
rename to core/src/main/java/bisq/core/trade/protocol/TakerProtocol.java
index b02b7cba91d..249d0ac73bd 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/TakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/TakerProtocol.java
@@ -15,9 +15,7 @@
* along with Bisq. If not, see .
*/
-package bisq.core.trade.protocol.bisq_v1;
-
-import bisq.core.trade.protocol.FluentProtocol;
+package bisq.core.trade.protocol;
public interface TakerProtocol {
void onTakeOffer();
diff --git a/core/src/main/java/bisq/core/trade/protocol/TradeProtocolFactory.java b/core/src/main/java/bisq/core/trade/protocol/TradeProtocolFactory.java
index 54549adc2f0..6eb8ae441a5 100644
--- a/core/src/main/java/bisq/core/trade/protocol/TradeProtocolFactory.java
+++ b/core/src/main/java/bisq/core/trade/protocol/TradeProtocolFactory.java
@@ -26,34 +26,55 @@
import bisq.core.trade.model.bsq_swap.BsqSwapBuyerAsTakerTrade;
import bisq.core.trade.model.bsq_swap.BsqSwapSellerAsMakerTrade;
import bisq.core.trade.model.bsq_swap.BsqSwapSellerAsTakerTrade;
+import bisq.core.trade.model.bsq_swap.BsqSwapTrade;
import bisq.core.trade.protocol.bisq_v1.BuyerAsMakerProtocol;
import bisq.core.trade.protocol.bisq_v1.BuyerAsTakerProtocol;
import bisq.core.trade.protocol.bisq_v1.SellerAsMakerProtocol;
import bisq.core.trade.protocol.bisq_v1.SellerAsTakerProtocol;
+import bisq.core.trade.protocol.bisq_v5.BuyerAsMakerProtocol_v5;
+import bisq.core.trade.protocol.bisq_v5.BuyerAsTakerProtocol_v5;
+import bisq.core.trade.protocol.bisq_v5.SellerAsMakerProtocol_v5;
+import bisq.core.trade.protocol.bisq_v5.SellerAsTakerProtocol_v5;
import bisq.core.trade.protocol.bsq_swap.BsqSwapBuyerAsMakerProtocol;
import bisq.core.trade.protocol.bsq_swap.BsqSwapBuyerAsTakerProtocol;
import bisq.core.trade.protocol.bsq_swap.BsqSwapSellerAsMakerProtocol;
import bisq.core.trade.protocol.bsq_swap.BsqSwapSellerAsTakerProtocol;
+import bisq.common.app.Version;
+
public class TradeProtocolFactory {
public static TradeProtocol getNewTradeProtocol(TradeModel tradeModel) {
+ if (tradeModel instanceof BsqSwapTrade) {
+ if (tradeModel instanceof BsqSwapBuyerAsMakerTrade) {
+ return new BsqSwapBuyerAsMakerProtocol((BsqSwapBuyerAsMakerTrade) tradeModel);
+ } else if (tradeModel instanceof BsqSwapBuyerAsTakerTrade) {
+ return new BsqSwapBuyerAsTakerProtocol((BsqSwapBuyerAsTakerTrade) tradeModel);
+ } else if (tradeModel instanceof BsqSwapSellerAsMakerTrade) {
+ return new BsqSwapSellerAsMakerProtocol((BsqSwapSellerAsMakerTrade) tradeModel);
+ } else if (tradeModel instanceof BsqSwapSellerAsTakerTrade) {
+ return new BsqSwapSellerAsTakerProtocol((BsqSwapSellerAsTakerTrade) tradeModel);
+ }
+ }
+
+ boolean tradeProtocolVersion5Activated = Version.isTradeProtocolVersion5Activated();
if (tradeModel instanceof BuyerAsMakerTrade) {
- return new BuyerAsMakerProtocol((BuyerAsMakerTrade) tradeModel);
+ return tradeProtocolVersion5Activated ?
+ new BuyerAsMakerProtocol_v5((BuyerAsMakerTrade) tradeModel) :
+ new BuyerAsMakerProtocol((BuyerAsMakerTrade) tradeModel);
} else if (tradeModel instanceof BuyerAsTakerTrade) {
- return new BuyerAsTakerProtocol((BuyerAsTakerTrade) tradeModel);
+ return tradeProtocolVersion5Activated ?
+ new BuyerAsTakerProtocol_v5((BuyerAsTakerTrade) tradeModel) :
+ new BuyerAsTakerProtocol((BuyerAsTakerTrade) tradeModel);
} else if (tradeModel instanceof SellerAsMakerTrade) {
- return new SellerAsMakerProtocol((SellerAsMakerTrade) tradeModel);
+ return tradeProtocolVersion5Activated ?
+ new SellerAsMakerProtocol_v5((SellerAsMakerTrade) tradeModel) :
+ new SellerAsMakerProtocol((SellerAsMakerTrade) tradeModel);
} else if (tradeModel instanceof SellerAsTakerTrade) {
- return new SellerAsTakerProtocol((SellerAsTakerTrade) tradeModel);
- } else if (tradeModel instanceof BsqSwapBuyerAsMakerTrade) {
- return new BsqSwapBuyerAsMakerProtocol((BsqSwapBuyerAsMakerTrade) tradeModel);
- } else if (tradeModel instanceof BsqSwapBuyerAsTakerTrade) {
- return new BsqSwapBuyerAsTakerProtocol((BsqSwapBuyerAsTakerTrade) tradeModel);
- } else if (tradeModel instanceof BsqSwapSellerAsMakerTrade) {
- return new BsqSwapSellerAsMakerProtocol((BsqSwapSellerAsMakerTrade) tradeModel);
- } else if (tradeModel instanceof BsqSwapSellerAsTakerTrade) {
- return new BsqSwapSellerAsTakerProtocol((BsqSwapSellerAsTakerTrade) tradeModel);
- } else
- throw new IllegalStateException("Trade not of expected type. Trade=" + tradeModel);
+ return tradeProtocolVersion5Activated ?
+ new SellerAsTakerProtocol_v5((SellerAsTakerTrade) tradeModel) :
+ new SellerAsTakerProtocol((SellerAsTakerTrade) tradeModel);
+ }
+
+ throw new IllegalStateException("Trade not of expected type. Trade=" + tradeModel);
}
}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BaseBuyerProtocol.java
similarity index 98%
rename from core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerProtocol.java
rename to core/src/main/java/bisq/core/trade/protocol/bisq_v1/BaseBuyerProtocol.java
index 858cada6c85..27a0deadd02 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BaseBuyerProtocol.java
@@ -19,6 +19,7 @@
import bisq.core.trade.model.bisq_v1.BuyerTrade;
import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.BuyerProtocol;
import bisq.core.trade.protocol.FluentProtocol;
import bisq.core.trade.protocol.TradeMessage;
import bisq.core.trade.protocol.TradeTaskRunner;
@@ -45,7 +46,7 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public abstract class BuyerProtocol extends DisputeProtocol {
+abstract class BaseBuyerProtocol extends DisputeProtocol implements BuyerProtocol {
enum BuyerEvent implements FluentProtocol.Event {
STARTUP,
PAYMENT_SENT
@@ -55,7 +56,7 @@ enum BuyerEvent implements FluentProtocol.Event {
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
- public BuyerProtocol(BuyerTrade trade) {
+ protected BaseBuyerProtocol(BuyerTrade trade) {
super(trade);
}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BaseSellerProtocol.java
similarity index 97%
rename from core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerProtocol.java
rename to core/src/main/java/bisq/core/trade/protocol/bisq_v1/BaseSellerProtocol.java
index 46a4a74fd15..a4c1270562d 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BaseSellerProtocol.java
@@ -20,6 +20,7 @@
import bisq.core.trade.model.bisq_v1.SellerTrade;
import bisq.core.trade.model.bisq_v1.Trade;
import bisq.core.trade.protocol.FluentProtocol;
+import bisq.core.trade.protocol.SellerProtocol;
import bisq.core.trade.protocol.TradeMessage;
import bisq.core.trade.protocol.TradeTaskRunner;
import bisq.core.trade.protocol.bisq_v1.messages.CounterCurrencyTransferStartedMessage;
@@ -47,13 +48,13 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public abstract class SellerProtocol extends DisputeProtocol {
+abstract class BaseSellerProtocol extends DisputeProtocol implements SellerProtocol {
enum SellerEvent implements FluentProtocol.Event {
STARTUP,
PAYMENT_RECEIVED
}
- public SellerProtocol(SellerTrade trade) {
+ protected BaseSellerProtocol(SellerTrade trade) {
super(trade);
}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerAsMakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerAsMakerProtocol.java
index 83bda8ac8bf..10fad61fa74 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerAsMakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerAsMakerProtocol.java
@@ -19,6 +19,7 @@
import bisq.core.trade.model.bisq_v1.BuyerAsMakerTrade;
import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.MakerProtocol;
import bisq.core.trade.protocol.TradeTaskRunner;
import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureRequest;
import bisq.core.trade.protocol.bisq_v1.messages.DepositTxAndDelayedPayoutTxMessage;
@@ -49,7 +50,7 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class BuyerAsMakerProtocol extends BuyerProtocol implements MakerProtocol {
+public class BuyerAsMakerProtocol extends BaseBuyerProtocol implements MakerProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@@ -111,7 +112,6 @@ protected void handle(DelayedPayoutTxSignatureRequest message, NodeAddress peer)
.executeTasks();
}
- // We keep the handler here in as well to make it more transparent which messages we expect
@Override
protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress peer) {
super.handle(message, peer);
@@ -122,7 +122,6 @@ protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress pe
// User interaction
///////////////////////////////////////////////////////////////////////////////////////////
- // We keep the handler here in as well to make it more transparent which events we expect
@Override
public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
super.onPaymentStarted(resultHandler, errorMessageHandler);
@@ -133,7 +132,6 @@ public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler er
// Incoming message Payout tx
///////////////////////////////////////////////////////////////////////////////////////////
- // We keep the handler here in as well to make it more transparent which messages we expect
@Override
protected void handle(PayoutTxPublishedMessage message, NodeAddress peer) {
super.handle(message, peer);
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerAsTakerProtocol.java
index d7b9413db59..b67b60507af 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerAsTakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/BuyerAsTakerProtocol.java
@@ -21,6 +21,7 @@
import bisq.core.offer.Offer;
import bisq.core.trade.model.bisq_v1.BuyerAsTakerTrade;
import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.TakerProtocol;
import bisq.core.trade.protocol.TradeMessage;
import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureRequest;
import bisq.core.trade.protocol.bisq_v1.messages.DepositTxAndDelayedPayoutTxMessage;
@@ -55,7 +56,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
-public class BuyerAsTakerProtocol extends BuyerProtocol implements TakerProtocol {
+public class BuyerAsTakerProtocol extends BaseBuyerProtocol implements TakerProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@@ -126,7 +127,6 @@ protected void handle(DelayedPayoutTxSignatureRequest message, NodeAddress peer)
.executeTasks();
}
- // We keep the handler here in as well to make it more transparent which messages we expect
@Override
protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress peer) {
super.handle(message, peer);
@@ -137,7 +137,6 @@ protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress pe
// User interaction
///////////////////////////////////////////////////////////////////////////////////////////
- // We keep the handler here in as well to make it more transparent which events we expect
@Override
public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
super.onPaymentStarted(resultHandler, errorMessageHandler);
@@ -148,7 +147,6 @@ public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler er
// Incoming message Payout tx
///////////////////////////////////////////////////////////////////////////////////////////
- // We keep the handler here in as well to make it more transparent which messages we expect
@Override
protected void handle(PayoutTxPublishedMessage message, NodeAddress peer) {
super.handle(message, peer);
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerAsMakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerAsMakerProtocol.java
index c88e7de0f87..3494a0cb124 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerAsMakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerAsMakerProtocol.java
@@ -20,12 +20,14 @@
import bisq.core.trade.model.bisq_v1.SellerAsMakerTrade;
import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.MakerProtocol;
import bisq.core.trade.protocol.TradeMessage;
import bisq.core.trade.protocol.TradeTaskRunner;
import bisq.core.trade.protocol.bisq_v1.messages.CounterCurrencyTransferStartedMessage;
import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureResponse;
import bisq.core.trade.protocol.bisq_v1.messages.DepositTxMessage;
import bisq.core.trade.protocol.bisq_v1.messages.InputsForDepositTxRequest;
+import bisq.core.trade.protocol.bisq_v1.messages.ShareBuyerPaymentAccountMessage;
import bisq.core.trade.protocol.bisq_v1.tasks.ApplyFilter;
import bisq.core.trade.protocol.bisq_v1.tasks.CheckIfDaoStateIsInSync;
import bisq.core.trade.protocol.bisq_v1.tasks.TradeTask;
@@ -51,7 +53,7 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class SellerAsMakerProtocol extends SellerProtocol implements MakerProtocol {
+public class SellerAsMakerProtocol extends BaseSellerProtocol implements MakerProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@@ -113,18 +115,21 @@ protected void handle(DepositTxMessage message, NodeAddress peer) {
.executeTasks();
}
- // We keep the handler here in as well to make it more transparent which messages we expect
@Override
protected void handle(DelayedPayoutTxSignatureResponse message, NodeAddress peer) {
super.handle(message, peer);
}
+ @Override
+ protected void handle(ShareBuyerPaymentAccountMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////
// Incoming message when buyer has clicked payment started button
///////////////////////////////////////////////////////////////////////////////////////////
- // We keep the handler here in as well to make it more transparent which messages we expect
@Override
protected void handle(CounterCurrencyTransferStartedMessage message, NodeAddress peer) {
super.handle(message, peer);
@@ -135,7 +140,6 @@ protected void handle(CounterCurrencyTransferStartedMessage message, NodeAddress
// User interaction
///////////////////////////////////////////////////////////////////////////////////////////
- // We keep the handler here in as well to make it more transparent which events we expect
@Override
public void onPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
super.onPaymentReceived(resultHandler, errorMessageHandler);
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerAsTakerProtocol.java
index 42804e7cd3d..84c37fe42ee 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerAsTakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v1/SellerAsTakerProtocol.java
@@ -21,10 +21,12 @@
import bisq.core.offer.Offer;
import bisq.core.trade.model.bisq_v1.SellerAsTakerTrade;
import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.TakerProtocol;
import bisq.core.trade.protocol.TradeMessage;
import bisq.core.trade.protocol.bisq_v1.messages.CounterCurrencyTransferStartedMessage;
import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureResponse;
import bisq.core.trade.protocol.bisq_v1.messages.InputsForDepositTxResponse;
+import bisq.core.trade.protocol.bisq_v1.messages.ShareBuyerPaymentAccountMessage;
import bisq.core.trade.protocol.bisq_v1.tasks.ApplyFilter;
import bisq.core.trade.protocol.bisq_v1.tasks.CheckIfDaoStateIsInSync;
import bisq.core.trade.protocol.bisq_v1.tasks.TradeTask;
@@ -51,7 +53,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
-public class SellerAsTakerProtocol extends SellerProtocol implements TakerProtocol {
+public class SellerAsTakerProtocol extends BaseSellerProtocol implements TakerProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@@ -107,18 +109,21 @@ private void handle(InputsForDepositTxResponse message, NodeAddress peer) {
.executeTasks();
}
- // We keep the handler here in as well to make it more transparent which messages we expect
@Override
protected void handle(DelayedPayoutTxSignatureResponse message, NodeAddress peer) {
super.handle(message, peer);
}
+ @Override
+ protected void handle(ShareBuyerPaymentAccountMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////
// Incoming message when buyer has clicked payment started button
///////////////////////////////////////////////////////////////////////////////////////////
- // We keep the handler here in as well to make it more transparent which messages we expect
@Override
protected void handle(CounterCurrencyTransferStartedMessage message, NodeAddress peer) {
super.handle(message, peer);
@@ -129,7 +134,6 @@ protected void handle(CounterCurrencyTransferStartedMessage message, NodeAddress
// User interaction
///////////////////////////////////////////////////////////////////////////////////////////
- // We keep the handler here in as well to make it more transparent which events we expect
@Override
public void onPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
super.onPaymentReceived(resultHandler, errorMessageHandler);
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BaseBuyerProtocol_v5.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BaseBuyerProtocol_v5.java
new file mode 100644
index 00000000000..31ef8bc38cb
--- /dev/null
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BaseBuyerProtocol_v5.java
@@ -0,0 +1,201 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.trade.protocol.bisq_v5;
+
+import bisq.core.trade.model.bisq_v1.BuyerTrade;
+import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.BuyerProtocol;
+import bisq.core.trade.protocol.FluentProtocol;
+import bisq.core.trade.protocol.TradeMessage;
+import bisq.core.trade.protocol.TradeTaskRunner;
+import bisq.core.trade.protocol.bisq_v1.DisputeProtocol;
+import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureRequest;
+import bisq.core.trade.protocol.bisq_v1.messages.DepositTxAndDelayedPayoutTxMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.PayoutTxPublishedMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.ApplyFilter;
+import bisq.core.trade.protocol.bisq_v1.tasks.TradeTask;
+import bisq.core.trade.protocol.bisq_v1.tasks.VerifyPeersAccountAgeWitness;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerProcessDepositTxAndDelayedPayoutTxMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerProcessPayoutTxPublishedMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSendCounterCurrencyTransferStartedMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSendsShareBuyerPaymentAccountMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSetupDepositTxListener;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSetupPayoutTxListener;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSignPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerVerifiesFinalDelayedPayoutTx;
+
+import bisq.network.p2p.NodeAddress;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.handlers.ResultHandler;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+abstract class BaseBuyerProtocol_v5 extends DisputeProtocol implements BuyerProtocol {
+ enum BuyerEvent implements FluentProtocol.Event {
+ STARTUP,
+ PAYMENT_SENT
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Constructor
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ protected BaseBuyerProtocol_v5(BuyerTrade trade) {
+ super(trade);
+ }
+
+ @Override
+ protected void onInitialized() {
+ super.onInitialized();
+ // We get called the constructor with any possible state and phase. As we don't want to log an error for such
+ // cases we use the alternative 'given' method instead of 'expect'.
+ given(phase(Trade.Phase.TAKER_FEE_PUBLISHED)
+ .with(BuyerEvent.STARTUP))
+ .setup(tasks(BuyerSetupDepositTxListener.class))
+ .executeTasks();
+
+ given(anyPhase(Trade.Phase.FIAT_SENT, Trade.Phase.FIAT_RECEIVED)
+ .with(BuyerEvent.STARTUP))
+ .setup(tasks(BuyerSetupPayoutTxListener.class))
+ .executeTasks();
+
+ given(anyPhase(Trade.Phase.FIAT_SENT, Trade.Phase.FIAT_RECEIVED)
+ .anyState(Trade.State.BUYER_STORED_IN_MAILBOX_FIAT_PAYMENT_INITIATED_MSG,
+ Trade.State.BUYER_SEND_FAILED_FIAT_PAYMENT_INITIATED_MSG)
+ .with(BuyerEvent.STARTUP))
+ .setup(tasks(BuyerSendCounterCurrencyTransferStartedMessage.class))
+ .executeTasks();
+ }
+
+ @Override
+ public void onMailboxMessage(TradeMessage message, NodeAddress peer) {
+ super.onMailboxMessage(message, peer);
+
+ if (message instanceof DepositTxAndDelayedPayoutTxMessage) {
+ handle((DepositTxAndDelayedPayoutTxMessage) message, peer);
+ } else if (message instanceof PayoutTxPublishedMessage) {
+ handle((PayoutTxPublishedMessage) message, peer);
+ }
+ }
+
+ protected abstract void handle(DelayedPayoutTxSignatureRequest message, NodeAddress peer);
+
+ // The DepositTxAndDelayedPayoutTxMessage is a mailbox message. Earlier we used only the deposit tx which can
+ // be set also when received by the network once published by the peer so that message was not mandatory and could
+ // have arrived as mailbox message.
+ // Now we send the delayed payout tx as well and with that this message is mandatory for continuing the protocol.
+ // We do not support mailbox message handling during the take offer process as it is expected that both peers
+ // are online.
+ // For backward compatibility and extra resilience we still keep DepositTxAndDelayedPayoutTxMessage as a
+ // mailbox message but the stored in mailbox case is not expected and the seller would try to send the message again
+ // in the hope to reach the buyer directly in case of network issues.
+ protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress peer) {
+ expect(anyPhase(Trade.Phase.TAKER_FEE_PUBLISHED, Trade.Phase.DEPOSIT_PUBLISHED)
+ .with(message)
+ .from(peer)
+ .preCondition(trade.getDepositTx() == null || processModel.getTradePeer().getPaymentAccountPayload() == null,
+ () -> {
+ log.warn("We received a DepositTxAndDelayedPayoutTxMessage but we have already processed the deposit and " +
+ "delayed payout tx so we ignore the message. This can happen if the ACK message to the peer did not " +
+ "arrive and the peer repeats sending us the message. We send another ACK msg.");
+ stopTimeout();
+ sendAckMessage(message, true, null);
+ removeMailboxMessageAfterProcessing(message);
+ }))
+ .setup(tasks(BuyerProcessDepositTxAndDelayedPayoutTxMessage.class,
+ ApplyFilter.class,
+ VerifyPeersAccountAgeWitness.class,
+ BuyerSendsShareBuyerPaymentAccountMessage.class,
+ BuyerVerifiesFinalDelayedPayoutTx.class)
+ .using(new TradeTaskRunner(trade,
+ () -> {
+ stopTimeout();
+ handleTaskRunnerSuccess(message);
+ },
+ errorMessage -> handleTaskRunnerFault(message, errorMessage))))
+ .executeTasks();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // User interaction
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
+ BuyerEvent event = BuyerEvent.PAYMENT_SENT;
+ expect(phase(Trade.Phase.DEPOSIT_CONFIRMED)
+ .with(event)
+ .preCondition(trade.confirmPermitted()))
+ .setup(tasks(ApplyFilter.class,
+ getVerifyPeersFeePaymentClass(),
+ BuyerSignPayoutTx.class,
+ BuyerSetupPayoutTxListener.class,
+ BuyerSendCounterCurrencyTransferStartedMessage.class)
+ .using(new TradeTaskRunner(trade,
+ () -> {
+ resultHandler.handleResult();
+ handleTaskRunnerSuccess(event);
+ },
+ (errorMessage) -> {
+ errorMessageHandler.handleErrorMessage(errorMessage);
+ handleTaskRunnerFault(event, errorMessage);
+ })))
+ .run(() -> {
+ trade.setState(Trade.State.BUYER_CONFIRMED_IN_UI_FIAT_PAYMENT_INITIATED);
+ processModel.getTradeManager().requestPersistence();
+ })
+ .executeTasks();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming message Payout tx
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ protected void handle(PayoutTxPublishedMessage message, NodeAddress peer) {
+ expect(anyPhase(Trade.Phase.FIAT_SENT, Trade.Phase.PAYOUT_PUBLISHED)
+ .with(message)
+ .from(peer))
+ .setup(tasks(BuyerProcessPayoutTxPublishedMessage.class))
+ .executeTasks();
+
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Message dispatcher
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
+ super.onTradeMessage(message, peer);
+
+ log.info("Received {} from {} with tradeId {} and uid {}",
+ message.getClass().getSimpleName(), peer, message.getTradeId(), message.getUid());
+
+ if (message instanceof DelayedPayoutTxSignatureRequest) {
+ handle((DelayedPayoutTxSignatureRequest) message, peer);
+ } else if (message instanceof DepositTxAndDelayedPayoutTxMessage) {
+ handle((DepositTxAndDelayedPayoutTxMessage) message, peer);
+ } else if (message instanceof PayoutTxPublishedMessage) {
+ handle((PayoutTxPublishedMessage) message, peer);
+ }
+ }
+
+ abstract protected Class extends TradeTask> getVerifyPeersFeePaymentClass();
+}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BaseSellerProtocol_v5.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BaseSellerProtocol_v5.java
new file mode 100644
index 00000000000..a98fb29ec5a
--- /dev/null
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BaseSellerProtocol_v5.java
@@ -0,0 +1,188 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.trade.protocol.bisq_v5;
+
+import bisq.core.trade.model.bisq_v1.SellerTrade;
+import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.FluentProtocol;
+import bisq.core.trade.protocol.SellerProtocol;
+import bisq.core.trade.protocol.TradeMessage;
+import bisq.core.trade.protocol.TradeTaskRunner;
+import bisq.core.trade.protocol.bisq_v1.DisputeProtocol;
+import bisq.core.trade.protocol.bisq_v1.messages.CounterCurrencyTransferStartedMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureResponse;
+import bisq.core.trade.protocol.bisq_v1.messages.ShareBuyerPaymentAccountMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.ApplyFilter;
+import bisq.core.trade.protocol.bisq_v1.tasks.TradeTask;
+import bisq.core.trade.protocol.bisq_v1.tasks.VerifyPeersAccountAgeWitness;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerBroadcastPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerFinalizesDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerProcessCounterCurrencyTransferStartedMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerProcessDelayedPayoutTxSignatureResponse;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerProcessShareBuyerPaymentAccountMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerPublishesDepositTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerPublishesTradeStatistics;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerSendPayoutTxPublishedMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerSendsDepositTxAndDelayedPayoutTxMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerSignAndFinalizePayoutTx;
+
+import bisq.network.p2p.NodeAddress;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.handlers.ResultHandler;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+abstract class BaseSellerProtocol_v5 extends DisputeProtocol implements SellerProtocol {
+ enum SellerEvent implements FluentProtocol.Event {
+ STARTUP,
+ PAYMENT_RECEIVED
+ }
+
+ protected BaseSellerProtocol_v5(SellerTrade trade) {
+ super(trade);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Mailbox
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void onMailboxMessage(TradeMessage message, NodeAddress peerNodeAddress) {
+ super.onMailboxMessage(message, peerNodeAddress);
+
+ if (message instanceof CounterCurrencyTransferStartedMessage) {
+ handle((CounterCurrencyTransferStartedMessage) message, peerNodeAddress);
+ }
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming messages
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ protected void handle(DelayedPayoutTxSignatureResponse message, NodeAddress peer) {
+ expect(phase(Trade.Phase.TAKER_FEE_PUBLISHED)
+ .with(message)
+ .from(peer))
+ .setup(tasks(SellerProcessDelayedPayoutTxSignatureResponse.class,
+ SellerFinalizesDelayedPayoutTx.class,
+ SellerSendsDepositTxAndDelayedPayoutTxMessage.class,
+ SellerPublishesDepositTx.class,
+ SellerPublishesTradeStatistics.class))
+ .executeTasks();
+ }
+
+ protected void handle(ShareBuyerPaymentAccountMessage message, NodeAddress peer) {
+ expect(anyPhase(Trade.Phase.TAKER_FEE_PUBLISHED, Trade.Phase.DEPOSIT_PUBLISHED, Trade.Phase.DEPOSIT_CONFIRMED)
+ .with(message)
+ .from(peer))
+ .setup(tasks(SellerProcessShareBuyerPaymentAccountMessage.class,
+ ApplyFilter.class,
+ VerifyPeersAccountAgeWitness.class))
+ .run(() -> {
+ // We stop timeout here and don't start a new one as the
+ // SellerSendsDepositTxAndDelayedPayoutTxMessage repeats to send the message and has it's own
+ // timeout if it never succeeds.
+ stopTimeout();
+ })
+ .executeTasks();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming message when buyer has clicked payment started button
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ protected void handle(CounterCurrencyTransferStartedMessage message, NodeAddress peer) {
+ // We are more tolerant with expected phase and allow also DEPOSIT_PUBLISHED as it can be the case
+ // that the wallet is still syncing and so the DEPOSIT_CONFIRMED state to yet triggered when we received
+ // a mailbox message with CounterCurrencyTransferStartedMessage.
+ // TODO A better fix would be to add a listener for the wallet sync state and process
+ // the mailbox msg once wallet is ready and trade state set.
+ expect(anyPhase(Trade.Phase.DEPOSIT_CONFIRMED, Trade.Phase.DEPOSIT_PUBLISHED)
+ .with(message)
+ .from(peer)
+ .preCondition(trade.getPayoutTx() == null,
+ () -> {
+ log.warn("We received a CounterCurrencyTransferStartedMessage but we have already created the payout tx " +
+ "so we ignore the message. This can happen if the ACK message to the peer did not " +
+ "arrive and the peer repeats sending us the message. We send another ACK msg.");
+ sendAckMessage(message, true, null);
+ removeMailboxMessageAfterProcessing(message);
+ }))
+ .setup(tasks(
+ SellerProcessCounterCurrencyTransferStartedMessage.class,
+ ApplyFilter.class,
+ getVerifyPeersFeePaymentClass()))
+ .executeTasks();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // User interaction
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public void onPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
+ SellerEvent event = SellerEvent.PAYMENT_RECEIVED;
+ expect(anyPhase(Trade.Phase.FIAT_SENT, Trade.Phase.PAYOUT_PUBLISHED)
+ .with(event)
+ .preCondition(trade.confirmPermitted()))
+ .setup(tasks(
+ ApplyFilter.class,
+ getVerifyPeersFeePaymentClass(),
+ SellerSignAndFinalizePayoutTx.class,
+ SellerBroadcastPayoutTx.class,
+ SellerSendPayoutTxPublishedMessage.class)
+ .using(new TradeTaskRunner(trade,
+ () -> {
+ resultHandler.handleResult();
+ handleTaskRunnerSuccess(event);
+ },
+ (errorMessage) -> {
+ errorMessageHandler.handleErrorMessage(errorMessage);
+ handleTaskRunnerFault(event, errorMessage);
+ })))
+ .run(() -> {
+ trade.setState(Trade.State.SELLER_CONFIRMED_IN_UI_FIAT_PAYMENT_RECEIPT);
+ processModel.getTradeManager().requestPersistence();
+ })
+ .executeTasks();
+ }
+
+
+ @Override
+ protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
+ log.info("Received {} from {} with tradeId {} and uid {}",
+ message.getClass().getSimpleName(), peer, message.getTradeId(), message.getUid());
+
+ super.onTradeMessage(message, peer);
+
+ if (message instanceof DelayedPayoutTxSignatureResponse) {
+ handle((DelayedPayoutTxSignatureResponse) message, peer);
+ } else if (message instanceof ShareBuyerPaymentAccountMessage) {
+ handle((ShareBuyerPaymentAccountMessage) message, peer);
+ } else if (message instanceof CounterCurrencyTransferStartedMessage) {
+ handle((CounterCurrencyTransferStartedMessage) message, peer);
+ }
+ }
+
+ abstract protected Class extends TradeTask> getVerifyPeersFeePaymentClass();
+
+}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BuyerAsMakerProtocol_v5.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BuyerAsMakerProtocol_v5.java
new file mode 100644
index 00000000000..0f5953d4258
--- /dev/null
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BuyerAsMakerProtocol_v5.java
@@ -0,0 +1,145 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.trade.protocol.bisq_v5;
+
+import bisq.core.trade.model.bisq_v1.BuyerAsMakerTrade;
+import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.MakerProtocol;
+import bisq.core.trade.protocol.TradeTaskRunner;
+import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureRequest;
+import bisq.core.trade.protocol.bisq_v1.messages.DepositTxAndDelayedPayoutTxMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.InputsForDepositTxRequest;
+import bisq.core.trade.protocol.bisq_v1.messages.PayoutTxPublishedMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.ApplyFilter;
+import bisq.core.trade.protocol.bisq_v1.tasks.CheckIfDaoStateIsInSync;
+import bisq.core.trade.protocol.bisq_v1.tasks.TradeTask;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerFinalizesDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerProcessDelayedPayoutTxSignatureRequest;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSendsDelayedPayoutTxSignatureResponse;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSetupDepositTxListener;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSignsDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerVerifiesPreparedDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer_as_maker.BuyerAsMakerCreatesAndSignsDepositTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer_as_maker.BuyerAsMakerSendsInputsForDepositTxResponse;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerCreateAndSignContract;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerProcessesInputsForDepositTxRequest;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerRemovesOpenOffer;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerSetsLockTime;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerVerifyTakerFeePayment;
+
+import bisq.network.p2p.NodeAddress;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.handlers.ResultHandler;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class BuyerAsMakerProtocol_v5 extends BaseBuyerProtocol_v5 implements MakerProtocol {
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Constructor
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public BuyerAsMakerProtocol_v5(BuyerAsMakerTrade trade) {
+ super(trade);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Handle take offer request
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void handleTakeOfferRequest(InputsForDepositTxRequest message,
+ NodeAddress peer,
+ ErrorMessageHandler errorMessageHandler) {
+ expect(phase(Trade.Phase.INIT)
+ .with(message)
+ .from(peer))
+ .setup(tasks(
+ CheckIfDaoStateIsInSync.class,
+ MakerProcessesInputsForDepositTxRequest.class,
+ ApplyFilter.class,
+ getVerifyPeersFeePaymentClass(),
+ MakerSetsLockTime.class,
+ MakerCreateAndSignContract.class,
+ BuyerAsMakerCreatesAndSignsDepositTx.class,
+ BuyerSetupDepositTxListener.class,
+ BuyerAsMakerSendsInputsForDepositTxResponse.class).
+ using(new TradeTaskRunner(trade,
+ () -> handleTaskRunnerSuccess(message),
+ errorMessage -> {
+ errorMessageHandler.handleErrorMessage(errorMessage);
+ handleTaskRunnerFault(message, errorMessage);
+ }))
+ .withTimeout(120))
+ .executeTasks();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming messages Take offer process
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ protected void handle(DelayedPayoutTxSignatureRequest message, NodeAddress peer) {
+ expect(phase(Trade.Phase.TAKER_FEE_PUBLISHED)
+ .with(message)
+ .from(peer))
+ .setup(tasks(
+ MakerRemovesOpenOffer.class,
+ BuyerProcessDelayedPayoutTxSignatureRequest.class,
+ BuyerVerifiesPreparedDelayedPayoutTx.class,
+ BuyerSignsDelayedPayoutTx.class,
+ BuyerFinalizesDelayedPayoutTx.class,
+ BuyerSendsDelayedPayoutTxSignatureResponse.class)
+ .withTimeout(120))
+ .executeTasks();
+ }
+
+ @Override
+ protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // User interaction
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
+ super.onPaymentStarted(resultHandler, errorMessageHandler);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming message Payout tx
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void handle(PayoutTxPublishedMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+
+ @Override
+ protected Class extends TradeTask> getVerifyPeersFeePaymentClass() {
+ return MakerVerifyTakerFeePayment.class;
+ }
+}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BuyerAsTakerProtocol_v5.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BuyerAsTakerProtocol_v5.java
new file mode 100644
index 00000000000..a31a4bf3376
--- /dev/null
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/BuyerAsTakerProtocol_v5.java
@@ -0,0 +1,173 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.trade.protocol.bisq_v5;
+
+
+import bisq.core.offer.Offer;
+import bisq.core.trade.model.bisq_v1.BuyerAsTakerTrade;
+import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.TakerProtocol;
+import bisq.core.trade.protocol.TradeMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureRequest;
+import bisq.core.trade.protocol.bisq_v1.messages.DepositTxAndDelayedPayoutTxMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.InputsForDepositTxResponse;
+import bisq.core.trade.protocol.bisq_v1.messages.PayoutTxPublishedMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.ApplyFilter;
+import bisq.core.trade.protocol.bisq_v1.tasks.CheckIfDaoStateIsInSync;
+import bisq.core.trade.protocol.bisq_v1.tasks.TradeTask;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerFinalizesDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerProcessDelayedPayoutTxSignatureRequest;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSendsDelayedPayoutTxSignatureResponse;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSetupDepositTxListener;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerSignsDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer.BuyerVerifiesPreparedDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer_as_taker.BuyerAsTakerCreatesDepositTxInputs;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer_as_taker.BuyerAsTakerSendsDepositTxMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.buyer_as_taker.BuyerAsTakerSignsDepositTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.CreateTakerFeeTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerProcessesInputsForDepositTxResponse;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerPublishFeeTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerSendInputsForDepositTxRequest;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerVerifyAndSignContract;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerVerifyMakerFeePayment;
+
+import bisq.network.p2p.NodeAddress;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.handlers.ResultHandler;
+
+import lombok.extern.slf4j.Slf4j;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@Slf4j
+public class BuyerAsTakerProtocol_v5 extends BaseBuyerProtocol_v5 implements TakerProtocol {
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Constructor
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public BuyerAsTakerProtocol_v5(BuyerAsTakerTrade trade) {
+ super(trade);
+
+ Offer offer = checkNotNull(trade.getOffer());
+ processModel.getTradePeer().setPubKeyRing(offer.getPubKeyRing());
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Take offer
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void onTakeOffer() {
+ expect(phase(Trade.Phase.INIT)
+ .with(TakerEvent.TAKE_OFFER))
+ .setup(tasks(
+ CheckIfDaoStateIsInSync.class,
+ ApplyFilter.class,
+ getVerifyPeersFeePaymentClass(),
+ CreateTakerFeeTx.class,
+ BuyerAsTakerCreatesDepositTxInputs.class,
+ TakerSendInputsForDepositTxRequest.class)
+ .withTimeout(120))
+ .run(() -> {
+ processModel.setTempTradingPeerNodeAddress(trade.getTradingPeerNodeAddress());
+ processModel.getTradeManager().requestPersistence();
+ })
+ .executeTasks();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming messages Take offer process
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ private void handle(InputsForDepositTxResponse message, NodeAddress peer) {
+ expect(phase(Trade.Phase.INIT)
+ .with(message)
+ .from(peer))
+ .setup(tasks(TakerProcessesInputsForDepositTxResponse.class,
+ ApplyFilter.class,
+ TakerVerifyAndSignContract.class,
+ TakerPublishFeeTx.class,
+ BuyerAsTakerSignsDepositTx.class,
+ BuyerSetupDepositTxListener.class,
+ BuyerAsTakerSendsDepositTxMessage.class)
+ .withTimeout(120))
+ .executeTasks();
+ }
+
+ protected void handle(DelayedPayoutTxSignatureRequest message, NodeAddress peer) {
+ expect(phase(Trade.Phase.TAKER_FEE_PUBLISHED)
+ .with(message)
+ .from(peer))
+ .setup(tasks(
+ BuyerProcessDelayedPayoutTxSignatureRequest.class,
+ BuyerVerifiesPreparedDelayedPayoutTx.class,
+ BuyerSignsDelayedPayoutTx.class,
+ BuyerFinalizesDelayedPayoutTx.class,
+ BuyerSendsDelayedPayoutTxSignatureResponse.class)
+ .withTimeout(120))
+ .executeTasks();
+ }
+
+ @Override
+ protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // User interaction
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void onPaymentStarted(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
+ super.onPaymentStarted(resultHandler, errorMessageHandler);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming message Payout tx
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void handle(PayoutTxPublishedMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Message dispatcher
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
+ super.onTradeMessage(message, peer);
+
+ if (message instanceof InputsForDepositTxResponse) {
+ handle((InputsForDepositTxResponse) message, peer);
+ }
+ }
+
+ @Override
+ protected Class extends TradeTask> getVerifyPeersFeePaymentClass() {
+ return TakerVerifyMakerFeePayment.class;
+ }
+}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v5/SellerAsMakerProtocol_v5.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/SellerAsMakerProtocol_v5.java
new file mode 100644
index 00000000000..4ca11fe4670
--- /dev/null
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/SellerAsMakerProtocol_v5.java
@@ -0,0 +1,169 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.trade.protocol.bisq_v5;
+
+
+import bisq.core.trade.model.bisq_v1.SellerAsMakerTrade;
+import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.MakerProtocol;
+import bisq.core.trade.protocol.TradeMessage;
+import bisq.core.trade.protocol.TradeTaskRunner;
+import bisq.core.trade.protocol.bisq_v1.messages.CounterCurrencyTransferStartedMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureResponse;
+import bisq.core.trade.protocol.bisq_v1.messages.DepositTxMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.InputsForDepositTxRequest;
+import bisq.core.trade.protocol.bisq_v1.messages.ShareBuyerPaymentAccountMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.ApplyFilter;
+import bisq.core.trade.protocol.bisq_v1.tasks.CheckIfDaoStateIsInSync;
+import bisq.core.trade.protocol.bisq_v1.tasks.TradeTask;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerCreateAndSignContract;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerProcessesInputsForDepositTxRequest;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerRemovesOpenOffer;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerSetsLockTime;
+import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerVerifyTakerFeePayment;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.MaybeCreateSubAccount;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerCreatesDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerSendDelayedPayoutTxSignatureRequest;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerSignsDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller_as_maker.SellerAsMakerCreatesUnsignedDepositTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller_as_maker.SellerAsMakerFinalizesDepositTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller_as_maker.SellerAsMakerProcessDepositTxMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller_as_maker.SellerAsMakerSendsInputsForDepositTxResponse;
+
+import bisq.network.p2p.NodeAddress;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.handlers.ResultHandler;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class SellerAsMakerProtocol_v5 extends BaseSellerProtocol_v5 implements MakerProtocol {
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Constructor
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public SellerAsMakerProtocol_v5(SellerAsMakerTrade trade) {
+ super(trade);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Handle take offer request
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void handleTakeOfferRequest(InputsForDepositTxRequest message,
+ NodeAddress peer,
+ ErrorMessageHandler errorMessageHandler) {
+ expect(phase(Trade.Phase.INIT)
+ .with(message)
+ .from(peer))
+ .setup(tasks(
+ CheckIfDaoStateIsInSync.class,
+ MaybeCreateSubAccount.class,
+ MakerProcessesInputsForDepositTxRequest.class,
+ ApplyFilter.class,
+ getVerifyPeersFeePaymentClass(),
+ MakerSetsLockTime.class,
+ MakerCreateAndSignContract.class,
+ SellerAsMakerCreatesUnsignedDepositTx.class,
+ SellerAsMakerSendsInputsForDepositTxResponse.class)
+ .using(new TradeTaskRunner(trade,
+ () -> handleTaskRunnerSuccess(message),
+ errorMessage -> {
+ errorMessageHandler.handleErrorMessage(errorMessage);
+ handleTaskRunnerFault(message, errorMessage);
+ }))
+ .withTimeout(120))
+ .executeTasks();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming messages Take offer process
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ protected void handle(DepositTxMessage message, NodeAddress peer) {
+ expect(phase(Trade.Phase.TAKER_FEE_PUBLISHED)
+ .with(message)
+ .from(peer))
+ .setup(tasks(
+ MakerRemovesOpenOffer.class,
+ SellerAsMakerProcessDepositTxMessage.class,
+ SellerAsMakerFinalizesDepositTx.class,
+ SellerCreatesDelayedPayoutTx.class,
+ SellerSignsDelayedPayoutTx.class,
+ SellerSendDelayedPayoutTxSignatureRequest.class)
+ .withTimeout(120))
+ .executeTasks();
+ }
+
+ @Override
+ protected void handle(DelayedPayoutTxSignatureResponse message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+ @Override
+ protected void handle(ShareBuyerPaymentAccountMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming message when buyer has clicked payment started button
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void handle(CounterCurrencyTransferStartedMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // User interaction
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void onPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
+ super.onPaymentReceived(resultHandler, errorMessageHandler);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Massage dispatcher
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
+ super.onTradeMessage(message, peer);
+
+ log.info("Received {} from {} with tradeId {} and uid {}",
+ message.getClass().getSimpleName(), peer, message.getTradeId(), message.getUid());
+
+ if (message instanceof DepositTxMessage) {
+ handle((DepositTxMessage) message, peer);
+ }
+ }
+
+ @Override
+ protected Class extends TradeTask> getVerifyPeersFeePaymentClass() {
+ return MakerVerifyTakerFeePayment.class;
+ }
+}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bisq_v5/SellerAsTakerProtocol_v5.java b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/SellerAsTakerProtocol_v5.java
new file mode 100644
index 00000000000..036cf1a6048
--- /dev/null
+++ b/core/src/main/java/bisq/core/trade/protocol/bisq_v5/SellerAsTakerProtocol_v5.java
@@ -0,0 +1,163 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.core.trade.protocol.bisq_v5;
+
+
+import bisq.core.offer.Offer;
+import bisq.core.trade.model.bisq_v1.SellerAsTakerTrade;
+import bisq.core.trade.model.bisq_v1.Trade;
+import bisq.core.trade.protocol.TakerProtocol;
+import bisq.core.trade.protocol.TradeMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.CounterCurrencyTransferStartedMessage;
+import bisq.core.trade.protocol.bisq_v1.messages.DelayedPayoutTxSignatureResponse;
+import bisq.core.trade.protocol.bisq_v1.messages.InputsForDepositTxResponse;
+import bisq.core.trade.protocol.bisq_v1.messages.ShareBuyerPaymentAccountMessage;
+import bisq.core.trade.protocol.bisq_v1.tasks.ApplyFilter;
+import bisq.core.trade.protocol.bisq_v1.tasks.CheckIfDaoStateIsInSync;
+import bisq.core.trade.protocol.bisq_v1.tasks.TradeTask;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.MaybeCreateSubAccount;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerCreatesDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerSendDelayedPayoutTxSignatureRequest;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller.SellerSignsDelayedPayoutTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller_as_taker.SellerAsTakerCreatesDepositTxInputs;
+import bisq.core.trade.protocol.bisq_v1.tasks.seller_as_taker.SellerAsTakerSignsDepositTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.CreateTakerFeeTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerProcessesInputsForDepositTxResponse;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerPublishFeeTx;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerSendInputsForDepositTxRequest;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerVerifyAndSignContract;
+import bisq.core.trade.protocol.bisq_v1.tasks.taker.TakerVerifyMakerFeePayment;
+
+import bisq.network.p2p.NodeAddress;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.handlers.ResultHandler;
+
+import lombok.extern.slf4j.Slf4j;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@Slf4j
+public class SellerAsTakerProtocol_v5 extends BaseSellerProtocol_v5 implements TakerProtocol {
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Constructor
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public SellerAsTakerProtocol_v5(SellerAsTakerTrade trade) {
+ super(trade);
+ Offer offer = checkNotNull(trade.getOffer());
+ processModel.getTradePeer().setPubKeyRing(offer.getPubKeyRing());
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // User interaction: Take offer
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void onTakeOffer() {
+ expect(phase(Trade.Phase.INIT)
+ .with(TakerEvent.TAKE_OFFER)
+ .from(trade.getTradingPeerNodeAddress()))
+ .setup(tasks(
+ CheckIfDaoStateIsInSync.class,
+ MaybeCreateSubAccount.class,
+ ApplyFilter.class,
+ getVerifyPeersFeePaymentClass(),
+ CreateTakerFeeTx.class,
+ SellerAsTakerCreatesDepositTxInputs.class,
+ TakerSendInputsForDepositTxRequest.class)
+ .withTimeout(120))
+ .executeTasks();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming messages Take offer process
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ private void handle(InputsForDepositTxResponse message, NodeAddress peer) {
+ expect(phase(Trade.Phase.INIT)
+ .with(message)
+ .from(peer))
+ .setup(tasks(
+ TakerProcessesInputsForDepositTxResponse.class,
+ ApplyFilter.class,
+ TakerVerifyAndSignContract.class,
+ TakerPublishFeeTx.class,
+ SellerAsTakerSignsDepositTx.class,
+ SellerCreatesDelayedPayoutTx.class,
+ SellerSignsDelayedPayoutTx.class,
+ SellerSendDelayedPayoutTxSignatureRequest.class)
+ .withTimeout(120))
+ .executeTasks();
+ }
+
+ @Override
+ protected void handle(DelayedPayoutTxSignatureResponse message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+ @Override
+ protected void handle(ShareBuyerPaymentAccountMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Incoming message when buyer has clicked payment started button
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void handle(CounterCurrencyTransferStartedMessage message, NodeAddress peer) {
+ super.handle(message, peer);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // User interaction
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void onPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
+ super.onPaymentReceived(resultHandler, errorMessageHandler);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Massage dispatcher
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
+ super.onTradeMessage(message, peer);
+
+ log.info("Received {} from {} with tradeId {} and uid {}",
+ message.getClass().getSimpleName(), peer, message.getTradeId(), message.getUid());
+
+ if (message instanceof InputsForDepositTxResponse) {
+ handle((InputsForDepositTxResponse) message, peer);
+ }
+ }
+
+ @Override
+ protected Class extends TradeTask> getVerifyPeersFeePaymentClass() {
+ return TakerVerifyMakerFeePayment.class;
+ }
+}
diff --git a/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapBuyerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapBuyerAsTakerProtocol.java
index 943806038e4..245149a4ccf 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapBuyerAsTakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapBuyerAsTakerProtocol.java
@@ -37,7 +37,7 @@
import lombok.extern.slf4j.Slf4j;
import static bisq.core.trade.model.bsq_swap.BsqSwapTrade.State.PREPARATION;
-import static bisq.core.trade.protocol.bisq_v1.TakerProtocol.TakerEvent.TAKE_OFFER;
+import static bisq.core.trade.protocol.TakerProtocol.TakerEvent.TAKE_OFFER;
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
diff --git a/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapSellerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapSellerAsTakerProtocol.java
index f055d7f32fe..fffdba9f76b 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapSellerAsTakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapSellerAsTakerProtocol.java
@@ -39,7 +39,7 @@
import static bisq.core.trade.model.bsq_swap.BsqSwapTrade.State.COMPLETED;
import static bisq.core.trade.model.bsq_swap.BsqSwapTrade.State.PREPARATION;
-import static bisq.core.trade.protocol.bisq_v1.TakerProtocol.TakerEvent.TAKE_OFFER;
+import static bisq.core.trade.protocol.TakerProtocol.TakerEvent.TAKE_OFFER;
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
diff --git a/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapTakerProtocol.java
index 8b339f0a1fe..f38b2559638 100644
--- a/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapTakerProtocol.java
+++ b/core/src/main/java/bisq/core/trade/protocol/bsq_swap/BsqSwapTakerProtocol.java
@@ -17,7 +17,7 @@
package bisq.core.trade.protocol.bsq_swap;
-import bisq.core.trade.protocol.bisq_v1.TakerProtocol;
+import bisq.core.trade.protocol.TakerProtocol;
public interface BsqSwapTakerProtocol extends TakerProtocol {
}
diff --git a/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofService.java b/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofService.java
index 02612ee025f..0a24ae350c2 100644
--- a/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofService.java
+++ b/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofService.java
@@ -28,7 +28,7 @@
import bisq.core.trade.model.Tradable;
import bisq.core.trade.model.bisq_v1.SellerTrade;
import bisq.core.trade.model.bisq_v1.Trade;
-import bisq.core.trade.protocol.bisq_v1.SellerProtocol;
+import bisq.core.trade.protocol.SellerProtocol;
import bisq.core.trade.txproof.AssetTxProofResult;
import bisq.core.trade.txproof.AssetTxProofService;
import bisq.core.user.AutoConfirmSettings;
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java
index 519dba1295d..5e92290ab97 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java
@@ -53,9 +53,9 @@
import bisq.core.trade.model.bisq_v1.BuyerTrade;
import bisq.core.trade.model.bisq_v1.SellerTrade;
import bisq.core.trade.model.bisq_v1.Trade;
-import bisq.core.trade.protocol.bisq_v1.BuyerProtocol;
+import bisq.core.trade.protocol.BuyerProtocol;
+import bisq.core.trade.protocol.SellerProtocol;
import bisq.core.trade.protocol.bisq_v1.DisputeProtocol;
-import bisq.core.trade.protocol.bisq_v1.SellerProtocol;
import bisq.core.user.Preferences;
import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter;
diff --git a/desktop/src/main/java/bisq/desktop/main/settings/about/AboutView.java b/desktop/src/main/java/bisq/desktop/main/settings/about/AboutView.java
index 5dcedaf1528..113df7769cb 100644
--- a/desktop/src/main/java/bisq/desktop/main/settings/about/AboutView.java
+++ b/desktop/src/main/java/bisq/desktop/main/settings/about/AboutView.java
@@ -91,7 +91,7 @@ public void initialize() {
Version.P2P_NETWORK_VERSION,
Version.getP2PMessageVersion(),
Version.LOCAL_DB_VERSION,
- Version.TRADE_PROTOCOL_VERSION));
+ Version.getTradeProtocolVersion()));
addTitledGroupBg(root, ++gridRow, 18, Res.get("setting.about.shortcuts"), Layout.GROUP_DISTANCE);