From cb65de6d2e1497eb8eaf86404fc3285729aba87c Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Fri, 23 Oct 2020 12:47:06 -0300
Subject: [PATCH 01/30] Block on tx-fee-request in core TakeOfferModel init
Added license comment too.
---
.../core/offer/takeoffer/TakeOfferModel.java | 38 ++++++++++++++++---
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/core/src/main/java/bisq/core/offer/takeoffer/TakeOfferModel.java b/core/src/main/java/bisq/core/offer/takeoffer/TakeOfferModel.java
index efd0523ec19..c48b3c8ad4c 100644
--- a/core/src/main/java/bisq/core/offer/takeoffer/TakeOfferModel.java
+++ b/core/src/main/java/bisq/core/offer/takeoffer/TakeOfferModel.java
@@ -1,3 +1,20 @@
+/*
+ * 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.offer.takeoffer;
import bisq.core.account.witness.AccountAgeWitnessService;
@@ -20,6 +37,8 @@
import javax.inject.Inject;
import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@@ -141,12 +160,19 @@ private void calculateTxFees() {
// Payout tx: 371 bytes
// Disputed payout tx: 408 bytes
- // Request actual fees:
- log.info("Start requestTxFee: txFeeFromFeeService={}", txFeeFromFeeService);
- feeService.requestFees(() -> {
- txFeePerByteFromFeeService = feeService.getTxFeePerByte();
- txFeeFromFeeService = offerUtil.getTxFeeBySize(txFeePerByteFromFeeService, feeTxSize);
- });
+ txFeePerByteFromFeeService = getTxFeePerByte();
+ txFeeFromFeeService = offerUtil.getTxFeeBySize(txFeePerByteFromFeeService, feeTxSize);
+ log.info("{} txFeePerByte = {}", feeService.getClass().getSimpleName(), txFeePerByteFromFeeService);
+ }
+
+ private Coin getTxFeePerByte() {
+ try {
+ CompletableFuture feeRequestFuture = CompletableFuture.runAsync(feeService::requestFees);
+ feeRequestFuture.get(); // Block until async fee request is complete.
+ return feeService.getTxFeePerByte();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new IllegalStateException("Could not request fees from fee service.", e);
+ }
}
private void calculateTotalToPay() {
From ab20225cd2d50003a8f7f45feca6227a2370a9fb Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sat, 24 Oct 2020 16:25:20 -0300
Subject: [PATCH 02/30] Add compiler warning suppression, remove comment
---
core/src/main/java/bisq/core/api/model/OfferInfo.java | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/core/src/main/java/bisq/core/api/model/OfferInfo.java b/core/src/main/java/bisq/core/api/model/OfferInfo.java
index ad2389e438a..219045b2762 100644
--- a/core/src/main/java/bisq/core/api/model/OfferInfo.java
+++ b/core/src/main/java/bisq/core/api/model/OfferInfo.java
@@ -125,13 +125,9 @@ public bisq.proto.grpc.OfferInfo toProtoMessage() {
.build();
}
+ @SuppressWarnings({"unused", "SameReturnValue"})
public static OfferInfo fromProto(bisq.proto.grpc.OfferInfo proto) {
- /*
- TODO?
- return new OfferInfo(proto.getOfferPayload().getId(),
- proto.getOfferPayload().getDate());
- */
- return null;
+ return null; // TODO
}
/*
From 63cf4369904855013ac5b8e37de43462c02e1551 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sat, 24 Oct 2020 16:27:03 -0300
Subject: [PATCH 03/30] Add fields to grpc TradeInfo proto & wrapper
---
.../java/bisq/core/api/model/TradeInfo.java | 133 +++++++++++++++++-
proto/src/main/proto/grpc.proto | 29 ++--
2 files changed, 149 insertions(+), 13 deletions(-)
diff --git a/core/src/main/java/bisq/core/api/model/TradeInfo.java b/core/src/main/java/bisq/core/api/model/TradeInfo.java
index 33b8059f9b5..6e4adeca4ae 100644
--- a/core/src/main/java/bisq/core/api/model/TradeInfo.java
+++ b/core/src/main/java/bisq/core/api/model/TradeInfo.java
@@ -21,6 +21,8 @@
import bisq.common.Payload;
+import java.util.Objects;
+
import lombok.EqualsAndHashCode;
import lombok.Getter;
@@ -37,6 +39,16 @@ public class TradeInfo implements Payload {
private final OfferInfo offer;
private final String tradeId;
private final String shortId;
+ private final long date;
+ private final boolean isCurrencyForTakerFeeBtc;
+ private final long txFeeAsLong;
+ private final long takerFeeAsLong;
+ private final String takerFeeTxId;
+ private final String depositTxId;
+ private final String payoutTxId;
+ private final long tradeAmountAsLong;
+ private final long tradePrice;
+ private final String tradingPeerNodeAddress;
private final String state;
private final String phase;
private final String tradePeriodState;
@@ -46,11 +58,22 @@ public class TradeInfo implements Payload {
private final boolean isFiatReceived;
private final boolean isPayoutPublished;
private final boolean isWithdrawn;
+ private final String contractAsJson;
public TradeInfo(TradeInfoBuilder builder) {
this.offer = builder.offer;
this.tradeId = builder.tradeId;
this.shortId = builder.shortId;
+ this.date = builder.date;
+ this.isCurrencyForTakerFeeBtc = builder.isCurrencyForTakerFeeBtc;
+ this.txFeeAsLong = builder.txFeeAsLong;
+ this.takerFeeAsLong = builder.takerFeeAsLong;
+ this.takerFeeTxId = builder.takerFeeTxId;
+ this.depositTxId = builder.depositTxId;
+ this.payoutTxId = builder.payoutTxId;
+ this.tradeAmountAsLong = builder.tradeAmountAsLong;
+ this.tradePrice = builder.tradePrice;
+ this.tradingPeerNodeAddress = builder.tradingPeerNodeAddress;
this.state = builder.state;
this.phase = builder.phase;
this.tradePeriodState = builder.tradePeriodState;
@@ -60,6 +83,7 @@ public TradeInfo(TradeInfoBuilder builder) {
this.isFiatReceived = builder.isFiatReceived;
this.isPayoutPublished = builder.isPayoutPublished;
this.isWithdrawn = builder.isWithdrawn;
+ this.contractAsJson = builder.contractAsJson;
}
public static TradeInfo toTradeInfo(Trade trade) {
@@ -67,6 +91,18 @@ public static TradeInfo toTradeInfo(Trade trade) {
.withOffer(toOfferInfo(trade.getOffer()))
.withTradeId(trade.getId())
.withShortId(trade.getShortId())
+ .withDate(trade.getDate().getTime())
+ .withIsCurrencyForTakerFeeBtc(trade.isCurrencyForTakerFeeBtc())
+ .withTxFeeAsLong(trade.getTxFeeAsLong())
+ .withTakerFeeAsLong(trade.getTakerFeeAsLong())
+ .withTakerFeeAsLong(trade.getTakerFeeAsLong())
+ .withTakerFeeTxId(trade.getTakerFeeTxId())
+ .withDepositTxId(trade.getDepositTxId())
+ .withPayoutTxId(trade.getPayoutTxId())
+ .withTradeAmountAsLong(trade.getTradeAmountAsLong())
+ .withTradePrice(trade.getTradePrice().getValue())
+ .withTradingPeerNodeAddress(Objects.requireNonNull(
+ trade.getTradingPeerNodeAddress()).getHostNameWithoutPostFix())
.withState(trade.getState().name())
.withPhase(trade.getPhase().name())
.withTradePeriodState(trade.getTradePeriodState().name())
@@ -76,6 +112,7 @@ public static TradeInfo toTradeInfo(Trade trade) {
.withIsFiatReceived(trade.isFiatReceived())
.withIsPayoutPublished(trade.isPayoutPublished())
.withIsWithdrawn(trade.isWithdrawn())
+ .withContractAsJson(trade.getContractAsJson())
.build();
}
@@ -89,6 +126,16 @@ public bisq.proto.grpc.TradeInfo toProtoMessage() {
.setOffer(offer.toProtoMessage())
.setTradeId(tradeId)
.setShortId(shortId)
+ .setDate(date)
+ .setIsCurrencyForTakerFeeBtc(isCurrencyForTakerFeeBtc)
+ .setTxFeeAsLong(txFeeAsLong)
+ .setTakerFeeAsLong(takerFeeAsLong)
+ .setTakerFeeTxId(takerFeeTxId == null ? "" : takerFeeTxId)
+ .setDepositTxId(depositTxId == null ? "" : depositTxId)
+ .setPayoutTxId(payoutTxId == null ? "" : payoutTxId)
+ .setTradeAmountAsLong(tradeAmountAsLong)
+ .setTradePrice(tradePrice)
+ .setTradingPeerNodeAddress(tradingPeerNodeAddress)
.setState(state)
.setPhase(phase)
.setTradePeriodState(tradePeriodState)
@@ -98,12 +145,13 @@ public bisq.proto.grpc.TradeInfo toProtoMessage() {
.setIsFiatReceived(isFiatReceived)
.setIsPayoutPublished(isPayoutPublished)
.setIsWithdrawn(isWithdrawn)
+ .setContractAsJson(contractAsJson == null ? "" : contractAsJson)
.build();
}
+ @SuppressWarnings({"unused", "SameReturnValue"})
public static TradeInfo fromProto(bisq.proto.grpc.TradeInfo proto) {
- // TODO
- return null;
+ return null; // TODO
}
/*
@@ -116,6 +164,16 @@ public static class TradeInfoBuilder {
private OfferInfo offer;
private String tradeId;
private String shortId;
+ private long date;
+ private boolean isCurrencyForTakerFeeBtc;
+ private long txFeeAsLong;
+ private long takerFeeAsLong;
+ private String takerFeeTxId;
+ private String depositTxId;
+ private String payoutTxId;
+ private long tradeAmountAsLong;
+ private long tradePrice;
+ private String tradingPeerNodeAddress;
private String state;
private String phase;
private String tradePeriodState;
@@ -125,6 +183,7 @@ public static class TradeInfoBuilder {
private boolean isFiatReceived;
private boolean isPayoutPublished;
private boolean isWithdrawn;
+ private String contractAsJson;
public TradeInfoBuilder withOffer(OfferInfo offer) {
this.offer = offer;
@@ -141,6 +200,56 @@ public TradeInfoBuilder withShortId(String shortId) {
return this;
}
+ public TradeInfoBuilder withDate(long date) {
+ this.date = date;
+ return this;
+ }
+
+ public TradeInfoBuilder withIsCurrencyForTakerFeeBtc(boolean isCurrencyForTakerFeeBtc) {
+ this.isCurrencyForTakerFeeBtc = isCurrencyForTakerFeeBtc;
+ return this;
+ }
+
+ public TradeInfoBuilder withTxFeeAsLong(long txFeeAsLong) {
+ this.txFeeAsLong = txFeeAsLong;
+ return this;
+ }
+
+ public TradeInfoBuilder withTakerFeeAsLong(long takerFeeAsLong) {
+ this.takerFeeAsLong = takerFeeAsLong;
+ return this;
+ }
+
+ public TradeInfoBuilder withTakerFeeTxId(String takerFeeTxId) {
+ this.takerFeeTxId = takerFeeTxId;
+ return this;
+ }
+
+ public TradeInfoBuilder withDepositTxId(String depositTxId) {
+ this.depositTxId = depositTxId;
+ return this;
+ }
+
+ public TradeInfoBuilder withPayoutTxId(String payoutTxId) {
+ this.payoutTxId = payoutTxId;
+ return this;
+ }
+
+ public TradeInfoBuilder withTradeAmountAsLong(long tradeAmountAsLong) {
+ this.tradeAmountAsLong = tradeAmountAsLong;
+ return this;
+ }
+
+ public TradeInfoBuilder withTradePrice(long tradePrice) {
+ this.tradePrice = tradePrice;
+ return this;
+ }
+
+ public TradeInfoBuilder withTradePeriodState(String tradePeriodState) {
+ this.tradePeriodState = tradePeriodState;
+ return this;
+ }
+
public TradeInfoBuilder withState(String state) {
this.state = state;
return this;
@@ -151,8 +260,8 @@ public TradeInfoBuilder withPhase(String phase) {
return this;
}
- public TradeInfoBuilder withTradePeriodState(String tradePeriodState) {
- this.tradePeriodState = tradePeriodState;
+ public TradeInfoBuilder withTradingPeerNodeAddress(String tradingPeerNodeAddress) {
+ this.tradingPeerNodeAddress = tradingPeerNodeAddress;
return this;
}
@@ -186,6 +295,11 @@ public TradeInfoBuilder withIsWithdrawn(boolean isWithdrawn) {
return this;
}
+ public TradeInfoBuilder withContractAsJson(String contractAsJson) {
+ this.contractAsJson = contractAsJson;
+ return this;
+ }
+
public TradeInfo build() {
return new TradeInfo(this);
}
@@ -196,6 +310,16 @@ public String toString() {
return "TradeInfo{" +
" tradeId='" + tradeId + '\'' + "\n" +
", shortId='" + shortId + '\'' + "\n" +
+ ", date='" + date + '\'' + "\n" +
+ ", isCurrencyForTakerFeeBtc='" + isCurrencyForTakerFeeBtc + '\'' + "\n" +
+ ", txFeeAsLong='" + txFeeAsLong + '\'' + "\n" +
+ ", takerFeeAsLong='" + takerFeeAsLong + '\'' + "\n" +
+ ", takerFeeTxId='" + takerFeeTxId + '\'' + "\n" +
+ ", depositTxId='" + depositTxId + '\'' + "\n" +
+ ", payoutTxId='" + payoutTxId + '\'' + "\n" +
+ ", tradeAmountAsLong='" + tradeAmountAsLong + '\'' + "\n" +
+ ", tradePrice='" + tradePrice + '\'' + "\n" +
+ ", tradingPeerNodeAddress='" + tradingPeerNodeAddress + '\'' + "\n" +
", state='" + state + '\'' + "\n" +
", phase='" + phase + '\'' + "\n" +
", tradePeriodState='" + tradePeriodState + '\'' + "\n" +
@@ -206,6 +330,7 @@ public String toString() {
", isPayoutPublished=" + isPayoutPublished + "\n" +
", isWithdrawn=" + isWithdrawn + "\n" +
", offer=" + offer + "\n" +
+ ", contractAsJson=" + contractAsJson + "\n" +
'}';
}
}
diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto
index 38ddd4a9dbb..68121d00596 100644
--- a/proto/src/main/proto/grpc.proto
+++ b/proto/src/main/proto/grpc.proto
@@ -217,15 +217,26 @@ message TradeInfo {
OfferInfo offer = 1;
string tradeId = 2;
string shortId = 3;
- string state = 4;
- string phase = 5;
- string tradePeriodState = 6;
- bool isDepositPublished = 7;
- bool isDepositConfirmed = 8;
- bool isFiatSent = 9;
- bool isFiatReceived = 10;
- bool isPayoutPublished = 11;
- bool isWithdrawn = 12;
+ uint64 date = 4;
+ bool isCurrencyForTakerFeeBtc = 5;
+ uint64 txFeeAsLong = 6;
+ uint64 takerFeeAsLong = 7;
+ string takerFeeTxId = 8;
+ string depositTxId = 9;
+ string payoutTxId = 10;
+ uint64 tradeAmountAsLong = 11;
+ uint64 tradePrice = 12;
+ string tradingPeerNodeAddress = 13;
+ string state = 14;
+ string phase = 15;
+ string tradePeriodState = 16;
+ bool isDepositPublished = 17;
+ bool isDepositConfirmed = 18;
+ bool isFiatSent = 19;
+ bool isFiatReceived = 20;
+ bool isPayoutPublished = 21;
+ bool isWithdrawn = 22;
+ string contractAsJson = 23;
}
///////////////////////////////////////////////////////////////////////////////////////////
From 296e4f98cb6231ed2226e72d95c1317981a9d008 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sat, 24 Oct 2020 17:26:10 -0300
Subject: [PATCH 04/30] Replace static TradeUtil with singleton TradeUtil
The API is going to need some desktop trade utilities, which should be
shared between :desktop and :core.api.
---
.../java/bisq/core/trade/TradeManager.java | 5 +-
.../trade/{TradeUtils.java => TradeUtil.java} | 60 ++++++++++++++-----
.../trade/failed/FailedTradesManager.java | 7 ++-
3 files changed, 55 insertions(+), 17 deletions(-)
rename core/src/main/java/bisq/core/trade/{TradeUtils.java => TradeUtil.java} (57%)
diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java
index 0d8d02a2414..d8278018d56 100644
--- a/core/src/main/java/bisq/core/trade/TradeManager.java
+++ b/core/src/main/java/bisq/core/trade/TradeManager.java
@@ -120,6 +120,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
private final P2PService p2PService;
private final PriceFeedService priceFeedService;
private final TradeStatisticsManager tradeStatisticsManager;
+ private final TradeUtil tradeUtil;
@Getter
private final ArbitratorManager arbitratorManager;
private final MediatorManager mediatorManager;
@@ -157,6 +158,7 @@ public TradeManager(User user,
P2PService p2PService,
PriceFeedService priceFeedService,
TradeStatisticsManager tradeStatisticsManager,
+ TradeUtil tradeUtil,
ArbitratorManager arbitratorManager,
MediatorManager mediatorManager,
ProcessModelServiceProvider processModelServiceProvider,
@@ -175,6 +177,7 @@ public TradeManager(User user,
this.p2PService = p2PService;
this.priceFeedService = priceFeedService;
this.tradeStatisticsManager = tradeStatisticsManager;
+ this.tradeUtil = tradeUtil;
this.arbitratorManager = arbitratorManager;
this.mediatorManager = mediatorManager;
this.processModelServiceProvider = processModelServiceProvider;
@@ -634,7 +637,7 @@ private boolean unFailTrade(Trade trade) {
// the relevant entries are changed, otherwise it's not added and no address entries are changed
private boolean recoverAddresses(Trade trade) {
// Find addresses associated with this trade.
- var entries = TradeUtils.getAvailableAddresses(trade, btcWalletService, keyRing);
+ var entries = tradeUtil.getAvailableAddresses(trade);
if (entries == null)
return false;
diff --git a/core/src/main/java/bisq/core/trade/TradeUtils.java b/core/src/main/java/bisq/core/trade/TradeUtil.java
similarity index 57%
rename from core/src/main/java/bisq/core/trade/TradeUtils.java
rename to core/src/main/java/bisq/core/trade/TradeUtil.java
index 10a5da8fdf8..001dbd21217 100644
--- a/core/src/main/java/bisq/core/trade/TradeUtils.java
+++ b/core/src/main/java/bisq/core/trade/TradeUtil.java
@@ -1,18 +1,18 @@
/*
* This file is part of Bisq.
*
- * Bisq is free software: you can redistribute it and/or modify it
+ * 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
+ * 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 .
+ * along with bisq. If not, see .
*/
package bisq.core.trade;
@@ -23,20 +23,44 @@
import bisq.common.util.Tuple2;
import bisq.common.util.Utilities;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
import java.util.Objects;
-public class TradeUtils {
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * This class contains trade utility methods.
+ */
+@Slf4j
+@Singleton
+public class TradeUtil {
+
+ private final BtcWalletService btcWalletService;
+ private final KeyRing keyRing;
- // Returns if both are AVAILABLE, otherwise null
- static Tuple2 getAvailableAddresses(Trade trade, BtcWalletService btcWalletService,
- KeyRing keyRing) {
- var addresses = getTradeAddresses(trade, btcWalletService, keyRing);
+ @Inject
+ public TradeUtil(BtcWalletService btcWalletService, KeyRing keyRing) {
+ this.btcWalletService = btcWalletService;
+ this.keyRing = keyRing;
+ }
+
+ /**
+ * Returns if and only if both are AVAILABLE,
+ * otherwise null.
+ * @param trade the trade being queried for MULTI_SIG, TRADE_PAYOUT addresses
+ * @return Tuple2 tuple containing MULTI_SIG, TRADE_PAYOUT addresses for trade
+ */
+ public Tuple2 getAvailableAddresses(Trade trade) {
+ var addresses = getTradeAddresses(trade);
if (addresses == null)
return null;
if (btcWalletService.getAvailableAddressEntries().stream()
.noneMatch(e -> Objects.equals(e.getAddressString(), addresses.first)))
return null;
+
if (btcWalletService.getAvailableAddressEntries().stream()
.noneMatch(e -> Objects.equals(e.getAddressString(), addresses.second)))
return null;
@@ -44,18 +68,25 @@ static Tuple2 getAvailableAddresses(Trade trade, BtcWalletServic
return new Tuple2<>(addresses.first, addresses.second);
}
- // Returns addresses as strings if they're known by the wallet
- public static Tuple2 getTradeAddresses(Trade trade, BtcWalletService btcWalletService,
- KeyRing keyRing) {
+ /**
+ * Returns addresses as strings if they're known by the
+ * wallet.
+ * @param trade the trade being queried for MULTI_SIG, TRADE_PAYOUT addresses
+ * @return Tuple2 tuple containing MULTI_SIG, TRADE_PAYOUT addresses for trade
+ */
+ public Tuple2 getTradeAddresses(Trade trade) {
var contract = trade.getContract();
if (contract == null)
return null;
// Get multisig address
var isMyRoleBuyer = contract.isMyRoleBuyer(keyRing.getPubKeyRing());
- var multiSigPubKey = isMyRoleBuyer ? contract.getBuyerMultiSigPubKey() : contract.getSellerMultiSigPubKey();
+ var multiSigPubKey = isMyRoleBuyer
+ ? contract.getBuyerMultiSigPubKey()
+ : contract.getSellerMultiSigPubKey();
if (multiSigPubKey == null)
return null;
+
var multiSigPubKeyString = Utilities.bytesAsHexString(multiSigPubKey);
var multiSigAddress = btcWalletService.getAddressEntryListAsImmutableList().stream()
.filter(e -> e.getKeyPair().getPublicKeyAsHex().equals(multiSigPubKeyString))
@@ -65,8 +96,9 @@ public static Tuple2 getTradeAddresses(Trade trade, BtcWalletSer
return null;
// Get payout address
- var payoutAddress = isMyRoleBuyer ?
- contract.getBuyerPayoutAddressString() : contract.getSellerPayoutAddressString();
+ var payoutAddress = isMyRoleBuyer
+ ? contract.getBuyerPayoutAddressString()
+ : contract.getSellerPayoutAddressString();
var payoutAddressEntry = btcWalletService.getAddressEntryListAsImmutableList().stream()
.filter(e -> Objects.equals(e.getAddressString(), payoutAddress))
.findAny()
diff --git a/core/src/main/java/bisq/core/trade/failed/FailedTradesManager.java b/core/src/main/java/bisq/core/trade/failed/FailedTradesManager.java
index a584f6b783f..4782ef080d2 100644
--- a/core/src/main/java/bisq/core/trade/failed/FailedTradesManager.java
+++ b/core/src/main/java/bisq/core/trade/failed/FailedTradesManager.java
@@ -24,7 +24,7 @@
import bisq.core.trade.DumpDelayedPayoutTx;
import bisq.core.trade.TradableList;
import bisq.core.trade.Trade;
-import bisq.core.trade.TradeUtils;
+import bisq.core.trade.TradeUtil;
import bisq.common.crypto.KeyRing;
import bisq.common.persistence.PersistenceManager;
@@ -50,6 +50,7 @@ public class FailedTradesManager implements PersistedDataHost {
private final PriceFeedService priceFeedService;
private final BtcWalletService btcWalletService;
private final PersistenceManager> persistenceManager;
+ private final TradeUtil tradeUtil;
private final DumpDelayedPayoutTx dumpDelayedPayoutTx;
@Setter
private Function unFailTradeCallback;
@@ -59,12 +60,14 @@ public FailedTradesManager(KeyRing keyRing,
PriceFeedService priceFeedService,
BtcWalletService btcWalletService,
PersistenceManager> persistenceManager,
+ TradeUtil tradeUtil,
DumpDelayedPayoutTx dumpDelayedPayoutTx) {
this.keyRing = keyRing;
this.priceFeedService = priceFeedService;
this.btcWalletService = btcWalletService;
this.dumpDelayedPayoutTx = dumpDelayedPayoutTx;
this.persistenceManager = persistenceManager;
+ this.tradeUtil = tradeUtil;
this.persistenceManager.initialize(failedTrades, "FailedTrades", PersistenceManager.Source.PRIVATE);
}
@@ -127,7 +130,7 @@ public void unFailTrade(Trade trade) {
}
public String checkUnFail(Trade trade) {
- var addresses = TradeUtils.getTradeAddresses(trade, btcWalletService, keyRing);
+ var addresses = tradeUtil.getTradeAddresses(trade);
if (addresses == null) {
return "Addresses not found";
}
From ccd3c99f2e5b9cf276e6b70bceb34e73fb0a6858 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sat, 24 Oct 2020 17:45:01 -0300
Subject: [PATCH 05/30] Fix comment typos
---
core/src/main/java/bisq/core/trade/TradeUtil.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/core/src/main/java/bisq/core/trade/TradeUtil.java b/core/src/main/java/bisq/core/trade/TradeUtil.java
index 001dbd21217..c93e5e2be3b 100644
--- a/core/src/main/java/bisq/core/trade/TradeUtil.java
+++ b/core/src/main/java/bisq/core/trade/TradeUtil.java
@@ -1,18 +1,18 @@
/*
* This file is part of Bisq.
*
- * bisq is free software: you can redistribute it and/or modify it
+ * 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
+ * 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 .
+ * along with Bisq. If not, see .
*/
package bisq.core.trade;
From 24ba9215cd12f65605b23c2f5d53037258afd019 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 10:41:19 -0300
Subject: [PATCH 06/30] Refactor PendingTradesViewModel methods -> TradeUtil &
OfferUtil
---
.../main/java/bisq/core/offer/OfferUtil.java | 4 +
.../main/java/bisq/core/trade/TradeUtil.java | 96 +++++++++++++++
.../pendingtrades/PendingTradesViewModel.java | 112 ++++++------------
3 files changed, 137 insertions(+), 75 deletions(-)
diff --git a/core/src/main/java/bisq/core/offer/OfferUtil.java b/core/src/main/java/bisq/core/offer/OfferUtil.java
index 373df679073..84e783f5b14 100644
--- a/core/src/main/java/bisq/core/offer/OfferUtil.java
+++ b/core/src/main/java/bisq/core/offer/OfferUtil.java
@@ -261,6 +261,10 @@ public boolean isBsqForTakerFeeAvailable(@Nullable Coin amount) {
return !availableBalance.subtract(takerFee).isNegative();
}
+ public boolean isBlockChainPaymentMethod(Offer offer) {
+ return offer != null && offer.getPaymentMethod().isAsset();
+ }
+
public Optional getFeeInUserFiatCurrency(Coin makerFee,
boolean isCurrencyForMakerFeeBtc,
CoinFormatter bsqFormatter) {
diff --git a/core/src/main/java/bisq/core/trade/TradeUtil.java b/core/src/main/java/bisq/core/trade/TradeUtil.java
index c93e5e2be3b..a89dec32459 100644
--- a/core/src/main/java/bisq/core/trade/TradeUtil.java
+++ b/core/src/main/java/bisq/core/trade/TradeUtil.java
@@ -18,6 +18,8 @@
package bisq.core.trade;
import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.locale.Res;
+import bisq.core.offer.Offer;
import bisq.common.crypto.KeyRing;
import bisq.common.util.Tuple2;
@@ -26,10 +28,18 @@
import javax.inject.Inject;
import javax.inject.Singleton;
+import java.util.Date;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
+import javax.annotation.Nullable;
+
+import static bisq.core.locale.CurrencyUtil.getCurrencyPair;
+import static bisq.core.locale.CurrencyUtil.isFiatCurrency;
+import static bisq.core.util.FormattingUtils.formatDurationAsWords;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* This class contains trade utility methods.
*/
@@ -108,4 +118,90 @@ public Tuple2 getTradeAddresses(Trade trade) {
return new Tuple2<>(multiSigAddress.getAddressString(), payoutAddress);
}
+
+ public long getRemainingTradeDuration(Trade trade) {
+ return trade.getMaxTradePeriodDate() != null
+ ? trade.getMaxTradePeriodDate().getTime() - new Date().getTime()
+ : getMaxTradePeriod(trade);
+ }
+
+ public long getMaxTradePeriod(Trade trade) {
+ return trade.getOffer() != null
+ ? trade.getOffer().getPaymentMethod().getMaxTradePeriod()
+ : 0;
+ }
+
+ public double getRemainingTradeDurationAsPercentage(Trade trade) {
+ long maxPeriod = getMaxTradePeriod(trade);
+ long remaining = getRemainingTradeDuration(trade);
+ if (maxPeriod != 0) {
+ return 1 - (double) remaining / (double) maxPeriod;
+ } else
+ return 0;
+ }
+
+ public String getRemainingTradeDurationAsWords(Trade trade) {
+ return formatDurationAsWords(Math.max(0, getRemainingTradeDuration(trade)));
+ }
+
+ @Nullable
+ public Date getHalfTradePeriodDate(Trade trade) {
+ return trade != null ? trade.getHalfTradePeriodDate() : null;
+ }
+
+ public Date getDateForOpenDispute(Trade trade) {
+ return new Date(new Date().getTime() + getRemainingTradeDuration(trade));
+ }
+
+ public String getMarketDescription(Trade trade) {
+ if (trade == null)
+ return "";
+
+ checkNotNull(trade.getOffer());
+ checkNotNull(trade.getOffer().getCurrencyCode());
+ return getCurrencyPair(trade.getOffer().getCurrencyCode());
+ }
+
+ public String getPaymentMethodNameWithCountryCode(Trade trade) {
+ String paymentMethodDescription = "";
+ if (trade != null) {
+ Offer offer = trade.getOffer();
+ checkNotNull(offer);
+ checkNotNull(offer.getPaymentMethod());
+ paymentMethodDescription = offer.getPaymentMethodNameWithCountryCode();
+ }
+ return paymentMethodDescription;
+ }
+
+ /**
+ * Returns a string describing a trader's role.
+ *
+ * @param isBuyerMakerAndSellerTaker boolean
+ * @param isMaker boolean
+ * @param currencyCode String
+ * @return String describing a trader's role
+ */
+ public String getRole(boolean isBuyerMakerAndSellerTaker, boolean isMaker, String currencyCode) {
+ if (isFiatCurrency(currencyCode)) {
+ String baseCurrencyCode = Res.getBaseCurrencyCode();
+ if (isBuyerMakerAndSellerTaker)
+ return isMaker
+ ? Res.get("formatter.asMaker", baseCurrencyCode, Res.get("shared.buyer"))
+ : Res.get("formatter.asTaker", baseCurrencyCode, Res.get("shared.seller"));
+ else
+ return isMaker
+ ? Res.get("formatter.asMaker", baseCurrencyCode, Res.get("shared.seller"))
+ : Res.get("formatter.asTaker", baseCurrencyCode, Res.get("shared.buyer"));
+ } else {
+ if (isBuyerMakerAndSellerTaker)
+ return isMaker
+ ? Res.get("formatter.asMaker", currencyCode, Res.get("shared.seller"))
+ : Res.get("formatter.asTaker", currencyCode, Res.get("shared.buyer"));
+ else
+ return isMaker
+ ? Res.get("formatter.asMaker", currencyCode, Res.get("shared.buyer"))
+ : Res.get("formatter.asTaker", currencyCode, Res.get("shared.seller"));
+ }
+
+ }
}
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
index 35934419fdf..53369839bd0 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
@@ -24,13 +24,13 @@
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.btc.wallet.Restrictions;
-import bisq.core.locale.CurrencyUtil;
-import bisq.core.locale.Res;
import bisq.core.network.MessageState;
import bisq.core.offer.Offer;
+import bisq.core.offer.OfferUtil;
import bisq.core.provider.fee.FeeService;
import bisq.core.trade.Contract;
import bisq.core.trade.Trade;
+import bisq.core.trade.TradeUtil;
import bisq.core.trade.closed.ClosedTradableManager;
import bisq.core.user.User;
import bisq.core.util.FormattingUtils;
@@ -97,6 +97,8 @@ enum SellerState implements State {
final AccountAgeWitnessService accountAgeWitnessService;
public final P2PService p2PService;
private final ClosedTradableManager closedTradableManager;
+ private final OfferUtil offerUtil;
+ private final TradeUtil tradeUtil;
public final ClockWatcher clockWatcher;
@Getter
private final User user;
@@ -120,6 +122,8 @@ public PendingTradesViewModel(PendingTradesDataModel dataModel,
BtcAddressValidator btcAddressValidator,
P2PService p2PService,
ClosedTradableManager closedTradableManager,
+ OfferUtil offerUtil,
+ TradeUtil tradeUtil,
AccountAgeWitnessService accountAgeWitnessService,
ClockWatcher clockWatcher,
User user) {
@@ -130,6 +134,8 @@ public PendingTradesViewModel(PendingTradesDataModel dataModel,
this.btcAddressValidator = btcAddressValidator;
this.p2PService = p2PService;
this.closedTradableManager = closedTradableManager;
+ this.offerUtil = offerUtil;
+ this.tradeUtil = tradeUtil;
this.accountAgeWitnessService = accountAgeWitnessService;
this.clockWatcher = clockWatcher;
this.user = user;
@@ -199,55 +205,30 @@ ReadOnlyObjectProperty getSellerState() {
}
public String getPayoutAmount() {
- return dataModel.getTrade() != null ? btcFormatter.formatCoinWithCode(dataModel.getTrade().getPayoutAmount()) : "";
+ return dataModel.getTrade() != null
+ ? btcFormatter.formatCoinWithCode(dataModel.getTrade().getPayoutAmount())
+ : "";
}
String getMarketLabel(PendingTradesListItem item) {
- if ((item == null))
- return "";
-
- checkNotNull(item.getTrade().getOffer());
- checkNotNull(item.getTrade().getOffer().getCurrencyCode());
- return CurrencyUtil.getCurrencyPair(item.getTrade().getOffer().getCurrencyCode());
- }
-
- private long getMaxTradePeriod() {
- return dataModel.getOffer() != null ? dataModel.getOffer().getPaymentMethod().getMaxTradePeriod() : 0;
- }
-
- @Nullable
- private Date getMaxTradePeriodDate() {
- return dataModel.getTrade() != null ? dataModel.getTrade().getMaxTradePeriodDate() : null;
- }
-
- @Nullable
- private Date getHalfTradePeriodDate() {
- return dataModel.getTrade() != null ? dataModel.getTrade().getHalfTradePeriodDate() : null;
- }
-
- private long getRemainingTradeDuration() {
- return getMaxTradePeriodDate() != null ? getMaxTradePeriodDate().getTime() - new Date().getTime() : getMaxTradePeriod();
+ return item == null ? "" : tradeUtil.getMarketDescription(item.getTrade());
}
public String getRemainingTradeDurationAsWords() {
- return FormattingUtils.formatDurationAsWords(Math.max(0, getRemainingTradeDuration()));
+ return tradeUtil.getRemainingTradeDurationAsWords(dataModel.getTrade());
}
public double getRemainingTradeDurationAsPercentage() {
- long maxPeriod = getMaxTradePeriod();
- long remaining = getRemainingTradeDuration();
- if (maxPeriod != 0) {
- return 1 - (double) remaining / (double) maxPeriod;
- } else
- return 0;
+ return tradeUtil.getRemainingTradeDurationAsPercentage(dataModel.getTrade());
}
public String getDateForOpenDispute() {
- return DisplayUtils.formatDateTime(new Date(new Date().getTime() + getRemainingTradeDuration()));
+ return DisplayUtils.formatDateTime(tradeUtil.getDateForOpenDispute(dataModel.getTrade()));
}
public boolean showWarning() {
- return getHalfTradePeriodDate() != null && new Date().after(getHalfTradePeriodDate());
+ Date halfTradePeriodDate = tradeUtil.getHalfTradePeriodDate(dataModel.getTrade());
+ return halfTradePeriodDate != null && new Date().after(halfTradePeriodDate);
}
public boolean showDispute() {
@@ -263,36 +244,36 @@ String getMyRole(PendingTradesListItem item) {
Offer offer = trade.getOffer();
checkNotNull(offer);
checkNotNull(offer.getCurrencyCode());
- return getRole(contract.isBuyerMakerAndSellerTaker(), dataModel.isMaker(offer), offer.getCurrencyCode());
+ return tradeUtil.getRole(contract.isBuyerMakerAndSellerTaker(),
+ dataModel.isMaker(offer),
+ offer.getCurrencyCode());
} else {
return "";
}
}
String getPaymentMethod(PendingTradesListItem item) {
- String result = "";
- if (item != null) {
- Offer offer = item.getTrade().getOffer();
- checkNotNull(offer);
- checkNotNull(offer.getPaymentMethod());
- result = offer.getPaymentMethodNameWithCountryCode();
- }
- return result;
+ return item == null ? "" : tradeUtil.getPaymentMethodNameWithCountryCode(item.getTrade());
}
// summary
public String getTradeVolume() {
- return dataModel.getTrade() != null ? btcFormatter.formatCoinWithCode(dataModel.getTrade().getTradeAmount()) : "";
+ return dataModel.getTrade() != null
+ ? btcFormatter.formatCoinWithCode(dataModel.getTrade().getTradeAmount())
+ : "";
}
public String getFiatVolume() {
- return dataModel.getTrade() != null ? DisplayUtils.formatVolumeWithCode(dataModel.getTrade().getTradeVolume()) : "";
+ return dataModel.getTrade() != null
+ ? DisplayUtils.formatVolumeWithCode(dataModel.getTrade().getTradeVolume())
+ : "";
}
public String getTxFee() {
if (trade != null && trade.getTradeAmount() != null) {
Coin txFee = dataModel.getTxFee();
- String percentage = GUIUtil.getPercentageOfTradeAmount(txFee, trade.getTradeAmount(),
+ String percentage = GUIUtil.getPercentageOfTradeAmount(txFee,
+ trade.getTradeAmount(),
Coin.ZERO);
return btcFormatter.formatCoinWithCode(txFee) + percentage;
} else {
@@ -344,7 +325,7 @@ public String getSecurityDeposit() {
}
public boolean isBlockChainMethod() {
- return dataModel.getOffer() != null && dataModel.getOffer().getPaymentMethod().isAsset();
+ return offerUtil.isBlockChainPaymentMethod(dataModel.getOffer());
}
public int getNumPastTrades(Trade trade) {
@@ -362,7 +343,13 @@ public int getNumPastTrades(Trade trade) {
.collect(Collectors.toSet())
.size();
}
-
+
+ @Nullable
+ private Date getMaxTradePeriodDate() {
+ return dataModel.getTrade() != null
+ ? dataModel.getTrade().getMaxTradePeriodDate()
+ : null;
+ }
///////////////////////////////////////////////////////////////////////////////////////////
// States
@@ -479,29 +466,4 @@ private void onTradeStateChanged(Trade.State tradeState) {
break;
}
}
-
- private static String getRole(boolean isBuyerMakerAndSellerTaker, boolean isMaker, String currencyCode) {
- if (CurrencyUtil.isFiatCurrency(currencyCode)) {
- String baseCurrencyCode = Res.getBaseCurrencyCode();
- if (isBuyerMakerAndSellerTaker)
- return isMaker ?
- Res.get("formatter.asMaker", baseCurrencyCode, Res.get("shared.buyer")) :
- Res.get("formatter.asTaker", baseCurrencyCode, Res.get("shared.seller"));
- else
- return isMaker ?
- Res.get("formatter.asMaker", baseCurrencyCode, Res.get("shared.seller")) :
- Res.get("formatter.asTaker", baseCurrencyCode, Res.get("shared.buyer"));
- } else {
- if (isBuyerMakerAndSellerTaker)
- return isMaker ?
- Res.get("formatter.asMaker", currencyCode, Res.get("shared.seller")) :
- Res.get("formatter.asTaker", currencyCode, Res.get("shared.buyer"));
- else
- return isMaker ?
- Res.get("formatter.asMaker", currencyCode, Res.get("shared.buyer")) :
- Res.get("formatter.asTaker", currencyCode, Res.get("shared.seller"));
- }
-
- }
-
}
From 36ad1379496d29bf26d6d3c90c4cc50b8c74b928 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 10:54:40 -0300
Subject: [PATCH 07/30] Remove trailing spaces for codacy
---
.../main/portfolio/pendingtrades/PendingTradesViewModel.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
index 53369839bd0..6a9b4dff06c 100644
--- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesViewModel.java
@@ -343,7 +343,7 @@ public int getNumPastTrades(Trade trade) {
.collect(Collectors.toSet())
.size();
}
-
+
@Nullable
private Date getMaxTradePeriodDate() {
return dataModel.getTrade() != null
From 95bcb1ef9c74c6fa48f946ebc29b9af55bd1ed70 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 11:27:30 -0300
Subject: [PATCH 08/30] Refactor PendingTradesDataModel methods -> TradeUtil
Scope of this refactoring is small; more can be done, but the short
term goal is to share trade util logic with core api.
- Removed unused method getCurrencyCode()
- Made minor style changes
- Removed duplicated code block
---
.../main/java/bisq/core/trade/TradeUtil.java | 2 +
.../pendingtrades/PendingTradesDataModel.java | 83 +++++++------------
2 files changed, 34 insertions(+), 51 deletions(-)
diff --git a/core/src/main/java/bisq/core/trade/TradeUtil.java b/core/src/main/java/bisq/core/trade/TradeUtil.java
index a89dec32459..2837e4e9319 100644
--- a/core/src/main/java/bisq/core/trade/TradeUtil.java
+++ b/core/src/main/java/bisq/core/trade/TradeUtil.java
@@ -25,6 +25,8 @@
import bisq.common.util.Tuple2;
import bisq.common.util.Utilities;
+import org.bitcoinj.core.Coin;
+
import javax.inject.Inject;
import javax.inject.Singleton;
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 fa000d8e6f7..bce37344b80 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
@@ -35,6 +35,7 @@
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
+import bisq.core.offer.OfferUtil;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.support.SupportType;
import bisq.core.support.dispute.Dispute;
@@ -107,6 +108,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
public final Navigation navigation;
public final WalletPasswordWindow walletPasswordWindow;
private final NotificationCenter notificationCenter;
+ private final OfferUtil offerUtil;
final ObservableList list = FXCollections.observableArrayList();
private final ListChangeListener tradesListChangeListener;
@@ -142,7 +144,8 @@ public PendingTradesDataModel(TradeManager tradeManager,
DaoFacade daoFacade,
Navigation navigation,
WalletPasswordWindow walletPasswordWindow,
- NotificationCenter notificationCenter) {
+ NotificationCenter notificationCenter,
+ OfferUtil offerUtil) {
this.tradeManager = tradeManager;
this.btcWalletService = btcWalletService;
this.pubKeyRing = pubKeyRing;
@@ -157,6 +160,7 @@ public PendingTradesDataModel(TradeManager tradeManager,
this.navigation = navigation;
this.walletPasswordWindow = walletPasswordWindow;
this.notificationCenter = notificationCenter;
+ this.offerUtil = offerUtil;
tradesListChangeListener = change -> onListChanged();
notificationCenter.setSelectItemByTradeIdConsumer(this::selectItemByTradeId);
@@ -253,7 +257,7 @@ Offer getOffer() {
}
private boolean isBuyOffer() {
- return getOffer() != null && getOffer().getDirection() == OfferPayload.Direction.BUY;
+ return getOffer() != null && offerUtil.isBuyOffer(getOffer().getDirection());
}
boolean isBuyer() {
@@ -348,11 +352,6 @@ Coin getTradeFeeAsBsq() {
}
}
- public String getCurrencyCode() {
- return getOffer() != null ? getOffer().getCurrencyCode() : "";
- }
-
-
@Nullable
public PaymentAccountPayload getSellersPaymentAccountPayload() {
if (getTrade() != null && getTrade().getContract() != null)
@@ -555,26 +554,7 @@ private void doOpenDispute(boolean isSupportTicket, Transaction depositTx) {
}
trade.setDisputeState(Trade.DisputeState.MEDIATION_REQUESTED);
- disputeManager.sendOpenNewDisputeMessage(dispute,
- false,
- resultHandler,
- (errorMessage, throwable) -> {
- if ((throwable instanceof DisputeAlreadyOpenException)) {
- errorMessage += "\n\n" + Res.get("portfolio.pending.openAgainDispute.msg");
- new Popup().warning(errorMessage)
- .actionButtonText(Res.get("portfolio.pending.openAgainDispute.button"))
- .onAction(() -> disputeManager.sendOpenNewDisputeMessage(dispute,
- true,
- resultHandler,
- (e, t) -> {
- log.error(e);
- }))
- .closeButtonText(Res.get("shared.cancel"))
- .show();
- } else {
- new Popup().warning(errorMessage).show();
- }
- });
+ sendOpenDisputeMessage(disputeManager, resultHandler, dispute);
} else if (useRefundAgent) {
resultHandler = () -> navigation.navigateTo(MainView.class, SupportView.class, RefundClientView.class);
@@ -643,35 +623,13 @@ private void doOpenDispute(boolean isSupportTicket, Transaction depositTx) {
dispute.setDonationAddressOfDelayedPayoutTx(donationAddressString.get());
dispute.setDelayedPayoutTxId(delayedPayoutTx.getTxId().toString());
-
trade.setDisputeState(Trade.DisputeState.REFUND_REQUESTED);
((DisputeProtocol) tradeManager.getTradeProtocol(trade)).onPublishDelayedPayoutTx(() -> {
log.info("DelayedPayoutTx published and message sent to peer");
- disputeManager.sendOpenNewDisputeMessage(dispute,
- false,
- resultHandler,
- (errorMessage, throwable) -> {
- if ((throwable instanceof DisputeAlreadyOpenException)) {
- errorMessage += "\n\n" + Res.get("portfolio.pending.openAgainDispute.msg");
- new Popup().warning(errorMessage)
- .actionButtonText(Res.get("portfolio.pending.openAgainDispute.button"))
- .onAction(() -> disputeManager.sendOpenNewDisputeMessage(dispute,
- true,
- resultHandler,
- (e, t) -> {
- log.error(e);
- }))
- .closeButtonText(Res.get("shared.cancel"))
- .show();
- } else {
- new Popup().warning(errorMessage).show();
- }
- });
+ sendOpenDisputeMessage(disputeManager, resultHandler, dispute);
},
- errorMessage -> {
- new Popup().error(errorMessage).show();
- });
+ errorMessage -> new Popup().error(errorMessage).show());
} else {
log.warn("Invalid dispute state {}", disputeState.name());
@@ -694,5 +652,28 @@ public void onMoveInvalidTradeToFailedTrades(Trade trade) {
public boolean isSignWitnessTrade() {
return accountAgeWitnessService.isSignWitnessTrade(selectedTrade);
}
+
+ private void sendOpenDisputeMessage(DisputeManager extends DisputeList> disputeManager,
+ ResultHandler resultHandler,
+ Dispute dispute) {
+ disputeManager.sendOpenNewDisputeMessage(dispute,
+ false,
+ resultHandler,
+ (errorMessage, throwable) -> {
+ if ((throwable instanceof DisputeAlreadyOpenException)) {
+ errorMessage += "\n\n" + Res.get("portfolio.pending.openAgainDispute.msg");
+ new Popup().warning(errorMessage)
+ .actionButtonText(Res.get("portfolio.pending.openAgainDispute.button"))
+ .onAction(() -> disputeManager.sendOpenNewDisputeMessage(dispute,
+ true,
+ resultHandler,
+ (e, t) -> log.error(e)))
+ .closeButtonText(Res.get("shared.cancel"))
+ .show();
+ } else {
+ new Popup().warning(errorMessage).show();
+ }
+ });
+ }
}
From bbd7a31c88907e7c29ce473e5a71603f976ace21 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 11:38:03 -0300
Subject: [PATCH 09/30] Remove unused import
---
core/src/main/java/bisq/core/trade/TradeUtil.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/core/src/main/java/bisq/core/trade/TradeUtil.java b/core/src/main/java/bisq/core/trade/TradeUtil.java
index 2837e4e9319..a89dec32459 100644
--- a/core/src/main/java/bisq/core/trade/TradeUtil.java
+++ b/core/src/main/java/bisq/core/trade/TradeUtil.java
@@ -25,8 +25,6 @@
import bisq.common.util.Tuple2;
import bisq.common.util.Utilities;
-import org.bitcoinj.core.Coin;
-
import javax.inject.Inject;
import javax.inject.Singleton;
From 161dbade0d04dcd7439e3ed94929a4c4ce3fdab0 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 16:22:20 -0300
Subject: [PATCH 10/30] Add getRole(tradeId) to core api
API users will need to see their role as maker/taker when looking at trade details.
- Add getRole(trade) to TradeUtil.
- Add getTradeRole(tradeId) to CoreApi, CoreTradesService.
- Add role field to TradeInfo proto and its wrapper class.
---
core/src/main/java/bisq/core/api/CoreApi.java | 4 ++
.../java/bisq/core/api/CoreTradesService.java | 9 +++++
.../java/bisq/core/api/model/TradeInfo.java | 15 +++++++
.../main/java/bisq/core/trade/TradeUtil.java | 23 ++++++++++-
.../bisq/daemon/grpc/GrpcTradesService.java | 3 +-
proto/src/main/proto/grpc.proto | 39 ++++++++++---------
6 files changed, 72 insertions(+), 21 deletions(-)
diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java
index 01f70d312f4..05886dd6e9e 100644
--- a/core/src/main/java/bisq/core/api/CoreApi.java
+++ b/core/src/main/java/bisq/core/api/CoreApi.java
@@ -193,6 +193,10 @@ public Trade getTrade(String tradeId) {
return coreTradesService.getTrade(tradeId);
}
+ public String getTradeRole(String tradeId) {
+ return coreTradesService.getTradeRole(tradeId);
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////
// Wallets
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/src/main/java/bisq/core/api/CoreTradesService.java b/core/src/main/java/bisq/core/api/CoreTradesService.java
index d0200a78ce5..85877488315 100644
--- a/core/src/main/java/bisq/core/api/CoreTradesService.java
+++ b/core/src/main/java/bisq/core/api/CoreTradesService.java
@@ -21,6 +21,7 @@
import bisq.core.offer.takeoffer.TakeOfferModel;
import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;
+import bisq.core.trade.TradeUtil;
import bisq.core.trade.protocol.BuyerProtocol;
import bisq.core.trade.protocol.SellerProtocol;
import bisq.core.user.User;
@@ -38,14 +39,17 @@ class CoreTradesService {
private final TakeOfferModel takeOfferModel;
private final TradeManager tradeManager;
+ private final TradeUtil tradeUtil;
private final User user;
@Inject
public CoreTradesService(TakeOfferModel takeOfferModel,
TradeManager tradeManager,
+ TradeUtil tradeUtil,
User user) {
this.takeOfferModel = takeOfferModel;
this.tradeManager = tradeManager;
+ this.tradeUtil = tradeUtil;
this.user = user;
}
@@ -57,6 +61,7 @@ void takeOffer(Offer offer,
throw new IllegalArgumentException(format("payment account with id '%s' not found", paymentAccountId));
var useSavingsWallet = true;
+ //noinspection ConstantConditions
takeOfferModel.initModel(offer, paymentAccount, useSavingsWallet);
log.info("Initiating take {} offer, {}",
offer.isBuyOffer() ? "buy" : "sell",
@@ -111,6 +116,10 @@ void confirmPaymentReceived(String tradeId) {
}
}
+ String getTradeRole(String tradeId) {
+ return tradeUtil.getRole(getTrade(tradeId));
+ }
+
Trade getTrade(String tradeId) {
return tradeManager.getTradeById(tradeId).orElseThrow(() ->
new IllegalArgumentException(format("trade with id '%s' not found", tradeId)));
diff --git a/core/src/main/java/bisq/core/api/model/TradeInfo.java b/core/src/main/java/bisq/core/api/model/TradeInfo.java
index 6e4adeca4ae..1a717a7672e 100644
--- a/core/src/main/java/bisq/core/api/model/TradeInfo.java
+++ b/core/src/main/java/bisq/core/api/model/TradeInfo.java
@@ -40,6 +40,7 @@ public class TradeInfo implements Payload {
private final String tradeId;
private final String shortId;
private final long date;
+ private final String role;
private final boolean isCurrencyForTakerFeeBtc;
private final long txFeeAsLong;
private final long takerFeeAsLong;
@@ -65,6 +66,7 @@ public TradeInfo(TradeInfoBuilder builder) {
this.tradeId = builder.tradeId;
this.shortId = builder.shortId;
this.date = builder.date;
+ this.role = builder.role;
this.isCurrencyForTakerFeeBtc = builder.isCurrencyForTakerFeeBtc;
this.txFeeAsLong = builder.txFeeAsLong;
this.takerFeeAsLong = builder.takerFeeAsLong;
@@ -87,11 +89,16 @@ public TradeInfo(TradeInfoBuilder builder) {
}
public static TradeInfo toTradeInfo(Trade trade) {
+ return toTradeInfo(trade, null);
+ }
+
+ public static TradeInfo toTradeInfo(Trade trade, String role) {
return new TradeInfo.TradeInfoBuilder()
.withOffer(toOfferInfo(trade.getOffer()))
.withTradeId(trade.getId())
.withShortId(trade.getShortId())
.withDate(trade.getDate().getTime())
+ .withRole(role == null ? "" : role)
.withIsCurrencyForTakerFeeBtc(trade.isCurrencyForTakerFeeBtc())
.withTxFeeAsLong(trade.getTxFeeAsLong())
.withTakerFeeAsLong(trade.getTakerFeeAsLong())
@@ -127,6 +134,7 @@ public bisq.proto.grpc.TradeInfo toProtoMessage() {
.setTradeId(tradeId)
.setShortId(shortId)
.setDate(date)
+ .setRole(role)
.setIsCurrencyForTakerFeeBtc(isCurrencyForTakerFeeBtc)
.setTxFeeAsLong(txFeeAsLong)
.setTakerFeeAsLong(takerFeeAsLong)
@@ -165,6 +173,7 @@ public static class TradeInfoBuilder {
private String tradeId;
private String shortId;
private long date;
+ private String role;
private boolean isCurrencyForTakerFeeBtc;
private long txFeeAsLong;
private long takerFeeAsLong;
@@ -205,6 +214,11 @@ public TradeInfoBuilder withDate(long date) {
return this;
}
+ public TradeInfoBuilder withRole(String role) {
+ this.role = role;
+ return this;
+ }
+
public TradeInfoBuilder withIsCurrencyForTakerFeeBtc(boolean isCurrencyForTakerFeeBtc) {
this.isCurrencyForTakerFeeBtc = isCurrencyForTakerFeeBtc;
return this;
@@ -311,6 +325,7 @@ public String toString() {
" tradeId='" + tradeId + '\'' + "\n" +
", shortId='" + shortId + '\'' + "\n" +
", date='" + date + '\'' + "\n" +
+ ", role='" + role + '\'' + "\n" +
", isCurrencyForTakerFeeBtc='" + isCurrencyForTakerFeeBtc + '\'' + "\n" +
", txFeeAsLong='" + txFeeAsLong + '\'' + "\n" +
", takerFeeAsLong='" + takerFeeAsLong + '\'' + "\n" +
diff --git a/core/src/main/java/bisq/core/trade/TradeUtil.java b/core/src/main/java/bisq/core/trade/TradeUtil.java
index a89dec32459..cd4fd074aad 100644
--- a/core/src/main/java/bisq/core/trade/TradeUtil.java
+++ b/core/src/main/java/bisq/core/trade/TradeUtil.java
@@ -39,6 +39,7 @@
import static bisq.core.locale.CurrencyUtil.isFiatCurrency;
import static bisq.core.util.FormattingUtils.formatDurationAsWords;
import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
/**
* This class contains trade utility methods.
@@ -173,6 +174,27 @@ public String getPaymentMethodNameWithCountryCode(Trade trade) {
return paymentMethodDescription;
}
+ /**
+ * Returns a string describing a trader's role for a given trade.
+ * @param trade Trade
+ * @return String describing a trader's role for a given trade
+ */
+ public String getRole(Trade trade) {
+ Contract contract = trade.getContract();
+ if (contract == null)
+ throw new IllegalStateException(format("could not get role because no contract was found for trade '%s'",
+ trade.getShortId()));
+
+ Offer offer = trade.getOffer();
+ if (offer == null)
+ throw new IllegalStateException(format("could not get role because no offer was found for trade '%s'",
+ trade.getShortId()));
+
+ return getRole(contract.isBuyerMakerAndSellerTaker(),
+ offer.isMyOffer(keyRing),
+ offer.getCurrencyCode());
+ }
+
/**
* Returns a string describing a trader's role.
*
@@ -202,6 +224,5 @@ public String getRole(boolean isBuyerMakerAndSellerTaker, boolean isMaker, Strin
? Res.get("formatter.asMaker", currencyCode, Res.get("shared.buyer"))
: Res.get("formatter.asTaker", currencyCode, Res.get("shared.seller"));
}
-
}
}
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java
index 0ffbd71f044..e23651bb207 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java
@@ -56,8 +56,9 @@ public void getTrade(GetTradeRequest req,
StreamObserver responseObserver) {
try {
Trade trade = coreApi.getTrade(req.getTradeId());
+ String role = coreApi.getTradeRole(req.getTradeId());
var reply = GetTradeReply.newBuilder()
- .setTrade(toTradeInfo(trade).toProtoMessage())
+ .setTrade(toTradeInfo(trade, role).toProtoMessage())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto
index 68121d00596..041f1278ea2 100644
--- a/proto/src/main/proto/grpc.proto
+++ b/proto/src/main/proto/grpc.proto
@@ -218,25 +218,26 @@ message TradeInfo {
string tradeId = 2;
string shortId = 3;
uint64 date = 4;
- bool isCurrencyForTakerFeeBtc = 5;
- uint64 txFeeAsLong = 6;
- uint64 takerFeeAsLong = 7;
- string takerFeeTxId = 8;
- string depositTxId = 9;
- string payoutTxId = 10;
- uint64 tradeAmountAsLong = 11;
- uint64 tradePrice = 12;
- string tradingPeerNodeAddress = 13;
- string state = 14;
- string phase = 15;
- string tradePeriodState = 16;
- bool isDepositPublished = 17;
- bool isDepositConfirmed = 18;
- bool isFiatSent = 19;
- bool isFiatReceived = 20;
- bool isPayoutPublished = 21;
- bool isWithdrawn = 22;
- string contractAsJson = 23;
+ string role = 5;
+ bool isCurrencyForTakerFeeBtc = 6;
+ uint64 txFeeAsLong = 7;
+ uint64 takerFeeAsLong = 8;
+ string takerFeeTxId = 9;
+ string depositTxId = 10;
+ string payoutTxId = 11;
+ uint64 tradeAmountAsLong = 12;
+ uint64 tradePrice = 13;
+ string tradingPeerNodeAddress = 14;
+ string state = 15;
+ string phase = 16;
+ string tradePeriodState = 17;
+ bool isDepositPublished = 18;
+ bool isDepositConfirmed = 19;
+ bool isFiatSent = 20;
+ bool isFiatReceived = 21;
+ bool isPayoutPublished = 22;
+ bool isWithdrawn = 23;
+ string contractAsJson = 24;
}
///////////////////////////////////////////////////////////////////////////////////////////
From 3379376babab645af1f65cf595aca06768fd40c1 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 16:50:22 -0300
Subject: [PATCH 11/30] Refactor CLI output formatting code & add trade
formatter
- Move output column header specs to its own shared constants class.
- Add new TradeFormat class for printing trade details in the console.
- Print formatted trade in api trade tests -- to see output before
using formatter in CLI (in next PR).
---
.../method/trade/AbstractTradeTest.java | 1 -
.../method/trade/TakeBuyBTCOfferTest.java | 6 +
.../method/trade/TakeSellBTCOfferTest.java | 7 ++
.../java/bisq/cli/ColumnHeaderConstants.java | 38 ++++++
cli/src/main/java/bisq/cli/TableFormat.java | 26 +---
cli/src/main/java/bisq/cli/TradeFormat.java | 119 ++++++++++++++++++
6 files changed, 173 insertions(+), 24 deletions(-)
create mode 100644 cli/src/main/java/bisq/cli/ColumnHeaderConstants.java
create mode 100644 cli/src/main/java/bisq/cli/TradeFormat.java
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
index 5364de7f7d8..094007abd40 100644
--- a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
@@ -28,5 +28,4 @@ protected final void verifyExpectedTradeStateAndPhase(TradeInfo trade,
assertEquals(expectedState.name(), trade.getState());
assertEquals(expectedPhase.name(), trade.getPhase());
}
-
}
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java
index 040cee5a18d..4aba67fc715 100644
--- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java
@@ -31,6 +31,7 @@
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
+import static bisq.cli.TradeFormat.format;
import static bisq.core.trade.Trade.Phase.DEPOSIT_CONFIRMED;
import static bisq.core.trade.Trade.Phase.DEPOSIT_PUBLISHED;
import static bisq.core.trade.Trade.Phase.FIAT_SENT;
@@ -39,6 +40,7 @@
import static bisq.core.trade.Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN;
import static bisq.core.trade.Trade.State.SELLER_PUBLISHED_DEPOSIT_TX;
import static bisq.core.trade.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG;
+import static java.lang.System.out;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
@@ -85,10 +87,12 @@ public void testTakeAlicesBuyOffer() {
trade = getTrade(bobdaemon, trade.getTradeId());
verifyExpectedTradeStateAndPhase(trade, SELLER_PUBLISHED_DEPOSIT_TX, DEPOSIT_PUBLISHED);
+ out.println(format(trade));
genBtcBlocksThenWait(1, 2250);
trade = getTrade(bobdaemon, trade.getTradeId());
verifyExpectedTradeStateAndPhase(trade, DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN, DEPOSIT_CONFIRMED);
+ out.println(format(trade));
} catch (StatusRuntimeException e) {
fail(e);
}
@@ -107,6 +111,7 @@ public void testAlicesConfirmPaymentStarted() {
trade = getTrade(alicedaemon, tradeId);
assertEquals(OFFER_FEE_PAID.name(), trade.getOffer().getState());
verifyExpectedTradeStateAndPhase(trade, BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG, FIAT_SENT);
+ out.println(format(trade));
} catch (StatusRuntimeException e) {
fail(e);
}
@@ -125,5 +130,6 @@ public void testBobsConfirmPaymentReceived() {
// TODO is this a bug? Why is offer.state == available?
assertEquals(AVAILABLE.name(), trade.getOffer().getState());
verifyExpectedTradeStateAndPhase(trade, SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG, PAYOUT_PUBLISHED);
+ out.println(format(trade));
}
}
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java
index 5347159daae..658b4083231 100644
--- a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java
@@ -31,6 +31,7 @@
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
+import static bisq.cli.TradeFormat.format;
import static bisq.core.trade.Trade.Phase.DEPOSIT_CONFIRMED;
import static bisq.core.trade.Trade.Phase.DEPOSIT_PUBLISHED;
import static bisq.core.trade.Trade.Phase.FIAT_SENT;
@@ -39,6 +40,7 @@
import static bisq.core.trade.Trade.State.BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG;
import static bisq.core.trade.Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN;
import static bisq.core.trade.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG;
+import static java.lang.System.out;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
@@ -86,10 +88,12 @@ public void testTakeAlicesSellOffer() {
trade = getTrade(bobdaemon, trade.getTradeId());
verifyExpectedTradeStateAndPhase(trade, BUYER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG, DEPOSIT_PUBLISHED);
+ out.println(format(trade));
genBtcBlocksThenWait(1, 2250);
trade = getTrade(bobdaemon, trade.getTradeId());
verifyExpectedTradeStateAndPhase(trade, DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN, DEPOSIT_CONFIRMED);
+ out.println(format(trade));
} catch (StatusRuntimeException e) {
fail(e);
@@ -110,6 +114,8 @@ public void testBobsConfirmPaymentStarted() {
// TODO is this a bug? Why is offer.state == available?
assertEquals(AVAILABLE.name(), trade.getOffer().getState());
verifyExpectedTradeStateAndPhase(trade, BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG, FIAT_SENT);
+
+ out.println(format(trade));
} catch (StatusRuntimeException e) {
fail(e);
}
@@ -127,5 +133,6 @@ public void testAlicesConfirmPaymentReceived() {
trade = getTrade(alicedaemon, tradeId);
assertEquals(OFFER_FEE_PAID.name(), trade.getOffer().getState());
verifyExpectedTradeStateAndPhase(trade, SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG, PAYOUT_PUBLISHED);
+ out.println(format(trade));
}
}
diff --git a/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java b/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java
new file mode 100644
index 00000000000..f5744f6cc71
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java
@@ -0,0 +1,38 @@
+package bisq.cli;
+
+import static com.google.common.base.Strings.padEnd;
+import static com.google.common.base.Strings.padStart;
+
+class ColumnHeaderConstants {
+
+ // For inserting 2 spaces between column headers.
+ static final String COL_HEADER_DELIMITER = " ";
+
+ // Table column header format specs, right padded with two spaces. In some cases
+ // such as COL_HEADER_CREATION_DATE, COL_HEADER_VOLUME and COL_HEADER_UUID, the
+ // expected max data string length is accounted for. In others, the column header length
+ // are expected to be greater than any column value length.
+ static final String COL_HEADER_ADDRESS = padEnd("Address", 34, ' ');
+ static final String COL_HEADER_AMOUNT = padEnd("BTC(min - max)", 24, ' ');
+ static final String COL_HEADER_BALANCE = padStart("Balance", 12, ' ');
+ static final String COL_HEADER_CONFIRMATIONS = "Confirmations";
+ static final String COL_HEADER_CREATION_DATE = padEnd("Creation Date (UTC)", 20, ' ');
+ static final String COL_HEADER_CURRENCY = "Currency";
+ static final String COL_HEADER_DIRECTION = "Buy/Sell";
+ static final String COL_HEADER_NAME = "Name";
+ static final String COL_HEADER_PAYMENT_METHOD = "Payment Method";
+ static final String COL_HEADER_PRICE = "Price in %-3s for 1 BTC";
+ static final String COL_HEADER_TRADE_AMOUNT = padStart("Amount(%-3s)", 12, ' ');
+ static final String COL_HEADER_TRADE_DEPOSIT_CONFIRMED = "Deposit Confirmed";
+ static final String COL_HEADER_TRADE_DEPOSIT_PUBLISHED = "Deposit Published";
+ static final String COL_HEADER_TRADE_FIAT_SENT = "Fiat Sent";
+ static final String COL_HEADER_TRADE_FIAT_RECEIVED = "Fiat Received";
+ static final String COL_HEADER_TRADE_PAYOUT_PUBLISHED = "Payout Published";
+ static final String COL_HEADER_TRADE_WITHDRAWN = "Withdrawn";
+ static final String COL_HEADER_TRADE_ROLE = "My Role";
+ static final String COL_HEADER_TRADE_SHORT_ID = "ID";
+ static final String COL_HEADER_TRADE_TX_FEE = "Tx Fee(%-3s)";
+ static final String COL_HEADER_TRADE_TAKER_FEE = "Taker Fee(%-3s)";
+ static final String COL_HEADER_VOLUME = padEnd("%-3s(min - max)", 15, ' ');
+ static final String COL_HEADER_UUID = padEnd("ID", 52, ' ');
+}
diff --git a/cli/src/main/java/bisq/cli/TableFormat.java b/cli/src/main/java/bisq/cli/TableFormat.java
index 7d02af562f5..e9868f336e4 100644
--- a/cli/src/main/java/bisq/cli/TableFormat.java
+++ b/cli/src/main/java/bisq/cli/TableFormat.java
@@ -29,12 +29,12 @@
import java.util.TimeZone;
import java.util.stream.Collectors;
+import static bisq.cli.ColumnHeaderConstants.*;
import static bisq.cli.CurrencyFormat.formatAmountRange;
import static bisq.cli.CurrencyFormat.formatOfferPrice;
import static bisq.cli.CurrencyFormat.formatSatoshis;
import static bisq.cli.CurrencyFormat.formatVolumeRange;
import static com.google.common.base.Strings.padEnd;
-import static com.google.common.base.Strings.padStart;
import static java.lang.String.format;
import static java.util.Collections.max;
import static java.util.Comparator.comparing;
@@ -42,28 +42,8 @@
class TableFormat {
- private static final TimeZone TZ_UTC = getTimeZone("UTC");
- private static final SimpleDateFormat DATE_FORMAT_ISO_8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-
- // For inserting 2 spaces between column headers.
- private static final String COL_HEADER_DELIMITER = " ";
-
- // Table column header format specs, right padded with two spaces. In some cases
- // such as COL_HEADER_CREATION_DATE, COL_HEADER_VOLUME and COL_HEADER_UUID, the
- // expected max data string length is accounted for. In others, the column header length
- // are expected to be greater than any column value length.
- private static final String COL_HEADER_ADDRESS = padEnd("Address", 34, ' ');
- private static final String COL_HEADER_AMOUNT = padEnd("BTC(min - max)", 24, ' ');
- private static final String COL_HEADER_BALANCE = padStart("Balance", 12, ' ');
- private static final String COL_HEADER_CONFIRMATIONS = "Confirmations";
- private static final String COL_HEADER_CREATION_DATE = padEnd("Creation Date (UTC)", 20, ' ');
- private static final String COL_HEADER_CURRENCY = "Currency";
- private static final String COL_HEADER_DIRECTION = "Buy/Sell"; // TODO "Take Offer to
- private static final String COL_HEADER_NAME = "Name";
- private static final String COL_HEADER_PAYMENT_METHOD = "Payment Method";
- private static final String COL_HEADER_PRICE = "Price in %-3s for 1 BTC";
- private static final String COL_HEADER_VOLUME = padEnd("%-3s(min - max)", 15, ' ');
- private static final String COL_HEADER_UUID = padEnd("ID", 52, ' ');
+ static final TimeZone TZ_UTC = getTimeZone("UTC");
+ static final SimpleDateFormat DATE_FORMAT_ISO_8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
static String formatAddressBalanceTbl(List addressBalanceInfo) {
String headerLine = (COL_HEADER_ADDRESS + COL_HEADER_DELIMITER
diff --git a/cli/src/main/java/bisq/cli/TradeFormat.java b/cli/src/main/java/bisq/cli/TradeFormat.java
new file mode 100644
index 00000000000..4eadfa9008c
--- /dev/null
+++ b/cli/src/main/java/bisq/cli/TradeFormat.java
@@ -0,0 +1,119 @@
+/*
+ * 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.cli;
+
+import bisq.proto.grpc.TradeInfo;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.function.Supplier;
+
+import static bisq.cli.ColumnHeaderConstants.*;
+import static bisq.cli.CurrencyFormat.formatOfferPrice;
+import static bisq.cli.CurrencyFormat.formatSatoshis;
+import static com.google.common.base.Strings.padEnd;
+
+@VisibleForTesting
+public class TradeFormat {
+
+ @VisibleForTesting
+ public static String format(TradeInfo tradeInfo) {
+ // Some column values might be longer than header, so we need to calculated them.
+ int shortIdColWidth = Math.max(COL_HEADER_TRADE_SHORT_ID.length(), tradeInfo.getShortId().length());
+ int roleColWidth = Math.max(COL_HEADER_TRADE_ROLE.length(), tradeInfo.getRole().length());
+
+ // We only show taker fee under its header when user is the taker.
+ boolean isTaker = tradeInfo.getRole().toLowerCase().contains("taker");
+ Supplier takerFeeHeaderFormat = () -> isTaker ?
+ padEnd(COL_HEADER_TRADE_TAKER_FEE, 12, ' ') + COL_HEADER_DELIMITER
+ : "";
+ Supplier takerFeeHeader = () -> isTaker ?
+ "%" + (COL_HEADER_TRADE_TAKER_FEE.length() + 1) + "s"
+ : "";
+
+ String headersFormat = padEnd(COL_HEADER_TRADE_SHORT_ID, shortIdColWidth, ' ') + COL_HEADER_DELIMITER
+ + padEnd(COL_HEADER_TRADE_ROLE, roleColWidth, ' ') + COL_HEADER_DELIMITER
+ + COL_HEADER_PRICE + COL_HEADER_DELIMITER // includes %s -> currencyCode
+ + padEnd(COL_HEADER_TRADE_AMOUNT, 12, ' ') + COL_HEADER_DELIMITER
+ + padEnd(COL_HEADER_TRADE_TX_FEE, 12, ' ') + COL_HEADER_DELIMITER
+ + takerFeeHeaderFormat.get()
+ + COL_HEADER_TRADE_DEPOSIT_PUBLISHED + COL_HEADER_DELIMITER
+ + COL_HEADER_TRADE_DEPOSIT_CONFIRMED + COL_HEADER_DELIMITER
+ + COL_HEADER_TRADE_FIAT_SENT + COL_HEADER_DELIMITER
+ + COL_HEADER_TRADE_FIAT_RECEIVED + COL_HEADER_DELIMITER
+ + COL_HEADER_TRADE_PAYOUT_PUBLISHED + COL_HEADER_DELIMITER
+ + COL_HEADER_TRADE_WITHDRAWN + COL_HEADER_DELIMITER
+ + "%n";
+
+ String counterCurrencyCode = tradeInfo.getOffer().getCounterCurrencyCode();
+ String baseCurrencyCode = tradeInfo.getOffer().getBaseCurrencyCode();
+ String headerLine = isTaker
+ ? String.format(headersFormat, counterCurrencyCode, baseCurrencyCode, baseCurrencyCode, baseCurrencyCode)
+ : String.format(headersFormat, counterCurrencyCode, baseCurrencyCode, baseCurrencyCode);
+
+ String colDataFormat = "%-" + shortIdColWidth + "s" // left justify
+ + " %-" + (roleColWidth + COL_HEADER_DELIMITER.length()) + "s" // left justify
+ + "%" + (COL_HEADER_PRICE.length() - 1) + "s" // right justify
+ + "%" + (COL_HEADER_TRADE_AMOUNT.length() + 1) + "s" // right justify
+ + "%" + (COL_HEADER_TRADE_TX_FEE.length() + 1) + "s" // right justify
+ + takerFeeHeader.get() // right justify
+ + " %-" + COL_HEADER_TRADE_DEPOSIT_PUBLISHED.length() + "s" // left justify
+ + " %-" + COL_HEADER_TRADE_DEPOSIT_CONFIRMED.length() + "s" // left justify
+ + " %-" + COL_HEADER_TRADE_FIAT_SENT.length() + "s" // left justify
+ + " %-" + COL_HEADER_TRADE_FIAT_RECEIVED.length() + "s" // left justify
+ + " %-" + COL_HEADER_TRADE_PAYOUT_PUBLISHED.length() + "s" // left justify
+ + " %-" + COL_HEADER_TRADE_WITHDRAWN.length() + "s" // left justify
+ ;
+
+ return headerLine +
+ (isTaker
+ ? formatTradeForTaker(colDataFormat, tradeInfo)
+ : formatTradeForMaker(colDataFormat, tradeInfo));
+ }
+
+ private static String formatTradeForMaker(String format, TradeInfo tradeInfo) {
+ return String.format(format,
+ tradeInfo.getShortId(),
+ tradeInfo.getRole(),
+ formatOfferPrice(tradeInfo.getTradePrice()),
+ formatSatoshis(tradeInfo.getTradeAmountAsLong()),
+ formatSatoshis(tradeInfo.getTxFeeAsLong()),
+ tradeInfo.getIsDepositPublished() ? "YES" : "NO",
+ tradeInfo.getIsDepositConfirmed() ? "YES" : "NO",
+ tradeInfo.getIsFiatSent() ? "YES" : "NO",
+ tradeInfo.getIsFiatReceived() ? "YES" : "NO",
+ tradeInfo.getIsPayoutPublished() ? "YES" : "NO",
+ tradeInfo.getIsWithdrawn() ? "YES" : "NO");
+ }
+
+ private static String formatTradeForTaker(String format, TradeInfo tradeInfo) {
+ return String.format(format,
+ tradeInfo.getShortId(),
+ tradeInfo.getRole(),
+ formatOfferPrice(tradeInfo.getTradePrice()),
+ formatSatoshis(tradeInfo.getTradeAmountAsLong()),
+ formatSatoshis(tradeInfo.getTxFeeAsLong()),
+ formatSatoshis(tradeInfo.getTakerFeeAsLong()),
+ tradeInfo.getIsDepositPublished() ? "YES" : "NO",
+ tradeInfo.getIsDepositConfirmed() ? "YES" : "NO",
+ tradeInfo.getIsFiatSent() ? "YES" : "NO",
+ tradeInfo.getIsFiatReceived() ? "YES" : "NO",
+ tradeInfo.getIsPayoutPublished() ? "YES" : "NO",
+ tradeInfo.getIsWithdrawn() ? "YES" : "NO");
+ }
+}
From d8bc26588c90d35436380143988e485b62a19e83 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 16:52:45 -0300
Subject: [PATCH 12/30] Add license comment
---
.../java/bisq/cli/ColumnHeaderConstants.java | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java b/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java
index f5744f6cc71..03500e4f47a 100644
--- a/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java
+++ b/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java
@@ -1,3 +1,20 @@
+/*
+ * 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.cli;
import static com.google.common.base.Strings.padEnd;
From 31435bba51162f2ba352a7c055f5af9106010e5f Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 17:02:40 -0300
Subject: [PATCH 13/30] Move semicolon up from blank line
---
cli/src/main/java/bisq/cli/TradeFormat.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/cli/src/main/java/bisq/cli/TradeFormat.java b/cli/src/main/java/bisq/cli/TradeFormat.java
index 4eadfa9008c..ab9075fe341 100644
--- a/cli/src/main/java/bisq/cli/TradeFormat.java
+++ b/cli/src/main/java/bisq/cli/TradeFormat.java
@@ -77,8 +77,7 @@ public static String format(TradeInfo tradeInfo) {
+ " %-" + COL_HEADER_TRADE_FIAT_SENT.length() + "s" // left justify
+ " %-" + COL_HEADER_TRADE_FIAT_RECEIVED.length() + "s" // left justify
+ " %-" + COL_HEADER_TRADE_PAYOUT_PUBLISHED.length() + "s" // left justify
- + " %-" + COL_HEADER_TRADE_WITHDRAWN.length() + "s" // left justify
- ;
+ + " %-" + COL_HEADER_TRADE_WITHDRAWN.length() + "s"; // left justify
return headerLine +
(isTaker
From 2b23704b5af862f947b64b1ca30234f8641b0114 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 17:15:02 -0300
Subject: [PATCH 14/30] Add 'gettrade' to api method CLI
---
cli/src/main/java/bisq/cli/CliMain.java | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java
index d8f66dabbef..b7a5d80e216 100644
--- a/cli/src/main/java/bisq/cli/CliMain.java
+++ b/cli/src/main/java/bisq/cli/CliMain.java
@@ -27,6 +27,7 @@
import bisq.proto.grpc.GetOfferRequest;
import bisq.proto.grpc.GetOffersRequest;
import bisq.proto.grpc.GetPaymentAccountsRequest;
+import bisq.proto.grpc.GetTradeRequest;
import bisq.proto.grpc.GetVersionRequest;
import bisq.proto.grpc.LockWalletRequest;
import bisq.proto.grpc.RegisterDisputeAgentRequest;
@@ -74,6 +75,7 @@ private enum Method {
getoffer,
getoffers,
takeoffer,
+ gettrade,
confirmpaymentstarted,
confirmpaymentreceived,
createpaymentacct,
@@ -275,6 +277,18 @@ public static void run(String[] args) {
out.printf("trade '%s' successfully taken", reply.getTrade().getShortId());
return;
}
+ case gettrade: {
+ if (nonOptionArgs.size() < 2)
+ throw new IllegalArgumentException("incorrect parameter count, expecting trade id");
+
+ var tradeId = nonOptionArgs.get(1);
+ var request = GetTradeRequest.newBuilder()
+ .setTradeId(tradeId)
+ .build();
+ var reply = tradesService.getTrade(request);
+ out.println(TradeFormat.format(reply.getTrade()));
+ return;
+ }
case confirmpaymentstarted: {
if (nonOptionArgs.size() < 2)
throw new IllegalArgumentException("incorrect parameter count, expecting trade id");
@@ -427,6 +441,7 @@ private static void printHelp(OptionParser parser, PrintStream stream) {
stream.format(rowFormat, "getoffer", "offer id", "Get current offer with id");
stream.format(rowFormat, "getoffers", "buy | sell, currency code", "Get current offers");
stream.format(rowFormat, "takeoffer", "offer id", "Take offer with id");
+ stream.format(rowFormat, "gettrade", "trade id", "Get trade details and protocol status");
stream.format(rowFormat, "confirmpaymentstarted", "trade id", "Confirm payment started");
stream.format(rowFormat, "confirmpaymentreceived", "trade id", "Confirm payment received");
stream.format(rowFormat, "createpaymentacct", "account name, account number, currency code", "Create PerfectMoney dummy account");
From a2b292318cfbe753f8aca403051a59d7ddc8b8d2 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sun, 25 Oct 2020 17:44:18 -0300
Subject: [PATCH 15/30] Add boolean 'showcontract' argument to api's 'gettrade'
Optionally print the json contract for a given trade id.
---
cli/src/main/java/bisq/cli/CliMain.java | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java
index b7a5d80e216..f72fd26eb58 100644
--- a/cli/src/main/java/bisq/cli/CliMain.java
+++ b/cli/src/main/java/bisq/cli/CliMain.java
@@ -279,14 +279,21 @@ public static void run(String[] args) {
}
case gettrade: {
if (nonOptionArgs.size() < 2)
- throw new IllegalArgumentException("incorrect parameter count, expecting trade id");
+ throw new IllegalArgumentException("incorrect parameter count, expecting trade id, [,showcontract = true|false]");
var tradeId = nonOptionArgs.get(1);
+ var showContract = false;
+ if (nonOptionArgs.size() == 3)
+ showContract = Boolean.getBoolean(nonOptionArgs.get(2));
+
var request = GetTradeRequest.newBuilder()
.setTradeId(tradeId)
.build();
var reply = tradesService.getTrade(request);
- out.println(TradeFormat.format(reply.getTrade()));
+ if (showContract)
+ out.println(reply.getTrade().getContractAsJson());
+ else
+ out.println(TradeFormat.format(reply.getTrade()));
return;
}
case confirmpaymentstarted: {
@@ -441,7 +448,7 @@ private static void printHelp(OptionParser parser, PrintStream stream) {
stream.format(rowFormat, "getoffer", "offer id", "Get current offer with id");
stream.format(rowFormat, "getoffers", "buy | sell, currency code", "Get current offers");
stream.format(rowFormat, "takeoffer", "offer id", "Take offer with id");
- stream.format(rowFormat, "gettrade", "trade id", "Get trade details and protocol status");
+ stream.format(rowFormat, "gettrade", "trade id [,showcontract]", "Get trade summary or full contract");
stream.format(rowFormat, "confirmpaymentstarted", "trade id", "Confirm payment started");
stream.format(rowFormat, "confirmpaymentreceived", "trade id", "Confirm payment received");
stream.format(rowFormat, "createpaymentacct", "account name, account number, currency code", "Create PerfectMoney dummy account");
From a8decafc2ffd9956c273d35470d86866a29d810f Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 26 Oct 2020 17:43:08 -0300
Subject: [PATCH 16/30] Stub out api methods 'keepfunds', 'withdrawfunds'
This PR adds trade closing method stubs to keep funds in the
Bisq wallet or send them to an external BTC wallet.
- Add grpc protos
- Add new methods to GrpcTradesService, CoreApi
- Stub out implementations in CoreTradesService
- Add methods to CLI
---
cli/src/main/java/bisq/cli/CliMain.java | 32 +++++++++++++++++
core/src/main/java/bisq/core/api/CoreApi.java | 8 +++++
.../java/bisq/core/api/CoreTradesService.java | 10 ++++++
.../bisq/daemon/grpc/GrpcTradesService.java | 34 +++++++++++++++++++
proto/src/main/proto/grpc.proto | 19 +++++++++++
5 files changed, 103 insertions(+)
diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java
index f72fd26eb58..cecaadf0d56 100644
--- a/cli/src/main/java/bisq/cli/CliMain.java
+++ b/cli/src/main/java/bisq/cli/CliMain.java
@@ -29,12 +29,14 @@
import bisq.proto.grpc.GetPaymentAccountsRequest;
import bisq.proto.grpc.GetTradeRequest;
import bisq.proto.grpc.GetVersionRequest;
+import bisq.proto.grpc.KeepFundsRequest;
import bisq.proto.grpc.LockWalletRequest;
import bisq.proto.grpc.RegisterDisputeAgentRequest;
import bisq.proto.grpc.RemoveWalletPasswordRequest;
import bisq.proto.grpc.SetWalletPasswordRequest;
import bisq.proto.grpc.TakeOfferRequest;
import bisq.proto.grpc.UnlockWalletRequest;
+import bisq.proto.grpc.WithdrawFundsRequest;
import io.grpc.StatusRuntimeException;
@@ -78,6 +80,8 @@ private enum Method {
gettrade,
confirmpaymentstarted,
confirmpaymentreceived,
+ keepfunds,
+ withdrawfunds,
createpaymentacct,
getpaymentaccts,
getversion,
@@ -320,6 +324,32 @@ public static void run(String[] args) {
out.printf("trade '%s' payment received message sent", tradeId);
return;
}
+ case keepfunds: {
+ if (nonOptionArgs.size() < 2)
+ throw new IllegalArgumentException("incorrect parameter count, expecting trade id");
+
+ var tradeId = nonOptionArgs.get(1);
+ var request = KeepFundsRequest.newBuilder()
+ .setTradeId(tradeId)
+ .build();
+ tradesService.keepFunds(request);
+ out.printf("funds from trade '%s' saved in bisq wallet", tradeId);
+ return;
+ }
+ case withdrawfunds: {
+ if (nonOptionArgs.size() < 3)
+ throw new IllegalArgumentException("incorrect parameter count, expecting trade id, bitcoin wallet address");
+
+ var tradeId = nonOptionArgs.get(1);
+ var address = nonOptionArgs.get(2);
+ var request = WithdrawFundsRequest.newBuilder()
+ .setTradeId(tradeId)
+ .setAddress(address)
+ .build();
+ tradesService.withdrawFunds(request);
+ out.printf("funds from trade '%s' sent to btc address '%s'", tradeId, address);
+ return;
+ }
case createpaymentacct: {
if (nonOptionArgs.size() < 5)
throw new IllegalArgumentException(
@@ -451,6 +481,8 @@ private static void printHelp(OptionParser parser, PrintStream stream) {
stream.format(rowFormat, "gettrade", "trade id [,showcontract]", "Get trade summary or full contract");
stream.format(rowFormat, "confirmpaymentstarted", "trade id", "Confirm payment started");
stream.format(rowFormat, "confirmpaymentreceived", "trade id", "Confirm payment received");
+ stream.format(rowFormat, "keepfunds", "trade id", "Keep received funds in Bisq wallet");
+ stream.format(rowFormat, "withdrawfunds", "trade id, bitcoin wallet address", "Withdraw received funds to external wallet address");
stream.format(rowFormat, "createpaymentacct", "account name, account number, currency code", "Create PerfectMoney dummy account");
stream.format(rowFormat, "getpaymentaccts", "", "Get user payment accounts");
stream.format(rowFormat, "lockwallet", "", "Remove wallet password from memory, locking the wallet");
diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java
index 05886dd6e9e..001bf4773bc 100644
--- a/core/src/main/java/bisq/core/api/CoreApi.java
+++ b/core/src/main/java/bisq/core/api/CoreApi.java
@@ -189,6 +189,14 @@ public void confirmPaymentReceived(String tradeId) {
coreTradesService.confirmPaymentReceived(tradeId);
}
+ public void keepFunds(String tradeId) {
+ coreTradesService.keepFunds(tradeId);
+ }
+
+ public void withdrawFunds(String tradeId, String address) {
+ coreTradesService.withdrawFunds(tradeId, address);
+ }
+
public Trade getTrade(String tradeId) {
return coreTradesService.getTrade(tradeId);
}
diff --git a/core/src/main/java/bisq/core/api/CoreTradesService.java b/core/src/main/java/bisq/core/api/CoreTradesService.java
index 85877488315..88ab0128cd2 100644
--- a/core/src/main/java/bisq/core/api/CoreTradesService.java
+++ b/core/src/main/java/bisq/core/api/CoreTradesService.java
@@ -116,6 +116,16 @@ void confirmPaymentReceived(String tradeId) {
}
}
+ @SuppressWarnings("unused")
+ void keepFunds(String tradeId) {
+ log.info("TODO");
+ }
+
+ @SuppressWarnings("unused")
+ void withdrawFunds(String tradeId, String address) {
+ log.info("TODO");
+ }
+
String getTradeRole(String tradeId) {
return tradeUtil.getRole(getTrade(tradeId));
}
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java
index e23651bb207..74cd04ead93 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java
@@ -27,9 +27,13 @@
import bisq.proto.grpc.ConfirmPaymentStartedRequest;
import bisq.proto.grpc.GetTradeReply;
import bisq.proto.grpc.GetTradeRequest;
+import bisq.proto.grpc.KeepFundsReply;
+import bisq.proto.grpc.KeepFundsRequest;
import bisq.proto.grpc.TakeOfferReply;
import bisq.proto.grpc.TakeOfferRequest;
import bisq.proto.grpc.TradesGrpc;
+import bisq.proto.grpc.WithdrawFundsReply;
+import bisq.proto.grpc.WithdrawFundsRequest;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
@@ -119,4 +123,34 @@ public void confirmPaymentReceived(ConfirmPaymentReceivedRequest req,
throw ex;
}
}
+
+ @Override
+ public void keepFunds(KeepFundsRequest req,
+ StreamObserver responseObserver) {
+ try {
+ coreApi.keepFunds(req.getTradeId());
+ var reply = KeepFundsReply.newBuilder().build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ } catch (IllegalStateException | IllegalArgumentException cause) {
+ var ex = new StatusRuntimeException(Status.UNKNOWN.withDescription(cause.getMessage()));
+ responseObserver.onError(ex);
+ throw ex;
+ }
+ }
+
+ @Override
+ public void withdrawFunds(WithdrawFundsRequest req,
+ StreamObserver responseObserver) {
+ try {
+ coreApi.withdrawFunds(req.getTradeId(), req.getAddress());
+ var reply = WithdrawFundsReply.newBuilder().build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ } catch (IllegalStateException | IllegalArgumentException cause) {
+ var ex = new StatusRuntimeException(Status.UNKNOWN.withDescription(cause.getMessage()));
+ responseObserver.onError(ex);
+ throw ex;
+ }
+ }
}
diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto
index 041f1278ea2..006c6a6f111 100644
--- a/proto/src/main/proto/grpc.proto
+++ b/proto/src/main/proto/grpc.proto
@@ -180,6 +180,10 @@ service Trades {
}
rpc ConfirmPaymentReceived (ConfirmPaymentReceivedRequest) returns (ConfirmPaymentReceivedReply) {
}
+ rpc KeepFunds (KeepFundsRequest) returns (KeepFundsReply) {
+ }
+ rpc WithdrawFunds (WithdrawFundsRequest) returns (WithdrawFundsReply) {
+ }
}
message TakeOfferRequest {
@@ -213,6 +217,21 @@ message GetTradeReply {
TradeInfo trade = 1;
}
+message KeepFundsRequest {
+ string tradeId = 1;
+}
+
+message KeepFundsReply {
+}
+
+message WithdrawFundsRequest {
+ string tradeId = 1;
+ string address = 2;
+}
+
+message WithdrawFundsReply {
+}
+
message TradeInfo {
OfferInfo offer = 1;
string tradeId = 2;
From a3631a022f477cd2e9a00134be978c75a0ce3ec4 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 26 Oct 2020 20:44:39 -0300
Subject: [PATCH 17/30] Implement api methods 'keepfunds', 'withdrawfunds'
The CoreTradesService was refactored to work for newly added api methods:
- keepfunds -- close trade, keep funds in bisq wallet
- withdrawfunds -- close trade, withdraw funds to external btc wallet
A getKey accessor was added to CoreWalletsService (needed by withdrawfunds impl).
---
.../java/bisq/core/api/CoreTradesService.java | 120 ++++++++++++++++--
.../bisq/core/api/CoreWalletsService.java | 6 +
2 files changed, 118 insertions(+), 8 deletions(-)
diff --git a/core/src/main/java/bisq/core/api/CoreTradesService.java b/core/src/main/java/bisq/core/api/CoreTradesService.java
index 88ab0128cd2..1b58334466b 100644
--- a/core/src/main/java/bisq/core/api/CoreTradesService.java
+++ b/core/src/main/java/bisq/core/api/CoreTradesService.java
@@ -17,36 +17,57 @@
package bisq.core.api;
+import bisq.core.btc.model.AddressEntry;
+import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.offer.Offer;
import bisq.core.offer.takeoffer.TakeOfferModel;
import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;
import bisq.core.trade.TradeUtil;
+import bisq.core.trade.closed.ClosedTradableManager;
import bisq.core.trade.protocol.BuyerProtocol;
import bisq.core.trade.protocol.SellerProtocol;
import bisq.core.user.User;
+import bisq.core.util.validation.BtcAddressValidator;
+
+import org.bitcoinj.core.Coin;
import javax.inject.Inject;
+import java.util.Optional;
import java.util.function.Consumer;
import lombok.extern.slf4j.Slf4j;
+import static bisq.core.btc.model.AddressEntry.Context.TRADE_PAYOUT;
import static java.lang.String.format;
@Slf4j
class CoreTradesService {
+ // Dependencies on core api services in this package must be kept to an absolute
+ // minimum, but some trading functions require an unlocked wallet's key, so an
+ // exception is made in this case.
+ private final CoreWalletsService coreWalletsService;
+
+ private final BtcWalletService btcWalletService;
+ private final ClosedTradableManager closedTradableManager;
private final TakeOfferModel takeOfferModel;
private final TradeManager tradeManager;
private final TradeUtil tradeUtil;
private final User user;
@Inject
- public CoreTradesService(TakeOfferModel takeOfferModel,
+ public CoreTradesService(CoreWalletsService coreWalletsService,
+ BtcWalletService btcWalletService,
+ ClosedTradableManager closedTradableManager,
+ TakeOfferModel takeOfferModel,
TradeManager tradeManager,
TradeUtil tradeUtil,
User user) {
+ this.coreWalletsService = coreWalletsService;
+ this.btcWalletService = btcWalletService;
+ this.closedTradableManager = closedTradableManager;
this.takeOfferModel = takeOfferModel;
this.tradeManager = tradeManager;
this.tradeUtil = tradeUtil;
@@ -116,14 +137,50 @@ void confirmPaymentReceived(String tradeId) {
}
}
- @SuppressWarnings("unused")
void keepFunds(String tradeId) {
- log.info("TODO");
+ verifyTradeIsNotClosed(tradeId);
+ var trade = getOpenTrade(tradeId).orElseThrow(() ->
+ new IllegalArgumentException(format("trade with id '%s' not found", tradeId)));
+ log.info("Keeping funds received from trade {}", tradeId);
+ tradeManager.onTradeCompleted(trade);
}
- @SuppressWarnings("unused")
- void withdrawFunds(String tradeId, String address) {
- log.info("TODO");
+ void withdrawFunds(String tradeId, String toAddress) {
+ // An encrypted wallet must be unlocked for this operation.
+ verifyTradeIsNotClosed(tradeId);
+ var trade = getOpenTrade(tradeId).orElseThrow(() ->
+ new IllegalArgumentException(format("trade with id '%s' not found", tradeId)));
+
+ verifyIsValidBTCAddress(toAddress);
+
+ var fromAddressEntry = btcWalletService.getOrCreateAddressEntry(trade.getId(), TRADE_PAYOUT);
+ verifyFundsNotWithdrawn(fromAddressEntry);
+
+ var amount = trade.getPayoutAmount();
+ var fee = getEstimatedTxFee(fromAddressEntry.getAddressString(), toAddress, amount);
+ var receiverAmount = amount.subtract(fee);
+
+ log.info(format("Withdrawing funds received from trade %s:"
+ + "%n From %s%n To %s%n Amt %s%n Tx Fee %s%n Receiver Amt %s",
+ tradeId,
+ fromAddressEntry.getAddressString(),
+ toAddress,
+ amount.toFriendlyString(),
+ fee.toFriendlyString(),
+ receiverAmount.toFriendlyString()));
+
+ tradeManager.onWithdrawRequest(
+ toAddress,
+ amount,
+ fee,
+ coreWalletsService.getKey(),
+ trade,
+ () -> {
+ },
+ (errorMessage, throwable) -> {
+ log.error(errorMessage, throwable);
+ throw new IllegalStateException(errorMessage, throwable);
+ });
}
String getTradeRole(String tradeId) {
@@ -131,11 +188,58 @@ String getTradeRole(String tradeId) {
}
Trade getTrade(String tradeId) {
- return tradeManager.getTradeById(tradeId).orElseThrow(() ->
- new IllegalArgumentException(format("trade with id '%s' not found", tradeId)));
+ return getOpenTrade(tradeId).orElseGet(() ->
+ getClosedTrade(tradeId).orElseThrow(() ->
+ new IllegalArgumentException(format("trade with id '%s' not found", tradeId))
+ ));
+ }
+
+ private Optional getOpenTrade(String tradeId) {
+ return tradeManager.getTradeById(tradeId);
+ }
+
+ private Optional getClosedTrade(String tradeId) {
+ return closedTradableManager.getTradableById(tradeId).map(value -> (Trade) value);
}
private boolean isFollowingBuyerProtocol(Trade trade) {
return tradeManager.getTradeProtocol(trade) instanceof BuyerProtocol;
}
+
+ private Coin getEstimatedTxFee(String fromAddress, String toAddress, Coin amount) {
+ // TODO This and identical logic should be refactored into TradeUtil.
+ try {
+ return btcWalletService.getFeeEstimationTransaction(fromAddress,
+ toAddress,
+ amount,
+ TRADE_PAYOUT).getFee();
+ } catch (Exception ex) {
+ log.error("", ex);
+ throw new IllegalStateException(format("could not estimate tx fee: %s", ex.getMessage()));
+ }
+ }
+
+ // Throws a RuntimeException trade is already closed.
+ private void verifyTradeIsNotClosed(String tradeId) {
+ if (getClosedTrade(tradeId).isPresent())
+ throw new IllegalArgumentException(format("trade '%s' is already closed", tradeId));
+ }
+
+ // Throws a RuntimeException if address is not valid.
+ private void verifyIsValidBTCAddress(String address) {
+ try {
+ new BtcAddressValidator().validate(address);
+ } catch (Throwable t) {
+ log.error("", t);
+ throw new IllegalArgumentException(format("'%s' is not a valid btc address", address));
+ }
+ }
+
+ // Throws a RuntimeException if address has a zero balance.
+ private void verifyFundsNotWithdrawn(AddressEntry fromAddressEntry) {
+ Coin fromAddressBalance = btcWalletService.getBalanceForAddress(fromAddressEntry.getAddress());
+ if (fromAddressBalance.isZero())
+ throw new IllegalStateException(format("funds already withdrawn from address '%s'",
+ fromAddressEntry.getAddressString()));
+ }
}
diff --git a/core/src/main/java/bisq/core/api/CoreWalletsService.java b/core/src/main/java/bisq/core/api/CoreWalletsService.java
index 0f1e1db0844..29394aad8ac 100644
--- a/core/src/main/java/bisq/core/api/CoreWalletsService.java
+++ b/core/src/main/java/bisq/core/api/CoreWalletsService.java
@@ -71,6 +71,12 @@ public CoreWalletsService(Balances balances,
this.btcWalletService = btcWalletService;
}
+ @Nullable
+ KeyParameter getKey() {
+ verifyEncryptedWalletIsUnlocked();
+ return tempAesKey;
+ }
+
long getAvailableBalance() {
verifyWalletsAreAvailable();
verifyEncryptedWalletIsUnlocked();
From f1db254073577ac656a0bbd59cdc6246502d4bfa Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 27 Oct 2020 13:01:33 -0300
Subject: [PATCH 18/30] Make formatSatoshis visible for testing
---
cli/src/main/java/bisq/cli/CurrencyFormat.java | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java
index 798af169d40..e4d8f89c6c7 100644
--- a/cli/src/main/java/bisq/cli/CurrencyFormat.java
+++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java
@@ -17,6 +17,8 @@
package bisq.cli;
+import com.google.common.annotations.VisibleForTesting;
+
import java.text.DecimalFormat;
import java.text.NumberFormat;
@@ -27,15 +29,17 @@
import static java.lang.String.format;
-class CurrencyFormat {
+@VisibleForTesting
+public class CurrencyFormat {
private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance(Locale.US);
static final BigDecimal SATOSHI_DIVISOR = new BigDecimal(100000000);
static final DecimalFormat BTC_FORMAT = new DecimalFormat("###,##0.00000000");
+ @VisibleForTesting
@SuppressWarnings("BigDecimalMethodWithoutRoundingCalled")
- static String formatSatoshis(long sats) {
+ public static String formatSatoshis(long sats) {
return BTC_FORMAT.format(BigDecimal.valueOf(sats).divide(SATOSHI_DIVISOR));
}
From b8ae566b69578405cc87b8c08c362c98abb3ac99 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 27 Oct 2020 13:03:48 -0300
Subject: [PATCH 19/30] Add method for printing current jupiter test name
---
apitest/src/test/java/bisq/apitest/ApiTestCase.java | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/apitest/src/test/java/bisq/apitest/ApiTestCase.java b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
index 854ce4c59bc..7f84772f543 100644
--- a/apitest/src/test/java/bisq/apitest/ApiTestCase.java
+++ b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
@@ -26,6 +26,8 @@
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
+import org.junit.jupiter.api.TestInfo;
+
import static java.util.Arrays.stream;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -117,4 +119,10 @@ protected static void sleep(long ms) {
// empty
}
}
+
+ protected final String testName(TestInfo testInfo) {
+ return testInfo.getTestMethod().isPresent()
+ ? testInfo.getTestMethod().get().getName()
+ : "unknown test name";
+ }
}
From 1e25be5bdc40073921de795191b8f7327f494e5e Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 27 Oct 2020 13:04:53 -0300
Subject: [PATCH 20/30] Test trade closing api methods 'keepfunds'
withdrawfunds'
Some refactoring of the api test case hierarchy is included in this commit.
---
.../java/bisq/apitest/method/MethodTest.java | 45 ++++++++
.../method/offer/AbstractOfferTest.java | 3 -
.../method/trade/AbstractTradeTest.java | 107 +++++++++++++++++-
.../method/trade/TakeBuyBTCOfferTest.java | 93 ++++++++-------
.../method/trade/TakeSellBTCOfferTest.java | 103 ++++++++++-------
5 files changed, 261 insertions(+), 90 deletions(-)
diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
index 6a175d118ce..64f6710c7e2 100644
--- a/apitest/src/test/java/bisq/apitest/method/MethodTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
@@ -25,6 +25,7 @@
import bisq.proto.grpc.GetOfferRequest;
import bisq.proto.grpc.GetPaymentAccountsRequest;
import bisq.proto.grpc.GetTradeRequest;
+import bisq.proto.grpc.KeepFundsRequest;
import bisq.proto.grpc.LockWalletRequest;
import bisq.proto.grpc.MarketPriceRequest;
import bisq.proto.grpc.OfferInfo;
@@ -34,11 +35,16 @@
import bisq.proto.grpc.TakeOfferRequest;
import bisq.proto.grpc.TradeInfo;
import bisq.proto.grpc.UnlockWalletRequest;
+import bisq.proto.grpc.WithdrawFundsRequest;
import protobuf.PaymentAccount;
import java.util.stream.Collectors;
+import org.junit.jupiter.api.BeforeEach;
+
+import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static bisq.apitest.config.BisqAppConfig.bobdaemon;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
import static bisq.core.payment.payload.PaymentMethod.PERFECT_MONEY;
import static java.util.Comparator.comparing;
@@ -48,6 +54,7 @@
import bisq.apitest.ApiTestCase;
import bisq.apitest.config.BisqAppConfig;
+import bisq.cli.GrpcStubs;
public class MethodTest extends ApiTestCase {
@@ -55,6 +62,18 @@ public class MethodTest extends ApiTestCase {
protected static final String MEDIATOR = "mediator";
protected static final String REFUND_AGENT = "refundagent";
+ protected static GrpcStubs aliceStubs;
+ protected static GrpcStubs bobStubs;
+
+ protected PaymentAccount alicesDummyAcct;
+ protected PaymentAccount bobsDummyAcct;
+
+ @BeforeEach
+ public void initDummyPaymentAccounts() {
+ alicesDummyAcct = getDefaultPerfectDummyPaymentAccount(alicedaemon);
+ bobsDummyAcct = getDefaultPerfectDummyPaymentAccount(bobdaemon);
+ }
+
// Convenience methods for building gRPC request objects
protected final GetBalanceRequest createBalanceRequest() {
@@ -109,6 +128,19 @@ protected final ConfirmPaymentReceivedRequest createConfirmPaymentReceivedReques
return ConfirmPaymentReceivedRequest.newBuilder().setTradeId(tradeId).build();
}
+ protected final KeepFundsRequest createKeepFundsRequest(String tradeId) {
+ return KeepFundsRequest.newBuilder()
+ .setTradeId(tradeId)
+ .build();
+ }
+
+ protected final WithdrawFundsRequest createWithdrawFundsRequest(String tradeId, String address) {
+ return WithdrawFundsRequest.newBuilder()
+ .setTradeId(tradeId)
+ .setAddress(address)
+ .build();
+ }
+
// Convenience methods for calling frequently used & thoroughly tested gRPC services.
protected final long getBalance(BisqAppConfig bisqAppConfig) {
@@ -175,16 +207,29 @@ protected final TradeInfo getTrade(BisqAppConfig bisqAppConfig, String tradeId)
return grpcStubs(bisqAppConfig).tradesService.getTrade(req).getTrade();
}
+ @SuppressWarnings("ResultOfMethodCallIgnored")
protected final void confirmPaymentStarted(BisqAppConfig bisqAppConfig, String tradeId) {
var req = createConfirmPaymentStartedRequest(tradeId);
grpcStubs(bisqAppConfig).tradesService.confirmPaymentStarted(req);
}
+ @SuppressWarnings("ResultOfMethodCallIgnored")
protected final void confirmPaymentReceived(BisqAppConfig bisqAppConfig, String tradeId) {
var req = createConfirmPaymentReceivedRequest(tradeId);
grpcStubs(bisqAppConfig).tradesService.confirmPaymentReceived(req);
}
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ protected final void keepFunds(BisqAppConfig bisqAppConfig, String tradeId) {
+ var req = createKeepFundsRequest(tradeId);
+ grpcStubs(bisqAppConfig).tradesService.keepFunds(req);
+ }
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ protected final void withdrawFunds(BisqAppConfig bisqAppConfig, String tradeId, String address) {
+ var req = createWithdrawFundsRequest(tradeId, address);
+ grpcStubs(bisqAppConfig).tradesService.withdrawFunds(req);
+ }
// Static conveniences for test methods and test case fixture setups.
protected static RegisterDisputeAgentRequest createRegisterDisputeAgentRequest(String disputeAgentType) {
diff --git a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
index 979d7a33e6a..bc233721d0f 100644
--- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
@@ -59,9 +59,6 @@
@Slf4j
public abstract class AbstractOfferTest extends MethodTest {
- protected static GrpcStubs aliceStubs;
- protected static GrpcStubs bobStubs;
-
@BeforeAll
public static void setUp() {
startSupportingApps();
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
index 094007abd40..7e4c22e9689 100644
--- a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
@@ -4,6 +4,12 @@
import bisq.proto.grpc.TradeInfo;
+import org.slf4j.Logger;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.TestInfo;
+
+import static bisq.cli.TradeFormat.format;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -13,19 +19,110 @@
public class AbstractTradeTest extends AbstractOfferTest {
+ // A test fixture encapsulating expected trade protocol status.
+ // ExpectedProtocolStatus.init should be called before any @Test begins.
+ protected static final ExpectedProtocolStatus EXPECTED_PROTOCOL_STATUS = new ExpectedProtocolStatus();
+
+ // A Trade ID cache for use in @Test sequences.
+ protected static String tradeId;
+
+ @BeforeAll
+ public static void clearExpectedPaymentStatusFlags() {
+ EXPECTED_PROTOCOL_STATUS.init();
+ }
+
protected final TradeInfo takeAlicesOffer(String offerId, String paymentAccountId) {
return bobStubs.tradesService.takeOffer(createTakeOfferRequest(offerId, paymentAccountId)).getTrade();
}
+ @SuppressWarnings("unused")
protected final TradeInfo takeBobsOffer(String offerId, String paymentAccountId) {
return aliceStubs.tradesService.takeOffer(createTakeOfferRequest(offerId, paymentAccountId)).getTrade();
}
- protected final void verifyExpectedTradeStateAndPhase(TradeInfo trade,
- Trade.State expectedState,
- Trade.Phase expectedPhase) {
+ protected final void verifyExpectedProtocolStatus(TradeInfo trade) {
assertNotNull(trade);
- assertEquals(expectedState.name(), trade.getState());
- assertEquals(expectedPhase.name(), trade.getPhase());
+ assertEquals(EXPECTED_PROTOCOL_STATUS.state.name(), trade.getState());
+ assertEquals(EXPECTED_PROTOCOL_STATUS.phase.name(), trade.getPhase());
+ assertEquals(EXPECTED_PROTOCOL_STATUS.isDepositPublished, trade.getIsDepositPublished());
+ assertEquals(EXPECTED_PROTOCOL_STATUS.isDepositConfirmed, trade.getIsDepositConfirmed());
+ assertEquals(EXPECTED_PROTOCOL_STATUS.isFiatSent, trade.getIsFiatSent());
+ assertEquals(EXPECTED_PROTOCOL_STATUS.isFiatReceived, trade.getIsFiatReceived());
+ assertEquals(EXPECTED_PROTOCOL_STATUS.isPayoutPublished, trade.getIsPayoutPublished());
+ assertEquals(EXPECTED_PROTOCOL_STATUS.isWithdrawn, trade.getIsWithdrawn());
+ }
+
+ protected final void logTrade(Logger log,
+ TestInfo testInfo,
+ String description,
+ TradeInfo trade) {
+ log.info(String.format("%s %s%n%s",
+ testName(testInfo),
+ description.toUpperCase(),
+ format(trade)));
+ }
+
+ @SuppressWarnings("UnusedReturnValue")
+ static class ExpectedProtocolStatus {
+ Trade.State state;
+ Trade.Phase phase;
+ boolean isDepositPublished;
+ boolean isDepositConfirmed;
+ boolean isFiatSent;
+ boolean isFiatReceived;
+ boolean isPayoutPublished;
+ boolean isWithdrawn;
+
+ ExpectedProtocolStatus setState(Trade.State state) {
+ this.state = state;
+ return this;
+ }
+
+ ExpectedProtocolStatus setPhase(Trade.Phase phase) {
+ this.phase = phase;
+ return this;
+ }
+
+ ExpectedProtocolStatus setDepositPublished(boolean depositPublished) {
+ isDepositPublished = depositPublished;
+ return this;
+ }
+
+ ExpectedProtocolStatus setDepositConfirmed(boolean depositConfirmed) {
+ isDepositConfirmed = depositConfirmed;
+ return this;
+ }
+
+ ExpectedProtocolStatus setFiatSent(boolean fiatSent) {
+ isFiatSent = fiatSent;
+ return this;
+ }
+
+ ExpectedProtocolStatus setFiatReceived(boolean fiatReceived) {
+ isFiatReceived = fiatReceived;
+ return this;
+ }
+
+ ExpectedProtocolStatus setPayoutPublished(boolean payoutPublished) {
+ isPayoutPublished = payoutPublished;
+ return this;
+ }
+
+ ExpectedProtocolStatus setWithdrawn(boolean withdrawn) {
+ isWithdrawn = withdrawn;
+ return this;
+ }
+
+ @SuppressWarnings("unused")
+ void init() {
+ state = null;
+ phase = null;
+ isDepositPublished = false;
+ isDepositConfirmed = false;
+ isFiatSent = false;
+ isFiatReceived = false;
+ isPayoutPublished = false;
+ isWithdrawn = false;
+ }
}
}
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java
index 4aba67fc715..bb7d8ea8239 100644
--- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java
@@ -17,30 +17,24 @@
package bisq.apitest.method.trade;
-import protobuf.PaymentAccount;
-
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.TestMethodOrder;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
-import static bisq.cli.TradeFormat.format;
+import static bisq.cli.CurrencyFormat.formatSatoshis;
import static bisq.core.trade.Trade.Phase.DEPOSIT_CONFIRMED;
import static bisq.core.trade.Trade.Phase.DEPOSIT_PUBLISHED;
import static bisq.core.trade.Trade.Phase.FIAT_SENT;
import static bisq.core.trade.Trade.Phase.PAYOUT_PUBLISHED;
-import static bisq.core.trade.Trade.State.BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG;
-import static bisq.core.trade.Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN;
-import static bisq.core.trade.Trade.State.SELLER_PUBLISHED_DEPOSIT_TX;
-import static bisq.core.trade.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG;
-import static java.lang.System.out;
+import static bisq.core.trade.Trade.State.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
@@ -53,22 +47,14 @@ public class TakeBuyBTCOfferTest extends AbstractTradeTest {
// Alice is buyer, Bob is seller.
- private static String tradeId;
-
- private PaymentAccount alicesAccount;
- private PaymentAccount bobsAccount;
-
- @BeforeEach
- public void init() {
- alicesAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
- bobsAccount = getDefaultPerfectDummyPaymentAccount(bobdaemon);
- }
-
@Test
@Order(1)
- public void testTakeAlicesBuyOffer() {
+ public void testTakeAlicesBuyOffer(final TestInfo testInfo) {
try {
- var alicesOffer = createAliceOffer(alicesAccount, "buy", "usd", 12500000);
+ var alicesOffer = createAliceOffer(alicesDummyAcct,
+ "buy",
+ "usd",
+ 12500000);
var offerId = alicesOffer.getId();
// Wait for Alice's AddToOfferBook task.
@@ -76,7 +62,7 @@ public void testTakeAlicesBuyOffer() {
sleep(3000);
assertEquals(1, getOpenOffersCount(aliceStubs, "buy", "usd"));
- var trade = takeAlicesOffer(offerId, bobsAccount.getId());
+ var trade = takeAlicesOffer(offerId, bobsDummyAcct.getId());
assertNotNull(trade);
assertEquals(offerId, trade.getTradeId());
// Cache the trade id for the other tests.
@@ -86,13 +72,19 @@ public void testTakeAlicesBuyOffer() {
assertEquals(0, getOpenOffersCount(aliceStubs, "buy", "usd"));
trade = getTrade(bobdaemon, trade.getTradeId());
- verifyExpectedTradeStateAndPhase(trade, SELLER_PUBLISHED_DEPOSIT_TX, DEPOSIT_PUBLISHED);
- out.println(format(trade));
+ EXPECTED_PROTOCOL_STATUS.setState(SELLER_PUBLISHED_DEPOSIT_TX)
+ .setPhase(DEPOSIT_PUBLISHED)
+ .setDepositPublished(true);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Bob's view after taking offer and sending deposit", trade);
genBtcBlocksThenWait(1, 2250);
trade = getTrade(bobdaemon, trade.getTradeId());
- verifyExpectedTradeStateAndPhase(trade, DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN, DEPOSIT_CONFIRMED);
- out.println(format(trade));
+ EXPECTED_PROTOCOL_STATUS.setState(DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN)
+ .setPhase(DEPOSIT_CONFIRMED)
+ .setDepositConfirmed(true);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Bob's view after deposit is confirmed", trade);
} catch (StatusRuntimeException e) {
fail(e);
}
@@ -100,18 +92,19 @@ public void testTakeAlicesBuyOffer() {
@Test
@Order(2)
- public void testAlicesConfirmPaymentStarted() {
+ public void testAlicesConfirmPaymentStarted(final TestInfo testInfo) {
try {
var trade = getTrade(alicedaemon, tradeId);
- assertNotNull(trade);
-
confirmPaymentStarted(alicedaemon, trade.getTradeId());
sleep(3000);
trade = getTrade(alicedaemon, tradeId);
assertEquals(OFFER_FEE_PAID.name(), trade.getOffer().getState());
- verifyExpectedTradeStateAndPhase(trade, BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG, FIAT_SENT);
- out.println(format(trade));
+ EXPECTED_PROTOCOL_STATUS.setState(BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG)
+ .setPhase(FIAT_SENT)
+ .setFiatSent(true);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Alice's view after confirming fiat payment sent", trade);
} catch (StatusRuntimeException e) {
fail(e);
}
@@ -119,17 +112,41 @@ public void testAlicesConfirmPaymentStarted() {
@Test
@Order(3)
- public void testBobsConfirmPaymentReceived() {
+ public void testBobsConfirmPaymentReceived(final TestInfo testInfo) {
var trade = getTrade(bobdaemon, tradeId);
- assertNotNull(trade);
-
confirmPaymentReceived(bobdaemon, trade.getTradeId());
sleep(3000);
trade = getTrade(bobdaemon, tradeId);
- // TODO is this a bug? Why is offer.state == available?
+ // Note: offer.state == available
assertEquals(AVAILABLE.name(), trade.getOffer().getState());
- verifyExpectedTradeStateAndPhase(trade, SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG, PAYOUT_PUBLISHED);
- out.println(format(trade));
+ EXPECTED_PROTOCOL_STATUS.setState(SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG)
+ .setPhase(PAYOUT_PUBLISHED)
+ .setPayoutPublished(true)
+ .setFiatReceived(true);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Bob's view after confirming fiat payment received", trade);
+ }
+
+ @Test
+ @Order(4)
+ public void testAlicesKeepFunds(final TestInfo testInfo) {
+ genBtcBlocksThenWait(1, 2250);
+
+ var trade = getTrade(alicedaemon, tradeId);
+ logTrade(log, testInfo, "Alice's view before keeping funds", trade);
+
+ keepFunds(alicedaemon, tradeId);
+
+ genBtcBlocksThenWait(1, 2250);
+
+ trade = getTrade(alicedaemon, tradeId);
+ EXPECTED_PROTOCOL_STATUS.setState(BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG)
+ .setPhase(PAYOUT_PUBLISHED);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Alice's view after keeping funds", trade);
+ log.info("{} Alice's current available balance: {} BTC",
+ testName(testInfo),
+ formatSatoshis(getBalance(alicedaemon)));
}
}
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java
index 658b4083231..c1786082ba8 100644
--- a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java
@@ -17,30 +17,21 @@
package bisq.apitest.method.trade;
-import protobuf.PaymentAccount;
-
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.TestMethodOrder;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
-import static bisq.cli.TradeFormat.format;
-import static bisq.core.trade.Trade.Phase.DEPOSIT_CONFIRMED;
-import static bisq.core.trade.Trade.Phase.DEPOSIT_PUBLISHED;
-import static bisq.core.trade.Trade.Phase.FIAT_SENT;
-import static bisq.core.trade.Trade.Phase.PAYOUT_PUBLISHED;
-import static bisq.core.trade.Trade.State.BUYER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG;
-import static bisq.core.trade.Trade.State.BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG;
-import static bisq.core.trade.Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN;
-import static bisq.core.trade.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG;
-import static java.lang.System.out;
+import static bisq.cli.CurrencyFormat.formatSatoshis;
+import static bisq.core.trade.Trade.Phase.*;
+import static bisq.core.trade.Trade.State.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
@@ -53,22 +44,14 @@ public class TakeSellBTCOfferTest extends AbstractTradeTest {
// Alice is seller, Bob is buyer.
- private static String tradeId;
-
- private PaymentAccount alicesAccount;
- private PaymentAccount bobsAccount;
-
- @BeforeEach
- public void init() {
- alicesAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
- bobsAccount = getDefaultPerfectDummyPaymentAccount(bobdaemon);
- }
-
@Test
@Order(1)
- public void testTakeAlicesSellOffer() {
+ public void testTakeAlicesSellOffer(final TestInfo testInfo) {
try {
- var alicesOffer = createAliceOffer(alicesAccount, "sell", "usd", 12500000);
+ var alicesOffer = createAliceOffer(alicesDummyAcct,
+ "sell",
+ "usd",
+ 12500000);
var offerId = alicesOffer.getId();
// Wait for Alice's AddToOfferBook task.
@@ -77,7 +60,7 @@ public void testTakeAlicesSellOffer() {
sleep(3000);
assertEquals(1, getOpenOffersCount(bobStubs, "sell", "usd"));
- var trade = takeAlicesOffer(offerId, bobsAccount.getId());
+ var trade = takeAlicesOffer(offerId, bobsDummyAcct.getId());
assertNotNull(trade);
assertEquals(offerId, trade.getTradeId());
// Cache the trade id for the other tests.
@@ -87,14 +70,20 @@ public void testTakeAlicesSellOffer() {
assertEquals(0, getOpenOffersCount(bobStubs, "sell", "usd"));
trade = getTrade(bobdaemon, trade.getTradeId());
- verifyExpectedTradeStateAndPhase(trade, BUYER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG, DEPOSIT_PUBLISHED);
- out.println(format(trade));
+ EXPECTED_PROTOCOL_STATUS.setState(BUYER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG)
+ .setPhase(DEPOSIT_PUBLISHED)
+ .setDepositPublished(true);
+ verifyExpectedProtocolStatus(trade);
+
+ logTrade(log, testInfo, "Bob's view after taking offer and sending deposit", trade);
genBtcBlocksThenWait(1, 2250);
trade = getTrade(bobdaemon, trade.getTradeId());
- verifyExpectedTradeStateAndPhase(trade, DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN, DEPOSIT_CONFIRMED);
- out.println(format(trade));
-
+ EXPECTED_PROTOCOL_STATUS.setState(DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN)
+ .setPhase(DEPOSIT_CONFIRMED)
+ .setDepositConfirmed(true);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Bob's view after deposit is confirmed", trade);
} catch (StatusRuntimeException e) {
fail(e);
}
@@ -102,20 +91,20 @@ public void testTakeAlicesSellOffer() {
@Test
@Order(2)
- public void testBobsConfirmPaymentStarted() {
+ public void testBobsConfirmPaymentStarted(final TestInfo testInfo) {
try {
var trade = getTrade(bobdaemon, tradeId);
- assertNotNull(trade);
-
confirmPaymentStarted(bobdaemon, trade.getTradeId());
sleep(3000);
trade = getTrade(bobdaemon, tradeId);
- // TODO is this a bug? Why is offer.state == available?
+ // Note: offer.state == available
assertEquals(AVAILABLE.name(), trade.getOffer().getState());
- verifyExpectedTradeStateAndPhase(trade, BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG, FIAT_SENT);
-
- out.println(format(trade));
+ EXPECTED_PROTOCOL_STATUS.setState(BUYER_SAW_ARRIVED_FIAT_PAYMENT_INITIATED_MSG)
+ .setPhase(FIAT_SENT)
+ .setFiatSent(true);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Bob's view after confirming fiat payment sent", trade);
} catch (StatusRuntimeException e) {
fail(e);
}
@@ -123,16 +112,42 @@ public void testBobsConfirmPaymentStarted() {
@Test
@Order(3)
- public void testAlicesConfirmPaymentReceived() {
+ public void testAlicesConfirmPaymentReceived(final TestInfo testInfo) {
var trade = getTrade(alicedaemon, tradeId);
- assertNotNull(trade);
-
confirmPaymentReceived(alicedaemon, trade.getTradeId());
sleep(3000);
trade = getTrade(alicedaemon, tradeId);
assertEquals(OFFER_FEE_PAID.name(), trade.getOffer().getState());
- verifyExpectedTradeStateAndPhase(trade, SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG, PAYOUT_PUBLISHED);
- out.println(format(trade));
+ EXPECTED_PROTOCOL_STATUS.setState(SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG)
+ .setPhase(PAYOUT_PUBLISHED)
+ .setPayoutPublished(true)
+ .setFiatReceived(true);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Alice's view after confirming fiat payment received", trade);
+ }
+
+ @Test
+ @Order(4)
+ public void testBobsBtcWithdrawalToExternalAddress(final TestInfo testInfo) {
+ genBtcBlocksThenWait(1, 2250);
+
+ var trade = getTrade(bobdaemon, tradeId);
+ logTrade(log, testInfo, "Bob's view before withdrawing funds to external wallet", trade);
+
+ String toAddress = bitcoinCli.getNewBtcAddress();
+ withdrawFunds(bobdaemon, tradeId, toAddress);
+
+ genBtcBlocksThenWait(1, 2250);
+
+ trade = getTrade(bobdaemon, tradeId);
+ EXPECTED_PROTOCOL_STATUS.setState(WITHDRAW_COMPLETED)
+ .setPhase(WITHDRAWN)
+ .setWithdrawn(true);
+ verifyExpectedProtocolStatus(trade);
+ logTrade(log, testInfo, "Bob's view after withdrawing funds to external wallet", trade);
+ log.info("{} Bob's current available balance: {} BTC",
+ testName(testInfo),
+ formatSatoshis(getBalance(bobdaemon)));
}
}
From 2746b276744a6c282d96170326146ed298f1df97 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 27 Oct 2020 13:47:23 -0300
Subject: [PATCH 21/30] Fix apitest dummy payment acct init bug
This commit fixes non-trade tests broken by the last refactoring.
---
.../java/bisq/apitest/method/MethodTest.java | 8 ++---
.../method/RegisterDisputeAgentsTest.java | 12 +++-----
.../method/offer/AbstractOfferTest.java | 6 ++++
.../offer/CreateOfferUsingFixedPriceTest.java | 23 +++++++--------
...CreateOfferUsingMarketPriceMarginTest.java | 29 ++++++++-----------
.../method/offer/ValidateCreateOfferTest.java | 4 +--
.../method/trade/AbstractTradeTest.java | 7 +++++
7 files changed, 44 insertions(+), 45 deletions(-)
diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
index 64f6710c7e2..cf5b74c750c 100644
--- a/apitest/src/test/java/bisq/apitest/method/MethodTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
@@ -41,8 +41,6 @@
import java.util.stream.Collectors;
-import org.junit.jupiter.api.BeforeEach;
-
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
@@ -68,9 +66,11 @@ public class MethodTest extends ApiTestCase {
protected PaymentAccount alicesDummyAcct;
protected PaymentAccount bobsDummyAcct;
- @BeforeEach
- public void initDummyPaymentAccounts() {
+ protected final void initAlicesDummyPaymentAccount() {
alicesDummyAcct = getDefaultPerfectDummyPaymentAccount(alicedaemon);
+ }
+
+ protected final void initBobsDummyPaymentAccount() {
bobsDummyAcct = getDefaultPerfectDummyPaymentAccount(bobdaemon);
}
diff --git a/apitest/src/test/java/bisq/apitest/method/RegisterDisputeAgentsTest.java b/apitest/src/test/java/bisq/apitest/method/RegisterDisputeAgentsTest.java
index 9c875012080..379fbc3a004 100644
--- a/apitest/src/test/java/bisq/apitest/method/RegisterDisputeAgentsTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/RegisterDisputeAgentsTest.java
@@ -56,8 +56,7 @@ public static void setUp() {
@Test
@Order(1)
public void testRegisterArbitratorShouldThrowException() {
- var req =
- createRegisterDisputeAgentRequest(ARBITRATOR);
+ var req = createRegisterDisputeAgentRequest(ARBITRATOR);
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
assertEquals("INVALID_ARGUMENT: arbitrators must be registered in a Bisq UI",
@@ -67,8 +66,7 @@ public void testRegisterArbitratorShouldThrowException() {
@Test
@Order(2)
public void testInvalidDisputeAgentTypeArgShouldThrowException() {
- var req =
- createRegisterDisputeAgentRequest("badagent");
+ var req = createRegisterDisputeAgentRequest("badagent");
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
assertEquals("INVALID_ARGUMENT: unknown dispute agent type 'badagent'",
@@ -90,16 +88,14 @@ public void testInvalidRegistrationKeyArgShouldThrowException() {
@Test
@Order(4)
public void testRegisterMediator() {
- var req =
- createRegisterDisputeAgentRequest(MEDIATOR);
+ var req = createRegisterDisputeAgentRequest(MEDIATOR);
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req);
}
@Test
@Order(5)
public void testRegisterRefundAgent() {
- var req =
- createRegisterDisputeAgentRequest(REFUND_AGENT);
+ var req = createRegisterDisputeAgentRequest(REFUND_AGENT);
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req);
}
diff --git a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
index bc233721d0f..a08e08d0bc3 100644
--- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
@@ -36,6 +36,7 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
@@ -64,6 +65,11 @@ public static void setUp() {
startSupportingApps();
}
+ @BeforeEach
+ public void initDummyPaymentAccount() {
+ super.initAlicesDummyPaymentAccount();
+ }
+
static void startSupportingApps() {
try {
// setUpScaffold(new String[]{"--supportingApps", "bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon", "--enableBisqDebugging", "true"});
diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java
index 739faf71e96..10ca6c9e4cb 100644
--- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java
@@ -28,7 +28,6 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
-import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@@ -37,12 +36,12 @@
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class CreateOfferUsingFixedPriceTest extends AbstractOfferTest {
+
@Test
@Order(1)
public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() {
- var paymentAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
var req = CreateOfferRequest.newBuilder()
- .setPaymentAccountId(paymentAccount.getId())
+ .setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("buy")
.setCurrencyCode("aud")
.setAmount(10000000)
@@ -61,7 +60,7 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("AUD", newOffer.getCounterCurrencyCode());
@@ -73,7 +72,7 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("AUD", newOffer.getCounterCurrencyCode());
}
@@ -81,9 +80,8 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() {
@Test
@Order(2)
public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() {
- var paymentAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
var req = CreateOfferRequest.newBuilder()
- .setPaymentAccountId(paymentAccount.getId())
+ .setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("buy")
.setCurrencyCode("usd")
.setAmount(10000000)
@@ -102,7 +100,7 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("USD", newOffer.getCounterCurrencyCode());
@@ -114,7 +112,7 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("USD", newOffer.getCounterCurrencyCode());
}
@@ -122,9 +120,8 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() {
@Test
@Order(3)
public void testCreateEURBTCSellOfferUsingFixedPrice95001234() {
- var paymentAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
var req = CreateOfferRequest.newBuilder()
- .setPaymentAccountId(paymentAccount.getId())
+ .setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("sell")
.setCurrencyCode("eur")
.setAmount(10000000)
@@ -143,7 +140,7 @@ public void testCreateEURBTCSellOfferUsingFixedPrice95001234() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("EUR", newOffer.getCounterCurrencyCode());
@@ -155,7 +152,7 @@ public void testCreateEURBTCSellOfferUsingFixedPrice95001234() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("EUR", newOffer.getCounterCurrencyCode());
}
diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java
index f9d379131bb..b0c017baff0 100644
--- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java
@@ -31,7 +31,6 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
-import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.common.util.MathUtils.scaleDownByPowerOf10;
import static bisq.common.util.MathUtils.scaleUpByPowerOf10;
import static java.lang.Math.abs;
@@ -52,10 +51,9 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest {
@Test
@Order(1)
public void testCreateUSDBTCBuyOffer5PctPriceMargin() {
- var paymentAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
double priceMarginPctInput = 5.00;
var req = CreateOfferRequest.newBuilder()
- .setPaymentAccountId(paymentAccount.getId())
+ .setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("buy")
.setCurrencyCode("usd")
.setAmount(10000000)
@@ -73,7 +71,7 @@ public void testCreateUSDBTCBuyOffer5PctPriceMargin() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("USD", newOffer.getCounterCurrencyCode());
@@ -84,7 +82,7 @@ public void testCreateUSDBTCBuyOffer5PctPriceMargin() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("USD", newOffer.getCounterCurrencyCode());
@@ -94,10 +92,9 @@ public void testCreateUSDBTCBuyOffer5PctPriceMargin() {
@Test
@Order(2)
public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() {
- var paymentAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
double priceMarginPctInput = -2.00;
var req = CreateOfferRequest.newBuilder()
- .setPaymentAccountId(paymentAccount.getId())
+ .setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("buy")
.setCurrencyCode("nzd")
.setAmount(10000000)
@@ -115,7 +112,7 @@ public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("NZD", newOffer.getCounterCurrencyCode());
@@ -126,7 +123,7 @@ public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("NZD", newOffer.getCounterCurrencyCode());
@@ -136,10 +133,9 @@ public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() {
@Test
@Order(3)
public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() {
- var paymentAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
double priceMarginPctInput = -1.5;
var req = CreateOfferRequest.newBuilder()
- .setPaymentAccountId(paymentAccount.getId())
+ .setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("sell")
.setCurrencyCode("gbp")
.setAmount(10000000)
@@ -158,7 +154,7 @@ public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("GBP", newOffer.getCounterCurrencyCode());
@@ -169,7 +165,7 @@ public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("GBP", newOffer.getCounterCurrencyCode());
@@ -179,10 +175,9 @@ public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() {
@Test
@Order(4)
public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() {
- var paymentAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
double priceMarginPctInput = 6.55;
var req = CreateOfferRequest.newBuilder()
- .setPaymentAccountId(paymentAccount.getId())
+ .setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("sell")
.setCurrencyCode("brl")
.setAmount(10000000)
@@ -201,7 +196,7 @@ public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("BRL", newOffer.getCounterCurrencyCode());
@@ -212,7 +207,7 @@ public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() {
assertEquals(10000000, newOffer.getAmount());
assertEquals(10000000, newOffer.getMinAmount());
assertEquals(1500000, newOffer.getBuyerSecurityDeposit());
- assertEquals(paymentAccount.getId(), newOffer.getPaymentAccountId());
+ assertEquals(alicesDummyAcct.getId(), newOffer.getPaymentAccountId());
assertEquals("BTC", newOffer.getBaseCurrencyCode());
assertEquals("BRL", newOffer.getCounterCurrencyCode());
diff --git a/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java
index 785dc97fdcb..ecf09b1e421 100644
--- a/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java
@@ -30,7 +30,6 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
-import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -41,9 +40,8 @@ public class ValidateCreateOfferTest extends AbstractOfferTest {
@Test
@Order(1)
public void testAmtTooLargeShouldThrowException() {
- var paymentAccount = getDefaultPerfectDummyPaymentAccount(alicedaemon);
var req = CreateOfferRequest.newBuilder()
- .setPaymentAccountId(paymentAccount.getId())
+ .setPaymentAccountId(alicesDummyAcct.getId())
.setDirection("buy")
.setCurrencyCode("usd")
.setAmount(100000000000L)
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
index 7e4c22e9689..22aee1d70dd 100644
--- a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
@@ -7,6 +7,7 @@
import org.slf4j.Logger;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
import static bisq.cli.TradeFormat.format;
@@ -31,6 +32,12 @@ public static void clearExpectedPaymentStatusFlags() {
EXPECTED_PROTOCOL_STATUS.init();
}
+ @BeforeEach
+ public void initDummyPaymentAccounts() {
+ super.initAlicesDummyPaymentAccount();
+ super.initBobsDummyPaymentAccount();
+ }
+
protected final TradeInfo takeAlicesOffer(String offerId, String paymentAccountId) {
return bobStubs.tradesService.takeOffer(createTakeOfferRequest(offerId, paymentAccountId)).getTrade();
}
From 027a7d5cd3bfaf4afefbd92612c67356a43d6353 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 27 Oct 2020 14:54:50 -0300
Subject: [PATCH 22/30] Stub out canceloffer api method
The implementation will be added to CoreOffersService in the next PR.
---
cli/src/main/java/bisq/cli/CliMain.java | 17 ++++++++++++++++-
core/src/main/java/bisq/core/api/CoreApi.java | 4 ++++
.../java/bisq/core/api/CoreOffersService.java | 4 ++++
.../bisq/daemon/grpc/GrpcOffersService.java | 17 +++++++++++++++++
proto/src/main/proto/grpc.proto | 9 +++++++++
5 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java
index cecaadf0d56..8639c95602f 100644
--- a/cli/src/main/java/bisq/cli/CliMain.java
+++ b/cli/src/main/java/bisq/cli/CliMain.java
@@ -17,6 +17,7 @@
package bisq.cli;
+import bisq.proto.grpc.CancelOfferRequest;
import bisq.proto.grpc.ConfirmPaymentReceivedRequest;
import bisq.proto.grpc.ConfirmPaymentStartedRequest;
import bisq.proto.grpc.CreateOfferRequest;
@@ -74,6 +75,7 @@ public class CliMain {
private enum Method {
createoffer,
+ canceloffer,
getoffer,
getoffers,
takeoffer,
@@ -238,6 +240,18 @@ public static void run(String[] args) {
out.println(formatOfferTable(singletonList(reply.getOffer()), currencyCode));
return;
}
+ case canceloffer: {
+ if (nonOptionArgs.size() < 2)
+ throw new IllegalArgumentException("incorrect parameter count, expecting offer id");
+
+ var offerId = nonOptionArgs.get(1);
+ var request = CancelOfferRequest.newBuilder()
+ .setId(offerId)
+ .build();
+ offersService.cancelOffer(request);
+ out.println("offer canceled and removed from offer book");
+ return;
+ }
case getoffer: {
if (nonOptionArgs.size() < 2)
throw new IllegalArgumentException("incorrect parameter count, expecting offer id");
@@ -246,7 +260,7 @@ public static void run(String[] args) {
var request = GetOfferRequest.newBuilder()
.setId(offerId)
.build();
- var reply = offersService.getOffer(request);
+ var reply =offersService.getOffer(request);
out.println(formatOfferTable(singletonList(reply.getOffer()),
reply.getOffer().getCounterCurrencyCode()));
return;
@@ -475,6 +489,7 @@ private static void printHelp(OptionParser parser, PrintStream stream) {
stream.format(rowFormat, "", "amount (btc), min amount, use mkt based price, \\", "");
stream.format(rowFormat, "", "fixed price (btc) | mkt price margin (%), \\", "");
stream.format(rowFormat, "", "security deposit (%)", "");
+ stream.format(rowFormat, "canceloffer", "offer id", "Cancel offer with id");
stream.format(rowFormat, "getoffer", "offer id", "Get current offer with id");
stream.format(rowFormat, "getoffers", "buy | sell, currency code", "Get current offers");
stream.format(rowFormat, "takeoffer", "offer id", "Take offer with id");
diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java
index 001bf4773bc..7cfcc5ce152 100644
--- a/core/src/main/java/bisq/core/api/CoreApi.java
+++ b/core/src/main/java/bisq/core/api/CoreApi.java
@@ -142,6 +142,10 @@ public Offer editOffer(String offerId,
paymentAccount);
}
+ public void cancelOffer(String id) {
+ coreOffersService.cancelOffer(id);
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////
// PaymentAccounts
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java
index da07677f1b2..1a35af4ea2e 100644
--- a/core/src/main/java/bisq/core/api/CoreOffersService.java
+++ b/core/src/main/java/bisq/core/api/CoreOffersService.java
@@ -160,6 +160,10 @@ Offer editOffer(String offerId,
paymentAccount);
}
+ void cancelOffer(String id) {
+ log.info("TODO");
+ }
+
private void placeOffer(Offer offer,
double buyerSecurityDeposit,
boolean useSavingsWallet,
diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
index d7785935563..f03155d2f8d 100644
--- a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
@@ -21,6 +21,8 @@
import bisq.core.api.model.OfferInfo;
import bisq.core.offer.Offer;
+import bisq.proto.grpc.CancelOfferReply;
+import bisq.proto.grpc.CancelOfferRequest;
import bisq.proto.grpc.CreateOfferReply;
import bisq.proto.grpc.CreateOfferRequest;
import bisq.proto.grpc.GetOfferReply;
@@ -114,4 +116,19 @@ public void createOffer(CreateOfferRequest req,
throw ex;
}
}
+
+ @Override
+ public void cancelOffer(CancelOfferRequest req,
+ StreamObserver responseObserver) {
+ try {
+ coreApi.cancelOffer(req.getId());
+ var reply = CancelOfferReply.newBuilder().build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ } catch (IllegalStateException | IllegalArgumentException cause) {
+ var ex = new StatusRuntimeException(Status.UNKNOWN.withDescription(cause.getMessage()));
+ responseObserver.onError(ex);
+ throw ex;
+ }
+ }
}
diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto
index 006c6a6f111..d9e0a3973d8 100644
--- a/proto/src/main/proto/grpc.proto
+++ b/proto/src/main/proto/grpc.proto
@@ -51,6 +51,8 @@ service Offers {
}
rpc CreateOffer (CreateOfferRequest) returns (CreateOfferReply) {
}
+ rpc CancelOffer (CancelOfferRequest) returns (CancelOfferReply) {
+ }
}
message GetOfferRequest {
@@ -85,6 +87,13 @@ message CreateOfferReply {
OfferInfo offer = 1;
}
+message CancelOfferRequest {
+ string id = 1;
+}
+
+message CancelOfferReply {
+}
+
message OfferInfo {
string id = 1;
string direction = 2;
From 0f1d4f8ac38d0591c2e4c1b10608938b36c8619a Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 27 Oct 2020 15:03:36 -0300
Subject: [PATCH 23/30] Fix typo
---
cli/src/main/java/bisq/cli/CliMain.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java
index 8639c95602f..ec0e5e71bb6 100644
--- a/cli/src/main/java/bisq/cli/CliMain.java
+++ b/cli/src/main/java/bisq/cli/CliMain.java
@@ -260,7 +260,7 @@ public static void run(String[] args) {
var request = GetOfferRequest.newBuilder()
.setId(offerId)
.build();
- var reply =offersService.getOffer(request);
+ var reply = offersService.getOffer(request);
out.println(formatOfferTable(singletonList(reply.getOffer()),
reply.getOffer().getCounterCurrencyCode()));
return;
From b38507c6e68aca9176da48515633dcc613e80ddc Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 27 Oct 2020 15:31:57 -0300
Subject: [PATCH 24/30] Implement api method 'canceloffer'
---
core/src/main/java/bisq/core/api/CoreOffersService.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java
index 1a35af4ea2e..6d8641c0579 100644
--- a/core/src/main/java/bisq/core/api/CoreOffersService.java
+++ b/core/src/main/java/bisq/core/api/CoreOffersService.java
@@ -161,7 +161,13 @@ Offer editOffer(String offerId,
}
void cancelOffer(String id) {
- log.info("TODO");
+ Offer offer = getOffer(id);
+ openOfferManager.removeOffer(offer,
+ () -> {
+ },
+ errorMessage -> {
+ throw new IllegalStateException(errorMessage);
+ });
}
private void placeOffer(Offer offer,
From 91a2e2ce1ff0e900ac0ad91b92da1de420dc3171 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 27 Oct 2020 19:06:59 -0300
Subject: [PATCH 25/30] Add canceloffer test
---
.../java/bisq/apitest/method/MethodTest.java | 11 +++
.../method/offer/AbstractOfferTest.java | 5 ++
.../apitest/method/offer/CancelOfferTest.java | 81 +++++++++++++++++++
3 files changed, 97 insertions(+)
create mode 100644 apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java
diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
index cf5b74c750c..dcf438f245e 100644
--- a/apitest/src/test/java/bisq/apitest/method/MethodTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
@@ -17,6 +17,7 @@
package bisq.apitest.method;
+import bisq.proto.grpc.CancelOfferRequest;
import bisq.proto.grpc.ConfirmPaymentReceivedRequest;
import bisq.proto.grpc.ConfirmPaymentStartedRequest;
import bisq.proto.grpc.CreatePaymentAccountRequest;
@@ -112,6 +113,10 @@ protected final GetOfferRequest createGetOfferRequest(String offerId) {
return GetOfferRequest.newBuilder().setId(offerId).build();
}
+ protected final CancelOfferRequest createCancelOfferRequest(String offerId) {
+ return CancelOfferRequest.newBuilder().setId(offerId).build();
+ }
+
protected final TakeOfferRequest createTakeOfferRequest(String offerId, String paymentAccountId) {
return TakeOfferRequest.newBuilder().setOfferId(offerId).setPaymentAccountId(paymentAccountId).build();
}
@@ -202,6 +207,12 @@ protected final OfferInfo getOffer(BisqAppConfig bisqAppConfig, String offerId)
return grpcStubs(bisqAppConfig).offersService.getOffer(req).getOffer();
}
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ protected final void cancelOffer(BisqAppConfig bisqAppConfig, String offerId) {
+ var req = createCancelOfferRequest(offerId);
+ grpcStubs(bisqAppConfig).offersService.cancelOffer(req);
+ }
+
protected final TradeInfo getTrade(BisqAppConfig bisqAppConfig, String tradeId) {
var req = createGetTradeRequest(tradeId);
return grpcStubs(bisqAppConfig).tradesService.getTrade(req).getTrade();
diff --git a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
index a08e08d0bc3..b1bae6fbd86 100644
--- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
@@ -123,6 +123,11 @@ protected final OfferInfo getOffer(String offerId) {
return aliceStubs.offersService.getOffer(createGetOfferRequest(offerId)).getOffer();
}
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ protected final void cancelOffer(GrpcStubs grpcStubs, String offerId) {
+ grpcStubs.offersService.cancelOffer(createCancelOfferRequest(offerId));
+ }
+
protected final OfferInfo getMostRecentOffer(GrpcStubs grpcStubs, String direction, String currencyCode) {
List offerInfoList = getOffersSortedByDate(grpcStubs, direction, currencyCode);
if (offerInfoList.isEmpty())
diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java
new file mode 100644
index 00000000000..6affb9ac38a
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.apitest.method.offer;
+
+import bisq.core.btc.wallet.Restrictions;
+
+import bisq.proto.grpc.CreateOfferRequest;
+import bisq.proto.grpc.OfferInfo;
+
+import java.util.List;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+
+@Slf4j
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class CancelOfferTest extends AbstractOfferTest {
+
+ private static final int MAX_OFFERS = 3;
+
+ @Test
+ @Order(1)
+ public void testCancelOffer() {
+ var req = CreateOfferRequest.newBuilder()
+ .setPaymentAccountId(alicesDummyAcct.getId())
+ .setDirection("buy")
+ .setCurrencyCode("cad")
+ .setAmount(10000000)
+ .setMinAmount(10000000)
+ .setUseMarketBasedPrice(true)
+ .setMarketPriceMargin(0.00)
+ .setPrice("0")
+ .setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent())
+ .build();
+
+ // Create some offers.
+ for (int i = 1; i <= MAX_OFFERS; i++) {
+ //noinspection ResultOfMethodCallIgnored
+ aliceStubs.offersService.createOffer(req);
+ // Wait for Alice's AddToOfferBook task.
+ // Wait times vary; my logs show >= 2 second delay.
+ sleep(2500);
+ }
+
+ List offers = getOffersSortedByDate(aliceStubs, "buy", "cad");
+ assertEquals(MAX_OFFERS, offers.size());
+
+ // Cancel the offers, checking the open offer count after each offer removal.
+ for (int i = 1; i <= MAX_OFFERS; i++) {
+ cancelOffer(aliceStubs, offers.remove(0).getId());
+ assertEquals(MAX_OFFERS - i, getOpenOffersCount(aliceStubs, "buy", "cad"));
+ }
+
+ sleep(1000); // wait for offer removal
+
+ offers = getOffersSortedByDate(aliceStubs, "buy", "cad");
+ assertEquals(0, offers.size());
+ }
+}
From 8e51e1e495d79470defae2c9877f3a8d43cb095f Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 28 Oct 2020 17:21:04 -0300
Subject: [PATCH 26/30] Upgrade jupiterVersion = '5.7.0'
This upgrades jupiter for all subprojects using this library, but
it does not affect released code.
---
build.gradle | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/build.gradle b/build.gradle
index 6007dd14475..57624f26fe5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -55,7 +55,7 @@ configure(subprojects) {
joptVersion = '5.0.4'
jsonsimpleVersion = '1.1.1'
junitVersion = '4.12'
- jupiterVersion = '5.3.2'
+ jupiterVersion = '5.7.0'
kotlinVersion = '1.3.41'
knowmXchangeVersion = '4.4.2'
langVersion = '3.8'
@@ -658,12 +658,12 @@ configure(project(':apitest')) {
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
- testCompile "org.junit.jupiter:junit-jupiter-api:5.6.2"
- testCompile "org.junit.jupiter:junit-jupiter-params:5.6.2"
+ testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
+ testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
+ testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
testRuntime "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
- testRuntime("org.junit.jupiter:junit-jupiter-engine:5.6.2")
}
}
From d6524bf46d5e8a9960c1c992a12a106be8877401 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 28 Oct 2020 17:39:50 -0300
Subject: [PATCH 27/30] Improve apitest cmd line console logging
- Show full stack traces in console
- Do use previously cached test outputs
- Do not show skipped test name in console (too noisy)
- Show test run summary, including number of skipped tests
- Show note about skipped test info in the html report
- Show link to html report on test SUCCESS
---
build.gradle | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 57624f26fe5..56ede17a7b1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -627,8 +627,31 @@ configure(project(':apitest')) {
test {
useJUnitPlatform()
+ outputs.upToDateWhen { false } // Don't use previously cached test outputs.
testLogging {
- events "passed", "skipped", "failed"
+ showStackTraces = true // Show full stack traces in the console.
+ exceptionFormat = "full"
+ // Show passed & failed tests, and anything printed to stderr by the tests in the console.
+ // Do not show skipped tests in the console; they are shown in the html report.
+ events "passed", "failed", "standardError"
+ }
+
+ afterSuite { desc, result ->
+ if (!desc.parent) {
+ println("${result.resultType} " +
+ "[${result.testCount} tests, " +
+ "${result.successfulTestCount} passed, " +
+ "${result.failedTestCount} failed, " +
+ "${result.skippedTestCount} skipped] html report contains skipped test info")
+
+ // Show report link if all tests passed in case you want to see more detail, stdout, skipped, etc.
+ if(result.resultType == TestResult.ResultType.SUCCESS) {
+ DirectoryReport htmlReport = getReports().getHtml()
+ String reportUrl = new org.gradle.internal.logging.ConsoleRenderer()
+ .asClickableFileUrl(htmlReport.getEntryPoint())
+ println("REPORT " + reportUrl)
+ }
+ }
}
}
From 2a052035190081c51d561e4e431ffca2b68987ec Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 28 Oct 2020 17:46:30 -0300
Subject: [PATCH 28/30] Remove dead code
---
.../src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
index 4687477e956..770df37ede2 100644
--- a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
+++ b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
@@ -70,10 +70,8 @@ public boolean hasShutdownExceptions() {
@Override
public void logExceptions(List exceptions, org.slf4j.Logger log) {
- StringBuilder errorBuilder = new StringBuilder();
for (Throwable t : exceptions) {
log.error("", t);
- errorBuilder.append(t.getMessage()).append("\n");
}
}
From f61f148db194f38b16b299027a82289eea6d78ca Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 28 Oct 2020 17:59:15 -0300
Subject: [PATCH 29/30] Refactor api test fixture setup
- Remove dead code from AbstractLinuxProcess.
- Make default dummy accts static in MethodTest.
- Simplify gRPC stub creation, btc block generation, dispute agent
registration, and dummy acct initialization in test case startup.
- Make ExpectedProtocolStatus visible to scenario test pkg.
---
.../java/bisq/apitest/method/MethodTest.java | 47 ++++++++---
.../method/offer/AbstractOfferTest.java | 30 ++-----
.../method/trade/AbstractTradeTest.java | 79 +------------------
.../method/trade/ExpectedProtocolStatus.java | 69 ++++++++++++++++
4 files changed, 115 insertions(+), 110 deletions(-)
create mode 100644 apitest/src/test/java/bisq/apitest/method/trade/ExpectedProtocolStatus.java
diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
index dcf438f245e..6b21d76fb4a 100644
--- a/apitest/src/test/java/bisq/apitest/method/MethodTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
@@ -43,11 +43,14 @@
import java.util.stream.Collectors;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static bisq.apitest.config.BisqAppConfig.arbdaemon;
import static bisq.apitest.config.BisqAppConfig.bobdaemon;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
import static bisq.core.payment.payload.PaymentMethod.PERFECT_MONEY;
+import static java.util.Arrays.stream;
import static java.util.Comparator.comparing;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
@@ -64,15 +67,39 @@ public class MethodTest extends ApiTestCase {
protected static GrpcStubs aliceStubs;
protected static GrpcStubs bobStubs;
- protected PaymentAccount alicesDummyAcct;
- protected PaymentAccount bobsDummyAcct;
-
- protected final void initAlicesDummyPaymentAccount() {
- alicesDummyAcct = getDefaultPerfectDummyPaymentAccount(alicedaemon);
- }
-
- protected final void initBobsDummyPaymentAccount() {
- bobsDummyAcct = getDefaultPerfectDummyPaymentAccount(bobdaemon);
+ protected static PaymentAccount alicesDummyAcct;
+ protected static PaymentAccount bobsDummyAcct;
+
+ public static void startSupportingApps(boolean registerDisputeAgents,
+ boolean generateBtcBlock,
+ Enum>... supportingApps) {
+ try {
+ // To run Bisq apps in debug mode, use the other setUpScaffold method:
+ // setUpScaffold(new String[]{"--supportingApps", "bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon",
+ // "--enableBisqDebugging", "true"});
+ setUpScaffold(supportingApps);
+ if (registerDisputeAgents) {
+ registerDisputeAgents(arbdaemon);
+ }
+
+ if (stream(supportingApps).map(Enum::name).anyMatch(name -> name.equals(alicedaemon.name()))) {
+ aliceStubs = grpcStubs(alicedaemon);
+ alicesDummyAcct = getDefaultPerfectDummyPaymentAccount(alicedaemon);
+ }
+
+ if (stream(supportingApps).map(Enum::name).anyMatch(name -> name.equals(bobdaemon.name()))) {
+ bobStubs = grpcStubs(bobdaemon);
+ bobsDummyAcct = getDefaultPerfectDummyPaymentAccount(bobdaemon);
+ }
+
+ // Generate 1 regtest block for alice's and/or bob's wallet to
+ // show 10 BTC balance, and allow time for daemons parse the new block.
+ if (generateBtcBlock)
+ genBtcBlocksThenWait(1, 1500);
+
+ } catch (Exception ex) {
+ fail(ex);
+ }
}
// Convenience methods for building gRPC request objects
@@ -185,7 +212,7 @@ protected final CreatePaymentAccountRequest createCreatePerfectMoneyPaymentAccou
.build();
}
- protected final PaymentAccount getDefaultPerfectDummyPaymentAccount(BisqAppConfig bisqAppConfig) {
+ protected static PaymentAccount getDefaultPerfectDummyPaymentAccount(BisqAppConfig bisqAppConfig) {
var req = GetPaymentAccountsRequest.newBuilder().build();
var paymentAccountsService = grpcStubs(bisqAppConfig).paymentAccountsService;
PaymentAccount paymentAccount = paymentAccountsService.getPaymentAccounts(req)
diff --git a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
index b1bae6fbd86..fe9a98aaaae 100644
--- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java
@@ -36,7 +36,6 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
import static bisq.apitest.Scaffold.BitcoinCoreApp.bitcoind;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
@@ -62,28 +61,13 @@ public abstract class AbstractOfferTest extends MethodTest {
@BeforeAll
public static void setUp() {
- startSupportingApps();
- }
-
- @BeforeEach
- public void initDummyPaymentAccount() {
- super.initAlicesDummyPaymentAccount();
- }
-
- static void startSupportingApps() {
- try {
- // setUpScaffold(new String[]{"--supportingApps", "bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon", "--enableBisqDebugging", "true"});
- setUpScaffold(bitcoind, seednode, arbdaemon, alicedaemon, bobdaemon);
- registerDisputeAgents(arbdaemon);
- aliceStubs = grpcStubs(alicedaemon);
- bobStubs = grpcStubs(bobdaemon);
-
- // Generate 1 regtest block for alice's wallet to show 10 BTC balance,
- // and give alicedaemon time to parse the new block.
- genBtcBlocksThenWait(1, 1500);
- } catch (Exception ex) {
- fail(ex);
- }
+ startSupportingApps(true,
+ true,
+ bitcoind,
+ seednode,
+ arbdaemon,
+ alicedaemon,
+ bobdaemon);
}
protected final OfferInfo createAliceOffer(PaymentAccount paymentAccount,
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
index 22aee1d70dd..e8537206dbf 100644
--- a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
@@ -1,13 +1,10 @@
package bisq.apitest.method.trade;
-import bisq.core.trade.Trade;
-
import bisq.proto.grpc.TradeInfo;
import org.slf4j.Logger;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
import static bisq.cli.TradeFormat.format;
@@ -20,24 +17,16 @@
public class AbstractTradeTest extends AbstractOfferTest {
- // A test fixture encapsulating expected trade protocol status.
- // ExpectedProtocolStatus.init should be called before any @Test begins.
- protected static final ExpectedProtocolStatus EXPECTED_PROTOCOL_STATUS = new ExpectedProtocolStatus();
+ public static final ExpectedProtocolStatus EXPECTED_PROTOCOL_STATUS = new ExpectedProtocolStatus();
// A Trade ID cache for use in @Test sequences.
protected static String tradeId;
@BeforeAll
- public static void clearExpectedPaymentStatusFlags() {
+ public static void initStaticFixtures() {
EXPECTED_PROTOCOL_STATUS.init();
}
- @BeforeEach
- public void initDummyPaymentAccounts() {
- super.initAlicesDummyPaymentAccount();
- super.initBobsDummyPaymentAccount();
- }
-
protected final TradeInfo takeAlicesOffer(String offerId, String paymentAccountId) {
return bobStubs.tradesService.takeOffer(createTakeOfferRequest(offerId, paymentAccountId)).getTrade();
}
@@ -68,68 +57,4 @@ protected final void logTrade(Logger log,
description.toUpperCase(),
format(trade)));
}
-
- @SuppressWarnings("UnusedReturnValue")
- static class ExpectedProtocolStatus {
- Trade.State state;
- Trade.Phase phase;
- boolean isDepositPublished;
- boolean isDepositConfirmed;
- boolean isFiatSent;
- boolean isFiatReceived;
- boolean isPayoutPublished;
- boolean isWithdrawn;
-
- ExpectedProtocolStatus setState(Trade.State state) {
- this.state = state;
- return this;
- }
-
- ExpectedProtocolStatus setPhase(Trade.Phase phase) {
- this.phase = phase;
- return this;
- }
-
- ExpectedProtocolStatus setDepositPublished(boolean depositPublished) {
- isDepositPublished = depositPublished;
- return this;
- }
-
- ExpectedProtocolStatus setDepositConfirmed(boolean depositConfirmed) {
- isDepositConfirmed = depositConfirmed;
- return this;
- }
-
- ExpectedProtocolStatus setFiatSent(boolean fiatSent) {
- isFiatSent = fiatSent;
- return this;
- }
-
- ExpectedProtocolStatus setFiatReceived(boolean fiatReceived) {
- isFiatReceived = fiatReceived;
- return this;
- }
-
- ExpectedProtocolStatus setPayoutPublished(boolean payoutPublished) {
- isPayoutPublished = payoutPublished;
- return this;
- }
-
- ExpectedProtocolStatus setWithdrawn(boolean withdrawn) {
- isWithdrawn = withdrawn;
- return this;
- }
-
- @SuppressWarnings("unused")
- void init() {
- state = null;
- phase = null;
- isDepositPublished = false;
- isDepositConfirmed = false;
- isFiatSent = false;
- isFiatReceived = false;
- isPayoutPublished = false;
- isWithdrawn = false;
- }
- }
}
diff --git a/apitest/src/test/java/bisq/apitest/method/trade/ExpectedProtocolStatus.java b/apitest/src/test/java/bisq/apitest/method/trade/ExpectedProtocolStatus.java
new file mode 100644
index 00000000000..63655585947
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/method/trade/ExpectedProtocolStatus.java
@@ -0,0 +1,69 @@
+package bisq.apitest.method.trade;
+
+import bisq.core.trade.Trade;
+
+/**
+ * A test fixture encapsulating expected trade protocol status.
+ * Status flags should be cleared via init() before starting a new trade protocol.
+ */
+public class ExpectedProtocolStatus {
+ Trade.State state;
+ Trade.Phase phase;
+ boolean isDepositPublished;
+ boolean isDepositConfirmed;
+ boolean isFiatSent;
+ boolean isFiatReceived;
+ boolean isPayoutPublished;
+ boolean isWithdrawn;
+
+ public ExpectedProtocolStatus setState(Trade.State state) {
+ this.state = state;
+ return this;
+ }
+
+ public ExpectedProtocolStatus setPhase(Trade.Phase phase) {
+ this.phase = phase;
+ return this;
+ }
+
+ public ExpectedProtocolStatus setDepositPublished(boolean depositPublished) {
+ isDepositPublished = depositPublished;
+ return this;
+ }
+
+ public ExpectedProtocolStatus setDepositConfirmed(boolean depositConfirmed) {
+ isDepositConfirmed = depositConfirmed;
+ return this;
+ }
+
+ public ExpectedProtocolStatus setFiatSent(boolean fiatSent) {
+ isFiatSent = fiatSent;
+ return this;
+ }
+
+ public ExpectedProtocolStatus setFiatReceived(boolean fiatReceived) {
+ isFiatReceived = fiatReceived;
+ return this;
+ }
+
+ public ExpectedProtocolStatus setPayoutPublished(boolean payoutPublished) {
+ isPayoutPublished = payoutPublished;
+ return this;
+ }
+
+ public ExpectedProtocolStatus setWithdrawn(boolean withdrawn) {
+ isWithdrawn = withdrawn;
+ return this;
+ }
+
+ public void init() {
+ state = null;
+ phase = null;
+ isDepositPublished = false;
+ isDepositConfirmed = false;
+ isFiatSent = false;
+ isFiatReceived = false;
+ isPayoutPublished = false;
+ isWithdrawn = false;
+ }
+}
From e8e55d2286ec8063361c3ece281883648e6c6ba9 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 28 Oct 2020 18:01:49 -0300
Subject: [PATCH 30/30] Remove redundant ScenarioTest superclass
---
.../scenario/FundWalletScenarioTest.java | 6 +++-
.../bisq/apitest/scenario/ScenarioTest.java | 28 -------------------
2 files changed, 5 insertions(+), 29 deletions(-)
delete mode 100644 apitest/src/test/java/bisq/apitest/scenario/ScenarioTest.java
diff --git a/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java b/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
index 75977949c33..4b7d40f516c 100644
--- a/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
+++ b/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
@@ -33,9 +33,13 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
+
+
+import bisq.apitest.method.MethodTest;
+
@Slf4j
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-public class FundWalletScenarioTest extends ScenarioTest {
+public class FundWalletScenarioTest extends MethodTest {
@BeforeAll
public static void setUp() {
diff --git a/apitest/src/test/java/bisq/apitest/scenario/ScenarioTest.java b/apitest/src/test/java/bisq/apitest/scenario/ScenarioTest.java
deleted file mode 100644
index 9750b2ed9d6..00000000000
--- a/apitest/src/test/java/bisq/apitest/scenario/ScenarioTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.apitest.scenario;
-
-import lombok.extern.slf4j.Slf4j;
-
-
-
-import bisq.apitest.method.MethodTest;
-
-@Slf4j
-public class ScenarioTest extends MethodTest {
-}