From 135a42ba4545ed5680904a1fcfd7698a78a0bdc9 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 15:00:52 -0300 Subject: [PATCH 01/41] Delete deprecated CLI console output formatting classes The new console output formatting (tbl) api is working, and the deprecated classes just add maintenance work. Update affected test cases. --- .../bisq/apitest/scenario/bot/RobotBob.java | 12 +- .../scenario/bot/protocol/BotProtocol.java | 11 +- .../bot/protocol/MakerBotProtocol.java | 12 +- .../bot/protocol/TakerBotProtocol.java | 5 +- .../java/bisq/cli/ColumnHeaderConstants.java | 81 ----- .../main/java/bisq/cli/DirectionFormat.java | 61 ---- cli/src/main/java/bisq/cli/OfferFormat.java | 309 ------------------ cli/src/main/java/bisq/cli/TableFormat.java | 156 --------- cli/src/main/java/bisq/cli/TradeFormat.java | 222 ------------- .../main/java/bisq/cli/TransactionFormat.java | 60 ---- .../cli/table/AddressCliOutputDiffTest.java | 17 +- .../table/GetBalanceCliOutputDiffTest.java | 15 +- .../cli/table/GetOffersCliOutputDiffTest.java | 9 +- .../cli/table/GetTradeCliOutputDiffTest.java | 9 +- .../GetTransactionCliOutputDiffTest.java | 10 +- .../PaymentAccountsCliOutputDiffTest.java | 9 +- 16 files changed, 65 insertions(+), 933 deletions(-) delete mode 100644 cli/src/main/java/bisq/cli/ColumnHeaderConstants.java delete mode 100644 cli/src/main/java/bisq/cli/DirectionFormat.java delete mode 100644 cli/src/main/java/bisq/cli/OfferFormat.java delete mode 100644 cli/src/main/java/bisq/cli/TableFormat.java delete mode 100644 cli/src/main/java/bisq/cli/TradeFormat.java delete mode 100644 cli/src/main/java/bisq/cli/TransactionFormat.java diff --git a/apitest/src/test/java/bisq/apitest/scenario/bot/RobotBob.java b/apitest/src/test/java/bisq/apitest/scenario/bot/RobotBob.java index d81f385a2ba..618b64c66ad 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/bot/RobotBob.java +++ b/apitest/src/test/java/bisq/apitest/scenario/bot/RobotBob.java @@ -22,7 +22,8 @@ import static bisq.apitest.scenario.bot.protocol.ProtocolStep.DONE; import static bisq.apitest.scenario.bot.shutdown.ManualShutdown.isShutdownCalled; -import static bisq.cli.TableFormat.formatBalancesTbls; +import static bisq.cli.table.builder.TableType.BSQ_BALANCE_TBL; +import static bisq.cli.table.builder.TableType.BTC_BALANCE_TBL; import static java.util.concurrent.TimeUnit.SECONDS; @@ -34,6 +35,7 @@ import bisq.apitest.scenario.bot.script.BashScriptGenerator; import bisq.apitest.scenario.bot.script.BotScript; import bisq.apitest.scenario.bot.shutdown.ManualBotShutdownException; +import bisq.cli.table.builder.TableBuilder; @Slf4j public @@ -74,10 +76,16 @@ public void run() { throw new IllegalStateException(botProtocol.getClass().getSimpleName() + " failed to complete."); } + StringBuilder balancesBuilder = new StringBuilder(); + balancesBuilder.append("BTC").append("\n"); + balancesBuilder.append(new TableBuilder(BTC_BALANCE_TBL, botClient.getBalance().getBtc()).build().toString()).append("\n"); + balancesBuilder.append("BSQ").append("\n"); + balancesBuilder.append(new TableBuilder(BSQ_BALANCE_TBL, botClient.getBalance().getBsq()).build().toString()); + log.info("Completed {} successful trade{}. Current Balance:\n{}", ++numTrades, numTrades == 1 ? "" : "s", - formatBalancesTbls(botClient.getBalance())); + balancesBuilder); if (numTrades < actions.length) { try { diff --git a/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/BotProtocol.java b/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/BotProtocol.java index b090742a917..3fde8c2715b 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/BotProtocol.java +++ b/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/BotProtocol.java @@ -39,6 +39,7 @@ import static bisq.apitest.scenario.bot.protocol.ProtocolStep.*; import static bisq.apitest.scenario.bot.shutdown.ManualShutdown.checkIfShutdownCalled; +import static bisq.cli.table.builder.TableType.TRADE_DETAIL_TBL; import static java.lang.String.format; import static java.lang.System.currentTimeMillis; import static java.util.Arrays.stream; @@ -50,7 +51,7 @@ import bisq.apitest.scenario.bot.BotClient; import bisq.apitest.scenario.bot.script.BashScriptGenerator; import bisq.apitest.scenario.bot.shutdown.ManualBotShutdownException; -import bisq.cli.TradeFormat; +import bisq.cli.table.builder.TableBuilder; @Slf4j public abstract class BotProtocol { @@ -133,7 +134,8 @@ protected void printBotProtocolStep() { try { var t = this.getBotClient().getTrade(trade.getTradeId()); if (t.getIsFiatSent()) { - log.info("Buyer has started payment for trade:\n{}", TradeFormat.format(t)); + log.info("Buyer has started payment for trade:\n{}", + new TableBuilder(TRADE_DETAIL_TBL, t).build().toString()); return t; } } catch (Exception ex) { @@ -167,7 +169,8 @@ protected void printBotProtocolStep() { try { var t = this.getBotClient().getTrade(trade.getTradeId()); if (t.getIsFiatReceived()) { - log.info("Seller has received payment for trade:\n{}", TradeFormat.format(t)); + log.info("Seller has received payment for trade:\n{}", + new TableBuilder(TRADE_DETAIL_TBL, t).build().toString()); return t; } } catch (Exception ex) { @@ -202,7 +205,7 @@ protected void printBotProtocolStep() { if (t.getIsPayoutPublished()) { log.info("Payout tx {} has been published for trade:\n{}", t.getPayoutTxId(), - TradeFormat.format(t)); + new TableBuilder(TRADE_DETAIL_TBL, t).build().toString()); return t; } } catch (Exception ex) { diff --git a/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/MakerBotProtocol.java b/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/MakerBotProtocol.java index 3f757dbbd28..a5ce8f5bcaf 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/MakerBotProtocol.java +++ b/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/MakerBotProtocol.java @@ -16,8 +16,8 @@ import static bisq.apitest.scenario.bot.protocol.ProtocolStep.DONE; import static bisq.apitest.scenario.bot.protocol.ProtocolStep.WAIT_FOR_OFFER_TAKER; import static bisq.apitest.scenario.bot.shutdown.ManualShutdown.checkIfShutdownCalled; -import static bisq.cli.OfferFormat.formatOfferTable; -import static java.util.Collections.singletonList; +import static bisq.cli.table.builder.TableType.OFFER_TBL; +import static bisq.cli.table.builder.TableType.TRADE_DETAIL_TBL; @@ -26,7 +26,7 @@ import bisq.apitest.scenario.bot.RandomOffer; import bisq.apitest.scenario.bot.script.BashScriptGenerator; import bisq.apitest.scenario.bot.shutdown.ManualBotShutdownException; -import bisq.cli.TradeFormat; +import bisq.cli.table.builder.TableBuilder; @Slf4j public class MakerBotProtocol extends BotProtocol { @@ -65,7 +65,7 @@ public void run() { private final Supplier randomOffer = () -> { checkIfShutdownCalled("Interrupted before creating random offer."); OfferInfo offer = new RandomOffer(botClient, paymentAccount).create().getOffer(); - log.info("Created random {} offer\n{}", currencyCode, formatOfferTable(singletonList(offer), currencyCode)); + log.info("Created random {} offer\n{}", currencyCode, new TableBuilder(OFFER_TBL, offer).build()); return offer; }; @@ -98,7 +98,9 @@ public void run() { private Optional getNewTrade(String offerId) { try { var trade = botClient.getTrade(offerId); - log.info("Offer {} was taken, new trade:\n{}", offerId, TradeFormat.format(trade)); + log.info("Offer {} was taken, new trade:\n{}", + offerId, + new TableBuilder(TRADE_DETAIL_TBL, trade).build().toString()); return Optional.of(trade); } catch (Exception ex) { // Get trade will throw a non-fatal gRPC exception if not found. diff --git a/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/TakerBotProtocol.java b/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/TakerBotProtocol.java index dd04b5c5bff..a0aba127d66 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/TakerBotProtocol.java +++ b/apitest/src/test/java/bisq/apitest/scenario/bot/protocol/TakerBotProtocol.java @@ -17,7 +17,7 @@ import static bisq.apitest.scenario.bot.protocol.ProtocolStep.FIND_OFFER; import static bisq.apitest.scenario.bot.protocol.ProtocolStep.TAKE_OFFER; import static bisq.apitest.scenario.bot.shutdown.ManualShutdown.checkIfShutdownCalled; -import static bisq.cli.OfferFormat.formatOfferTable; +import static bisq.cli.table.builder.TableType.OFFER_TBL; import static bisq.core.payment.payload.PaymentMethod.F2F_ID; @@ -26,6 +26,7 @@ import bisq.apitest.scenario.bot.BotClient; import bisq.apitest.scenario.bot.script.BashScriptGenerator; import bisq.apitest.scenario.bot.shutdown.ManualBotShutdownException; +import bisq.cli.table.builder.TableBuilder; @Slf4j public class TakerBotProtocol extends BotProtocol { @@ -64,7 +65,7 @@ public void run() { private final Supplier> firstOffer = () -> { var offers = botClient.getOffers(currencyCode); if (offers.size() > 0) { - log.info("Offers found:\n{}", formatOfferTable(offers, currencyCode)); + log.info("Offers found:\n{}", new TableBuilder(OFFER_TBL, offers).build()); OfferInfo offer = offers.get(0); log.info("Will take first offer {}", offer.getId()); return Optional.of(offer); diff --git a/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java b/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java deleted file mode 100644 index e71dde5eb1d..00000000000 --- a/cli/src/main/java/bisq/cli/ColumnHeaderConstants.java +++ /dev/null @@ -1,81 +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.cli; - -import static com.google.common.base.Strings.padEnd; -import static com.google.common.base.Strings.padStart; - -@Deprecated -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, column header - // lengths are expected to be greater than any column value length. - static final String COL_HEADER_ADDRESS = padEnd("%-3s Address", 52, ' '); - static final String COL_HEADER_AMOUNT = "BTC(min - max)"; - static final String COL_HEADER_AVAILABLE_BALANCE = "Available Balance"; - static final String COL_HEADER_AVAILABLE_CONFIRMED_BALANCE = "Available Confirmed Balance"; - static final String COL_HEADER_UNCONFIRMED_CHANGE_BALANCE = "Unconfirmed Change Balance"; - static final String COL_HEADER_RESERVED_BALANCE = "Reserved Balance"; - static final String COL_HEADER_TOTAL_AVAILABLE_BALANCE = "Total Available Balance"; - static final String COL_HEADER_LOCKED_BALANCE = "Locked Balance"; - static final String COL_HEADER_LOCKED_FOR_VOTING_BALANCE = "Locked For Voting Balance"; - static final String COL_HEADER_LOCKUP_BONDS_BALANCE = "Lockup Bonds Balance"; - static final String COL_HEADER_UNLOCKING_BONDS_BALANCE = "Unlocking Bonds Balance"; - static final String COL_HEADER_UNVERIFIED_BALANCE = "Unverified Balance"; - static final String COL_HEADER_CONFIRMATIONS = "Confirmations"; - static final String COL_HEADER_IS_USED_ADDRESS = "Is Used"; - 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_ENABLED = "Enabled"; - 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_PRICE_OF_ALTCOIN = "Price in BTC for 1 %-3s"; - static final String COL_HEADER_TRADE_AMOUNT = padStart("Amount(%-3s)", 12, ' '); - static final String COL_HEADER_TRADE_BSQ_BUYER_ADDRESS = "BSQ Buyer Address"; - static final String COL_HEADER_TRADE_BUYER_COST = padEnd("Buyer Cost(%-3s)", 15, ' '); - 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_PAYMENT_SENT = padEnd("%-3s Sent", 8, ' '); - static final String COL_HEADER_TRADE_PAYMENT_RECEIVED = padEnd("%-3s Received", 12, ' '); - 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 = padEnd("Tx Fee(BTC)", 12, ' '); - static final String COL_HEADER_TRADE_MAKER_FEE = padEnd("Maker Fee(%-3s)", 12, ' '); // "Maker Fee(%-3s)"; - static final String COL_HEADER_TRADE_TAKER_FEE = padEnd("Taker Fee(%-3s)", 12, ' '); // "Taker Fee(%-3s)"; - static final String COL_HEADER_TRIGGER_PRICE = "Trigger Price(%-3s)"; - static final String COL_HEADER_TX_ID = "Tx ID"; - static final String COL_HEADER_TX_INPUT_SUM = "Tx Inputs (BTC)"; - static final String COL_HEADER_TX_OUTPUT_SUM = "Tx Outputs (BTC)"; - static final String COL_HEADER_TX_FEE = "Tx Fee (BTC)"; - static final String COL_HEADER_TX_SIZE = "Tx Size (Bytes)"; - static final String COL_HEADER_TX_IS_CONFIRMED = "Is Confirmed"; - static final String COL_HEADER_TX_MEMO = "Memo"; - - 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/DirectionFormat.java b/cli/src/main/java/bisq/cli/DirectionFormat.java deleted file mode 100644 index c56d89467b1..00000000000 --- a/cli/src/main/java/bisq/cli/DirectionFormat.java +++ /dev/null @@ -1,61 +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.cli; - -import bisq.proto.grpc.OfferInfo; - -import java.util.List; -import java.util.function.Function; - -import static bisq.cli.ColumnHeaderConstants.COL_HEADER_DIRECTION; -import static java.lang.String.format; -import static protobuf.OfferDirection.BUY; -import static protobuf.OfferDirection.SELL; - -@Deprecated -class DirectionFormat { - - static int getLongestDirectionColWidth(List offers) { - if (offers.isEmpty() || offers.get(0).getBaseCurrencyCode().equals("BTC")) - return COL_HEADER_DIRECTION.length(); - else - return 18; // .e.g., "Sell BSQ (Buy BTC)".length() - } - - static final Function directionFormat = (offer) -> { - String baseCurrencyCode = offer.getBaseCurrencyCode(); - boolean isCryptoCurrencyOffer = !baseCurrencyCode.equals("BTC"); - if (!isCryptoCurrencyOffer) { - return baseCurrencyCode; - } else { - // Return "Sell BSQ (Buy BTC)", or "Buy BSQ (Sell BTC)". - String direction = offer.getDirection(); - String mirroredDirection = getMirroredDirection(direction); - Function mixedCase = (word) -> word.charAt(0) + word.substring(1).toLowerCase(); - return format("%s %s (%s %s)", - mixedCase.apply(mirroredDirection), - baseCurrencyCode, - mixedCase.apply(direction), - offer.getCounterCurrencyCode()); - } - }; - - static String getMirroredDirection(String directionAsString) { - return directionAsString.equalsIgnoreCase(BUY.name()) ? SELL.name() : BUY.name(); - } -} diff --git a/cli/src/main/java/bisq/cli/OfferFormat.java b/cli/src/main/java/bisq/cli/OfferFormat.java deleted file mode 100644 index 9aea2d91673..00000000000 --- a/cli/src/main/java/bisq/cli/OfferFormat.java +++ /dev/null @@ -1,309 +0,0 @@ -package bisq.cli; - -import bisq.proto.grpc.OfferInfo; - -import com.google.common.annotations.VisibleForTesting; - -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import static bisq.cli.ColumnHeaderConstants.*; -import static bisq.cli.CurrencyFormat.*; -import static bisq.cli.DirectionFormat.directionFormat; -import static bisq.cli.DirectionFormat.getLongestDirectionColWidth; -import static bisq.cli.TableFormat.formatTimestamp; -import static bisq.cli.TableFormat.getLongestColumnSize; -import static com.google.common.base.Strings.padEnd; -import static com.google.common.base.Strings.padStart; -import static java.lang.String.format; - -@Deprecated -@VisibleForTesting -public class OfferFormat { - - public static String formatOfferTable(List offers, String currencyCode) { - if (offers == null || offers.isEmpty()) - throw new IllegalArgumentException(format("%s offer list is empty", currencyCode.toLowerCase())); - - String baseCurrencyCode = offers.get(0).getBaseCurrencyCode(); - boolean isMyOffer = offers.get(0).getIsMyOffer(); - return baseCurrencyCode.equalsIgnoreCase("BTC") - ? formatFiatOfferTable(offers, currencyCode, isMyOffer) - : formatCryptoCurrencyOfferTable(offers, baseCurrencyCode, isMyOffer); - } - - private static String formatFiatOfferTable(List offers, - String fiatCurrencyCode, - boolean isMyOffer) { - // Some column values might be longer than header, so we need to calculate them. - int amountColWith = getLongestAmountColWidth(offers); - int volumeColWidth = getLongestVolumeColWidth(offers); - int paymentMethodColWidth = getLongestPaymentMethodColWidth(offers); - // "Enabled" and "Trigger Price" columns are displayed for my offers only. - String enabledHeaderFormat = isMyOffer ? - COL_HEADER_ENABLED + COL_HEADER_DELIMITER - : ""; - String triggerPriceHeaderFormat = isMyOffer ? - // COL_HEADER_TRIGGER_PRICE includes %s -> fiatCurrencyCode - COL_HEADER_TRIGGER_PRICE + COL_HEADER_DELIMITER - : ""; - String headersFormat = enabledHeaderFormat - + COL_HEADER_DIRECTION + COL_HEADER_DELIMITER - // COL_HEADER_PRICE includes %s -> fiatCurrencyCode - + COL_HEADER_PRICE + COL_HEADER_DELIMITER - + padStart(COL_HEADER_AMOUNT, amountColWith, ' ') + COL_HEADER_DELIMITER - // COL_HEADER_VOLUME includes %s -> fiatCurrencyCode - + padStart(COL_HEADER_VOLUME, volumeColWidth, ' ') + COL_HEADER_DELIMITER - + triggerPriceHeaderFormat - + padEnd(COL_HEADER_PAYMENT_METHOD, paymentMethodColWidth, ' ') + COL_HEADER_DELIMITER - + COL_HEADER_CREATION_DATE + COL_HEADER_DELIMITER - + COL_HEADER_UUID.trim() + "%n"; - String headerLine = format(headersFormat, - fiatCurrencyCode.toUpperCase(), - fiatCurrencyCode.toUpperCase(), - // COL_HEADER_TRIGGER_PRICE includes %s -> fiatCurrencyCode - isMyOffer ? fiatCurrencyCode.toUpperCase() : ""); - String colDataFormat = getFiatOfferColDataFormat(isMyOffer, - amountColWith, - volumeColWidth, - paymentMethodColWidth); - return formattedFiatOfferTable(offers, isMyOffer, headerLine, colDataFormat); - } - - private static String formattedFiatOfferTable(List offers, - boolean isMyOffer, - String headerLine, - String colDataFormat) { - if (isMyOffer) { - return headerLine - + offers.stream() - .map(o -> format(colDataFormat, - formatEnabled(o), - o.getDirection(), - formatPrice(o.getPrice()), - formatAmountRange(o.getMinAmount(), o.getAmount()), - formatVolumeRange(o.getMinVolume(), o.getVolume()), - o.getTriggerPrice() == 0 ? "" : formatPrice(o.getTriggerPrice()), - o.getPaymentMethodShortName(), - formatTimestamp(o.getDate()), - o.getId())) - .collect(Collectors.joining("\n")); - } else { - return headerLine - + offers.stream() - .map(o -> format(colDataFormat, - o.getDirection(), - formatPrice(o.getPrice()), - formatAmountRange(o.getMinAmount(), o.getAmount()), - formatVolumeRange(o.getMinVolume(), o.getVolume()), - o.getPaymentMethodShortName(), - formatTimestamp(o.getDate()), - o.getId())) - .collect(Collectors.joining("\n")); - } - } - - private static String getFiatOfferColDataFormat(boolean isMyOffer, - int amountColWith, - int volumeColWidth, - int paymentMethodColWidth) { - if (isMyOffer) { - return "%-" + (COL_HEADER_ENABLED.length() + COL_HEADER_DELIMITER.length()) + "s" - + "%-" + (COL_HEADER_DIRECTION.length() + COL_HEADER_DELIMITER.length()) + "s" - + "%" + (COL_HEADER_PRICE.length() - 1) + "s" - + " %" + amountColWith + "s" - + " %" + (volumeColWidth - 1) + "s" - + " %" + (COL_HEADER_TRIGGER_PRICE.length() - 1) + "s" - + " %-" + paymentMethodColWidth + "s" - + " %-" + (COL_HEADER_CREATION_DATE.length()) + "s" - + " %-" + COL_HEADER_UUID.length() + "s"; - } else { - return "%-" + (COL_HEADER_DIRECTION.length() + COL_HEADER_DELIMITER.length()) + "s" - + "%" + (COL_HEADER_PRICE.length() - 1) + "s" - + " %" + amountColWith + "s" - + " %" + (volumeColWidth - 1) + "s" - + " %-" + paymentMethodColWidth + "s" - + " %-" + (COL_HEADER_CREATION_DATE.length()) + "s" - + " %-" + COL_HEADER_UUID.length() + "s"; - } - } - - private static String formatCryptoCurrencyOfferTable(List offers, - String cryptoCurrencyCode, - boolean isMyOffer) { - // Some column values might be longer than header, so we need to calculate them. - int directionColWidth = getLongestDirectionColWidth(offers); - int amountColWith = getLongestAmountColWidth(offers); - int volumeColWidth = getLongestCryptoCurrencyVolumeColWidth(offers); - int paymentMethodColWidth = getLongestPaymentMethodColWidth(offers); - // "Enabled" column is displayed for my offers only. - String enabledHeaderFormat = isMyOffer ? - COL_HEADER_ENABLED + COL_HEADER_DELIMITER - : ""; - Supplier shouldShowTriggerPrice = () -> isMyOffer && !cryptoCurrencyCode.equalsIgnoreCase("BSQ"); - String triggerPriceHeaderFormat = shouldShowTriggerPrice.get() - ? COL_HEADER_TRIGGER_PRICE + COL_HEADER_DELIMITER - : ""; - // TODO use memoize function to avoid duplicate the formatting done above? - String headersFormat = enabledHeaderFormat - + padEnd(COL_HEADER_DIRECTION, directionColWidth, ' ') + COL_HEADER_DELIMITER - + COL_HEADER_PRICE_OF_ALTCOIN + COL_HEADER_DELIMITER // includes %s -> cryptoCurrencyCode - + padStart(COL_HEADER_AMOUNT, amountColWith, ' ') + COL_HEADER_DELIMITER - // COL_HEADER_VOLUME includes %s -> cryptoCurrencyCode - + padStart(COL_HEADER_VOLUME, volumeColWidth, ' ') + COL_HEADER_DELIMITER - + triggerPriceHeaderFormat // COL_HEADER_TRIGGER_PRICE includes %s -> cryptoCurrencyCode - + padEnd(COL_HEADER_PAYMENT_METHOD, paymentMethodColWidth, ' ') + COL_HEADER_DELIMITER - + COL_HEADER_CREATION_DATE + COL_HEADER_DELIMITER - + COL_HEADER_UUID.trim() + "%n"; - String headerLine = format(headersFormat, - cryptoCurrencyCode.toUpperCase(), - cryptoCurrencyCode.toUpperCase(), - shouldShowTriggerPrice.get() ? cryptoCurrencyCode.toUpperCase() : ""); - String colDataFormat = getCryptoCurrencyOfferColDataFormat(isMyOffer, - shouldShowTriggerPrice.get(), - directionColWidth, - amountColWith, - volumeColWidth, - paymentMethodColWidth); - if (isMyOffer) { - if (shouldShowTriggerPrice.get()) { - // Is my non-BSQ altcoin offer. Show ENABLED and TRIGGER_PRICE data. - return headerLine - + offers.stream() - .map(o -> format(colDataFormat, - formatEnabled(o), - directionFormat.apply(o), - formatCryptoCurrencyPrice(o.getPrice()), - formatAmountRange(o.getMinAmount(), o.getAmount()), - formatCryptoCurrencyVolumeRange(o.getMinVolume(), o.getVolume()), - o.getTriggerPrice() == 0 ? "" : formatCryptoCurrencyPrice(o.getTriggerPrice()), - o.getPaymentMethodShortName(), - formatTimestamp(o.getDate()), - o.getId())) - .collect(Collectors.joining("\n")); - } else { - // Is my BSQ altcoin offer. Show ENABLED, but not TRIGGER_PRICE data. - return headerLine - + offers.stream() - .map(o -> format(colDataFormat, - formatEnabled(o), - directionFormat.apply(o), - formatCryptoCurrencyPrice(o.getPrice()), - formatAmountRange(o.getMinAmount(), o.getAmount()), - formatCryptoCurrencyVolumeRange(o.getMinVolume(), o.getVolume()), - o.getPaymentMethodShortName(), - formatTimestamp(o.getDate()), - o.getId())) - .collect(Collectors.joining("\n")); - } - } else { - // Not my offer. Do not show ENABLED and TRIGGER_PRICE cols. - return headerLine - + offers.stream() - .map(o -> format(colDataFormat, - directionFormat.apply(o), - formatCryptoCurrencyPrice(o.getPrice()), - formatAmountRange(o.getMinAmount(), o.getAmount()), - formatCryptoCurrencyVolumeRange(o.getMinVolume(), o.getVolume()), - o.getPaymentMethodShortName(), - formatTimestamp(o.getDate()), - o.getId())) - .collect(Collectors.joining("\n")); - } - } - - private static String getCryptoCurrencyOfferColDataFormat(boolean isMyOffer, - boolean shouldShowTriggerPrice, - int directionColWidth, - int amountColWith, - int volumeColWidth, - int paymentMethodColWidth) { - if (isMyOffer) { - return getMyCryptoOfferColDataFormat(shouldShowTriggerPrice, - directionColWidth, - amountColWith, - volumeColWidth, - paymentMethodColWidth); - } else { - // Not my offer. Do not show ENABLED and TRIGGER_PRICE cols. - return "%-" + directionColWidth + "s" - + "%" + (COL_HEADER_PRICE_OF_ALTCOIN.length() + 1) + "s" - + " %" + amountColWith + "s" - + " %" + (volumeColWidth - 1) + "s" - + " %-" + paymentMethodColWidth + "s" - + " %-" + (COL_HEADER_CREATION_DATE.length()) + "s" - + " %-" + COL_HEADER_UUID.length() + "s"; - } - } - - private static String getMyCryptoOfferColDataFormat(boolean shouldShowTriggerPrice, - int directionColWidth, - int amountColWith, - int volumeColWidth, - int paymentMethodColWidth) { - if (shouldShowTriggerPrice) { - // Is my non-BSQ altcoin offer. Show ENABLED and TRIGGER_PRICE cols. - return "%-" + (COL_HEADER_ENABLED.length() + COL_HEADER_DELIMITER.length()) + "s" - + "%-" + directionColWidth + "s" - + "%" + (COL_HEADER_PRICE_OF_ALTCOIN.length() + 1) + "s" - + " %" + amountColWith + "s" - + " %" + (volumeColWidth - 1) + "s" - + " %" + (COL_HEADER_TRIGGER_PRICE.length() - 1) + "s" - + " %-" + paymentMethodColWidth + "s" - + " %-" + (COL_HEADER_CREATION_DATE.length()) + "s" - + " %-" + COL_HEADER_UUID.length() + "s"; - } else { - // Is my BSQ altcoin offer. Show ENABLED, but not TRIGGER_PRICE col. - return "%-" + (COL_HEADER_ENABLED.length() + COL_HEADER_DELIMITER.length()) + "s" - + "%-" + directionColWidth + "s" - + "%" + (COL_HEADER_PRICE_OF_ALTCOIN.length() + 1) + "s" - + " %" + amountColWith + "s" - + " %" + (volumeColWidth - 1) + "s" - + " %-" + paymentMethodColWidth + "s" - + " %-" + (COL_HEADER_CREATION_DATE.length()) + "s" - + " %-" + COL_HEADER_UUID.length() + "s"; - } - } - - private static String formatEnabled(OfferInfo offerInfo) { - if (offerInfo.getIsMyOffer() && offerInfo.getIsMyPendingOffer()) - return "PENDING"; - else - return offerInfo.getIsActivated() ? "YES" : "NO"; - } - - private static int getLongestPaymentMethodColWidth(List offers) { - return getLongestColumnSize( - COL_HEADER_PAYMENT_METHOD.length(), - offers.stream() - .map(OfferInfo::getPaymentMethodShortName) - .collect(Collectors.toList())); - } - - private static int getLongestAmountColWidth(List offers) { - return getLongestColumnSize( - COL_HEADER_AMOUNT.length(), - offers.stream() - .map(o -> formatAmountRange(o.getMinAmount(), o.getAmount())) - .collect(Collectors.toList())); - } - - private static int getLongestVolumeColWidth(List offers) { - // Pad this col width by 1 space. - return 1 + getLongestColumnSize( - COL_HEADER_VOLUME.length(), - offers.stream() - .map(o -> formatVolumeRange(o.getMinVolume(), o.getVolume())) - .collect(Collectors.toList())); - } - - private static int getLongestCryptoCurrencyVolumeColWidth(List offers) { - // Pad this col width by 1 space. - return 1 + getLongestColumnSize( - COL_HEADER_VOLUME.length(), - offers.stream() - .map(o -> formatCryptoCurrencyVolumeRange(o.getMinVolume(), o.getVolume())) - .collect(Collectors.toList())); - } -} diff --git a/cli/src/main/java/bisq/cli/TableFormat.java b/cli/src/main/java/bisq/cli/TableFormat.java deleted file mode 100644 index 37c3b36476c..00000000000 --- a/cli/src/main/java/bisq/cli/TableFormat.java +++ /dev/null @@ -1,156 +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.cli; - -import bisq.proto.grpc.AddressBalanceInfo; -import bisq.proto.grpc.BalancesInfo; -import bisq.proto.grpc.BsqBalanceInfo; -import bisq.proto.grpc.BtcBalanceInfo; - -import protobuf.PaymentAccount; - -import com.google.common.annotations.VisibleForTesting; - -import java.text.SimpleDateFormat; - -import java.util.Date; -import java.util.List; -import java.util.TimeZone; -import java.util.stream.Collectors; - -import static bisq.cli.ColumnHeaderConstants.*; -import static bisq.cli.CurrencyFormat.formatBsq; -import static bisq.cli.CurrencyFormat.formatSatoshis; -import static com.google.common.base.Strings.padEnd; -import static java.lang.String.format; -import static java.util.Collections.max; -import static java.util.Comparator.comparing; -import static java.util.TimeZone.getTimeZone; - -@Deprecated -@VisibleForTesting -public class TableFormat { - - static final TimeZone TZ_UTC = getTimeZone("UTC"); - static final SimpleDateFormat DATE_FORMAT_ISO_8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - - public static String formatAddressBalanceTbl(List addressBalanceInfo) { - String headerFormatString = COL_HEADER_ADDRESS + COL_HEADER_DELIMITER - + COL_HEADER_AVAILABLE_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_CONFIRMATIONS + COL_HEADER_DELIMITER - + COL_HEADER_IS_USED_ADDRESS + COL_HEADER_DELIMITER + "\n"; - String headerLine = format(headerFormatString, "BTC"); - - String colDataFormat = "%-" + COL_HEADER_ADDRESS.length() + "s" // lt justify - + " %" + (COL_HEADER_AVAILABLE_BALANCE.length() - 1) + "s" // rt justify - + " %" + COL_HEADER_CONFIRMATIONS.length() + "d" // rt justify - + " %-" + COL_HEADER_IS_USED_ADDRESS.length() + "s"; // lt justify - return headerLine - + addressBalanceInfo.stream() - .map(info -> format(colDataFormat, - info.getAddress(), - formatSatoshis(info.getBalance()), - info.getNumConfirmations(), - info.getIsAddressUnused() ? "NO" : "YES")) - .collect(Collectors.joining("\n")); - } - - public static String formatBalancesTbls(BalancesInfo balancesInfo) { - return "BTC" + "\n" - + formatBtcBalanceInfoTbl(balancesInfo.getBtc()) + "\n" - + "BSQ" + "\n" - + formatBsqBalanceInfoTbl(balancesInfo.getBsq()); - } - - public static String formatBsqBalanceInfoTbl(BsqBalanceInfo bsqBalanceInfo) { - String headerLine = COL_HEADER_AVAILABLE_CONFIRMED_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_UNVERIFIED_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_UNCONFIRMED_CHANGE_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_LOCKED_FOR_VOTING_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_LOCKUP_BONDS_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_UNLOCKING_BONDS_BALANCE + COL_HEADER_DELIMITER + "\n"; - String colDataFormat = "%" + COL_HEADER_AVAILABLE_CONFIRMED_BALANCE.length() + "s" // rt justify - + " %" + (COL_HEADER_UNVERIFIED_BALANCE.length() + 1) + "s" // rt justify - + " %" + (COL_HEADER_UNCONFIRMED_CHANGE_BALANCE.length() + 1) + "s" // rt justify - + " %" + (COL_HEADER_LOCKED_FOR_VOTING_BALANCE.length() + 1) + "s" // rt justify - + " %" + (COL_HEADER_LOCKUP_BONDS_BALANCE.length() + 1) + "s" // rt justify - + " %" + (COL_HEADER_UNLOCKING_BONDS_BALANCE.length() + 1) + "s"; // rt justify - return headerLine + format(colDataFormat, - formatBsq(bsqBalanceInfo.getAvailableConfirmedBalance()), - formatBsq(bsqBalanceInfo.getUnverifiedBalance()), - formatBsq(bsqBalanceInfo.getUnconfirmedChangeBalance()), - formatBsq(bsqBalanceInfo.getLockedForVotingBalance()), - formatBsq(bsqBalanceInfo.getLockupBondsBalance()), - formatBsq(bsqBalanceInfo.getUnlockingBondsBalance())); - } - - public static String formatBtcBalanceInfoTbl(BtcBalanceInfo btcBalanceInfo) { - String headerLine = COL_HEADER_AVAILABLE_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_RESERVED_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_TOTAL_AVAILABLE_BALANCE + COL_HEADER_DELIMITER - + COL_HEADER_LOCKED_BALANCE + COL_HEADER_DELIMITER + "\n"; - String colDataFormat = "%" + COL_HEADER_AVAILABLE_BALANCE.length() + "s" // rt justify - + " %" + (COL_HEADER_RESERVED_BALANCE.length() + 1) + "s" // rt justify - + " %" + (COL_HEADER_TOTAL_AVAILABLE_BALANCE.length() + 1) + "s" // rt justify - + " %" + (COL_HEADER_LOCKED_BALANCE.length() + 1) + "s"; // rt justify - return headerLine + format(colDataFormat, - formatSatoshis(btcBalanceInfo.getAvailableBalance()), - formatSatoshis(btcBalanceInfo.getReservedBalance()), - formatSatoshis(btcBalanceInfo.getTotalAvailableBalance()), - formatSatoshis(btcBalanceInfo.getLockedBalance())); - } - - public static String formatPaymentAcctTbl(List paymentAccounts) { - // Some column values might be longer than header, so we need to calculate them. - int nameColWidth = getLongestColumnSize( - COL_HEADER_NAME.length(), - paymentAccounts.stream().map(PaymentAccount::getAccountName) - .collect(Collectors.toList())); - int paymentMethodColWidth = getLongestColumnSize( - COL_HEADER_PAYMENT_METHOD.length(), - paymentAccounts.stream().map(a -> a.getPaymentMethod().getId()) - .collect(Collectors.toList())); - String headerLine = padEnd(COL_HEADER_NAME, nameColWidth, ' ') + COL_HEADER_DELIMITER - + COL_HEADER_CURRENCY + COL_HEADER_DELIMITER - + padEnd(COL_HEADER_PAYMENT_METHOD, paymentMethodColWidth, ' ') + COL_HEADER_DELIMITER - + COL_HEADER_UUID + COL_HEADER_DELIMITER + "\n"; - String colDataFormat = "%-" + nameColWidth + "s" // left justify - + " %-" + COL_HEADER_CURRENCY.length() + "s" // left justify - + " %-" + paymentMethodColWidth + "s" // left justify - + " %-" + COL_HEADER_UUID.length() + "s"; // left justify - return headerLine - + paymentAccounts.stream() - .map(a -> format(colDataFormat, - a.getAccountName(), - a.getSelectedTradeCurrency().getCode(), - a.getPaymentMethod().getId(), - a.getId())) - .collect(Collectors.joining("\n")); - } - - // Return size of the longest string value, or the header.len, whichever is greater. - static int getLongestColumnSize(int headerLength, List strings) { - int longest = max(strings, comparing(String::length)).length(); - return Math.max(longest, headerLength); - } - - static String formatTimestamp(long timestamp) { - DATE_FORMAT_ISO_8601.setTimeZone(TZ_UTC); - return DATE_FORMAT_ISO_8601.format(new Date(timestamp)); - } -} diff --git a/cli/src/main/java/bisq/cli/TradeFormat.java b/cli/src/main/java/bisq/cli/TradeFormat.java deleted file mode 100644 index 4ac85497288..00000000000 --- a/cli/src/main/java/bisq/cli/TradeFormat.java +++ /dev/null @@ -1,222 +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.cli; - -import bisq.proto.grpc.ContractInfo; -import bisq.proto.grpc.TradeInfo; - -import com.google.common.annotations.VisibleForTesting; - -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Supplier; - -import static bisq.cli.ColumnHeaderConstants.*; -import static bisq.cli.CurrencyFormat.*; -import static com.google.common.base.Strings.padEnd; - -@Deprecated -@VisibleForTesting -public class TradeFormat { - - private static final String YES = "YES"; - private static final String NO = "NO"; - - // TODO add String format(List trades) - - @VisibleForTesting - public static String format(TradeInfo tradeInfo) { - // Some column values might be longer than header, so we need to calculate 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 makerFeeHeader = () -> !isTaker ? - COL_HEADER_TRADE_MAKER_FEE + COL_HEADER_DELIMITER - : ""; - Supplier makerFeeHeaderSpec = () -> !isTaker ? - "%" + (COL_HEADER_TRADE_MAKER_FEE.length() + 2) + "s" - : ""; - Supplier takerFeeHeader = () -> isTaker ? - COL_HEADER_TRADE_TAKER_FEE + COL_HEADER_DELIMITER - : ""; - Supplier takerFeeHeaderSpec = () -> isTaker ? - "%" + (COL_HEADER_TRADE_TAKER_FEE.length() + 2) + "s" - : ""; - - boolean showBsqBuyerAddress = shouldShowBsqBuyerAddress(tradeInfo, isTaker); - Supplier bsqBuyerAddressHeader = () -> showBsqBuyerAddress ? COL_HEADER_TRADE_BSQ_BUYER_ADDRESS : ""; - Supplier bsqBuyerAddressHeaderSpec = () -> showBsqBuyerAddress ? "%s" : ""; - - String headersFormat = padEnd(COL_HEADER_TRADE_SHORT_ID, shortIdColWidth, ' ') + COL_HEADER_DELIMITER - + padEnd(COL_HEADER_TRADE_ROLE, roleColWidth, ' ') + COL_HEADER_DELIMITER - + priceHeader.apply(tradeInfo) + 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 - + makerFeeHeader.get() - // maker or taker fee header, not both - + takerFeeHeader.get() - + COL_HEADER_TRADE_DEPOSIT_PUBLISHED + COL_HEADER_DELIMITER - + COL_HEADER_TRADE_DEPOSIT_CONFIRMED + COL_HEADER_DELIMITER - + COL_HEADER_TRADE_BUYER_COST + COL_HEADER_DELIMITER - + COL_HEADER_TRADE_PAYMENT_SENT + COL_HEADER_DELIMITER - + COL_HEADER_TRADE_PAYMENT_RECEIVED + COL_HEADER_DELIMITER - + COL_HEADER_TRADE_PAYOUT_PUBLISHED + COL_HEADER_DELIMITER - + COL_HEADER_TRADE_WITHDRAWN + COL_HEADER_DELIMITER - + bsqBuyerAddressHeader.get() - + "%n"; - - String counterCurrencyCode = tradeInfo.getOffer().getCounterCurrencyCode(); - String baseCurrencyCode = tradeInfo.getOffer().getBaseCurrencyCode(); - - String headerLine = String.format(headersFormat, - /* COL_HEADER_PRICE */ priceHeaderCurrencyCode.apply(tradeInfo), - /* COL_HEADER_TRADE_AMOUNT */ baseCurrencyCode, - /* COL_HEADER_TRADE_(M||T)AKER_FEE */ makerTakerFeeHeaderCurrencyCode.apply(tradeInfo, isTaker), - /* COL_HEADER_TRADE_BUYER_COST */ counterCurrencyCode, - /* COL_HEADER_TRADE_PAYMENT_SENT */ paymentStatusHeaderCurrencyCode.apply(tradeInfo), - /* COL_HEADER_TRADE_PAYMENT_RECEIVED */ paymentStatusHeaderCurrencyCode.apply(tradeInfo)); - - String colDataFormat = "%-" + shortIdColWidth + "s" // lt justify - + " %-" + (roleColWidth + COL_HEADER_DELIMITER.length()) + "s" // left - + "%" + (COL_HEADER_PRICE.length() - 1) + "s" // rt justify - + "%" + (COL_HEADER_TRADE_AMOUNT.length() + 1) + "s" // rt justify - + "%" + (COL_HEADER_TRADE_TX_FEE.length() + 1) + "s" // rt justify - + makerFeeHeaderSpec.get() // rt justify - // OR (one of them is an empty string) - + takerFeeHeaderSpec.get() // rt justify - + " %-" + COL_HEADER_TRADE_DEPOSIT_PUBLISHED.length() + "s" // lt justify - + " %-" + COL_HEADER_TRADE_DEPOSIT_CONFIRMED.length() + "s" // lt justify - + "%" + (COL_HEADER_TRADE_BUYER_COST.length() + 1) + "s" // rt justify - + " %-" + (COL_HEADER_TRADE_PAYMENT_SENT.length() - 1) + "s" // left - + " %-" + (COL_HEADER_TRADE_PAYMENT_RECEIVED.length() - 1) + "s" // left - + " %-" + COL_HEADER_TRADE_PAYOUT_PUBLISHED.length() + "s" // lt justify - + " %-" + (COL_HEADER_TRADE_WITHDRAWN.length() + 2) + "s" - + bsqBuyerAddressHeaderSpec.get(); - - return headerLine + formatTradeData(colDataFormat, tradeInfo, isTaker, showBsqBuyerAddress); - } - - private static String formatTradeData(String format, - TradeInfo tradeInfo, - boolean isTaker, - boolean showBsqBuyerAddress) { - return String.format(format, - tradeInfo.getShortId(), - tradeInfo.getRole(), - priceFormat.apply(tradeInfo), - amountFormat.apply(tradeInfo), - makerTakerMinerTxFeeFormat.apply(tradeInfo, isTaker), - makerTakerFeeFormat.apply(tradeInfo, isTaker), - tradeInfo.getIsDepositPublished() ? YES : NO, - tradeInfo.getIsDepositConfirmed() ? YES : NO, - tradeCostFormat.apply(tradeInfo), - tradeInfo.getIsFiatSent() ? YES : NO, - tradeInfo.getIsFiatReceived() ? YES : NO, - tradeInfo.getIsPayoutPublished() ? YES : NO, - tradeInfo.getIsWithdrawn() ? YES : NO, - bsqReceiveAddress.apply(tradeInfo, showBsqBuyerAddress)); - } - - private static final Function priceHeader = (t) -> - t.getOffer().getBaseCurrencyCode().equals("BTC") - ? COL_HEADER_PRICE - : COL_HEADER_PRICE_OF_ALTCOIN; - - private static final Function priceHeaderCurrencyCode = (t) -> - t.getOffer().getBaseCurrencyCode().equals("BTC") - ? t.getOffer().getCounterCurrencyCode() - : t.getOffer().getBaseCurrencyCode(); - - private static final BiFunction makerTakerFeeHeaderCurrencyCode = (t, isTaker) -> { - if (isTaker) { - return t.getIsCurrencyForTakerFeeBtc() ? "BTC" : "BSQ"; - } else { - return t.getOffer().getIsCurrencyForMakerFeeBtc() ? "BTC" : "BSQ"; - } - }; - - private static final Function paymentStatusHeaderCurrencyCode = (t) -> - t.getOffer().getBaseCurrencyCode().equals("BTC") - ? t.getOffer().getCounterCurrencyCode() - : t.getOffer().getBaseCurrencyCode(); - - private static final Function priceFormat = (t) -> - t.getOffer().getBaseCurrencyCode().equals("BTC") - ? formatPrice(t.getTradePrice()) - : formatCryptoCurrencyPrice(t.getTradePrice()); - - private static final Function amountFormat = (t) -> - t.getOffer().getBaseCurrencyCode().equals("BTC") - ? formatSatoshis(t.getTradeAmountAsLong()) - : formatCryptoCurrencyVolume(t.getTradeVolume()); - - private static final BiFunction makerTakerMinerTxFeeFormat = (t, isTaker) -> { - if (isTaker) { - return formatSatoshis(t.getTxFeeAsLong()); - } else { - return formatSatoshis(t.getOffer().getTxFee()); - } - }; - - private static final BiFunction makerTakerFeeFormat = (t, isTaker) -> { - if (isTaker) { - return t.getIsCurrencyForTakerFeeBtc() - ? formatSatoshis(t.getTakerFeeAsLong()) - : formatBsq(t.getTakerFeeAsLong()); - } else { - return t.getOffer().getIsCurrencyForMakerFeeBtc() - ? formatSatoshis(t.getOffer().getMakerFee()) - : formatBsq(t.getOffer().getMakerFee()); - } - }; - - private static final Function tradeCostFormat = (t) -> - t.getOffer().getBaseCurrencyCode().equals("BTC") - ? formatFiatVolume(t.getTradeVolume()) - : formatSatoshis(t.getTradeAmountAsLong()); - - private static final BiFunction bsqReceiveAddress = (t, showBsqBuyerAddress) -> { - if (showBsqBuyerAddress) { - ContractInfo contract = t.getContract(); - boolean isBuyerMakerAndSellerTaker = contract.getIsBuyerMakerAndSellerTaker(); - return isBuyerMakerAndSellerTaker // (is BTC buyer / maker) - ? contract.getTakerPaymentAccountPayload().getAddress() - : contract.getMakerPaymentAccountPayload().getAddress(); - } else { - return ""; - } - }; - - private static boolean shouldShowBsqBuyerAddress(TradeInfo tradeInfo, boolean isTaker) { - if (tradeInfo.getOffer().getBaseCurrencyCode().equals("BTC")) { - return false; - } else { - ContractInfo contract = tradeInfo.getContract(); - // Do not forget buyer and seller refer to BTC buyer and seller, not BSQ - // buyer and seller. If you are buying BSQ, you are the (BTC) seller. - boolean isBuyerMakerAndSellerTaker = contract.getIsBuyerMakerAndSellerTaker(); - if (isTaker) { - return !isBuyerMakerAndSellerTaker; - } else { - return isBuyerMakerAndSellerTaker; - } - } - } -} diff --git a/cli/src/main/java/bisq/cli/TransactionFormat.java b/cli/src/main/java/bisq/cli/TransactionFormat.java deleted file mode 100644 index fd0553c537a..00000000000 --- a/cli/src/main/java/bisq/cli/TransactionFormat.java +++ /dev/null @@ -1,60 +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.cli; - -import bisq.proto.grpc.TxInfo; - -import com.google.common.annotations.VisibleForTesting; - -import static bisq.cli.ColumnHeaderConstants.*; -import static bisq.cli.CurrencyFormat.formatSatoshis; -import static com.google.common.base.Strings.padEnd; - -@Deprecated -@VisibleForTesting -public class TransactionFormat { - - public static String format(TxInfo txInfo) { - String headerLine = padEnd(COL_HEADER_TX_ID, txInfo.getTxId().length(), ' ') + COL_HEADER_DELIMITER - + COL_HEADER_TX_IS_CONFIRMED + COL_HEADER_DELIMITER - + COL_HEADER_TX_INPUT_SUM + COL_HEADER_DELIMITER - + COL_HEADER_TX_OUTPUT_SUM + COL_HEADER_DELIMITER - + COL_HEADER_TX_FEE + COL_HEADER_DELIMITER - + COL_HEADER_TX_SIZE + COL_HEADER_DELIMITER - + (txInfo.getMemo().isEmpty() ? "" : COL_HEADER_TX_MEMO + COL_HEADER_DELIMITER) - + "\n"; - - String colDataFormat = "%-" + txInfo.getTxId().length() + "s" - + " %" + COL_HEADER_TX_IS_CONFIRMED.length() + "s" - + " %" + COL_HEADER_TX_INPUT_SUM.length() + "s" - + " %" + COL_HEADER_TX_OUTPUT_SUM.length() + "s" - + " %" + COL_HEADER_TX_FEE.length() + "s" - + " %" + COL_HEADER_TX_SIZE.length() + "s" - + " %s"; - - return headerLine - + String.format(colDataFormat, - txInfo.getTxId(), - txInfo.getIsPending() ? "NO" : "YES", // pending=true means not confirmed - formatSatoshis(txInfo.getInputSum()), - formatSatoshis(txInfo.getOutputSum()), - formatSatoshis(txInfo.getFee()), - txInfo.getSize(), - txInfo.getMemo().isEmpty() ? "" : txInfo.getMemo()); - } -} diff --git a/cli/src/test/java/bisq/cli/table/AddressCliOutputDiffTest.java b/cli/src/test/java/bisq/cli/table/AddressCliOutputDiffTest.java index 2f8c8542cff..be5fd9de87e 100644 --- a/cli/src/test/java/bisq/cli/table/AddressCliOutputDiffTest.java +++ b/cli/src/test/java/bisq/cli/table/AddressCliOutputDiffTest.java @@ -11,7 +11,6 @@ import bisq.cli.AbstractCliTest; -import bisq.cli.TableFormat; import bisq.cli.table.builder.TableBuilder; @SuppressWarnings("unused") @@ -30,11 +29,13 @@ public AddressCliOutputDiffTest() { private void getFundingAddresses() { var fundingAddresses = aliceClient.getFundingAddresses(); if (fundingAddresses.size() > 0) { - var oldTbl = TableFormat.formatAddressBalanceTbl(fundingAddresses); + // TableFormat class had been deprecated, then deleted on 17-Feb-2022, but + // these diff tests can be useful for testing changes to the current tbl formatting api. + // var oldTbl = TableFormat.formatAddressBalanceTbl(fundingAddresses); var newTbl = new TableBuilder(ADDRESS_BALANCE_TBL, fundingAddresses).build().toString(); - printOldTbl(oldTbl); + // printOldTbl(oldTbl); printNewTbl(newTbl); - checkDiffsIgnoreWhitespace(oldTbl, newTbl); + // checkDiffsIgnoreWhitespace(oldTbl, newTbl); } else { err.println("no funding addresses found"); } @@ -52,10 +53,12 @@ private void getAddressBalance() { private void getAddressBalance(String address) { var addressBalance = singletonList(aliceClient.getAddressBalance(address)); - var oldTbl = TableFormat.formatAddressBalanceTbl(addressBalance); + // TableFormat class had been deprecated, then deleted on 17-Feb-2022, but these + // diff tests can be useful for testing changes to the current tbl formatting api. + // var oldTbl = TableFormat.formatAddressBalanceTbl(addressBalance); var newTbl = new TableBuilder(ADDRESS_BALANCE_TBL, addressBalance).build().toString(); - printOldTbl(oldTbl); + // printOldTbl(oldTbl); printNewTbl(newTbl); - checkDiffsIgnoreWhitespace(oldTbl, newTbl); + // checkDiffsIgnoreWhitespace(oldTbl, newTbl); } } diff --git a/cli/src/test/java/bisq/cli/table/GetBalanceCliOutputDiffTest.java b/cli/src/test/java/bisq/cli/table/GetBalanceCliOutputDiffTest.java index 0fa6d11c3da..d59e87004c2 100644 --- a/cli/src/test/java/bisq/cli/table/GetBalanceCliOutputDiffTest.java +++ b/cli/src/test/java/bisq/cli/table/GetBalanceCliOutputDiffTest.java @@ -6,7 +6,6 @@ import bisq.cli.AbstractCliTest; -import bisq.cli.TableFormat; import bisq.cli.table.builder.TableBuilder; @SuppressWarnings("unused") @@ -24,19 +23,21 @@ public GetBalanceCliOutputDiffTest() { private void getBtcBalance() { var balance = aliceClient.getBtcBalances(); - var oldTbl = TableFormat.formatBtcBalanceInfoTbl(balance); + // TableFormat class had been deprecated, then deleted on 17-Feb-2022, but these + // diff tests can be useful for testing changes to the current tbl formatting api. + // var oldTbl = TableFormat.formatBtcBalanceInfoTbl(balance); var newTbl = new TableBuilder(BTC_BALANCE_TBL, balance).build().toString(); - printOldTbl(oldTbl); + // printOldTbl(oldTbl); printNewTbl(newTbl); - checkDiffsIgnoreWhitespace(oldTbl, newTbl); + // checkDiffsIgnoreWhitespace(oldTbl, newTbl); } private void getBsqBalance() { var balance = aliceClient.getBsqBalances(); - var oldTbl = TableFormat.formatBsqBalanceInfoTbl(balance); + // var oldTbl = TableFormat.formatBsqBalanceInfoTbl(balance); var newTbl = new TableBuilder(BSQ_BALANCE_TBL, balance).build().toString(); - printOldTbl(oldTbl); + // printOldTbl(oldTbl); printNewTbl(newTbl); - checkDiffsIgnoreWhitespace(oldTbl, newTbl); + // checkDiffsIgnoreWhitespace(oldTbl, newTbl); } } diff --git a/cli/src/test/java/bisq/cli/table/GetOffersCliOutputDiffTest.java b/cli/src/test/java/bisq/cli/table/GetOffersCliOutputDiffTest.java index d97c9f8ded2..f5b85bdc62b 100644 --- a/cli/src/test/java/bisq/cli/table/GetOffersCliOutputDiffTest.java +++ b/cli/src/test/java/bisq/cli/table/GetOffersCliOutputDiffTest.java @@ -13,7 +13,6 @@ import bisq.cli.AbstractCliTest; -import bisq.cli.OfferFormat; import bisq.cli.table.builder.TableBuilder; @SuppressWarnings("unused") @@ -116,11 +115,13 @@ private void printAndCheckDiffs(List offers, log.warn("No {} {} offers to print.", direction, currencyCode); } else { log.info("Checking for diffs in {} {} offers.", direction, currencyCode); - var oldTbl = OfferFormat.formatOfferTable(offers, currencyCode); + // OfferFormat class had been deprecated, then deleted on 17-Feb-2022, but + // these diff tests can be useful for testing changes to the current tbl formatting api. + // var oldTbl = OfferFormat.formatOfferTable(offers, currencyCode); var newTbl = new TableBuilder(OFFER_TBL, offers).build().toString(); - printOldTbl(oldTbl); + // printOldTbl(oldTbl); printNewTbl(newTbl); - checkDiffsIgnoreWhitespace(oldTbl, newTbl); + // checkDiffsIgnoreWhitespace(oldTbl, newTbl); } } } diff --git a/cli/src/test/java/bisq/cli/table/GetTradeCliOutputDiffTest.java b/cli/src/test/java/bisq/cli/table/GetTradeCliOutputDiffTest.java index 8516033ee67..25c6ceed5a4 100644 --- a/cli/src/test/java/bisq/cli/table/GetTradeCliOutputDiffTest.java +++ b/cli/src/test/java/bisq/cli/table/GetTradeCliOutputDiffTest.java @@ -9,7 +9,6 @@ import bisq.cli.AbstractCliTest; import bisq.cli.GrpcClient; -import bisq.cli.TradeFormat; import bisq.cli.table.builder.TableBuilder; @SuppressWarnings("unused") @@ -43,10 +42,12 @@ private void getBobsTrade() { private void getTrade(GrpcClient client) { var trade = client.getTrade(tradeId); - var oldTbl = TradeFormat.format(trade); + // TradeFormat class had been deprecated, then deleted on 17-Feb-2022, but these + // diff tests can be useful for testing changes to the current tbl formatting api. + // var oldTbl = TradeFormat.format(trade); var newTbl = new TableBuilder(TRADE_DETAIL_TBL, trade).build().toString(); - printOldTbl(oldTbl); + // printOldTbl(oldTbl); printNewTbl(newTbl); - checkDiffsIgnoreWhitespace(oldTbl, newTbl); + // checkDiffsIgnoreWhitespace(oldTbl, newTbl); } } diff --git a/cli/src/test/java/bisq/cli/table/GetTransactionCliOutputDiffTest.java b/cli/src/test/java/bisq/cli/table/GetTransactionCliOutputDiffTest.java index 13fb639b6ed..d72749cd245 100644 --- a/cli/src/test/java/bisq/cli/table/GetTransactionCliOutputDiffTest.java +++ b/cli/src/test/java/bisq/cli/table/GetTransactionCliOutputDiffTest.java @@ -7,7 +7,6 @@ import bisq.cli.AbstractCliTest; -import bisq.cli.TransactionFormat; import bisq.cli.table.builder.TableBuilder; @SuppressWarnings("unused") @@ -31,11 +30,12 @@ public GetTransactionCliOutputDiffTest(String transactionId) { private void getTransaction() { var tx = aliceClient.getTransaction(transactionId); - var oldTbl = TransactionFormat.format(tx); + // TransactionFormat class had been deprecated, then deleted on 17-Feb-2022, but + // these diff tests can be useful for testing changes to the current tbl formatting api. + // var oldTbl = TransactionFormat.format(tx); var newTbl = new TableBuilder(TRANSACTION_TBL, tx).build().toString(); - printOldTbl(oldTbl); + // printOldTbl(oldTbl); printNewTbl(newTbl); - // Should show 1 (OK) diff due to new 'Is Confirmed' column being left justified (fixed). - checkDiffsIgnoreWhitespace(oldTbl, newTbl); + // checkDiffsIgnoreWhitespace(oldTbl, newTbl); } } diff --git a/cli/src/test/java/bisq/cli/table/PaymentAccountsCliOutputDiffTest.java b/cli/src/test/java/bisq/cli/table/PaymentAccountsCliOutputDiffTest.java index bf1ca88a1c4..30dda73d086 100644 --- a/cli/src/test/java/bisq/cli/table/PaymentAccountsCliOutputDiffTest.java +++ b/cli/src/test/java/bisq/cli/table/PaymentAccountsCliOutputDiffTest.java @@ -2,7 +2,6 @@ import lombok.extern.slf4j.Slf4j; -import static bisq.cli.TableFormat.formatPaymentAcctTbl; import static bisq.cli.table.builder.TableType.PAYMENT_ACCOUNT_TBL; @@ -26,11 +25,13 @@ public PaymentAccountsCliOutputDiffTest() { private void getPaymentAccounts() { var paymentAccounts = aliceClient.getPaymentAccounts(); if (paymentAccounts.size() > 0) { - var oldTbl = formatPaymentAcctTbl(paymentAccounts); + // The formatPaymentAcctTbl method had been deprecated, then deleted on 17-Feb-2022, + // but these diff tests can be useful for testing changes to the current tbl formatting api. + // var oldTbl = formatPaymentAcctTbl(paymentAccounts); var newTbl = new TableBuilder(PAYMENT_ACCOUNT_TBL, paymentAccounts).build().toString(); - printOldTbl(oldTbl); + // printOldTbl(oldTbl); printNewTbl(newTbl); - checkDiffsIgnoreWhitespace(oldTbl, newTbl); + // checkDiffsIgnoreWhitespace(oldTbl, newTbl); } else { log.warn("no payment accounts found"); } From 461edff6311b9d3ee74f4a83098a39deb8a7a709 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 17:27:15 -0300 Subject: [PATCH 02/41] Change OfferInfo proto's 'price' field type to string Much less ambiguous field value at cost of breaking backward compat in API. --- .../main/java/bisq/core/api/model/OfferInfo.java | 8 ++++++-- .../core/api/model/builder/OfferInfoBuilder.java | 4 ++-- proto/src/main/proto/grpc.proto | 13 +++++-------- 3 files changed, 13 insertions(+), 12 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 7e4c8c49b13..53e2f6537d8 100644 --- a/core/src/main/java/bisq/core/api/model/OfferInfo.java +++ b/core/src/main/java/bisq/core/api/model/OfferInfo.java @@ -28,6 +28,7 @@ import lombok.Getter; import lombok.ToString; +import static bisq.core.util.PriceUtil.reformatMarketPrice; import static java.util.Objects.requireNonNull; @EqualsAndHashCode @@ -41,7 +42,7 @@ public class OfferInfo implements Payload { private final String id; private final String direction; - private final long price; + private final String price; private final boolean useMarketBasedPrice; private final double marketPriceMargin; private final long amount; @@ -136,10 +137,13 @@ public static OfferInfo toMyOfferInfo(OpenOffer openOffer) { } private static OfferInfoBuilder getBuilder(Offer offer, boolean isMyOffer) { + var preciseOfferPrice = reformatMarketPrice( + requireNonNull(offer.getPrice()).toPlainString(), + offer.getCurrencyCode()); return new OfferInfoBuilder() .withId(offer.getId()) .withDirection(offer.getDirection().name()) - .withPrice(requireNonNull(offer.getPrice()).getValue()) + .withPrice(preciseOfferPrice) .withUseMarketBasedPrice(offer.isUseMarketBasedPrice()) .withMarketPriceMargin(offer.getMarketPriceMargin()) .withAmount(offer.getAmount().value) diff --git a/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java b/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java index 3773b465f72..556ef9b2a48 100644 --- a/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java +++ b/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java @@ -32,7 +32,7 @@ public final class OfferInfoBuilder { private String id; private String direction; - private long price; + private String price; private boolean useMarketBasedPrice; private double marketPriceMargin; private long amount; @@ -72,7 +72,7 @@ public OfferInfoBuilder withDirection(String direction) { return this; } - public OfferInfoBuilder withPrice(long price) { + public OfferInfoBuilder withPrice(String price) { this.price = price; return this; } diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index f39ce446bb5..51a2229445b 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -242,8 +242,8 @@ message EditOfferRequest { // 0 = disable // 1 = enable sint32 enable = 6; - // The EditType determines and constricts what offer details can - // be modified by the request, simplifying param validation. + // The EditType determines and constricts what offer details can be modified by the request, simplifying param + // validation. (The CLI need to infer this detail from 'editoffer' command options, other clients do not.) enum EditType { // Edit only the offer's activation state (enabled or disabled). ACTIVATION_STATE_ONLY = 0; @@ -286,12 +286,9 @@ message OfferInfo { string id = 1; // The offer's BUY (BTC) or SELL (BTC) direction. string direction = 2; - // For fiat offers: a long representing the BTC price of the offer to 4 decimal places. - // A USD fiat price of 45000.4321 USD is represented as 450004321. - // For altcoin offers: a long representing the BTC price of the offer in satoshis. - // An altcoin price of five hundred thousand satoshis is represented as 500000. - // TODO: Change to string type. - uint64 price = 3; + // For fiat offers: the fiat price for 1 BTC to 4 decimal places, e.g., 45000 EUR is "45000.0000". + // For altcoin offers: the altcoin price for 1 BTC to 8 decimal places, e.g., 0.5 BTC is "0.00005000". + string price = 3; // Whether the offer price is fixed, or market price margin based. bool useMarketBasedPrice = 4; // The offer's market price margin above or below the current market BTC price, represented as a decimal. From 3405dbf5c3d53972ecac312403e0bb6bc1968846 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 17:57:45 -0300 Subject: [PATCH 03/41] Adjust cli module to OfferInfo.price field change to string type --- cli/src/main/java/bisq/cli/CurrencyFormat.java | 1 + .../bisq/cli/request/OffersServiceRequest.java | 15 +++------------ .../bisq/cli/table/builder/OfferTableBuilder.java | 14 +++++++------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java index a9d87146199..9f8df8fe88f 100644 --- a/cli/src/main/java/bisq/cli/CurrencyFormat.java +++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java @@ -123,6 +123,7 @@ public static String formatInternalFiatPrice(double price) { return FRIENDLY_NUMBER_FORMAT.format(price); } + // TODO Deprecate after triggerPrice field type is changed to string. public static String formatPrice(long price) { FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(4); FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(4); diff --git a/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java b/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java index 7214d8bc0f8..20b9dc2c024 100644 --- a/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java +++ b/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java @@ -29,11 +29,8 @@ import bisq.proto.grpc.GetOffersRequest; import bisq.proto.grpc.OfferInfo; -import java.math.BigDecimal; - import java.util.ArrayList; import java.util.List; -import java.util.function.Function; import static bisq.cli.CryptoCurrencyUtil.apiDoesSupportCryptoCurrency; import static bisq.proto.grpc.EditOfferRequest.EditType.ACTIVATION_STATE_ONLY; @@ -52,12 +49,6 @@ public class OffersServiceRequest { - private final Function scaledPriceStringRequestFormat = (price) -> { - BigDecimal factor = new BigDecimal(10).pow(4); - //noinspection BigDecimalMethodWithoutRoundingCalled - return new BigDecimal(price).divide(factor).toPlainString(); - }; - private final GrpcStubs grpcStubs; public OffersServiceRequest(GrpcStubs grpcStubs) { @@ -159,11 +150,11 @@ public OfferInfo createOffer(String direction, public void editOfferActivationState(String offerId, int enable) { var offer = getMyOffer(offerId); - var scaledPriceString = offer.getUseMarketBasedPrice() + var offerPrice = offer.getUseMarketBasedPrice() ? "0.00" - : scaledPriceStringRequestFormat.apply(offer.getPrice()); + : offer.getPrice(); editOffer(offerId, - scaledPriceString, + offerPrice, offer.getUseMarketBasedPrice(), offer.getMarketPriceMargin(), offer.getTriggerPrice(), diff --git a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java index 08d19c09106..e9ddc14e18d 100644 --- a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java @@ -80,7 +80,7 @@ public Table build() { public Table buildFiatOfferTable(List offers) { @Nullable Column colEnabled = enabledColumn.get(); // Not boolean: YES, NO, or PENDING - Column colFiatPrice = new FiatColumn(format(COL_HEADER_DETAILED_PRICE, fiatTradeCurrency.get())); + Column colFiatPrice = new StringColumn(format(COL_HEADER_DETAILED_PRICE, fiatTradeCurrency.get()), RIGHT); Column colFiatVolume = new FiatColumn(format("Temp Volume (%s)", fiatTradeCurrency.get()), NONE, VOLUME); Column colMinFiatVolume = new FiatColumn(format("Temp Min Volume (%s)", fiatTradeCurrency.get()), NONE, VOLUME); @Nullable @@ -121,7 +121,7 @@ public Table buildFiatOfferTable(List offers) { if (isShowingMyOffers.get()) { return new Table(colEnabled.asStringColumn(), colDirection, - colFiatPrice.asStringColumn(), + colFiatPrice.justify(), amountRange.asStringColumn(EXCLUDE_DUPLICATES), volumeRange.asStringColumn(EXCLUDE_DUPLICATES), colTriggerPrice.asStringColumn(), @@ -130,7 +130,7 @@ public Table buildFiatOfferTable(List offers) { colOfferId); } else { return new Table(colDirection, - colFiatPrice.asStringColumn(), + colFiatPrice.justify(), amountRange.asStringColumn(EXCLUDE_DUPLICATES), volumeRange.asStringColumn(EXCLUDE_DUPLICATES), colPaymentMethod, @@ -143,7 +143,7 @@ public Table buildFiatOfferTable(List offers) { public Table buildCryptoCurrencyOfferTable(List offers) { @Nullable Column colEnabled = enabledColumn.get(); // Not boolean: YES, NO, or PENDING - Column colBtcPrice = new SatoshiColumn(format(COL_HEADER_DETAILED_PRICE_OF_ALTCOIN, altcoinTradeCurrency.get())); + Column colBtcPrice = new StringColumn(format(COL_HEADER_DETAILED_PRICE_OF_ALTCOIN, altcoinTradeCurrency.get()), RIGHT); Column colBtcVolume = new AltcoinColumn(format("Temp Volume (%s)", altcoinTradeCurrency.get()), NONE, ALTCOIN_OFFER_VOLUME); @@ -189,7 +189,7 @@ public Table buildCryptoCurrencyOfferTable(List offers) { if (isShowingBsqOffers.get()) { return new Table(colEnabled.asStringColumn(), colDirection, - colBtcPrice.asStringColumn(), + colBtcPrice.justify(), amountRange.asStringColumn(EXCLUDE_DUPLICATES), volumeRange.asStringColumn(EXCLUDE_DUPLICATES), colPaymentMethod, @@ -198,7 +198,7 @@ public Table buildCryptoCurrencyOfferTable(List offers) { } else { return new Table(colEnabled.asStringColumn(), colDirection, - colBtcPrice.asStringColumn(), + colBtcPrice.justify(), amountRange.asStringColumn(EXCLUDE_DUPLICATES), volumeRange.asStringColumn(EXCLUDE_DUPLICATES), colTriggerPrice.asStringColumn(), @@ -208,7 +208,7 @@ public Table buildCryptoCurrencyOfferTable(List offers) { } } else { return new Table(colDirection, - colBtcPrice.asStringColumn(), + colBtcPrice.justify(), amountRange.asStringColumn(EXCLUDE_DUPLICATES), volumeRange.asStringColumn(EXCLUDE_DUPLICATES), colPaymentMethod, From 89267e5851bb1c7ab27a21a7d6fb3838b0889240 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 18:11:46 -0300 Subject: [PATCH 04/41] Fix typo in comment --- proto/src/main/proto/grpc.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 51a2229445b..5088dce390c 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -287,7 +287,7 @@ message OfferInfo { // The offer's BUY (BTC) or SELL (BTC) direction. string direction = 2; // For fiat offers: the fiat price for 1 BTC to 4 decimal places, e.g., 45000 EUR is "45000.0000". - // For altcoin offers: the altcoin price for 1 BTC to 8 decimal places, e.g., 0.5 BTC is "0.00005000". + // For altcoin offers: the altcoin price for 1 BTC to 8 decimal places, e.g., 0.00005 BTC is "0.00005000". string price = 3; // Whether the offer price is fixed, or market price margin based. bool useMarketBasedPrice = 4; From 1d70b1bb5f5ae6cf6b2ca5dd4b303ed3a15a93a6 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 18:18:54 -0300 Subject: [PATCH 05/41] Adjust apitest cases to OfferInfo.price proto field type to string --- .../method/offer/AbstractOfferTest.java | 22 ++-- .../method/offer/BsqSwapOfferTest.java | 2 +- .../method/offer/CreateBSQOffersTest.java | 16 +-- .../offer/CreateOfferUsingFixedPriceTest.java | 12 +- ...CreateOfferUsingMarketPriceMarginTest.java | 17 +-- .../method/offer/CreateXMROffersTest.java | 8 +- .../apitest/method/offer/EditOfferTest.java | 106 +++++++++--------- .../method/trade/BsqSwapBuyBtcTradeTest.java | 2 +- .../method/trade/BsqSwapSellBtcTradeTest.java | 2 +- .../LongRunningOfferDeactivationTest.java | 4 +- 10 files changed, 88 insertions(+), 103 deletions(-) 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 57495bb696a..4b64cd5308f 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java @@ -24,6 +24,7 @@ import protobuf.PaymentAccount; import java.math.BigDecimal; +import java.math.MathContext; import java.util.ArrayList; import java.util.List; @@ -100,13 +101,6 @@ public static void setUp() { return price.multiply(factor).longValue(); }; - // Price value of altcoin offer returned from server will be scaled up by 10^8. - protected final Function scaledUpAltcoinOfferPrice = (altcoinPriceAsString) -> { - BigDecimal factor = new BigDecimal(10).pow(8); - BigDecimal priceAsBigDecimal = new BigDecimal(altcoinPriceAsString); - return priceAsBigDecimal.multiply(factor).longValue(); - }; - protected final BiFunction calcFiatTriggerPriceAsLong = (base, delta) -> { var priceAsDouble = new BigDecimal(base).add(new BigDecimal(delta)).doubleValue(); return Double.valueOf(exactMultiply(priceAsDouble, 10_000)).longValue(); @@ -117,18 +111,20 @@ public static void setUp() { return Double.valueOf(exactMultiply(priceAsDouble, 100_000_000)).longValue(); }; - protected final BiFunction calcPriceAsString = (base, delta) -> { - var priceAsBigDecimal = new BigDecimal(Double.toString(base)) - .add(new BigDecimal(Double.toString(delta))); - return priceAsBigDecimal.toPlainString(); - }; - protected final Function toOfferTable = (offer) -> new TableBuilder(OFFER_TBL, offer).build().toString(); protected final Function, String> toOffersTable = (offers) -> new TableBuilder(OFFER_TBL, offers).build().toString(); + protected String calcPriceAsString(double base, double delta, int precision) { + var mathContext = new MathContext(precision); + var priceAsBigDecimal = new BigDecimal(Double.toString(base), mathContext) + .add(new BigDecimal(Double.toString(delta), mathContext)) + .round(mathContext); + return String.format("%." + precision + "f", priceAsBigDecimal.doubleValue()); + } + protected OfferInfo getAvailableBsqSwapOffer(GrpcClient client, OfferDirection direction, boolean checkForLoggedExceptions) { diff --git a/apitest/src/test/java/bisq/apitest/method/offer/BsqSwapOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/BsqSwapOfferTest.java index c506794201e..60e96ca3dea 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/BsqSwapOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/BsqSwapOfferTest.java @@ -117,7 +117,7 @@ private void createBsqSwapOffer() { var newOfferId = bsqSwapOffer.getId(); assertNotEquals("", newOfferId); assertEquals(BUY.name(), bsqSwapOffer.getDirection()); - assertEquals(5_000, bsqSwapOffer.getPrice()); + assertEquals("0.00005000", bsqSwapOffer.getPrice()); assertEquals(1_000_000L, bsqSwapOffer.getAmount()); assertEquals(1_000_000L, bsqSwapOffer.getMinAmount()); assertEquals(BSQ, bsqSwapOffer.getBaseCurrencyCode()); diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java index 43f87fd1568..57b318e68ed 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java @@ -74,7 +74,7 @@ public void testCreateBuy1BTCFor20KBSQOffer() { assertNotEquals("", newOfferId); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(5_000, newOffer.getPrice()); + assertEquals("0.00005000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getMinAmount()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); @@ -91,7 +91,7 @@ public void testCreateBuy1BTCFor20KBSQOffer() { assertEquals(newOfferId, newOffer.getId()); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(5_000, newOffer.getPrice()); + assertEquals("0.00005000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getMinAmount()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); @@ -121,7 +121,7 @@ public void testCreateSell1BTCFor20KBSQOffer() { assertNotEquals("", newOfferId); assertEquals(SELL.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(5_000, newOffer.getPrice()); + assertEquals("0.00005000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getMinAmount()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); @@ -138,7 +138,7 @@ public void testCreateSell1BTCFor20KBSQOffer() { assertEquals(newOfferId, newOffer.getId()); assertEquals(SELL.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(5_000, newOffer.getPrice()); + assertEquals("0.00005000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getMinAmount()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); @@ -168,7 +168,7 @@ public void testCreateBuyBTCWith1To2KBSQOffer() { assertNotEquals("", newOfferId); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(5_000, newOffer.getPrice()); + assertEquals("0.00005000", newOffer.getPrice()); assertEquals(10_000_000L, newOffer.getAmount()); assertEquals(5_000_000L, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -185,7 +185,7 @@ public void testCreateBuyBTCWith1To2KBSQOffer() { assertEquals(newOfferId, newOffer.getId()); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(5_000, newOffer.getPrice()); + assertEquals("0.00005000", newOffer.getPrice()); assertEquals(10_000_000L, newOffer.getAmount()); assertEquals(5_000_000L, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -215,7 +215,7 @@ public void testCreateSellBTCFor5To10KBSQOffer() { assertNotEquals("", newOfferId); assertEquals(SELL.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(5_000, newOffer.getPrice()); + assertEquals("0.00005000", newOffer.getPrice()); assertEquals(50_000_000L, newOffer.getAmount()); assertEquals(25_000_000L, newOffer.getMinAmount()); assertEquals(7_500_000, newOffer.getBuyerSecurityDeposit()); @@ -232,7 +232,7 @@ public void testCreateSellBTCFor5To10KBSQOffer() { assertEquals(newOfferId, newOffer.getId()); assertEquals(SELL.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(5_000, newOffer.getPrice()); + assertEquals("0.00005000", newOffer.getPrice()); assertEquals(50_000_000L, newOffer.getAmount()); assertEquals(25_000_000L, newOffer.getMinAmount()); assertEquals(7_500_000, newOffer.getBuyerSecurityDeposit()); 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 7ec7d98d1d4..fb921a2cbdd 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java @@ -66,7 +66,7 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() { assertNotEquals("", newOfferId); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(360_000_000, newOffer.getPrice()); + assertEquals("36000.0000", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -81,7 +81,7 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() { assertEquals(newOfferId, newOffer.getId()); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(360_000_000, newOffer.getPrice()); + assertEquals("36000.0000", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -111,7 +111,7 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() { assertNotEquals("", newOfferId); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(300_001_234, newOffer.getPrice()); + assertEquals("30000.1234", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -126,7 +126,7 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() { assertEquals(newOfferId, newOffer.getId()); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(300_001_234, newOffer.getPrice()); + assertEquals("30000.1234", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -156,7 +156,7 @@ public void testCreateEURBTCSellOfferUsingFixedPrice95001234() { assertNotEquals("", newOfferId); assertEquals(SELL.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(295_001_234, newOffer.getPrice()); + assertEquals("29500.1234", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -171,7 +171,7 @@ public void testCreateEURBTCSellOfferUsingFixedPrice95001234() { assertEquals(newOfferId, newOffer.getId()); assertEquals(SELL.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(295_001_234, newOffer.getPrice()); + assertEquals("29500.1234", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); 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 cce443206a3..a4f7f23e993 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java @@ -17,14 +17,11 @@ package bisq.apitest.method.offer; -import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; import bisq.core.payment.PaymentAccount; import bisq.proto.grpc.OfferInfo; -import org.bitcoinj.utils.Fiat; - import java.text.DecimalFormat; import java.math.BigDecimal; @@ -43,7 +40,6 @@ import static bisq.common.util.MathUtils.scaleDownByPowerOf10; import static bisq.common.util.MathUtils.scaleUpByPowerOf10; import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; -import static bisq.core.locale.CurrencyUtil.isCryptoCurrency; import static java.lang.Math.abs; import static java.lang.String.format; import static java.math.RoundingMode.HALF_UP; @@ -287,17 +283,17 @@ private void assertCalculatedPriceIsCorrect(OfferInfo offer, double priceMarginP assertTrue(() -> { String counterCurrencyCode = offer.getCounterCurrencyCode(); double mktPrice = aliceClient.getBtcPrice(counterCurrencyCode); - double scaledOfferPrice = getScaledOfferPrice(offer.getPrice(), counterCurrencyCode); + double priceAsDouble = Double.parseDouble(offer.getPrice()); double expectedDiffPct = scaleDownByPowerOf10(priceMarginPctInput, 2); double actualDiffPct = offer.getDirection().equals(BUY.name()) - ? getPercentageDifference(scaledOfferPrice, mktPrice) - : getPercentageDifference(mktPrice, scaledOfferPrice); + ? getPercentageDifference(priceAsDouble, mktPrice) + : getPercentageDifference(mktPrice, priceAsDouble); double pctDiffDelta = abs(expectedDiffPct) - abs(actualDiffPct); return isCalculatedPriceWithinErrorTolerance(pctDiffDelta, expectedDiffPct, actualDiffPct, mktPrice, - scaledOfferPrice, + priceAsDouble, offer); }); } @@ -308,11 +304,6 @@ private double getPercentageDifference(double price1, double price2) { .doubleValue(); } - private double getScaledOfferPrice(double offerPrice, String currencyCode) { - int precision = isCryptoCurrency(currencyCode) ? Altcoin.SMALLEST_UNIT_EXPONENT : Fiat.SMALLEST_UNIT_EXPONENT; - return scaleDownByPowerOf10(offerPrice, precision); - } - private boolean isCalculatedPriceWithinErrorTolerance(double delta, double expectedDiffPct, double actualDiffPct, diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java index cf40632e8d9..b945238d7ea 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java @@ -77,7 +77,7 @@ public void testCreateFixedPriceBuy1BTCFor200KXMROffer() { assertNotEquals("", newOfferId); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(500_000L, newOffer.getPrice()); + assertEquals("0.00500000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(75_000_000L, newOffer.getMinAmount()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); @@ -94,7 +94,7 @@ public void testCreateFixedPriceBuy1BTCFor200KXMROffer() { assertEquals(newOfferId, newOffer.getId()); assertEquals(BUY.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(500_000L, newOffer.getPrice()); + assertEquals("0.00500000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(75_000_000L, newOffer.getMinAmount()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); @@ -124,7 +124,7 @@ public void testCreateFixedPriceSell1BTCFor200KXMROffer() { assertNotEquals("", newOfferId); assertEquals(SELL.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(500_000L, newOffer.getPrice()); + assertEquals("0.00500000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(50_000_000L, newOffer.getMinAmount()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); @@ -141,7 +141,7 @@ public void testCreateFixedPriceSell1BTCFor200KXMROffer() { assertEquals(newOfferId, newOffer.getId()); assertEquals(SELL.name(), newOffer.getDirection()); assertFalse(newOffer.getUseMarketBasedPrice()); - assertEquals(500_000L, newOffer.getPrice()); + assertEquals("0.00500000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(50_000_000L, newOffer.getMinAmount()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); diff --git a/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java index 33944dece8d..b0401c6522b 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java @@ -67,7 +67,7 @@ public void testOfferDisableAndEnable() { NO_TRIGGER_PRICE); log.debug("Original EUR offer:\n{}", toOfferTable.apply(originalOffer)); assertFalse(originalOffer.getIsActivated()); // Not activated until prep is done. - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); assertTrue(originalOffer.getIsActivated()); // Disable offer @@ -98,7 +98,7 @@ public void testEditTriggerPrice() { 0.0, NO_TRIGGER_PRICE); log.debug("Original EUR offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); assertEquals(0 /*no trigger price*/, originalOffer.getTriggerPrice()); @@ -127,7 +127,7 @@ public void testSetTriggerPriceToNegativeValueShouldThrowException() { 0.0, NO_TRIGGER_PRICE); log.debug("Original EUR offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. // Edit the offer's trigger price, set to -1, check error. Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOfferTriggerPrice(originalOffer.getId(), -1L)); @@ -148,7 +148,7 @@ public void testEditMktPriceMargin() { originalMktPriceMargin, NO_TRIGGER_PRICE); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin()); // Edit the offer's price margin, nothing else. var newMktPriceMargin = new BigDecimal("0.5").doubleValue(); @@ -166,22 +166,21 @@ public void testEditMktPriceMargin() { public void testEditFixedPrice() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU"); double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE); - String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000); + String fixedPriceAsString = calcPriceAsString(mktPriceAsDouble, 200_000.0000, 4); var originalOffer = createFixedPricedOfferForEdit(BUY.name(), RUBLE, paymentAcct.getId(), fixedPriceAsString); log.debug("Original RUB offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. // Edit the offer's fixed price, nothing else. - String editedFixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 100_000.0000); + String editedFixedPriceAsString = calcPriceAsString(mktPriceAsDouble, 100_000.0000, 4); aliceClient.editOfferFixedPrice(originalOffer.getId(), editedFixedPriceAsString); // Wait for edited offer to be removed from offer-book, edited, and re-published. genBtcBlocksThenWait(1, 2_500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited RUB offer:\n{}", toOfferTable.apply(editedOffer)); - var expectedNewFixedPrice = scaledUpFiatOfferPrice.apply(new BigDecimal(editedFixedPriceAsString)); - assertEquals(expectedNewFixedPrice, editedOffer.getPrice()); + assertEquals(editedFixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); doSanityCheck(originalOffer, editedOffer); @@ -192,15 +191,15 @@ public void testEditFixedPrice() { public void testEditFixedPriceAndDeactivation() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU"); double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE); - String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000); + String fixedPriceAsString = calcPriceAsString(mktPriceAsDouble, 200_000.0000, 4); var originalOffer = createFixedPricedOfferForEdit(BUY.name(), RUBLE, paymentAcct.getId(), fixedPriceAsString); log.debug("Original RUB offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. // Edit the offer's fixed price and deactivate it. - String editedFixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 100_000.0000); + String editedFixedPriceAsString = calcPriceAsString(mktPriceAsDouble, 100_000.0000, 4); aliceClient.editOffer(originalOffer.getId(), editedFixedPriceAsString, originalOffer.getUseMarketBasedPrice(), @@ -212,8 +211,7 @@ public void testEditFixedPriceAndDeactivation() { genBtcBlocksThenWait(1, 2_500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited RUB offer:\n{}", toOfferTable.apply(editedOffer)); - var expectedNewFixedPrice = scaledUpFiatOfferPrice.apply(new BigDecimal(editedFixedPriceAsString)); - assertEquals(expectedNewFixedPrice, editedOffer.getPrice()); + assertEquals(editedFixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getIsActivated()); assertFalse(editedOffer.getUseMarketBasedPrice()); @@ -232,7 +230,7 @@ public void testEditMktPriceMarginAndDeactivation() { originalMktPriceMargin, 0); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin()); @@ -270,7 +268,7 @@ public void testEditMktPriceMarginAndTriggerPriceAndDeactivation() { originalMktPriceMargin, originalTriggerPriceAsLong); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin()); assertEquals(originalTriggerPriceAsLong, originalOffer.getTriggerPrice()); @@ -307,7 +305,7 @@ public void testEditingFixedPriceInMktPriceMarginBasedOfferShouldThrowException( originalMktPriceMargin, NO_TRIGGER_PRICE); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. // Try to edit both the fixed price and mkt price margin. var newMktPriceMargin = new BigDecimal("0.25").doubleValue(); var newFixedPrice = "50000.0000"; @@ -332,13 +330,13 @@ public void testEditingFixedPriceInMktPriceMarginBasedOfferShouldThrowException( public void testEditingTriggerPriceInFixedPriceOfferShouldThrowException() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("RU"); double mktPriceAsDouble = aliceClient.getBtcPrice(RUBLE); - String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 200_000.0000); + String fixedPriceAsString = calcPriceAsString(mktPriceAsDouble, 200_000.0000, 4); var originalOffer = createFixedPricedOfferForEdit(BUY.name(), RUBLE, paymentAcct.getId(), fixedPriceAsString); log.debug("Original RUB offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. long newTriggerPrice = 1000000L; Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOfferTriggerPrice(originalOffer.getId(), newTriggerPrice)); @@ -354,13 +352,13 @@ public void testEditingTriggerPriceInFixedPriceOfferShouldThrowException() { public void testChangeFixedPriceOfferToPriceMarginBasedOfferWithTriggerPrice() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("MX"); double mktPriceAsDouble = aliceClient.getBtcPrice("MXN"); - String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 0.00); + String fixedPriceAsString = calcPriceAsString(mktPriceAsDouble, 0.00, 4); var originalOffer = createFixedPricedOfferForEdit(BUY.name(), "MXN", paymentAcct.getId(), fixedPriceAsString); log.debug("Original MXN offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. // Change the offer to mkt price based and set a trigger price. var newMktPriceMargin = new BigDecimal("0.05").doubleValue(); @@ -399,9 +397,9 @@ public void testChangePriceMarginBasedOfferToFixedPriceOfferAndDeactivateIt() { originalMktPriceMargin, originalTriggerPriceAsLong); log.debug("Original GBP offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. - String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 0.00); + String fixedPriceAsString = calcPriceAsString(mktPriceAsDouble, 0.00, 4); aliceClient.editOffer(originalOffer.getId(), fixedPriceAsString, false, @@ -413,7 +411,7 @@ public void testChangePriceMarginBasedOfferToFixedPriceOfferAndDeactivateIt() { genBtcBlocksThenWait(1, 2_500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited GBP offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(scaledUpFiatOfferPrice.apply(new BigDecimal(fixedPriceAsString)), editedOffer.getPrice()); + assertEquals(fixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); assertEquals(0, editedOffer.getTriggerPrice()); @@ -432,7 +430,7 @@ public void testChangeFixedPricedBsqOfferToPriceMarginBasedOfferShouldThrowExcep alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOffer(originalOffer.getId(), "0.00", @@ -459,7 +457,7 @@ public void testEditTriggerPriceOnFixedPriceBsqOfferShouldThrowException() { alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. var newTriggerPriceAsLong = calcFiatTriggerPriceAsLong.apply(0.00005, 0.00); Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOffer(originalOffer.getId(), @@ -488,7 +486,7 @@ public void testEditFixedPriceOnBsqOffer() { alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. String newFixedPriceAsString = "0.00003111"; aliceClient.editOffer(originalOffer.getId(), newFixedPriceAsString, @@ -501,7 +499,7 @@ public void testEditFixedPriceOnBsqOffer() { genBtcBlocksThenWait(1, 2_500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited BSQ offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice()); + assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertTrue(editedOffer.getIsActivated()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); @@ -511,7 +509,7 @@ public void testEditFixedPriceOnBsqOffer() { @Test @Order(16) public void testDisableBsqOffer() { - String fixedPriceAsString = "0.00005"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ + String fixedPriceAsString = "0.00005000"; var originalOffer = aliceClient.createFixedPricedOffer(BUY.name(), BSQ, 100_000_000L, @@ -521,7 +519,7 @@ public void testDisableBsqOffer() { alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. aliceClient.editOffer(originalOffer.getId(), fixedPriceAsString, false, @@ -534,7 +532,7 @@ public void testDisableBsqOffer() { OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited BSQ offer:\n{}", toOfferTable.apply(editedOffer)); assertFalse(editedOffer.getIsActivated()); - assertEquals(scaledUpAltcoinOfferPrice.apply(fixedPriceAsString), editedOffer.getPrice()); + assertEquals(fixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); assertEquals(0, editedOffer.getTriggerPrice()); @@ -543,7 +541,7 @@ public void testDisableBsqOffer() { @Test @Order(17) public void testEditFixedPriceAndDisableBsqOffer() { - String fixedPriceAsString = "0.00005"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ + String fixedPriceAsString = "0.00005000"; var originalOffer = aliceClient.createFixedPricedOffer(BUY.name(), BSQ, 100_000_000L, @@ -553,8 +551,8 @@ public void testEditFixedPriceAndDisableBsqOffer() { alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. - String newFixedPriceAsString = "0.000045"; + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. + String newFixedPriceAsString = "0.00004500"; aliceClient.editOffer(originalOffer.getId(), newFixedPriceAsString, false, @@ -567,7 +565,7 @@ public void testEditFixedPriceAndDisableBsqOffer() { OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited BSQ offer:\n{}", toOfferTable.apply(editedOffer)); assertFalse(editedOffer.getIsActivated()); - assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice()); + assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); assertEquals(0, editedOffer.getTriggerPrice()); @@ -587,12 +585,12 @@ public void testChangePriceMarginBasedXmrOfferWithTriggerPriceToFixedPricedAndDe 0.0, triggerPriceAsLong); log.debug("Pending XMR offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); - String newFixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, -0.001); + String newFixedPriceAsString = calcPriceAsString(mktPriceAsDouble, -0.001, 8); aliceClient.editOffer(originalOffer.getId(), newFixedPriceAsString, false, @@ -604,7 +602,7 @@ public void testChangePriceMarginBasedXmrOfferWithTriggerPriceToFixedPricedAndDe genBtcBlocksThenWait(1, 2500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice()); + assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); assertEquals(0, editedOffer.getTriggerPrice()); @@ -624,7 +622,7 @@ public void testEditTriggerPriceOnPriceMarginBasedXmrOffer() { mktPriceMargin, NO_TRIGGER_PRICE); log.debug("Pending XMR offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); log.info("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); @@ -655,7 +653,7 @@ public void testEditTriggerPriceOnPriceMarginBasedXmrOffer() { public void testChangeFixedPricedXmrOfferToPriceMarginBasedOfferWithTriggerPrice() { createXmrPaymentAccounts(); double mktPriceAsDouble = aliceClient.getBtcPrice(XMR); - String fixedPriceAsString = calcPriceAsString.apply(mktPriceAsDouble, 0.00); + String fixedPriceAsString = calcPriceAsString(mktPriceAsDouble, 0.00, 8); OfferInfo originalOffer = aliceClient.createFixedPricedOffer(BUY.name(), XMR, 100_000_000L, @@ -665,7 +663,7 @@ public void testChangeFixedPricedXmrOfferToPriceMarginBasedOfferWithTriggerPrice alicesXmrAcct.getId(), BSQ); log.debug("Pending XMR offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); @@ -706,7 +704,7 @@ public void testEditTriggerPriceOnFixedPriceXmrOfferShouldThrowException() { alicesXmrAcct.getId(), BSQ); log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. var newTriggerPriceAsLong = calcAltcoinTriggerPriceAsLong.apply(0.007, 0.001); Throwable exception = assertThrows(StatusRuntimeException.class, () -> @@ -737,8 +735,8 @@ public void testEditFixedPriceOnXmrOffer() { alicesXmrAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. - String newFixedPriceAsString = "0.009"; + genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. + String newFixedPriceAsString = "0.00900000"; aliceClient.editOffer(originalOffer.getId(), newFixedPriceAsString, false, @@ -750,7 +748,7 @@ public void testEditFixedPriceOnXmrOffer() { genBtcBlocksThenWait(1, 2500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice()); + assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertTrue(editedOffer.getIsActivated()); assertMarketBasedPriceFieldsAreIgnored(editedOffer); @@ -761,7 +759,7 @@ public void testEditFixedPriceOnXmrOffer() { @Order(23) public void testDisableXmrOffer() { createXmrPaymentAccounts(); - String fixedPriceAsString = "0.008"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ + String fixedPriceAsString = "0.00800000"; final OfferInfo originalOffer = aliceClient.createFixedPricedOffer(BUY.name(), XMR, 100_000_000L, @@ -771,7 +769,7 @@ public void testDisableXmrOffer() { alicesXmrAcct.getId(), BSQ); log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. aliceClient.editOffer(originalOffer.getId(), fixedPriceAsString, false, @@ -784,7 +782,7 @@ public void testDisableXmrOffer() { OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); assertFalse(editedOffer.getIsActivated()); - assertEquals(scaledUpAltcoinOfferPrice.apply(fixedPriceAsString), editedOffer.getPrice()); + assertEquals(fixedPriceAsString, editedOffer.getPrice()); assertMarketBasedPriceFieldsAreIgnored(editedOffer); doSanityCheck(originalOffer, editedOffer); @@ -794,7 +792,7 @@ public void testDisableXmrOffer() { @Order(24) public void testEditFixedPriceAndDisableXmrOffer() { createXmrPaymentAccounts(); - String fixedPriceAsString = "0.004"; // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ + String fixedPriceAsString = "0.004"; final OfferInfo originalOffer = aliceClient.createFixedPricedOffer(BUY.name(), XMR, 100_000_000L, @@ -804,8 +802,8 @@ public void testEditFixedPriceAndDisableXmrOffer() { alicesXmrAcct.getId(), BSQ); log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. - String newFixedPriceAsString = "0.000045"; + genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. + String newFixedPriceAsString = "0.00004500"; aliceClient.editOffer(originalOffer.getId(), newFixedPriceAsString, false, @@ -818,7 +816,7 @@ public void testEditFixedPriceAndDisableXmrOffer() { OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); assertFalse(editedOffer.getIsActivated()); - assertEquals(scaledUpAltcoinOfferPrice.apply(newFixedPriceAsString), editedOffer.getPrice()); + assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertMarketBasedPriceFieldsAreIgnored(editedOffer); doSanityCheck(originalOffer, editedOffer); @@ -837,14 +835,14 @@ public void testEditBsqSwapOfferShouldThrowException() { var newOfferId = originalOffer.getId(); assertNotEquals("", newOfferId); assertEquals(SELL.name(), originalOffer.getDirection()); - assertEquals(5_000, originalOffer.getPrice()); + assertEquals("0.00005000", originalOffer.getPrice()); assertEquals(1_250_000L, originalOffer.getAmount()); assertEquals(750_000L, originalOffer.getMinAmount()); assertEquals(BSQ, originalOffer.getBaseCurrencyCode()); assertEquals(BTC, originalOffer.getCounterCurrencyCode()); log.debug("Original BsqSwap offer:\n{}", toOfferTable.apply(originalOffer)); - genBtcBlocksThenWait(1, 2_500); // Wait for offer book entry. + genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. var newFixedPrice = "0.000055"; Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOffer(originalOffer.getId(), diff --git a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java index cfa330e7478..1072b21fc96 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java @@ -89,7 +89,7 @@ public void testAliceCreateBsqSwapBuyBtcOffer() { var newOfferId = mySwapOffer.getId(); assertNotEquals("", newOfferId); assertEquals(OfferDirection.BUY.name(), mySwapOffer.getDirection()); - assertEquals(5_000, mySwapOffer.getPrice()); + assertEquals("0.00005000", mySwapOffer.getPrice()); assertEquals(1_000_000L, mySwapOffer.getAmount()); assertEquals(1_000_000L, mySwapOffer.getMinAmount()); assertEquals(BSQ, mySwapOffer.getBaseCurrencyCode()); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapSellBtcTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapSellBtcTradeTest.java index 80cd48ec1f0..d699428c844 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapSellBtcTradeTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapSellBtcTradeTest.java @@ -87,7 +87,7 @@ public void testAliceCreateBsqSwapSellBtcOffer() { var newOfferId = mySwapOffer.getId(); assertNotEquals("", newOfferId); assertEquals(SELL.name(), mySwapOffer.getDirection()); - assertEquals(5_000, mySwapOffer.getPrice()); + assertEquals("0.00005000", mySwapOffer.getPrice()); assertEquals(1_000_000L, mySwapOffer.getAmount()); assertEquals(1_000_000L, mySwapOffer.getMinAmount()); assertEquals(BSQ, mySwapOffer.getBaseCurrencyCode()); diff --git a/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java b/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java index 61904bfad8b..7dee678d2c6 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java +++ b/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java @@ -72,7 +72,7 @@ public void testSellOfferAutoDisable(final TestInfo testInfo) { triggerPrice); log.info("SELL offer {} created with margin based price {}.", offer.getId(), - formatPrice(offer.getPrice())); + offer.getPrice()); genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. offer = aliceClient.getOffer(offer.getId()); // Offer has trigger price now. @@ -120,7 +120,7 @@ public void testBuyOfferAutoDisable(final TestInfo testInfo) { triggerPrice); log.info("BUY offer {} created with margin based price {}.", offer.getId(), - formatPrice(offer.getPrice())); + offer.getPrice()); genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. offer = aliceClient.getOffer(offer.getId()); // Offer has trigger price now. From 18888f4d7a6b8d78e378cb5fa3d146e4ddd7f218 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 18:30:27 -0300 Subject: [PATCH 06/41] Fix 'unnecessary use of fully qualified name'. --- .../test/java/bisq/apitest/method/offer/AbstractOfferTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4b64cd5308f..e014792565a 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java @@ -122,7 +122,7 @@ protected String calcPriceAsString(double base, double delta, int precision) { var priceAsBigDecimal = new BigDecimal(Double.toString(base), mathContext) .add(new BigDecimal(Double.toString(delta), mathContext)) .round(mathContext); - return String.format("%." + precision + "f", priceAsBigDecimal.doubleValue()); + return format("%." + precision + "f", priceAsBigDecimal.doubleValue()); } protected OfferInfo getAvailableBsqSwapOffer(GrpcClient client, From 62a0a1405d18a93275346b8220242e11824b5c17 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 11:23:41 -0300 Subject: [PATCH 07/41] Change existing `uint64 triggerPrice` field type in grpc.proto to `string triggerPrice`. --- proto/src/main/proto/grpc.proto | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 5088dce390c..87f6609f275 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -209,11 +209,10 @@ message CreateOfferRequest { // TODO: This parameter (where 0.## represents ##%) conflicts with marketPriceMargin (where #.## literally represents #.##%). // Backward compat breaking change to buyerSecurityDeposit is needed to make it consistent with marketPriceMargin (or vice-versa). double buyerSecurityDeposit = 8; - // For fiat, market price margin based offer, the current market BTC price at which the offer is automatically disabled. - // The parameter type is a long, representing the fiat price to 4 decimal places, but without the decimal. - // For example trigger price in EUR of 43749.3940 would be passed as 437493940. - // TODO: This should be a string type: "43749.3940", and converted to a long on the server. - uint64 triggerPrice = 9; + // A market price margin based offer's trigger price is the market BTC price at which the offer is automatically disabled. + // Disabled offers are never automatically enabled, they must be manually re-enabled. + // A zero value indicates trigger price is not set. Trigger price does not apply to fixed price offers. + string triggerPrice = 9; // The unique identifier of the payment account used to create the new offer, and send or receive trade payment. string paymentAccountId = 10; // The offer maker's trade fee currency: BTC or BSQ. @@ -234,8 +233,10 @@ message EditOfferRequest { bool useMarketBasedPrice = 3; // The offer's new market price margin as a percentage above or below the current market BTC price. double marketPriceMargin = 4; - // For market price margin based offer, the current market BTC price at which the offer is automatically disabled. - uint64 triggerPrice = 5; + // A market price margin based offer's trigger price is the market BTC price at which the offer is automatically disabled. + // Disabled offers are never automatically enabled, they must be manually re-enabled. + // A zero value indicates trigger price is not set. Trigger price does not apply to fixed price offers. + string triggerPrice = 5; // Whether the offer's activation state should be changed (disable or enable), or left alone. // Send a signed int, not a bool (with default=false). // -1 = do not change activation state @@ -311,10 +312,10 @@ message OfferInfo { uint64 minVolume = 9; // A long representing the BTC buyer's security deposit in satoshis. uint64 buyerSecurityDeposit = 10; - // A long representing a market price margin based offer's trigger price: the current market BTC price at - // which the offer is automatically disabled. For fiat offers, a trigger price of 40000.5000 is represented - // as 400005000. - uint64 triggerPrice = 11; + // A market price margin based offer's trigger price is the market BTC price at which the offer is automatically disabled. + // Disabled offers are never automatically enabled, they must be manually re-enabled. + // A zero value indicates trigger price is not set. Trigger price does not apply to fixed price offers. + string triggerPrice = 11; // Whether the offer maker paid the trading fee in BTC or not (BSQ). bool isCurrencyForMakerFeeBtc = 12; // The unique identifier of the payment account used to create the offer. From fafe416e856ace9214c548465d783932aa92156f Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 11:24:02 -0300 Subject: [PATCH 08/41] Adjust to `string triggerPrice` change in API core classes. --- core/src/main/java/bisq/core/api/CoreApi.java | 12 +++++------ .../java/bisq/core/api/CoreOffersService.java | 19 ++++++++++------- .../bisq/core/api/EditOfferValidator.java | 21 ++++++++++--------- .../java/bisq/core/api/model/OfferInfo.java | 16 +++++++++++--- .../api/model/builder/OfferInfoBuilder.java | 4 ++-- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java index 5740d47b88f..2587b51d60f 100644 --- a/core/src/main/java/bisq/core/api/CoreApi.java +++ b/core/src/main/java/bisq/core/api/CoreApi.java @@ -194,19 +194,19 @@ public void createAndPlaceBsqSwapOffer(String directionAsString, public void createAndPlaceOffer(String currencyCode, String directionAsString, - String priceAsString, + String price, boolean useMarketBasedPrice, double marketPriceMargin, long amountAsLong, long minAmountAsLong, double buyerSecurityDeposit, - long triggerPrice, + String triggerPrice, String paymentAccountId, String makerFeeCurrencyCode, Consumer resultHandler) { coreOffersService.createAndPlaceOffer(currencyCode, directionAsString, - priceAsString, + price, useMarketBasedPrice, marketPriceMargin, amountAsLong, @@ -219,14 +219,14 @@ public void createAndPlaceOffer(String currencyCode, } public void editOffer(String offerId, - String priceAsString, + String price, boolean useMarketBasedPrice, double marketPriceMargin, - long triggerPrice, + String triggerPrice, int enable, EditType editType) { coreOffersService.editOffer(offerId, - priceAsString, + price, useMarketBasedPrice, marketPriceMargin, triggerPrice, diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java index f321ad17d0c..03764b7d1e5 100644 --- a/core/src/main/java/bisq/core/api/CoreOffersService.java +++ b/core/src/main/java/bisq/core/api/CoreOffersService.java @@ -66,6 +66,7 @@ import static bisq.core.offer.OpenOffer.State.AVAILABLE; import static bisq.core.offer.OpenOffer.State.DEACTIVATED; import static bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer; +import static bisq.core.util.PriceUtil.getMarketPriceAsLong; import static bisq.proto.grpc.EditOfferRequest.EditType; import static bisq.proto.grpc.EditOfferRequest.EditType.FIXED_PRICE_AND_ACTIVATION_STATE; import static bisq.proto.grpc.EditOfferRequest.EditType.FIXED_PRICE_ONLY; @@ -276,7 +277,7 @@ void createAndPlaceOffer(String currencyCode, long amountAsLong, long minAmountAsLong, double buyerSecurityDeposit, - long triggerPrice, + String triggerPrice, String paymentAccountId, String makerFeeCurrencyCode, Consumer resultHandler) { @@ -321,15 +322,15 @@ void createAndPlaceOffer(String currencyCode, // Edit a placed offer. void editOffer(String offerId, - String editedPriceAsString, + String editedPrice, boolean editedUseMarketBasedPrice, double editedMarketPriceMargin, - long editedTriggerPrice, + String editedTriggerPrice, int editedEnable, EditType editType) { OpenOffer openOffer = getMyOpenOffer(offerId); var validator = new EditOfferValidator(openOffer, - editedPriceAsString, + editedPrice, editedUseMarketBasedPrice, editedMarketPriceMargin, editedTriggerPrice, @@ -346,7 +347,7 @@ void editOffer(String offerId, : editedEnable > 0 ? AVAILABLE : DEACTIVATED; OfferPayload editedPayload = getMergedOfferPayload(validator, openOffer, - editedPriceAsString, + editedPrice, editedMarketPriceMargin, editType); Offer editedOffer = new Offer(editedPayload); @@ -356,8 +357,9 @@ void editOffer(String offerId, openOfferManager.editOpenOfferStart(openOffer, () -> log.info("EditOpenOfferStart: offer {}", openOffer.getId()), log::error); + long triggerPriceAsLong = getMarketPriceAsLong(editedTriggerPrice, editedOffer.getCurrencyCode()); openOfferManager.editOpenOfferPublish(editedOffer, - editedTriggerPrice, + triggerPriceAsLong, newOfferState, () -> log.info("EditOpenOfferPublish: offer {}", openOffer.getId()), log::error); @@ -382,13 +384,14 @@ private void placeBsqSwapOffer(Offer offer, Runnable resultHandler) { private void placeOffer(Offer offer, double buyerSecurityDeposit, - long triggerPrice, + String triggerPrice, boolean useSavingsWallet, Consumer resultHandler) { + var triggerPriceAsLong = getMarketPriceAsLong(triggerPrice, offer.getCurrencyCode()); openOfferManager.placeOffer(offer, buyerSecurityDeposit, useSavingsWallet, - triggerPrice, + triggerPriceAsLong, resultHandler::accept, log::error); diff --git a/core/src/main/java/bisq/core/api/EditOfferValidator.java b/core/src/main/java/bisq/core/api/EditOfferValidator.java index 34515da5548..977b7a738e7 100644 --- a/core/src/main/java/bisq/core/api/EditOfferValidator.java +++ b/core/src/main/java/bisq/core/api/EditOfferValidator.java @@ -14,6 +14,7 @@ import static bisq.proto.grpc.EditOfferRequest.EditType.*; import static java.lang.String.format; +import static java.math.BigDecimal.ZERO; @Slf4j class EditOfferValidator { @@ -49,10 +50,10 @@ class EditOfferValidator { private final OpenOffer currentlyOpenOffer; - private final String newPriceAsString; + private final String newPrice; private final boolean newIsUseMarketBasedPrice; private final double newMarketPriceMargin; - private final long newTriggerPrice; + private final String newTriggerPrice; private final int newEnable; private final EditOfferRequest.EditType editType; @@ -60,14 +61,14 @@ class EditOfferValidator { private final boolean isZeroEditedTriggerPrice; EditOfferValidator(OpenOffer currentlyOpenOffer, - String newPriceAsString, + String newPrice, boolean newIsUseMarketBasedPrice, double newMarketPriceMargin, - long newTriggerPrice, + String newTriggerPrice, int newEnable, EditOfferRequest.EditType editType) { this.currentlyOpenOffer = currentlyOpenOffer; - this.newPriceAsString = newPriceAsString; + this.newPrice = newPrice; // The client cannot determine what offer.isUseMarketBasedPrice should be // when editType = ACTIVATION_STATE_ONLY. Override newIsUseMarketBasedPrice // param for the ACTIVATION_STATE_ONLY case. @@ -81,8 +82,8 @@ class EditOfferValidator { this.newEnable = newEnable; this.editType = editType; - this.isZeroEditedFixedPriceString = new BigDecimal(newPriceAsString).doubleValue() == 0; - this.isZeroEditedTriggerPrice = newTriggerPrice == 0; + this.isZeroEditedFixedPriceString = new BigDecimal(newPrice).doubleValue() == 0; + this.isZeroEditedTriggerPrice = new BigDecimal(newTriggerPrice).equals(ZERO); } EditOfferValidator validate() { @@ -123,7 +124,7 @@ public String toString() { return "EditOfferValidator{" + "\n" + " offer=" + offer.getId() + "\n" + ", offer.payloadBase.price=" + offer.getOfferPayloadBase().getPrice() + "\n" + - ", newPriceAsString=" + (isEditingPrice ? newPriceAsString : "N/A") + "\n" + + ", newPrice=" + (isEditingPrice ? newPrice : "N/A") + "\n" + ", offer.useMarketBasedPrice=" + offer.isUseMarketBasedPrice() + "\n" + ", newUseMarketBasedPrice=" + newIsUseMarketBasedPrice + "\n" + ", offer.marketPriceMargin=" + offer.getMarketPriceMargin() + "\n" + @@ -182,7 +183,7 @@ private void validateEditedMarketPriceMargin() { throw new IllegalStateException( format("programmer error: cannot set fixed price (%s)" + " in mkt price margin based offer with id '%s'", - newPriceAsString, + newPrice, currentlyOpenOffer.getId())); } @@ -195,7 +196,7 @@ private void validateEditedTriggerPrice() { + " in fixed price offer with id '%s'", currentlyOpenOffer.getId())); - if (newTriggerPrice < 0) + if (new BigDecimal(newTriggerPrice).compareTo(ZERO) < 0) throw new IllegalStateException( format("programmer error: cannot set trigger price to a negative value" + " in offer with id '%s'", 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 53e2f6537d8..c3703d2ab42 100644 --- a/core/src/main/java/bisq/core/api/model/OfferInfo.java +++ b/core/src/main/java/bisq/core/api/model/OfferInfo.java @@ -18,12 +18,15 @@ package bisq.core.api.model; import bisq.core.api.model.builder.OfferInfoBuilder; +import bisq.core.monetary.Price; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; import bisq.core.util.coin.CoinUtil; import bisq.common.Payload; +import java.util.Optional; + import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; @@ -54,7 +57,7 @@ public class OfferInfo implements Payload { private final String offerFeePaymentTxId; private final long buyerSecurityDeposit; private final long sellerSecurityDeposit; - private final long triggerPrice; + private final String triggerPrice; private final boolean isCurrencyForMakerFeeBtc; private final String paymentAccountId; private final String paymentMethodId; @@ -130,8 +133,15 @@ public static OfferInfo toMyPendingOfferInfo(Offer myNewOffer) { public static OfferInfo toMyOfferInfo(OpenOffer openOffer) { // An OpenOffer is always my offer. + var currencyCode = openOffer.getOffer().getCurrencyCode(); + Optional optionalTriggerPrice = openOffer.getTriggerPrice() > 0 + ? Optional.of(Price.valueOf(currencyCode, openOffer.getTriggerPrice())) + : Optional.empty(); + var preciseTriggerPrice = optionalTriggerPrice.isPresent() + ? reformatMarketPrice(optionalTriggerPrice.get().toPlainString(), currencyCode) + : "0"; return getBuilder(openOffer.getOffer(), true) - .withTriggerPrice(openOffer.getTriggerPrice()) + .withTriggerPrice(preciseTriggerPrice) .withIsActivated(!openOffer.isDeactivated()) .build(); } @@ -203,7 +213,7 @@ public bisq.proto.grpc.OfferInfo toProtoMessage() { .setOfferFeePaymentTxId(isBsqSwapOffer ? "" : offerFeePaymentTxId) .setBuyerSecurityDeposit(buyerSecurityDeposit) .setSellerSecurityDeposit(sellerSecurityDeposit) - .setTriggerPrice(triggerPrice) + .setTriggerPrice(triggerPrice == null ? "0" : triggerPrice) .setIsCurrencyForMakerFeeBtc(isCurrencyForMakerFeeBtc) .setPaymentAccountId(paymentAccountId) .setPaymentMethodId(paymentMethodId) diff --git a/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java b/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java index 556ef9b2a48..1ddb5e92de0 100644 --- a/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java +++ b/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java @@ -44,7 +44,7 @@ public final class OfferInfoBuilder { private String offerFeePaymentTxId; private long buyerSecurityDeposit; private long sellerSecurityDeposit; - private long triggerPrice; + private String triggerPrice; private boolean isCurrencyForMakerFeeBtc; private String paymentAccountId; private String paymentMethodId; @@ -132,7 +132,7 @@ public OfferInfoBuilder withSellerSecurityDeposit(long sellerSecurityDeposit) { return this; } - public OfferInfoBuilder withTriggerPrice(long triggerPrice) { + public OfferInfoBuilder withTriggerPrice(String triggerPrice) { this.triggerPrice = triggerPrice; return this; } From 68450c455f295ec59c77ec1de5e9056654b60028 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 11:24:23 -0300 Subject: [PATCH 09/41] Adjust to `string triggerPrice` change in API cli classes --- cli/src/main/java/bisq/cli/CliMain.java | 5 +-- .../main/java/bisq/cli/CurrencyFormat.java | 4 ++- cli/src/main/java/bisq/cli/GrpcClient.java | 14 ++++----- .../bisq/cli/opts/EditOfferOptionParser.java | 4 --- .../cli/request/OffersServiceRequest.java | 31 +++---------------- .../table/builder/AbstractTableBuilder.java | 3 ++ .../cli/table/builder/OfferTableBuilder.java | 22 ++++++------- .../bisq/cli/table/column/AltcoinColumn.java | 1 + .../bisq/cli/table/column/FiatColumn.java | 1 + 9 files changed, 32 insertions(+), 53 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index 4086b8cbcdf..325373f747c 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -348,7 +348,7 @@ public static void run(String[] args) { var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal(); var securityDeposit = isSwap ? 0.00 : toSecurityDepositAsPct(opts.getSecurityDeposit()); var makerFeeCurrencyCode = opts.getMakerFeeCurrencyCode(); - var triggerPrice = 0; // Cannot be defined until offer is in book. + var triggerPrice = "0"; // Cannot be defined until the new offer is added to book. OfferInfo offer; if (isSwap) { offer = client.createBsqSwapOffer(direction, @@ -388,7 +388,7 @@ public static void run(String[] args) { var fixedPrice = opts.getFixedPrice(); var isUsingMktPriceMargin = opts.isUsingMktPriceMargin(); var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal(); - var triggerPrice = toInternalTriggerPrice(client, offerId, opts.getTriggerPriceAsBigDecimal()); + var triggerPrice = opts.getTriggerPrice(); var enable = opts.getEnableAsSignedInt(); var editOfferType = opts.getOfferEditType(); client.editOffer(offerId, @@ -789,6 +789,7 @@ private static long toLong(String param) { } } + @Deprecated private static long toInternalTriggerPrice(GrpcClient client, String offerId, BigDecimal unscaledTriggerPrice) { diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java index 9f8df8fe88f..ba0e84fca2d 100644 --- a/cli/src/main/java/bisq/cli/CurrencyFormat.java +++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java @@ -123,7 +123,7 @@ public static String formatInternalFiatPrice(double price) { return FRIENDLY_NUMBER_FORMAT.format(price); } - // TODO Deprecate after triggerPrice field type is changed to string. + @Deprecated public static String formatPrice(long price) { FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(4); FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(4); @@ -157,10 +157,12 @@ public static String formatCryptoCurrencyVolume(long volume, int precision) { return FRIENDLY_NUMBER_FORMAT.format((double) volume / SATOSHI_DIVISOR.doubleValue()); } + @Deprecated public static long toInternalFiatPrice(BigDecimal fiatPrice) { return fiatPrice.multiply(new BigDecimal(10_000)).longValue(); } + @Deprecated public static long toInternalCryptoCurrencyPrice(BigDecimal altcoinPrice) { return altcoinPrice.multiply(new BigDecimal(100_000_000)).longValue(); } diff --git a/cli/src/main/java/bisq/cli/GrpcClient.java b/cli/src/main/java/bisq/cli/GrpcClient.java index 897599c66fa..0b9557c58d7 100644 --- a/cli/src/main/java/bisq/cli/GrpcClient.java +++ b/cli/src/main/java/bisq/cli/GrpcClient.java @@ -175,7 +175,7 @@ public OfferInfo createFixedPricedOffer(String direction, securityDeposit, paymentAcctId, makerFeeCurrencyCode, - 0 /* no trigger price */); + "0" /* no trigger price */); } public OfferInfo createMarketBasedPricedOffer(String direction, @@ -186,7 +186,7 @@ public OfferInfo createMarketBasedPricedOffer(String direction, double securityDeposit, String paymentAcctId, String makerFeeCurrencyCode, - long triggerPrice) { + String triggerPrice) { return offersServiceRequest.createOffer(direction, currencyCode, amount, @@ -210,7 +210,7 @@ public OfferInfo createOffer(String direction, double securityDeposit, String paymentAcctId, String makerFeeCurrencyCode, - long triggerPrice) { + String triggerPrice) { return offersServiceRequest.createOffer(direction, currencyCode, amount, @@ -236,22 +236,22 @@ public void editOfferPriceMargin(String offerId, double marketPriceMargin) { offersServiceRequest.editOfferPriceMargin(offerId, marketPriceMargin); } - public void editOfferTriggerPrice(String offerId, long triggerPrice) { + public void editOfferTriggerPrice(String offerId, String triggerPrice) { offersServiceRequest.editOfferTriggerPrice(offerId, triggerPrice); } public void editOffer(String offerId, - String priceAsString, + String price, boolean useMarketBasedPrice, double marketPriceMargin, - long triggerPrice, + String triggerPrice, int enable, EditType editType) { // Take care when using this method directly: // useMarketBasedPrice = true if margin based offer, false for fixed priced offer // scaledPriceString fmt = ######.#### offersServiceRequest.editOffer(offerId, - priceAsString, + price, useMarketBasedPrice, marketPriceMargin, triggerPrice, diff --git a/cli/src/main/java/bisq/cli/opts/EditOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/EditOfferOptionParser.java index 557a0ff77d4..17afa982f76 100644 --- a/cli/src/main/java/bisq/cli/opts/EditOfferOptionParser.java +++ b/cli/src/main/java/bisq/cli/opts/EditOfferOptionParser.java @@ -215,10 +215,6 @@ public String getTriggerPrice() { } } - public BigDecimal getTriggerPriceAsBigDecimal() { - return new BigDecimal(getTriggerPrice()); - } - public String getMktPriceMargin() { if (offerEditType.equals(MKT_PRICE_MARGIN_ONLY) || offerEditType.equals(MKT_PRICE_MARGIN_AND_ACTIVATION_STATE) diff --git a/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java b/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java index 20b9dc2c024..5f900d770ca 100644 --- a/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java +++ b/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java @@ -95,30 +95,7 @@ public OfferInfo createFixedPricedOffer(String direction, securityDeposit, paymentAcctId, makerFeeCurrencyCode, - 0 /* no trigger price */); - } - - @SuppressWarnings("unused") - public OfferInfo createMarketBasedPricedOffer(String direction, - String currencyCode, - long amount, - long minAmount, - double marketPriceMargin, - double securityDeposit, - String paymentAcctId, - String makerFeeCurrencyCode, - long triggerPrice) { - return createOffer(direction, - currencyCode, - amount, - minAmount, - true, - "0", - marketPriceMargin, - securityDeposit, - paymentAcctId, - makerFeeCurrencyCode, - triggerPrice); + "0" /* no trigger price */); } public OfferInfo createOffer(String direction, @@ -131,7 +108,7 @@ public OfferInfo createOffer(String direction, double securityDeposit, String paymentAcctId, String makerFeeCurrencyCode, - long triggerPrice) { + String triggerPrice) { var request = CreateOfferRequest.newBuilder() .setDirection(direction) .setCurrencyCode(currencyCode) @@ -184,7 +161,7 @@ public void editOfferPriceMargin(String offerId, double marketPriceMargin) { MKT_PRICE_MARGIN_ONLY); } - public void editOfferTriggerPrice(String offerId, long triggerPrice) { + public void editOfferTriggerPrice(String offerId, String triggerPrice) { var offer = getMyOffer(offerId); editOffer(offerId, "0.00", @@ -199,7 +176,7 @@ public void editOffer(String offerId, String scaledPriceString, boolean useMarketBasedPrice, double marketPriceMargin, - long triggerPrice, + String triggerPrice, int enable, EditOfferRequest.EditType editType) { // Take care when using this method directly: diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java index 1484e2c1f93..cdb5f3ffa3f 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java @@ -20,6 +20,7 @@ import bisq.proto.grpc.OfferInfo; import java.util.List; +import java.util.function.Function; import java.util.function.Predicate; @@ -31,6 +32,8 @@ */ abstract class AbstractTableBuilder { + protected final Function toBlankOrNonZeroValue = (s) -> s.trim().equals("0") ? "" : s; + protected final TableType tableType; protected final List protos; diff --git a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java index e9ddc14e18d..a97c73b848e 100644 --- a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java @@ -29,11 +29,9 @@ import static bisq.cli.table.builder.TableBuilderConstants.*; import static bisq.cli.table.builder.TableType.OFFER_TBL; import static bisq.cli.table.column.AltcoinColumn.DISPLAY_MODE.ALTCOIN_OFFER_VOLUME; -import static bisq.cli.table.column.AltcoinColumn.DISPLAY_MODE.ALTCOIN_TRIGGER_PRICE; import static bisq.cli.table.column.Column.JUSTIFICATION.LEFT; import static bisq.cli.table.column.Column.JUSTIFICATION.NONE; import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; -import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.TRIGGER_PRICE; import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.VOLUME; import static bisq.cli.table.column.ZippedStringColumns.DUPLICATION_MODE.EXCLUDE_DUPLICATES; import static java.lang.String.format; @@ -84,7 +82,7 @@ public Table buildFiatOfferTable(List offers) { Column colFiatVolume = new FiatColumn(format("Temp Volume (%s)", fiatTradeCurrency.get()), NONE, VOLUME); Column colMinFiatVolume = new FiatColumn(format("Temp Min Volume (%s)", fiatTradeCurrency.get()), NONE, VOLUME); @Nullable - Column colTriggerPrice = fiatTriggerPriceColumn.get(); + Column colTriggerPrice = fiatTriggerPriceColumn.get(); // Populate columns with offer info. @@ -101,7 +99,7 @@ public Table buildFiatOfferTable(List offers) { colFiatVolume.addRow(o.getVolume()); if (colTriggerPrice != null) - colTriggerPrice.addRow(o.getTriggerPrice()); + colTriggerPrice.addRow(toBlankOrNonZeroValue.apply(o.getTriggerPrice())); colPaymentMethod.addRow(o.getPaymentMethodShortName()); colCreateDate.addRow(o.getDate()); @@ -124,7 +122,7 @@ public Table buildFiatOfferTable(List offers) { colFiatPrice.justify(), amountRange.asStringColumn(EXCLUDE_DUPLICATES), volumeRange.asStringColumn(EXCLUDE_DUPLICATES), - colTriggerPrice.asStringColumn(), + colTriggerPrice.justify(), colPaymentMethod, colCreateDate.asStringColumn(), colOfferId); @@ -151,7 +149,7 @@ public Table buildCryptoCurrencyOfferTable(List offers) { NONE, ALTCOIN_OFFER_VOLUME); @Nullable - Column colTriggerPrice = altcoinTriggerPriceColumn.get(); + Column colTriggerPrice = altcoinTriggerPriceColumn.get(); // Populate columns with offer info. @@ -168,7 +166,7 @@ public Table buildCryptoCurrencyOfferTable(List offers) { colMinBtcVolume.addRow(o.getVolume()); if (colTriggerPrice != null) - colTriggerPrice.addRow(o.getTriggerPrice()); + colTriggerPrice.addRow(toBlankOrNonZeroValue.apply(o.getTriggerPrice())); colPaymentMethod.addRow(o.getPaymentMethodShortName()); colCreateDate.addRow(o.getDate()); @@ -201,7 +199,7 @@ public Table buildCryptoCurrencyOfferTable(List offers) { colBtcPrice.justify(), amountRange.asStringColumn(EXCLUDE_DUPLICATES), volumeRange.asStringColumn(EXCLUDE_DUPLICATES), - colTriggerPrice.asStringColumn(), + colTriggerPrice.justify(), colPaymentMethod, colCreateDate.asStringColumn(), colOfferId); @@ -231,14 +229,14 @@ public Table buildCryptoCurrencyOfferTable(List offers) { ? new StringColumn(COL_HEADER_ENABLED, LEFT) : null; @Nullable - private final Supplier fiatTriggerPriceColumn = () -> + private final Supplier fiatTriggerPriceColumn = () -> isShowingMyOffers.get() - ? new FiatColumn(format(COL_HEADER_TRIGGER_PRICE, fiatTradeCurrency.get()), RIGHT, TRIGGER_PRICE) + ? new StringColumn(format(COL_HEADER_TRIGGER_PRICE, fiatTradeCurrency.get()), RIGHT) : null; @Nullable - private final Supplier altcoinTriggerPriceColumn = () -> + private final Supplier altcoinTriggerPriceColumn = () -> isShowingMyOffers.get() && !isShowingBsqOffers.get() - ? new AltcoinColumn(format(COL_HEADER_TRIGGER_PRICE, altcoinTradeCurrency.get()), RIGHT, ALTCOIN_TRIGGER_PRICE) + ? new StringColumn(format(COL_HEADER_TRIGGER_PRICE, altcoinTradeCurrency.get()), RIGHT) : null; private final Function toEnabled = (o) -> { diff --git a/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java b/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java index 4c59eb03324..3b13171f7f7 100644 --- a/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java +++ b/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java @@ -34,6 +34,7 @@ public class AltcoinColumn extends LongColumn { public enum DISPLAY_MODE { ALTCOIN_OFFER_VOLUME, ALTCOIN_PRICE, + @Deprecated ALTCOIN_TRIGGER_PRICE } diff --git a/cli/src/main/java/bisq/cli/table/column/FiatColumn.java b/cli/src/main/java/bisq/cli/table/column/FiatColumn.java index e9b940ee9d7..9adb9de5a01 100644 --- a/cli/src/main/java/bisq/cli/table/column/FiatColumn.java +++ b/cli/src/main/java/bisq/cli/table/column/FiatColumn.java @@ -33,6 +33,7 @@ public class FiatColumn extends LongColumn { public enum DISPLAY_MODE { PRICE, + @Deprecated TRIGGER_PRICE, VOLUME } From 2af3ac22a3bde286d94258612e1741951953d491 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 11:25:18 -0300 Subject: [PATCH 10/41] Adjust to `string triggerPrice` change in API test cases --- .../method/offer/AbstractOfferTest.java | 19 +--- ...CreateOfferUsingMarketPriceMarginTest.java | 10 +- .../method/offer/CreateXMROffersTest.java | 8 +- .../apitest/method/offer/EditOfferTest.java | 100 +++++++++--------- .../LongRunningOfferDeactivationTest.java | 22 ++-- .../bisq/apitest/scenario/bot/BotClient.java | 3 +- .../apitest/scenario/bot/RandomOffer.java | 2 +- 7 files changed, 71 insertions(+), 93 deletions(-) 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 e014792565a..35a33c45c61 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java @@ -28,7 +28,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.function.BiFunction; import java.util.function.Function; import lombok.Setter; @@ -63,7 +62,7 @@ public abstract class AbstractOfferTest extends MethodTest { protected static final int ACTIVATE_OFFER = 1; protected static final int DEACTIVATE_OFFER = 0; - protected static final long NO_TRIGGER_PRICE = 0; + protected static final String NO_TRIGGER_PRICE = "0"; @Setter protected static boolean isLongRunningTest; @@ -95,22 +94,6 @@ public static void setUp() { protected final Function scaledDownMktPriceMargin = (mktPriceMargin) -> exactMultiply(mktPriceMargin, 0.01); - // Price value of fiat offer returned from server will be scaled up by 10^4. - protected final Function scaledUpFiatOfferPrice = (price) -> { - BigDecimal factor = new BigDecimal(10).pow(4); - return price.multiply(factor).longValue(); - }; - - protected final BiFunction calcFiatTriggerPriceAsLong = (base, delta) -> { - var priceAsDouble = new BigDecimal(base).add(new BigDecimal(delta)).doubleValue(); - return Double.valueOf(exactMultiply(priceAsDouble, 10_000)).longValue(); - }; - - protected final BiFunction calcAltcoinTriggerPriceAsLong = (base, delta) -> { - var priceAsDouble = new BigDecimal(base).add(new BigDecimal(delta)).doubleValue(); - return Double.valueOf(exactMultiply(priceAsDouble, 100_000_000)).longValue(); - }; - protected final Function toOfferTable = (offer) -> new TableBuilder(OFFER_TBL, offer).build().toString(); 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 a4f7f23e993..2dd32d44d3d 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java @@ -17,7 +17,6 @@ package bisq.apitest.method.offer; -import bisq.core.monetary.Price; import bisq.core.payment.PaymentAccount; import bisq.proto.grpc.OfferInfo; @@ -255,10 +254,7 @@ public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() { public void testCreateUSDBTCBuyOfferWithTriggerPrice() { PaymentAccount usdAccount = createDummyF2FAccount(aliceClient, "US"); double mktPriceAsDouble = aliceClient.getBtcPrice("usd"); - BigDecimal mktPrice = new BigDecimal(Double.toString(mktPriceAsDouble)); - BigDecimal triggerPrice = mktPrice.add(new BigDecimal("1000.9999")); - long triggerPriceAsLong = Price.parse(USD, triggerPrice.toString()).getValue(); - + String triggerPrice = calcPriceAsString(mktPriceAsDouble, Double.parseDouble("1000.9999"), 4); var newOffer = aliceClient.createMarketBasedPricedOffer(BUY.name(), "usd", 10_000_000L, @@ -267,7 +263,7 @@ public void testCreateUSDBTCBuyOfferWithTriggerPrice() { getDefaultBuyerSecurityDepositAsPercent(), usdAccount.getId(), MAKER_FEE_CURRENCY_CODE, - triggerPriceAsLong); + triggerPrice); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -276,7 +272,7 @@ public void testCreateUSDBTCBuyOfferWithTriggerPrice() { log.debug("OFFER #5:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertFalse(newOffer.getIsMyPendingOffer()); - assertEquals(triggerPriceAsLong, newOffer.getTriggerPrice()); + assertEquals(triggerPrice, newOffer.getTriggerPrice()); } private void assertCalculatedPriceIsCorrect(OfferInfo offer, double priceMarginPctInput) { diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java index b945238d7ea..33fad708d85 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java @@ -156,7 +156,7 @@ public void testCreateFixedPriceSell1BTCFor200KXMROffer() { public void testCreatePriceMarginBasedBuy1BTCOfferWithTriggerPrice() { double priceMarginPctInput = 1.00; double mktPriceAsDouble = aliceClient.getBtcPrice(XMR); - long triggerPriceAsLong = calcAltcoinTriggerPriceAsLong.apply(mktPriceAsDouble, -0.001); + String triggerPrice = calcPriceAsString(mktPriceAsDouble, Double.parseDouble("-0.001"), 8); var newOffer = aliceClient.createMarketBasedPricedOffer(BUY.name(), XMR, 100_000_000L, @@ -165,7 +165,7 @@ public void testCreatePriceMarginBasedBuy1BTCOfferWithTriggerPrice() { getDefaultBuyerSecurityDepositAsPercent(), alicesXmrAcct.getId(), MAKER_FEE_CURRENCY_CODE, - triggerPriceAsLong); + triggerPrice); log.debug("Pending Sell XMR (Buy BTC) offer:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -176,7 +176,7 @@ public void testCreatePriceMarginBasedBuy1BTCOfferWithTriggerPrice() { assertTrue(newOffer.getUseMarketBasedPrice()); // There is no trigger price while offer is pending. - assertEquals(0, newOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, newOffer.getTriggerPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(75_000_000L, newOffer.getMinAmount()); @@ -197,7 +197,7 @@ public void testCreatePriceMarginBasedBuy1BTCOfferWithTriggerPrice() { assertTrue(newOffer.getUseMarketBasedPrice()); // The trigger price should exist on the prepared offer. - assertEquals(triggerPriceAsLong, newOffer.getTriggerPrice()); + assertEquals(triggerPrice, newOffer.getTriggerPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(75_000_000L, newOffer.getMinAmount()); diff --git a/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java index b0401c6522b..55b041ed3c1 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java @@ -100,18 +100,18 @@ public void testEditTriggerPrice() { log.debug("Original EUR offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); - assertEquals(0 /*no trigger price*/, originalOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, originalOffer.getTriggerPrice()); // Edit the offer's trigger price, nothing else. var mktPrice = aliceClient.getBtcPrice(EUR); var delta = 5_000.00; - var newTriggerPriceAsLong = calcFiatTriggerPriceAsLong.apply(mktPrice, delta); + var newTriggerPrice = calcPriceAsString(mktPrice, delta, 4); - aliceClient.editOfferTriggerPrice(originalOffer.getId(), newTriggerPriceAsLong); + aliceClient.editOfferTriggerPrice(originalOffer.getId(), newTriggerPrice); sleep(2_500); // Wait for offer book re-entry. OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited EUR offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice()); + assertEquals(newTriggerPrice, editedOffer.getTriggerPrice()); assertTrue(editedOffer.getUseMarketBasedPrice()); doSanityCheck(originalOffer, editedOffer); @@ -130,7 +130,7 @@ public void testSetTriggerPriceToNegativeValueShouldThrowException() { genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. // Edit the offer's trigger price, set to -1, check error. Throwable exception = assertThrows(StatusRuntimeException.class, () -> - aliceClient.editOfferTriggerPrice(originalOffer.getId(), -1L)); + aliceClient.editOfferTriggerPrice(originalOffer.getId(), "-1")); String expectedExceptionMessage = format("UNKNOWN: programmer error: cannot set trigger price to a negative value in offer with id '%s'", originalOffer.getId()); @@ -228,7 +228,7 @@ public void testEditMktPriceMarginAndDeactivation() { USD, paymentAcct.getId(), originalMktPriceMargin, - 0); + NO_TRIGGER_PRICE); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); @@ -240,7 +240,7 @@ public void testEditMktPriceMarginAndDeactivation() { "0.00", originalOffer.getUseMarketBasedPrice(), newMktPriceMargin, - 0, + NO_TRIGGER_PRICE, DEACTIVATE_OFFER, MKT_PRICE_MARGIN_AND_ACTIVATION_STATE); // Wait for edited offer to be removed from offer-book, edited, and re-published. @@ -248,7 +248,7 @@ public void testEditMktPriceMarginAndDeactivation() { OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited USD offer:\n{}", toOfferTable.apply(editedOffer)); assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); - assertEquals(0, editedOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); assertFalse(editedOffer.getIsActivated()); assertTrue(editedOffer.getUseMarketBasedPrice()); @@ -261,26 +261,26 @@ public void testEditMktPriceMarginAndTriggerPriceAndDeactivation() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("US"); var originalMktPriceMargin = new BigDecimal("0.0").doubleValue(); var mktPriceAsDouble = aliceClient.getBtcPrice(USD); - var originalTriggerPriceAsLong = calcFiatTriggerPriceAsLong.apply(mktPriceAsDouble, -5_000.0000); + var originalTriggerPrice = calcPriceAsString(mktPriceAsDouble, -5_000.0000, 4); OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(), USD, paymentAcct.getId(), originalMktPriceMargin, - originalTriggerPriceAsLong); + originalTriggerPrice); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin()); - assertEquals(originalTriggerPriceAsLong, originalOffer.getTriggerPrice()); + assertEquals(originalTriggerPrice, originalOffer.getTriggerPrice()); // Edit the offer's price margin and trigger price, and deactivate it. var newMktPriceMargin = new BigDecimal("0.1").doubleValue(); - var newTriggerPriceAsLong = calcFiatTriggerPriceAsLong.apply(mktPriceAsDouble, -2_000.0000); + var newTriggerPrice = calcPriceAsString(mktPriceAsDouble, -2_000.0000, 4); aliceClient.editOffer(originalOffer.getId(), "0.00", originalOffer.getUseMarketBasedPrice(), newMktPriceMargin, - newTriggerPriceAsLong, + newTriggerPrice, DEACTIVATE_OFFER, MKT_PRICE_MARGIN_AND_TRIGGER_PRICE_AND_ACTIVATION_STATE); // Wait for edited offer to be removed from offer-book, edited, and re-published. @@ -288,7 +288,7 @@ public void testEditMktPriceMarginAndTriggerPriceAndDeactivation() { OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited USD offer:\n{}", toOfferTable.apply(editedOffer)); assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); - assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice()); + assertEquals(newTriggerPrice, editedOffer.getTriggerPrice()); assertFalse(editedOffer.getIsActivated()); doSanityCheck(originalOffer, editedOffer); @@ -337,7 +337,7 @@ public void testEditingTriggerPriceInFixedPriceOfferShouldThrowException() { fixedPriceAsString); log.debug("Original RUB offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. - long newTriggerPrice = 1000000L; + var newTriggerPrice = "1000000"; Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOfferTriggerPrice(originalOffer.getId(), newTriggerPrice)); String expectedExceptionMessage = @@ -363,12 +363,12 @@ public void testChangeFixedPriceOfferToPriceMarginBasedOfferWithTriggerPrice() { // Change the offer to mkt price based and set a trigger price. var newMktPriceMargin = new BigDecimal("0.05").doubleValue(); var delta = 200_000.0000; // trigger price on buy offer is 200K above mkt price - var newTriggerPriceAsLong = calcFiatTriggerPriceAsLong.apply(mktPriceAsDouble, delta); + var newTriggerPrice = calcPriceAsString(mktPriceAsDouble, delta, 4); aliceClient.editOffer(originalOffer.getId(), "0.00", true, newMktPriceMargin, - newTriggerPriceAsLong, + newTriggerPrice, ACTIVATE_OFFER, MKT_PRICE_MARGIN_AND_TRIGGER_PRICE); // Wait for edited offer to be removed from offer-book, edited, and re-published. @@ -377,7 +377,7 @@ public void testChangeFixedPriceOfferToPriceMarginBasedOfferWithTriggerPrice() { log.debug("Edited MXN offer:\n{}", toOfferTable.apply(editedOffer)); assertTrue(editedOffer.getUseMarketBasedPrice()); assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); - assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice()); + assertEquals(newTriggerPrice, editedOffer.getTriggerPrice()); assertTrue(editedOffer.getIsActivated()); doSanityCheck(originalOffer, editedOffer); @@ -390,7 +390,7 @@ public void testChangePriceMarginBasedOfferToFixedPriceOfferAndDeactivateIt() { double mktPriceAsDouble = aliceClient.getBtcPrice("GBP"); var originalMktPriceMargin = new BigDecimal("0.25").doubleValue(); var delta = 1_000.0000; // trigger price on sell offer is 1K below mkt price - var originalTriggerPriceAsLong = calcFiatTriggerPriceAsLong.apply(mktPriceAsDouble, delta); + var originalTriggerPriceAsLong = calcPriceAsString(mktPriceAsDouble, delta, 4); var originalOffer = createMktPricedOfferForEdit(SELL.name(), "GBP", paymentAcct.getId(), @@ -404,7 +404,7 @@ public void testChangePriceMarginBasedOfferToFixedPriceOfferAndDeactivateIt() { fixedPriceAsString, false, 0.00, - 0, + NO_TRIGGER_PRICE, DEACTIVATE_OFFER, FIXED_PRICE_AND_ACTIVATION_STATE); // Wait for edited offer to be removed from offer-book, edited, and re-published. @@ -414,7 +414,7 @@ public void testChangePriceMarginBasedOfferToFixedPriceOfferAndDeactivateIt() { assertEquals(fixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); - assertEquals(0, editedOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); assertFalse(editedOffer.getIsActivated()); } @@ -436,7 +436,7 @@ public void testChangeFixedPricedBsqOfferToPriceMarginBasedOfferShouldThrowExcep "0.00", true, 0.1, - 0, + NO_TRIGGER_PRICE, ACTIVATE_OFFER, MKT_PRICE_MARGIN_ONLY)); String expectedExceptionMessage = format("UNKNOWN: cannot set mkt price margin or" @@ -458,7 +458,7 @@ public void testEditTriggerPriceOnFixedPriceBsqOfferShouldThrowException() { BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. - var newTriggerPriceAsLong = calcFiatTriggerPriceAsLong.apply(0.00005, 0.00); + var newTriggerPriceAsLong = calcPriceAsString(0.00005, 0.00, 8); Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOffer(originalOffer.getId(), "0.00", @@ -492,7 +492,7 @@ public void testEditFixedPriceOnBsqOffer() { newFixedPriceAsString, false, 0.0, - 0, + NO_TRIGGER_PRICE, ACTIVATE_OFFER, FIXED_PRICE_ONLY); // Wait for edited offer to be edited and removed from offer-book. @@ -503,7 +503,7 @@ public void testEditFixedPriceOnBsqOffer() { assertTrue(editedOffer.getIsActivated()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); - assertEquals(0, editedOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); } @Test @@ -524,7 +524,7 @@ public void testDisableBsqOffer() { fixedPriceAsString, false, 0.0, - 0, + NO_TRIGGER_PRICE, DEACTIVATE_OFFER, ACTIVATION_STATE_ONLY); // Wait for edited offer to be removed from offer-book. @@ -535,7 +535,7 @@ public void testDisableBsqOffer() { assertEquals(fixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); - assertEquals(0, editedOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); } @Test @@ -557,7 +557,7 @@ public void testEditFixedPriceAndDisableBsqOffer() { newFixedPriceAsString, false, 0.0, - 0, + NO_TRIGGER_PRICE, DEACTIVATE_OFFER, FIXED_PRICE_AND_ACTIVATION_STATE); // Wait for edited offer to be edited and removed from offer-book. @@ -568,7 +568,7 @@ public void testEditFixedPriceAndDisableBsqOffer() { assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); - assertEquals(0, editedOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); } // Edit XMR Offers @@ -578,12 +578,12 @@ public void testEditFixedPriceAndDisableBsqOffer() { public void testChangePriceMarginBasedXmrOfferWithTriggerPriceToFixedPricedAndDeactivateIt() { createXmrPaymentAccounts(); double mktPriceAsDouble = aliceClient.getBtcPrice(XMR); - long triggerPriceAsLong = calcAltcoinTriggerPriceAsLong.apply(mktPriceAsDouble, 0.001); + String triggerPrice = calcPriceAsString(mktPriceAsDouble, 0.001, 8); OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(), XMR, alicesXmrAcct.getId(), 0.0, - triggerPriceAsLong); + triggerPrice); log.debug("Pending XMR offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. @@ -595,7 +595,7 @@ public void testChangePriceMarginBasedXmrOfferWithTriggerPriceToFixedPricedAndDe newFixedPriceAsString, false, 0.00, - 0, + NO_TRIGGER_PRICE, DEACTIVATE_OFFER, FIXED_PRICE_AND_ACTIVATION_STATE); // Wait for edited offer to be removed from offer-book, edited & not re-published. @@ -605,7 +605,7 @@ public void testChangePriceMarginBasedXmrOfferWithTriggerPriceToFixedPricedAndDe assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); - assertEquals(0, editedOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); assertFalse(editedOffer.getIsActivated()); doSanityCheck(originalOffer, editedOffer); @@ -628,12 +628,12 @@ public void testEditTriggerPriceOnPriceMarginBasedXmrOffer() { log.info("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); double mktPriceAsDouble = aliceClient.getBtcPrice(XMR); - long triggerPriceAsLong = calcAltcoinTriggerPriceAsLong.apply(mktPriceAsDouble, 0.001); + String triggerPrice = calcPriceAsString(mktPriceAsDouble, 0.001, 8); aliceClient.editOffer(originalOffer.getId(), "0", true, mktPriceMargin, - triggerPriceAsLong, + triggerPrice, ACTIVATE_OFFER, TRIGGER_PRICE_ONLY); // Wait for edited offer to be removed from offer-book, edited & not re-published. @@ -642,7 +642,7 @@ public void testEditTriggerPriceOnPriceMarginBasedXmrOffer() { log.info("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); assertTrue(editedOffer.getUseMarketBasedPrice()); assertEquals(scaledDownMktPriceMargin.apply(mktPriceMargin), editedOffer.getMarketPriceMargin()); - assertEquals(triggerPriceAsLong, editedOffer.getTriggerPrice()); + assertEquals(triggerPrice, editedOffer.getTriggerPrice()); assertTrue(editedOffer.getIsActivated()); doSanityCheck(originalOffer, editedOffer); @@ -671,12 +671,12 @@ public void testChangeFixedPricedXmrOfferToPriceMarginBasedOfferWithTriggerPrice // Change the offer to mkt price based and set a trigger price. var newMktPriceMargin = new BigDecimal("0.05").doubleValue(); var delta = -0.00100000; - var newTriggerPriceAsLong = calcAltcoinTriggerPriceAsLong.apply(mktPriceAsDouble, delta); + var newTriggerPrice = calcPriceAsString(mktPriceAsDouble, delta, 8); aliceClient.editOffer(originalOffer.getId(), "0.00", true, newMktPriceMargin, - newTriggerPriceAsLong, + newTriggerPrice, ACTIVATE_OFFER, MKT_PRICE_MARGIN_AND_TRIGGER_PRICE); // Wait for edited offer to be removed from offer-book, edited, and re-published. @@ -685,7 +685,7 @@ public void testChangeFixedPricedXmrOfferToPriceMarginBasedOfferWithTriggerPrice log.debug("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); assertTrue(editedOffer.getUseMarketBasedPrice()); assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); - assertEquals(newTriggerPriceAsLong, editedOffer.getTriggerPrice()); + assertEquals(newTriggerPrice, editedOffer.getTriggerPrice()); assertTrue(editedOffer.getIsActivated()); doSanityCheck(originalOffer, editedOffer); @@ -706,13 +706,13 @@ public void testEditTriggerPriceOnFixedPriceXmrOfferShouldThrowException() { log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. - var newTriggerPriceAsLong = calcAltcoinTriggerPriceAsLong.apply(0.007, 0.001); + var newTriggerPrice = calcPriceAsString(0.007, 0.001, 8); Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOffer(originalOffer.getId(), "0.00", false, 0.1, - newTriggerPriceAsLong, + newTriggerPrice, ACTIVATE_OFFER, TRIGGER_PRICE_ONLY)); String expectedExceptionMessage = format("UNKNOWN: programmer error: cannot set a trigger price" @@ -736,19 +736,19 @@ public void testEditFixedPriceOnXmrOffer() { BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. - String newFixedPriceAsString = "0.00900000"; + String newFixedPrice = "0.00900000"; aliceClient.editOffer(originalOffer.getId(), - newFixedPriceAsString, + newFixedPrice, false, 0.0, - 0, + NO_TRIGGER_PRICE, ACTIVATE_OFFER, FIXED_PRICE_ONLY); // Wait for edited offer to be edited and removed from offer-book. genBtcBlocksThenWait(1, 2500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(newFixedPriceAsString, editedOffer.getPrice()); + assertEquals(newFixedPrice, editedOffer.getPrice()); assertTrue(editedOffer.getIsActivated()); assertMarketBasedPriceFieldsAreIgnored(editedOffer); @@ -774,7 +774,7 @@ public void testDisableXmrOffer() { fixedPriceAsString, false, 0.0, - 0, + NO_TRIGGER_PRICE, DEACTIVATE_OFFER, ACTIVATION_STATE_ONLY); // Wait for edited offer to be removed from offer-book. @@ -808,7 +808,7 @@ public void testEditFixedPriceAndDisableXmrOffer() { newFixedPriceAsString, false, 0.0, - 0, + NO_TRIGGER_PRICE, DEACTIVATE_OFFER, FIXED_PRICE_AND_ACTIVATION_STATE); // Wait for edited offer to be edited and removed from offer-book. @@ -849,7 +849,7 @@ public void testEditBsqSwapOfferShouldThrowException() { newFixedPrice, false, 0.0, - 0, + NO_TRIGGER_PRICE, ACTIVATE_OFFER, TRIGGER_PRICE_ONLY)); String expectedExceptionMessage = format("UNKNOWN: cannot edit bsq swap offer with id '%s'", @@ -861,7 +861,7 @@ private OfferInfo createMktPricedOfferForEdit(String direction, String currencyCode, String paymentAccountId, double marketPriceMargin, - long triggerPrice) { + String triggerPrice) { return aliceClient.createMarketBasedPricedOffer(direction, currencyCode, AMOUNT, @@ -905,7 +905,7 @@ private void doSanityCheck(OfferInfo originalOffer, OfferInfo editedOffer) { private void assertMarketBasedPriceFieldsAreIgnored(OfferInfo editedOffer) { assertFalse(editedOffer.getUseMarketBasedPrice()); assertEquals(0.00, editedOffer.getMarketPriceMargin()); - assertEquals(0, editedOffer.getTriggerPrice()); + assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); } private PaymentAccount getOrCreatePaymentAccount(String countryCode) { diff --git a/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java b/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java index 7dee678d2c6..a27fa8174d4 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java +++ b/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java @@ -31,7 +31,6 @@ import org.junit.jupiter.api.condition.EnabledIf; import static bisq.apitest.config.ApiTestConfig.BTC; -import static bisq.cli.CurrencyFormat.formatPrice; import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static java.lang.System.getenv; import static org.junit.jupiter.api.Assertions.fail; @@ -59,8 +58,8 @@ public class LongRunningOfferDeactivationTest extends AbstractOfferTest { public void testSellOfferAutoDisable(final TestInfo testInfo) { PaymentAccount paymentAcct = createDummyF2FAccount(aliceClient, "US"); double mktPriceAsDouble = aliceClient.getBtcPrice("USD"); - long triggerPrice = calcFiatTriggerPriceAsLong.apply(mktPriceAsDouble, -50.0000); - log.info("Current USD mkt price = {} Trigger Price = {}", mktPriceAsDouble, formatPrice(triggerPrice)); + String triggerPrice = calcPriceAsString(mktPriceAsDouble, -50.0000, 4); + log.info("Current USD mkt price = {} Trigger Price = {}", mktPriceAsDouble, triggerPrice); OfferInfo offer = aliceClient.createMarketBasedPricedOffer(SELL.name(), "USD", 1_000_000, @@ -76,8 +75,7 @@ public void testSellOfferAutoDisable(final TestInfo testInfo) { genBtcBlocksThenWait(1, 2500); // Wait for offer book entry. offer = aliceClient.getOffer(offer.getId()); // Offer has trigger price now. - log.info("SELL offer should be automatically disabled when mkt price falls below {}.", - formatPrice(offer.getTriggerPrice())); + log.info("SELL offer should be automatically disabled when mkt price falls below {}.", offer.getTriggerPrice()); int numIterations = 0; while (++numIterations < MAX_ITERATIONS) { @@ -87,12 +85,12 @@ public void testSellOfferAutoDisable(final TestInfo testInfo) { if (offer.getIsActivated()) { log.info("Offer still enabled at mkt price {} > {} trigger price", mktPrice, - formatPrice(offer.getTriggerPrice())); + offer.getTriggerPrice()); sleep(1000 * 60); // 60s } else { log.info("Successful test completion after offer disabled at mkt price {} < {} trigger price.", mktPrice, - formatPrice(offer.getTriggerPrice())); + offer.getTriggerPrice()); break; } if (numIterations == MAX_ITERATIONS) @@ -107,8 +105,8 @@ public void testSellOfferAutoDisable(final TestInfo testInfo) { public void testBuyOfferAutoDisable(final TestInfo testInfo) { PaymentAccount paymentAcct = createDummyF2FAccount(aliceClient, "US"); double mktPriceAsDouble = aliceClient.getBtcPrice("USD"); - long triggerPrice = calcFiatTriggerPriceAsLong.apply(mktPriceAsDouble, 50.0000); - log.info("Current USD mkt price = {} Trigger Price = {}", mktPriceAsDouble, formatPrice(triggerPrice)); + String triggerPrice = calcPriceAsString(mktPriceAsDouble, 50.0000, 4); + log.info("Current USD mkt price = {} Trigger Price = {}", mktPriceAsDouble, triggerPrice); OfferInfo offer = aliceClient.createMarketBasedPricedOffer(BUY.name(), "USD", 1_000_000, @@ -125,7 +123,7 @@ public void testBuyOfferAutoDisable(final TestInfo testInfo) { offer = aliceClient.getOffer(offer.getId()); // Offer has trigger price now. log.info("BUY offer should be automatically disabled when mkt price rises above {}.", - formatPrice(offer.getTriggerPrice())); + offer.getTriggerPrice()); int numIterations = 0; while (++numIterations < MAX_ITERATIONS) { @@ -135,12 +133,12 @@ public void testBuyOfferAutoDisable(final TestInfo testInfo) { if (offer.getIsActivated()) { log.info("Offer still enabled at mkt price {} < {} trigger price", mktPrice, - formatPrice(offer.getTriggerPrice())); + offer.getTriggerPrice()); sleep(1000 * 60); // 60s } else { log.info("Successful test completion after offer disabled at mkt price {} > {} trigger price.", mktPrice, - formatPrice(offer.getTriggerPrice())); + offer.getTriggerPrice()); break; } if (numIterations == MAX_ITERATIONS) diff --git a/apitest/src/test/java/bisq/apitest/scenario/bot/BotClient.java b/apitest/src/test/java/bisq/apitest/scenario/bot/BotClient.java index 3ae53d7d55c..2a32aa77a54 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/bot/BotClient.java +++ b/apitest/src/test/java/bisq/apitest/scenario/bot/BotClient.java @@ -120,6 +120,7 @@ public List getSellOffers(String currencyCode) { * @param priceMarginAsPercent * @param securityDepositAsPercent * @param feeCurrency + * @param triggerPrice * @return OfferInfo */ public OfferInfo createOfferAtMarketBasedPrice(PaymentAccount paymentAccount, @@ -130,7 +131,7 @@ public OfferInfo createOfferAtMarketBasedPrice(PaymentAccount paymentAccount, double priceMarginAsPercent, double securityDepositAsPercent, String feeCurrency, - long triggerPrice) { + String triggerPrice) { return grpcClient.createMarketBasedPricedOffer(direction, currencyCode, amountInSatoshis, diff --git a/apitest/src/test/java/bisq/apitest/scenario/bot/RandomOffer.java b/apitest/src/test/java/bisq/apitest/scenario/bot/RandomOffer.java index de728aa76e9..5f6cf143d43 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/bot/RandomOffer.java +++ b/apitest/src/test/java/bisq/apitest/scenario/bot/RandomOffer.java @@ -129,7 +129,7 @@ public RandomOffer create() throws InvalidRandomOfferException { priceMargin, getDefaultBuyerSecurityDepositAsPercent(), feeCurrency, - 0 /*no trigger price*/); + "0" /*no trigger price*/); } else { this.offer = botClient.createOfferAtFixedPrice(paymentAccount, direction, From d42c58073fa30df50ea3f36e75badb0578182ea0 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 16:43:23 -0300 Subject: [PATCH 11/41] Change OfferInfo proto's volume fields' type to string --- .../java/bisq/core/api/model/OfferInfo.java | 18 +++++++++++------- .../api/model/builder/OfferInfoBuilder.java | 8 ++++---- proto/src/main/proto/grpc.proto | 16 ++++++---------- 3 files changed, 21 insertions(+), 21 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 c3703d2ab42..48a15be9425 100644 --- a/core/src/main/java/bisq/core/api/model/OfferInfo.java +++ b/core/src/main/java/bisq/core/api/model/OfferInfo.java @@ -32,6 +32,7 @@ import lombok.ToString; import static bisq.core.util.PriceUtil.reformatMarketPrice; +import static bisq.core.util.VolumeUtil.formatVolume; import static java.util.Objects.requireNonNull; @EqualsAndHashCode @@ -50,8 +51,8 @@ public class OfferInfo implements Payload { private final double marketPriceMargin; private final long amount; private final long minAmount; - private final long volume; - private final long minVolume; + private final String volume; + private final String minVolume; private final long txFee; private final long makerFee; private final String offerFeePaymentTxId; @@ -147,9 +148,12 @@ public static OfferInfo toMyOfferInfo(OpenOffer openOffer) { } private static OfferInfoBuilder getBuilder(Offer offer, boolean isMyOffer) { + var currencyCode = offer.getCurrencyCode(); var preciseOfferPrice = reformatMarketPrice( requireNonNull(offer.getPrice()).toPlainString(), - offer.getCurrencyCode()); + currencyCode); + var roundedVolume = formatVolume(requireNonNull(offer.getVolume())); + var roundedMinVolume = formatVolume(requireNonNull(offer.getMinVolume())); return new OfferInfoBuilder() .withId(offer.getId()) .withDirection(offer.getDirection().name()) @@ -158,8 +162,8 @@ private static OfferInfoBuilder getBuilder(Offer offer, boolean isMyOffer) { .withMarketPriceMargin(offer.getMarketPriceMargin()) .withAmount(offer.getAmount().value) .withMinAmount(offer.getMinAmount().value) - .withVolume(requireNonNull(offer.getVolume()).getValue()) - .withMinVolume(requireNonNull(offer.getMinVolume()).getValue()) + .withVolume(roundedVolume) + .withMinVolume(roundedMinVolume) .withMakerFee(getMakerFee(offer, isMyOffer)) .withTxFee(offer.getTxFee().value) .withOfferFeePaymentTxId(offer.getOfferFeePaymentTxId()) @@ -206,8 +210,8 @@ public bisq.proto.grpc.OfferInfo toProtoMessage() { .setMarketPriceMargin(marketPriceMargin) .setAmount(amount) .setMinAmount(minAmount) - .setVolume(volume) - .setMinVolume(minVolume) + .setVolume(volume == null ? "0" : volume) + .setMinVolume(minVolume == null ? "0" : minVolume) .setMakerFee(makerFee) .setTxFee(txFee) .setOfferFeePaymentTxId(isBsqSwapOffer ? "" : offerFeePaymentTxId) diff --git a/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java b/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java index 1ddb5e92de0..aadffccb6db 100644 --- a/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java +++ b/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java @@ -37,8 +37,8 @@ public final class OfferInfoBuilder { private double marketPriceMargin; private long amount; private long minAmount; - private long volume; - private long minVolume; + private String volume; + private String minVolume; private long txFee; private long makerFee; private String offerFeePaymentTxId; @@ -97,12 +97,12 @@ public OfferInfoBuilder withMinAmount(long minAmount) { return this; } - public OfferInfoBuilder withVolume(long volume) { + public OfferInfoBuilder withVolume(String volume) { this.volume = volume; return this; } - public OfferInfoBuilder withMinVolume(long minVolume) { + public OfferInfoBuilder withMinVolume(String minVolume) { this.minVolume = minVolume; return this; } diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 87f6609f275..3995d2de415 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -300,16 +300,12 @@ message OfferInfo { uint64 amount = 6; // The offer's minimum BTC amount in satoshis. One million satoshis is represented as 1000000. uint64 minAmount = 7; - // A long representing the rounded volume of currency to be traded for BTC. - // For EUR fiat offers, a volume of 29500.000 EUR would be represented as 29500000. - // TODO: Seems to be a bug in the volume, missing one trailing decimal. - // Price has 4 "ghost" decimal places. Volume has only 3 "ghost" decimal places, e.g., - // EUR PRICE: 295001234 - // EUR VOL: 29500000 - uint64 volume = 8; - // A long representing the minimum, rounded volume of currency to be traded for BTC. - // TODO: Resolve the problem mentioned above, in the volume field description. - uint64 minVolume = 9; + // The rounded volume of currency to be traded for BTC. + // Fiat volume is rounded to whole currency units (no cents). Altcoin volume is rounded to 2 decimal places. + string volume = 8; + // The rounded, minimum volume of currency to be traded for BTC. + // Fiat volume is rounded to whole currency units (no cents). Altcoin volume is rounded to 2 decimal places. + string minVolume = 9; // A long representing the BTC buyer's security deposit in satoshis. uint64 buyerSecurityDeposit = 10; // A market price margin based offer's trigger price is the market BTC price at which the offer is automatically disabled. From 2056e2638445f381d63631eb02403749ec91d6e6 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 16:45:37 -0300 Subject: [PATCH 12/41] Adjust cli module to grpc.proto::volume field type change (string) --- .../main/java/bisq/cli/CurrencyFormat.java | 66 ++++++++++++------- .../table/builder/AbstractTableBuilder.java | 10 +-- .../cli/table/builder/OfferTableBuilder.java | 44 ++++++++----- .../bisq/cli/table/column/AltcoinColumn.java | 1 + .../bisq/cli/table/column/FiatColumn.java | 1 + 5 files changed, 76 insertions(+), 46 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java index ba0e84fca2d..ba1029d3c72 100644 --- a/cli/src/main/java/bisq/cli/CurrencyFormat.java +++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java @@ -39,8 +39,8 @@ public class CurrencyFormat { // Use the US locale for all DecimalFormat objects. private static final DecimalFormatSymbols DECIMAL_FORMAT_SYMBOLS = DecimalFormatSymbols.getInstance(Locale.US); - // Format numbers in US locale for CLI console. - private static final NumberFormat FRIENDLY_NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); + // Format all numbers displayed in the CLI console with the US locale (no i18n support for CLI). + private static final NumberFormat US_LOCALE_NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); // Formats numbers for internal use, i.e., grpc request parameters. private static final DecimalFormat INTERNAL_FIAT_DECIMAL_FORMAT = new DecimalFormat("##############0.0000"); @@ -54,6 +54,9 @@ public class CurrencyFormat { static final DecimalFormat BSQ_FORMAT = new DecimalFormat("###,###,###,##0.00", DECIMAL_FORMAT_SYMBOLS); static final DecimalFormat SEND_BSQ_FORMAT = new DecimalFormat("###########0.00", DECIMAL_FORMAT_SYMBOLS); + static final DecimalFormat ALTCOIN_VOLUME_FORMAT = new DecimalFormat("########0.00", DECIMAL_FORMAT_SYMBOLS); + static final DecimalFormat FIAT_VOLUME_FORMAT = new DecimalFormat("###########0", DECIMAL_FORMAT_SYMBOLS); + static final BigDecimal SECURITY_DEPOSIT_MULTIPLICAND = new BigDecimal("0.01"); @SuppressWarnings("BigDecimalMethodWithoutRoundingCalled") @@ -71,13 +74,28 @@ public static String formatBsq(long sats) { return BSQ_FORMAT.format(BigDecimal.valueOf(sats).divide(BSQ_SATOSHI_DIVISOR)); } + @Deprecated // TODO delete public static String formatBsqAmount(long bsqSats) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(2); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(2); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(HALF_UP); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(2); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(2); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); return SEND_BSQ_FORMAT.format((double) bsqSats / SATOSHI_DIVISOR.doubleValue()); } + public static String formatVolumeString(String volumeString, int precision) { + if (volumeString == null || volumeString.isBlank()) + return ""; + + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(precision); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(precision); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); + var volAsDouble = new BigDecimal(volumeString).doubleValue(); + if (precision == 0) + return FIAT_VOLUME_FORMAT.format(volAsDouble); + else + return ALTCOIN_VOLUME_FORMAT.format(volAsDouble); + } + public static String formatTxFeeRateInfo(TxFeeRateInfo txFeeRateInfo) { if (txFeeRateInfo.getUseCustomTxFeeRate()) return format("custom tx fee rate: %s sats/byte, network rate: %s sats/byte, min network rate: %s sats/byte", @@ -118,31 +136,31 @@ public static String formatInternalFiatPrice(BigDecimal price) { } public static String formatInternalFiatPrice(double price) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(4); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(4); - return FRIENDLY_NUMBER_FORMAT.format(price); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(4); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(4); + return US_LOCALE_NUMBER_FORMAT.format(price); } @Deprecated public static String formatPrice(long price) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(4); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(4); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); - return FRIENDLY_NUMBER_FORMAT.format((double) price / 10_000); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(4); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(4); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); + return US_LOCALE_NUMBER_FORMAT.format((double) price / 10_000); } public static String formatCryptoCurrencyPrice(long price) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(8); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(8); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); - return FRIENDLY_NUMBER_FORMAT.format((double) price / SATOSHI_DIVISOR.doubleValue()); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(8); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(8); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); + return US_LOCALE_NUMBER_FORMAT.format((double) price / SATOSHI_DIVISOR.doubleValue()); } public static String formatFiatVolume(long volume) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(0); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(0); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(HALF_UP); - return FRIENDLY_NUMBER_FORMAT.format((double) volume / 10_000); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(0); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(0); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); + return US_LOCALE_NUMBER_FORMAT.format((double) volume / 10_000); } public static String formatCryptoCurrencyVolume(long volume) { @@ -151,10 +169,10 @@ public static String formatCryptoCurrencyVolume(long volume) { } public static String formatCryptoCurrencyVolume(long volume, int precision) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(precision); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(precision); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(HALF_UP); - return FRIENDLY_NUMBER_FORMAT.format((double) volume / SATOSHI_DIVISOR.doubleValue()); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(precision); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(precision); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); + return US_LOCALE_NUMBER_FORMAT.format((double) volume / SATOSHI_DIVISOR.doubleValue()); } @Deprecated diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java index cdb5f3ffa3f..1b57fa691c8 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java @@ -20,7 +20,6 @@ import bisq.proto.grpc.OfferInfo; import java.util.List; -import java.util.function.Function; import java.util.function.Predicate; @@ -32,7 +31,7 @@ */ abstract class AbstractTableBuilder { - protected final Function toBlankOrNonZeroValue = (s) -> s.trim().equals("0") ? "" : s; + protected final Predicate isFiatOffer = (o) -> o.getBaseCurrencyCode().equals("BTC"); protected final TableType tableType; protected final List protos; @@ -45,6 +44,9 @@ abstract class AbstractTableBuilder { } public abstract Table build(); - - protected final Predicate isFiatOffer = (o) -> o.getBaseCurrencyCode().equals("BTC"); } + +/* + var currencyCode = isFiatOffer.test(o); + + */ diff --git a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java index a97c73b848e..5a86ce92a79 100644 --- a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java @@ -26,13 +26,12 @@ import javax.annotation.Nullable; +import static bisq.cli.CurrencyFormat.formatVolumeString; import static bisq.cli.table.builder.TableBuilderConstants.*; import static bisq.cli.table.builder.TableType.OFFER_TBL; -import static bisq.cli.table.column.AltcoinColumn.DISPLAY_MODE.ALTCOIN_OFFER_VOLUME; import static bisq.cli.table.column.Column.JUSTIFICATION.LEFT; import static bisq.cli.table.column.Column.JUSTIFICATION.NONE; import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; -import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.VOLUME; import static bisq.cli.table.column.ZippedStringColumns.DUPLICATION_MODE.EXCLUDE_DUPLICATES; import static java.lang.String.format; import static protobuf.OfferDirection.BUY; @@ -41,9 +40,7 @@ import bisq.cli.table.Table; -import bisq.cli.table.column.AltcoinColumn; import bisq.cli.table.column.Column; -import bisq.cli.table.column.FiatColumn; import bisq.cli.table.column.Iso8601DateTimeColumn; import bisq.cli.table.column.SatoshiColumn; import bisq.cli.table.column.StringColumn; @@ -79,8 +76,8 @@ public Table buildFiatOfferTable(List offers) { @Nullable Column colEnabled = enabledColumn.get(); // Not boolean: YES, NO, or PENDING Column colFiatPrice = new StringColumn(format(COL_HEADER_DETAILED_PRICE, fiatTradeCurrency.get()), RIGHT); - Column colFiatVolume = new FiatColumn(format("Temp Volume (%s)", fiatTradeCurrency.get()), NONE, VOLUME); - Column colMinFiatVolume = new FiatColumn(format("Temp Min Volume (%s)", fiatTradeCurrency.get()), NONE, VOLUME); + Column colFiatVolume = new StringColumn(format("Temp Volume (%s)", fiatTradeCurrency.get()), NONE); + Column colMinFiatVolume = new StringColumn(format("Temp Min Volume (%s)", fiatTradeCurrency.get()), NONE); @Nullable Column colTriggerPrice = fiatTriggerPriceColumn.get(); @@ -95,8 +92,10 @@ public Table buildFiatOfferTable(List offers) { colFiatPrice.addRow(o.getPrice()); colMinAmount.addRow(o.getMinAmount()); colAmount.addRow(o.getAmount()); - colMinFiatVolume.addRow(o.getMinVolume()); - colFiatVolume.addRow(o.getVolume()); + + var volumePrecision = toOfferVolumePrecision.apply(o); + colMinFiatVolume.addRow(formatVolumeString(toBlankOrNonZeroValue.apply(o.getMinVolume()), volumePrecision)); + colFiatVolume.addRow(formatVolumeString(o.getVolume(), volumePrecision)); if (colTriggerPrice != null) colTriggerPrice.addRow(toBlankOrNonZeroValue.apply(o.getTriggerPrice())); @@ -142,12 +141,8 @@ public Table buildCryptoCurrencyOfferTable(List offers) { @Nullable Column colEnabled = enabledColumn.get(); // Not boolean: YES, NO, or PENDING Column colBtcPrice = new StringColumn(format(COL_HEADER_DETAILED_PRICE_OF_ALTCOIN, altcoinTradeCurrency.get()), RIGHT); - Column colBtcVolume = new AltcoinColumn(format("Temp Volume (%s)", altcoinTradeCurrency.get()), - NONE, - ALTCOIN_OFFER_VOLUME); - Column colMinBtcVolume = new AltcoinColumn(format("Temp Min Volume (%s)", altcoinTradeCurrency.get()), - NONE, - ALTCOIN_OFFER_VOLUME); + Column colBtcVolume = new StringColumn(format("Temp Volume (%s)", altcoinTradeCurrency.get()), NONE); + Column colMinBtcVolume = new StringColumn(format("Temp Min Volume (%s)", altcoinTradeCurrency.get()), NONE); @Nullable Column colTriggerPrice = altcoinTriggerPriceColumn.get(); @@ -162,8 +157,9 @@ public Table buildCryptoCurrencyOfferTable(List offers) { colBtcPrice.addRow(o.getPrice()); colAmount.addRow(o.getAmount()); colMinAmount.addRow(o.getMinAmount()); - colBtcVolume.addRow(o.getMinVolume()); - colMinBtcVolume.addRow(o.getVolume()); + var volumePrecision = toOfferVolumePrecision.apply(o); + colBtcVolume.addRow(formatVolumeString(o.getVolume(), volumePrecision)); + colMinBtcVolume.addRow(formatVolumeString(toBlankOrNonZeroValue.apply(o.getMinVolume()), volumePrecision)); if (colTriggerPrice != null) colTriggerPrice.addRow(toBlankOrNonZeroValue.apply(o.getTriggerPrice())); @@ -178,8 +174,8 @@ public Table buildCryptoCurrencyOfferTable(List offers) { new ZippedStringColumns(format(COL_HEADER_VOLUME_RANGE, altcoinTradeCurrency.get()), RIGHT, " - ", - colBtcVolume.asStringColumn(), - colMinBtcVolume.asStringColumn()); + colMinBtcVolume.asStringColumn(), + colBtcVolume.asStringColumn()); // Define and return the table instance with populated columns. @@ -215,6 +211,18 @@ public Table buildCryptoCurrencyOfferTable(List offers) { } } + // TODO Might want to move these three functions into superclass (if TradeTableBuilder needs them). + private final Function toBlankOrNonZeroValue = (s) -> s.trim().equals("0") ? "" : s; + private final Function toOfferCurrencyCode = (o) -> isFiatOffer.test(o) + ? o.getCounterCurrencyCode() + : o.getBaseCurrencyCode(); + private final Function toOfferVolumePrecision = (o) -> { + if (isFiatOffer.test(o)) + return 0; + else + return toOfferCurrencyCode.apply(o).equals("BSQ") ? 2 : 8; + }; + private final Supplier firstOfferInList = () -> (OfferInfo) protos.get(0); private final Supplier isShowingMyOffers = () -> firstOfferInList.get().getIsMyOffer(); private final Supplier isShowingFiatOffers = () -> isFiatOffer.test(firstOfferInList.get()); diff --git a/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java b/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java index 3b13171f7f7..79f4976bf5b 100644 --- a/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java +++ b/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java @@ -32,6 +32,7 @@ public class AltcoinColumn extends LongColumn { public enum DISPLAY_MODE { + @Deprecated ALTCOIN_OFFER_VOLUME, ALTCOIN_PRICE, @Deprecated diff --git a/cli/src/main/java/bisq/cli/table/column/FiatColumn.java b/cli/src/main/java/bisq/cli/table/column/FiatColumn.java index 9adb9de5a01..81ebcb7fe58 100644 --- a/cli/src/main/java/bisq/cli/table/column/FiatColumn.java +++ b/cli/src/main/java/bisq/cli/table/column/FiatColumn.java @@ -35,6 +35,7 @@ public enum DISPLAY_MODE { PRICE, @Deprecated TRIGGER_PRICE, + @Deprecated VOLUME } From 31c8fbb679b9574f3ec82a201161701add59e3b0 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 16:48:32 -0300 Subject: [PATCH 13/41] Remove some dead code --- .../main/java/bisq/cli/CurrencyFormat.java | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java index ba1029d3c72..403e5544ca7 100644 --- a/cli/src/main/java/bisq/cli/CurrencyFormat.java +++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java @@ -52,7 +52,6 @@ public class CurrencyFormat { static final BigDecimal BSQ_SATOSHI_DIVISOR = new BigDecimal(100); static final DecimalFormat BSQ_FORMAT = new DecimalFormat("###,###,###,##0.00", DECIMAL_FORMAT_SYMBOLS); - static final DecimalFormat SEND_BSQ_FORMAT = new DecimalFormat("###########0.00", DECIMAL_FORMAT_SYMBOLS); static final DecimalFormat ALTCOIN_VOLUME_FORMAT = new DecimalFormat("########0.00", DECIMAL_FORMAT_SYMBOLS); static final DecimalFormat FIAT_VOLUME_FORMAT = new DecimalFormat("###########0", DECIMAL_FORMAT_SYMBOLS); @@ -74,14 +73,6 @@ public static String formatBsq(long sats) { return BSQ_FORMAT.format(BigDecimal.valueOf(sats).divide(BSQ_SATOSHI_DIVISOR)); } - @Deprecated // TODO delete - public static String formatBsqAmount(long bsqSats) { - US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(2); - US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(2); - US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); - return SEND_BSQ_FORMAT.format((double) bsqSats / SATOSHI_DIVISOR.doubleValue()); - } - public static String formatVolumeString(String volumeString, int precision) { if (volumeString == null || volumeString.isBlank()) return ""; @@ -108,27 +99,6 @@ public static String formatTxFeeRateInfo(TxFeeRateInfo txFeeRateInfo) { formatFeeSatoshis(txFeeRateInfo.getMinFeeServiceRate())); } - @Deprecated - public static String formatAmountRange(long minAmount, long amount) { - return minAmount != amount - ? formatSatoshis(minAmount) + " - " + formatSatoshis(amount) - : formatSatoshis(amount); - } - - @Deprecated - public static String formatVolumeRange(long minVolume, long volume) { - return minVolume != volume - ? formatFiatVolume(minVolume) + " - " + formatFiatVolume(volume) - : formatFiatVolume(volume); - } - - @Deprecated - public static String formatCryptoCurrencyVolumeRange(long minVolume, long volume) { - return minVolume != volume - ? formatCryptoCurrencyVolume(minVolume) + " - " + formatCryptoCurrencyVolume(volume) - : formatCryptoCurrencyVolume(volume); - } - public static String formatInternalFiatPrice(BigDecimal price) { INTERNAL_FIAT_DECIMAL_FORMAT.setMinimumFractionDigits(4); INTERNAL_FIAT_DECIMAL_FORMAT.setMaximumFractionDigits(4); From 15f75eea3d1d0dda0a586e7c07496960294c8b04 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 16:49:51 -0300 Subject: [PATCH 14/41] Add some asserts on volume/min-volume strings from server --- .../method/offer/CreateBSQOffersTest.java | 28 +++++++++++++++---- .../offer/CreateOfferUsingFixedPriceTest.java | 18 ++++++++++-- ...CreateOfferUsingMarketPriceMarginTest.java | 10 +++---- .../method/trade/AbstractTradeTest.java | 12 +++++--- .../method/trade/TakeBuyBSQOfferTest.java | 2 +- .../method/trade/TakeSellBSQOfferTest.java | 2 +- 6 files changed, 52 insertions(+), 20 deletions(-) diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java index 57b318e68ed..2b878c1803d 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java @@ -66,7 +66,7 @@ public void testCreateBuy1BTCFor20KBSQOffer() { getDefaultBuyerSecurityDepositAsPercent(), alicesLegacyBsqAcct.getId(), MAKER_FEE_CURRENCY_CODE); - log.debug("Sell BSQ (Buy BTC) OFFER:\n{}", toOfferTable.apply(newOffer)); + log.debug("Sell BSQ (Buy BTC) Offer:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -77,6 +77,8 @@ public void testCreateBuy1BTCFor20KBSQOffer() { assertEquals("0.00005000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getMinAmount()); + assertEquals("20000.00", newOffer.getVolume()); + assertEquals("20000.00", newOffer.getMinVolume()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(alicesLegacyBsqAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(BSQ, newOffer.getBaseCurrencyCode()); @@ -94,6 +96,8 @@ public void testCreateBuy1BTCFor20KBSQOffer() { assertEquals("0.00005000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getMinAmount()); + assertEquals("20000.00", newOffer.getVolume()); + assertEquals("20000.00", newOffer.getMinVolume()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(alicesLegacyBsqAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(BSQ, newOffer.getBaseCurrencyCode()); @@ -113,7 +117,7 @@ public void testCreateSell1BTCFor20KBSQOffer() { getDefaultBuyerSecurityDepositAsPercent(), alicesLegacyBsqAcct.getId(), MAKER_FEE_CURRENCY_CODE); - log.debug("SELL 20K BSQ OFFER:\n{}", toOfferTable.apply(newOffer)); + log.debug("SELL 20K BSQ Offer:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -124,6 +128,8 @@ public void testCreateSell1BTCFor20KBSQOffer() { assertEquals("0.00005000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getMinAmount()); + assertEquals("20000.00", newOffer.getVolume()); + assertEquals("20000.00", newOffer.getMinVolume()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(alicesLegacyBsqAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(BSQ, newOffer.getBaseCurrencyCode()); @@ -141,6 +147,8 @@ public void testCreateSell1BTCFor20KBSQOffer() { assertEquals("0.00005000", newOffer.getPrice()); assertEquals(100_000_000L, newOffer.getAmount()); assertEquals(100_000_000L, newOffer.getMinAmount()); + assertEquals("20000.00", newOffer.getVolume()); + assertEquals("20000.00", newOffer.getMinVolume()); assertEquals(15_000_000, newOffer.getBuyerSecurityDeposit()); assertEquals(alicesLegacyBsqAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(BSQ, newOffer.getBaseCurrencyCode()); @@ -160,7 +168,7 @@ public void testCreateBuyBTCWith1To2KBSQOffer() { getDefaultBuyerSecurityDepositAsPercent(), alicesLegacyBsqAcct.getId(), MAKER_FEE_CURRENCY_CODE); - log.debug("BUY 1-2K BSQ OFFER:\n{}", toOfferTable.apply(newOffer)); + log.debug("BUY 1-2K BSQ Offer:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -171,6 +179,8 @@ public void testCreateBuyBTCWith1To2KBSQOffer() { assertEquals("0.00005000", newOffer.getPrice()); assertEquals(10_000_000L, newOffer.getAmount()); assertEquals(5_000_000L, newOffer.getMinAmount()); + assertEquals("2000.00", newOffer.getVolume()); + assertEquals("1000.00", newOffer.getMinVolume()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(alicesLegacyBsqAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(BSQ, newOffer.getBaseCurrencyCode()); @@ -188,6 +198,8 @@ public void testCreateBuyBTCWith1To2KBSQOffer() { assertEquals("0.00005000", newOffer.getPrice()); assertEquals(10_000_000L, newOffer.getAmount()); assertEquals(5_000_000L, newOffer.getMinAmount()); + assertEquals("2000.00", newOffer.getVolume()); + assertEquals("1000.00", newOffer.getMinVolume()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(alicesLegacyBsqAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(BSQ, newOffer.getBaseCurrencyCode()); @@ -207,7 +219,7 @@ public void testCreateSellBTCFor5To10KBSQOffer() { getDefaultBuyerSecurityDepositAsPercent(), alicesLegacyBsqAcct.getId(), MAKER_FEE_CURRENCY_CODE); - log.debug("SELL 5-10K BSQ OFFER:\n{}", toOfferTable.apply(newOffer)); + log.debug("SELL 5-10K BSQ Offer:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -218,6 +230,8 @@ public void testCreateSellBTCFor5To10KBSQOffer() { assertEquals("0.00005000", newOffer.getPrice()); assertEquals(50_000_000L, newOffer.getAmount()); assertEquals(25_000_000L, newOffer.getMinAmount()); + assertEquals("10000.00", newOffer.getVolume()); + assertEquals("5000.00", newOffer.getMinVolume()); assertEquals(7_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(alicesLegacyBsqAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(BSQ, newOffer.getBaseCurrencyCode()); @@ -235,6 +249,8 @@ public void testCreateSellBTCFor5To10KBSQOffer() { assertEquals("0.00005000", newOffer.getPrice()); assertEquals(50_000_000L, newOffer.getAmount()); assertEquals(25_000_000L, newOffer.getMinAmount()); + assertEquals("10000.00", newOffer.getVolume()); + assertEquals("5000.00", newOffer.getMinVolume()); assertEquals(7_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(alicesLegacyBsqAcct.getId(), newOffer.getPaymentAccountId()); assertEquals(BSQ, newOffer.getBaseCurrencyCode()); @@ -246,7 +262,7 @@ public void testCreateSellBTCFor5To10KBSQOffer() { @Order(5) public void testGetAllMyBsqOffers() { List offers = aliceClient.getMyCryptoCurrencyOffersSortedByDate(BSQ); - log.debug("ALL ALICE'S BSQ OFFERS:\n{}", toOffersTable.apply(offers)); + log.debug("All Alice's BSQ Offers:\n{}", toOffersTable.apply(offers)); assertEquals(4, offers.size()); log.debug("ALICE'S BALANCES\n{}", formatBalancesTbls(aliceClient.getBalances())); } @@ -255,7 +271,7 @@ public void testGetAllMyBsqOffers() { @Order(6) public void testGetAvailableBsqOffers() { List offers = bobClient.getCryptoCurrencyOffersSortedByDate(BSQ); - log.debug("ALL BOB'S AVAILABLE BSQ OFFERS:\n{}", toOffersTable.apply(offers)); + log.debug("All Bob's Available BSQ Offers:\n{}", toOffersTable.apply(offers)); assertEquals(4, offers.size()); log.debug("BOB'S BALANCES\n{}", formatBalancesTbls(bobClient.getBalances())); } 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 fb921a2cbdd..794fb1310a8 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java @@ -58,7 +58,7 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() { getDefaultBuyerSecurityDepositAsPercent(), audAccount.getId(), MAKER_FEE_CURRENCY_CODE); - log.debug("OFFER #1:\n{}", toOfferTable.apply(newOffer)); + log.debug("Offer #1:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -69,6 +69,8 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() { assertEquals("36000.0000", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); + assertEquals("3600", newOffer.getVolume()); + assertEquals("3600", newOffer.getMinVolume()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(audAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(BTC, newOffer.getBaseCurrencyCode()); @@ -84,6 +86,8 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() { assertEquals("36000.0000", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); + assertEquals("3600", newOffer.getVolume()); + assertEquals("3600", newOffer.getMinVolume()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(audAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(BTC, newOffer.getBaseCurrencyCode()); @@ -103,7 +107,7 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() { getDefaultBuyerSecurityDepositAsPercent(), usdAccount.getId(), MAKER_FEE_CURRENCY_CODE); - log.debug("OFFER #2:\n{}", toOfferTable.apply(newOffer)); + log.debug("Offer #2:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -114,6 +118,8 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() { assertEquals("30000.1234", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); + assertEquals("3000", newOffer.getVolume()); + assertEquals("3000", newOffer.getMinVolume()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(BTC, newOffer.getBaseCurrencyCode()); @@ -129,6 +135,8 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() { assertEquals("30000.1234", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); + assertEquals("3000", newOffer.getVolume()); + assertEquals("3000", newOffer.getMinVolume()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(usdAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(BTC, newOffer.getBaseCurrencyCode()); @@ -148,7 +156,7 @@ public void testCreateEURBTCSellOfferUsingFixedPrice95001234() { getDefaultBuyerSecurityDepositAsPercent(), eurAccount.getId(), MAKER_FEE_CURRENCY_CODE); - log.debug("OFFER #3:\n{}", toOfferTable.apply(newOffer)); + log.debug("Offer #3:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -159,6 +167,8 @@ public void testCreateEURBTCSellOfferUsingFixedPrice95001234() { assertEquals("29500.1234", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(5_000_000, newOffer.getMinAmount()); + assertEquals("2950", newOffer.getVolume()); + assertEquals("1475", newOffer.getMinVolume()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(eurAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(BTC, newOffer.getBaseCurrencyCode()); @@ -174,6 +184,8 @@ public void testCreateEURBTCSellOfferUsingFixedPrice95001234() { assertEquals("29500.1234", newOffer.getPrice()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(5_000_000, newOffer.getMinAmount()); + assertEquals("2950", newOffer.getVolume()); + assertEquals("1475", newOffer.getMinVolume()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); assertEquals(eurAccount.getId(), newOffer.getPaymentAccountId()); assertEquals(BTC, newOffer.getBaseCurrencyCode()); 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 2dd32d44d3d..7ad241f50c0 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java @@ -75,7 +75,7 @@ public void testCreateUSDBTCBuyOffer5PctPriceMargin() { usdAccount.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); - log.debug("OFFER #1:\n{}", toOfferTable.apply(newOffer)); + log.debug("Offer #1:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -122,7 +122,7 @@ public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() { nzdAccount.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); - log.debug("OFFER #2:\n{}", toOfferTable.apply(newOffer)); + log.debug("Offer #2:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -169,7 +169,7 @@ public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() { gbpAccount.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); - log.debug("OFFER #3:\n{}", toOfferTable.apply(newOffer)); + log.debug("Offer #3:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -216,7 +216,7 @@ public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() { brlAccount.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); - log.debug("OFFER #4:\n{}", toOfferTable.apply(newOffer)); + log.debug("Offer #4:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertTrue(newOffer.getIsMyPendingOffer()); @@ -269,7 +269,7 @@ public void testCreateUSDBTCBuyOfferWithTriggerPrice() { genBtcBlocksThenWait(1, 4000); // give time to add to offer book newOffer = aliceClient.getOffer(newOffer.getId()); - log.debug("OFFER #5:\n{}", toOfferTable.apply(newOffer)); + log.debug("Offer #5:\n{}", toOfferTable.apply(newOffer)); assertTrue(newOffer.getIsMyOffer()); assertFalse(newOffer.getIsMyPendingOffer()); assertEquals(triggerPrice, newOffer.getTriggerPrice()); 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 5ceebe026a2..5ea52777c63 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java @@ -14,7 +14,6 @@ import org.junit.jupiter.api.TestInfo; import static bisq.apitest.config.ApiTestConfig.BTC; -import static bisq.cli.CurrencyFormat.formatBsqAmount; import static bisq.cli.table.builder.TableType.TRADE_DETAIL_TBL; import static bisq.core.trade.model.bisq_v1.Trade.Phase.DEPOSIT_CONFIRMED; import static bisq.core.trade.model.bisq_v1.Trade.Phase.FIAT_SENT; @@ -208,7 +207,10 @@ protected final void sendBsqPayment(Logger log, String receiverAddress = contract.getIsBuyerMakerAndSellerTaker() ? contract.getTakerPaymentAccountPayload().getAddress() : contract.getMakerPaymentAccountPayload().getAddress(); - String sendBsqAmount = formatBsqAmount(trade.getOffer().getVolume()); + // TODO Fix trade vol src bug for subclasses. + // This bug was fixed for production CLI with https://github.com/bisq-network/bisq/pull/5704 on Sep 27, 2021 + String sendBsqAmount = trade.getOffer().getVolume(); + // String sendBsqAmount = trade.getTradeVolume(); log.debug("Sending {} BSQ to address {}", sendBsqAmount, receiverAddress); grpcClient.sendBsq(receiverAddress, sendBsqAmount, ""); } @@ -217,8 +219,10 @@ protected final void verifyBsqPaymentHasBeenReceived(Logger log, GrpcClient grpcClient, TradeInfo trade) { var contract = trade.getContract(); - var bsqSats = trade.getOffer().getVolume(); - var receiveAmountAsString = formatBsqAmount(bsqSats); + // TODO Fix trade vol src bug for subclasses. + // This bug was fixed for production with https://github.com/bisq-network/bisq/pull/5704 on Sep 27, 2021 + var receiveAmountAsString = trade.getOffer().getVolume(); + // String receiveAmountAsString = trade.getTradeVolume(); var address = contract.getIsBuyerMakerAndSellerTaker() ? contract.getTakerPaymentAccountPayload().getAddress() : contract.getMakerPaymentAccountPayload().getAddress(); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBSQOfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBSQOfferTest.java index 6a37a3d1217..50bde49e244 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBSQOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBSQOfferTest.java @@ -79,7 +79,7 @@ public void testTakeAlicesSellBTCForBSQOffer(final TestInfo testInfo) { getDefaultBuyerSecurityDepositAsPercent(), alicesLegacyBsqAcct.getId(), TRADE_FEE_CURRENCY_CODE); - log.debug("ALICE'S BUY BSQ (SELL BTC) OFFER:\n{}", toOfferTable.apply(alicesOffer)); + log.debug("Alice's BUY BSQ (SELL BTC) Offer:\n{}", toOfferTable.apply(alicesOffer)); genBtcBlocksThenWait(1, 5000); var offerId = alicesOffer.getId(); assertFalse(alicesOffer.getIsCurrencyForMakerFeeBtc()); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBSQOfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBSQOfferTest.java index f4411c51789..ac1f0569153 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBSQOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBSQOfferTest.java @@ -81,7 +81,7 @@ public void testTakeAlicesBuyBTCForBSQOffer(final TestInfo testInfo) { getDefaultBuyerSecurityDepositAsPercent(), alicesLegacyBsqAcct.getId(), TRADE_FEE_CURRENCY_CODE); - log.debug("ALICE'S SELL BSQ (BUY BTC) OFFER:\n{}", new TableBuilder(OFFER_TBL, alicesOffer).build()); + log.debug("Alice's SELL BSQ (BUY BTC) Offer:\n{}", new TableBuilder(OFFER_TBL, alicesOffer).build()); genBtcBlocksThenWait(1, 4_000); var offerId = alicesOffer.getId(); assertTrue(alicesOffer.getIsCurrencyForMakerFeeBtc()); From 3b22aeeb98b48ed3f72dc4f629a970ed0d57dcaf Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 19 Feb 2022 15:06:42 -0300 Subject: [PATCH 15/41] Change TradeInfo .proto's price & volume fields to string --- proto/src/main/proto/grpc.proto | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 3995d2de415..7d9b588a837 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -601,7 +601,9 @@ message TradeInfo { string depositTxId = 10; string payoutTxId = 11; uint64 tradeAmountAsLong = 12; - uint64 tradePrice = 13; + // For fiat trades: the fiat price for 1 BTC to 4 decimal places, e.g., 41000.50 EUR is "41000.5000". + // For altcoin trades: the altcoin price for 1 BTC to 8 decimal places, e.g., 0.5 BTC is "0.50000000". + string tradePrice = 13; string tradingPeerNodeAddress = 14; string state = 15; string phase = 16; @@ -614,7 +616,8 @@ message TradeInfo { bool isWithdrawn = 23; string contractAsJson = 24; ContractInfo contract = 25; - uint64 tradeVolume = 26; + // The volume of currency traded for BTC. + string tradeVolume = 26; BsqSwapTradeInfo bsqSwapTradeInfo = 28; // Needed by open/closed/failed trade list items. string closingStatus = 29; From a0b68bc7562ebe44871429daf25fea40224ae39c Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 19 Feb 2022 15:09:16 -0300 Subject: [PATCH 16/41] Adjust .proto wrappers to price & volume type change Some minor refactoring included. --- .../core/api/model/CanceledTradeInfo.java | 6 +-- .../java/bisq/core/api/model/TradeInfo.java | 50 +++++++++++++------ .../api/model/builder/TradeInfoV1Builder.java | 8 +-- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/bisq/core/api/model/CanceledTradeInfo.java b/core/src/main/java/bisq/core/api/model/CanceledTradeInfo.java index d44af9b0356..f63a70028cc 100644 --- a/core/src/main/java/bisq/core/api/model/CanceledTradeInfo.java +++ b/core/src/main/java/bisq/core/api/model/CanceledTradeInfo.java @@ -39,7 +39,7 @@ public static TradeInfo toCanceledTradeInfo(OpenOffer myCanceledOpenOffer) { Offer offer = myCanceledOpenOffer.getOffer(); OfferInfo offerInfo = toMyOfferInfo(offer); - return new TradeInfoV1Builder() // TODO May need to use BsqSwapTradeInfoBuilder? + return new TradeInfoV1Builder() .withOffer(offerInfo) .withTradeId(myCanceledOpenOffer.getId()) .withShortId(myCanceledOpenOffer.getShortId()) @@ -52,8 +52,8 @@ public static TradeInfo toCanceledTradeInfo(OpenOffer myCanceledOpenOffer) { .withDepositTxId("") // Ignored .withPayoutTxId("") // Ignored .withTradeAmountAsLong(0) // Ignored - .withTradePrice(offer.getPrice().getValue()) - .withTradeVolume(0) // Ignored + .withTradePrice(offerInfo.getPrice()) + .withTradeVolume("") // Ignored .withTradingPeerNodeAddress("") // Ignored .withState("") // Ignored .withPhase("") // Ignored 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 0bf0d791916..62df346206b 100644 --- a/core/src/main/java/bisq/core/api/model/TradeInfo.java +++ b/core/src/main/java/bisq/core/api/model/TradeInfo.java @@ -25,6 +25,9 @@ import bisq.common.Payload; +import java.util.function.BiFunction; +import java.util.function.Function; + import lombok.EqualsAndHashCode; import lombok.Getter; @@ -34,6 +37,8 @@ import static bisq.core.api.model.PaymentAccountPayloadInfo.toPaymentAccountPayloadInfo; import static bisq.core.offer.OfferDirection.BUY; import static bisq.core.offer.OfferDirection.SELL; +import static bisq.core.util.PriceUtil.reformatMarketPrice; +import static bisq.core.util.VolumeUtil.formatVolume; import static java.util.Objects.requireNonNull; @EqualsAndHashCode @@ -44,6 +49,23 @@ public class TradeInfo implements Payload { // lighter weight TradeInfo proto wrapper instead, containing just enough fields to // view and interact with trades. + private static final BiFunction toOfferInfo = (tradeModel, isMyOffer) -> + isMyOffer ? toMyOfferInfo(tradeModel.getOffer()) : toOfferInfo(tradeModel.getOffer()); + + private static final Function toPeerNodeAddress = (tradeModel) -> + tradeModel.getTradingPeerNodeAddress() == null + ? "" + : tradeModel.getTradingPeerNodeAddress().getFullAddress(); + + private static final Function toRoundedVolume = (tradeModel) -> + tradeModel.getVolume() == null + ? "" + : formatVolume(requireNonNull(tradeModel.getVolume())); + + private static final Function toPreciseTradePrice = (tradeModel) -> + reformatMarketPrice(requireNonNull(tradeModel.getPrice()).toPlainString(), + tradeModel.getOffer().getCurrencyCode()); + // Bisq v1 trade protocol fields (some are in common with the BSQ Swap protocol). private final OfferInfo offer; private final String tradeId; @@ -57,8 +79,8 @@ public class TradeInfo implements Payload { private final String depositTxId; private final String payoutTxId; private final long tradeAmountAsLong; - private final long tradePrice; - private final long tradeVolume; + private final String tradePrice; + private final String tradeVolume; private final String tradingPeerNodeAddress; private final String state; private final String phase; @@ -133,14 +155,12 @@ public static TradeInfo toTradeInfo(BsqSwapTrade bsqSwapTrade, boolean isMyOffer, int numConfirmations, String closingStatus) { - OfferInfo offerInfo = isMyOffer ? toMyOfferInfo(bsqSwapTrade.getOffer()) : toOfferInfo(bsqSwapTrade.getOffer()); + var offerInfo = toOfferInfo.apply(bsqSwapTrade, isMyOffer); // A BSQ Swap miner tx fee is paid in full by the BTC seller (buying BSQ). // The BTC buyer's payout = tradeamount minus his share of miner fee. var isBtcSeller = (isMyOffer && bsqSwapTrade.getOffer().getDirection().equals(SELL)) || (!isMyOffer && bsqSwapTrade.getOffer().getDirection().equals(BUY)); - var txFeeInBtc = isBtcSeller - ? bsqSwapTrade.getTxFee().value - : 0L; + var txFeeInBtc = isBtcSeller ? bsqSwapTrade.getTxFee().value : 0L; // A BSQ Swap trade fee is paid in full by the BTC buyer (selling BSQ). // The transferred BSQ (payout) is reduced by the peer's trade fee. var takerFeeInBsq = !isMyOffer && bsqSwapTrade.getOffer().getDirection().equals(SELL) @@ -157,9 +177,9 @@ public static TradeInfo toTradeInfo(BsqSwapTrade bsqSwapTrade, .withTakerFeeAsLong(takerFeeInBsq) // N/A for bsq-swaps: .withTakerFeeTxId(""), .withDepositTxId(""), .withPayoutTxId("") .withTradeAmountAsLong(bsqSwapTrade.getAmountAsLong()) - .withTradePrice(bsqSwapTrade.getPrice().getValue()) - .withTradeVolume(bsqSwapTrade.getVolume() == null ? 0 : bsqSwapTrade.getVolume().getValue()) - .withTradingPeerNodeAddress(requireNonNull(bsqSwapTrade.getTradingPeerNodeAddress().getFullAddress())) + .withTradePrice(toPreciseTradePrice.apply(bsqSwapTrade)) + .withTradeVolume(toRoundedVolume.apply(bsqSwapTrade)) + .withTradingPeerNodeAddress(toPeerNodeAddress.apply(bsqSwapTrade)) .withState(bsqSwapTrade.getTradeState().name()) .withPhase(bsqSwapTrade.getTradePhase().name()) // N/A for bsq-swaps: .withTradePeriodState(""), .withIsDepositPublished(false), .withIsDepositConfirmed(false) @@ -194,7 +214,7 @@ private static TradeInfo toTradeInfo(Trade trade, contractInfo = ContractInfo.emptyContract.get(); } - OfferInfo offerInfo = isMyOffer ? toMyOfferInfo(trade.getOffer()) : toOfferInfo(trade.getOffer()); + var offerInfo = toOfferInfo.apply(trade, isMyOffer); return new TradeInfoV1Builder() .withOffer(offerInfo) .withTradeId(trade.getId()) @@ -208,9 +228,9 @@ private static TradeInfo toTradeInfo(Trade trade, .withDepositTxId(trade.getDepositTxId()) .withPayoutTxId(trade.getPayoutTxId()) .withTradeAmountAsLong(trade.getAmountAsLong()) - .withTradePrice(trade.getPrice().getValue()) - .withTradeVolume(trade.getVolume() == null ? 0 : trade.getVolume().getValue()) - .withTradingPeerNodeAddress(requireNonNull(trade.getTradingPeerNodeAddress().getFullAddress())) + .withTradePrice(toPreciseTradePrice.apply(trade)) + .withTradeVolume(toRoundedVolume.apply(trade)) + .withTradingPeerNodeAddress(toPeerNodeAddress.apply(trade)) .withState(trade.getTradeState().name()) .withPhase(trade.getTradePhase().name()) .withTradePeriodState(trade.getTradePeriodState().name()) @@ -246,8 +266,8 @@ public bisq.proto.grpc.TradeInfo toProtoMessage() { .setDepositTxId(depositTxId == null ? "" : depositTxId) .setPayoutTxId(payoutTxId == null ? "" : payoutTxId) .setTradeAmountAsLong(tradeAmountAsLong) - .setTradePrice(tradePrice) - .setTradeVolume(tradeVolume) + .setTradePrice(tradePrice == null ? "" : tradePrice) + .setTradeVolume(tradeVolume == null ? "" : tradeVolume) .setTradingPeerNodeAddress(tradingPeerNodeAddress) .setState(state == null ? "" : state) .setPhase(phase == null ? "" : phase) diff --git a/core/src/main/java/bisq/core/api/model/builder/TradeInfoV1Builder.java b/core/src/main/java/bisq/core/api/model/builder/TradeInfoV1Builder.java index 3fcc29eff8c..db9cb78621e 100644 --- a/core/src/main/java/bisq/core/api/model/builder/TradeInfoV1Builder.java +++ b/core/src/main/java/bisq/core/api/model/builder/TradeInfoV1Builder.java @@ -44,8 +44,8 @@ public final class TradeInfoV1Builder { private String depositTxId; private String payoutTxId; private long tradeAmountAsLong; - private long tradePrice; - private long tradeVolume; + private String tradePrice; + private String tradeVolume; private String tradingPeerNodeAddress; private String state; private String phase; @@ -120,12 +120,12 @@ public TradeInfoV1Builder withTradeAmountAsLong(long tradeAmountAsLong) { return this; } - public TradeInfoV1Builder withTradePrice(long tradePrice) { + public TradeInfoV1Builder withTradePrice(String tradePrice) { this.tradePrice = tradePrice; return this; } - public TradeInfoV1Builder withTradeVolume(long tradeVolume) { + public TradeInfoV1Builder withTradeVolume(String tradeVolume) { this.tradeVolume = tradeVolume; return this; } From e49ab16a7af34329f672d92e262beeede6eab118 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 19 Feb 2022 15:16:32 -0300 Subject: [PATCH 17/41] Adjust cli to TradeInfo .proto's price & volume type change Quite a bit of refactoring. A lot of number-string formatting was removed. --- cli/src/main/java/bisq/cli/CliMain.java | 28 +------ .../main/java/bisq/cli/CurrencyFormat.java | 65 ++++------------- .../table/builder/AbstractTableBuilder.java | 5 -- .../builder/AbstractTradeListBuilder.java | 50 +++++++------ .../builder/ClosedTradeTableBuilder.java | 16 ++-- .../builder/FailedTradeTableBuilder.java | 16 ++-- .../cli/table/builder/OfferTableBuilder.java | 47 ++++-------- .../table/builder/OpenTradeTableBuilder.java | 16 ++-- .../builder/TradeDetailTableBuilder.java | 21 +++--- .../builder/TradeTableColumnSupplier.java | 36 ++++----- ...inColumn.java => AltcoinVolumeColumn.java} | 41 ++++------- .../bisq/cli/table/column/FiatColumn.java | 21 ++---- .../cli/table/column/MixedPriceColumn.java | 57 --------------- .../cli/table/column/MixedVolumeColumn.java | 73 ------------------- 14 files changed, 132 insertions(+), 360 deletions(-) rename cli/src/main/java/bisq/cli/table/column/{AltcoinColumn.java => AltcoinVolumeColumn.java} (65%) delete mode 100644 cli/src/main/java/bisq/cli/table/column/MixedPriceColumn.java delete mode 100644 cli/src/main/java/bisq/cli/table/column/MixedVolumeColumn.java diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index 325373f747c..b5430e67d5f 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -35,14 +35,15 @@ import java.io.PrintStream; import java.io.PrintWriter; -import java.math.BigDecimal; - import java.util.Date; import java.util.List; import lombok.extern.slf4j.Slf4j; -import static bisq.cli.CurrencyFormat.*; +import static bisq.cli.CurrencyFormat.formatInternalFiatPrice; +import static bisq.cli.CurrencyFormat.formatTxFeeRateInfo; +import static bisq.cli.CurrencyFormat.toSatoshis; +import static bisq.cli.CurrencyFormat.toSecurityDepositAsPct; import static bisq.cli.Method.*; import static bisq.cli.opts.OptLabel.*; import static bisq.cli.table.builder.TableType.*; @@ -53,7 +54,6 @@ import static java.lang.System.err; import static java.lang.System.exit; import static java.lang.System.out; -import static java.math.BigDecimal.ZERO; @@ -789,26 +789,6 @@ private static long toLong(String param) { } } - @Deprecated - private static long toInternalTriggerPrice(GrpcClient client, - String offerId, - BigDecimal unscaledTriggerPrice) { - if (unscaledTriggerPrice.compareTo(ZERO) >= 0) { - // Unfortunately, the EditOffer proto triggerPrice field was declared as - // a long instead of a string, so the CLI has to look at the offer to know - // how to scale the trigger-price (for a fiat or altcoin offer) param sent - // to the server in its 'editoffer' request. That means a preliminary round - // trip to the server: a 'getmyoffer' request. - var offer = client.getOffer(offerId); - if (offer.getCounterCurrencyCode().equals("BTC")) - return toInternalCryptoCurrencyPrice(unscaledTriggerPrice); - else - return toInternalFiatPrice(unscaledTriggerPrice); - } else { - return 0L; - } - } - private static File saveFileToDisk(String prefix, @SuppressWarnings("SameParameterValue") String suffix, String text) { diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java index 403e5544ca7..d7cbc0b5e8b 100644 --- a/cli/src/main/java/bisq/cli/CurrencyFormat.java +++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java @@ -33,13 +33,16 @@ import static java.math.RoundingMode.HALF_UP; import static java.math.RoundingMode.UNNECESSARY; +/** + * Utility for formatting amounts, volumes and fees; there is no i18n support in the CLI. + */ @VisibleForTesting public class CurrencyFormat { - // Use the US locale for all DecimalFormat objects. + // Use the US locale as a base for all DecimalFormats, but commas should be omitted from number strings. private static final DecimalFormatSymbols DECIMAL_FORMAT_SYMBOLS = DecimalFormatSymbols.getInstance(Locale.US); - // Format all numbers displayed in the CLI console with the US locale (no i18n support for CLI). + // Use the US locale as a base for all NumberFormats, but commas should be omitted from number strings. private static final NumberFormat US_LOCALE_NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); // Formats numbers for internal use, i.e., grpc request parameters. @@ -53,38 +56,26 @@ public class CurrencyFormat { static final BigDecimal BSQ_SATOSHI_DIVISOR = new BigDecimal(100); static final DecimalFormat BSQ_FORMAT = new DecimalFormat("###,###,###,##0.00", DECIMAL_FORMAT_SYMBOLS); - static final DecimalFormat ALTCOIN_VOLUME_FORMAT = new DecimalFormat("########0.00", DECIMAL_FORMAT_SYMBOLS); - static final DecimalFormat FIAT_VOLUME_FORMAT = new DecimalFormat("###########0", DECIMAL_FORMAT_SYMBOLS); - static final BigDecimal SECURITY_DEPOSIT_MULTIPLICAND = new BigDecimal("0.01"); + public static String formatSatoshis(String sats) { + //noinspection BigDecimalMethodWithoutRoundingCalled + return SATOSHI_FORMAT.format(new BigDecimal(sats).divide(SATOSHI_DIVISOR)); + } + @SuppressWarnings("BigDecimalMethodWithoutRoundingCalled") public static String formatSatoshis(long sats) { - return SATOSHI_FORMAT.format(BigDecimal.valueOf(sats).divide(SATOSHI_DIVISOR)); + return SATOSHI_FORMAT.format(new BigDecimal(sats).divide(SATOSHI_DIVISOR)); } @SuppressWarnings("BigDecimalMethodWithoutRoundingCalled") public static String formatBtc(long sats) { - return BTC_FORMAT.format(BigDecimal.valueOf(sats).divide(SATOSHI_DIVISOR)); + return BTC_FORMAT.format(new BigDecimal(sats).divide(SATOSHI_DIVISOR)); } @SuppressWarnings("BigDecimalMethodWithoutRoundingCalled") public static String formatBsq(long sats) { - return BSQ_FORMAT.format(BigDecimal.valueOf(sats).divide(BSQ_SATOSHI_DIVISOR)); - } - - public static String formatVolumeString(String volumeString, int precision) { - if (volumeString == null || volumeString.isBlank()) - return ""; - - US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(precision); - US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(precision); - US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); - var volAsDouble = new BigDecimal(volumeString).doubleValue(); - if (precision == 0) - return FIAT_VOLUME_FORMAT.format(volAsDouble); - else - return ALTCOIN_VOLUME_FORMAT.format(volAsDouble); + return BSQ_FORMAT.format(new BigDecimal(sats).divide(BSQ_SATOSHI_DIVISOR)); } public static String formatTxFeeRateInfo(TxFeeRateInfo txFeeRateInfo) { @@ -111,7 +102,6 @@ public static String formatInternalFiatPrice(double price) { return US_LOCALE_NUMBER_FORMAT.format(price); } - @Deprecated public static String formatPrice(long price) { US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(4); US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(4); @@ -119,13 +109,6 @@ public static String formatPrice(long price) { return US_LOCALE_NUMBER_FORMAT.format((double) price / 10_000); } - public static String formatCryptoCurrencyPrice(long price) { - US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(8); - US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(8); - US_LOCALE_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); - return US_LOCALE_NUMBER_FORMAT.format((double) price / SATOSHI_DIVISOR.doubleValue()); - } - public static String formatFiatVolume(long volume) { US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(0); US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(0); @@ -133,28 +116,6 @@ public static String formatFiatVolume(long volume) { return US_LOCALE_NUMBER_FORMAT.format((double) volume / 10_000); } - public static String formatCryptoCurrencyVolume(long volume) { - int defaultPrecision = 2; - return formatCryptoCurrencyVolume(volume, defaultPrecision); - } - - public static String formatCryptoCurrencyVolume(long volume, int precision) { - US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(precision); - US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(precision); - US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); - return US_LOCALE_NUMBER_FORMAT.format((double) volume / SATOSHI_DIVISOR.doubleValue()); - } - - @Deprecated - public static long toInternalFiatPrice(BigDecimal fiatPrice) { - return fiatPrice.multiply(new BigDecimal(10_000)).longValue(); - } - - @Deprecated - public static long toInternalCryptoCurrencyPrice(BigDecimal altcoinPrice) { - return altcoinPrice.multiply(new BigDecimal(100_000_000)).longValue(); - } - public static long toSatoshis(String btc) { if (btc.startsWith("-")) throw new IllegalArgumentException(format("'%s' is not a positive number", btc)); diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java index 1b57fa691c8..71a95538ae7 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java @@ -45,8 +45,3 @@ abstract class AbstractTableBuilder { public abstract Table build(); } - -/* - var currencyCode = isFiatOffer.test(o); - - */ diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java index 7c70d1d0653..478210c232d 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java @@ -33,6 +33,7 @@ import javax.annotation.Nullable; +import static bisq.cli.CurrencyFormat.formatSatoshis; import static bisq.cli.table.builder.TableBuilderConstants.COL_HEADER_BUYER_DEPOSIT; import static bisq.cli.table.builder.TableBuilderConstants.COL_HEADER_SELLER_DEPOSIT; import static bisq.cli.table.builder.TableType.TRADE_DETAIL_TBL; @@ -42,7 +43,6 @@ import bisq.cli.table.column.Column; import bisq.cli.table.column.MixedTradeFeeColumn; -import bisq.cli.table.column.MixedVolumeColumn; abstract class AbstractTradeListBuilder extends AbstractTableBuilder { @@ -55,15 +55,15 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder { protected final Column colCreateDate; @Nullable protected final Column colMarket; - protected final Column colPrice; + protected final Column colPrice; @Nullable protected final Column colPriceDeviation; @Nullable protected final Column colCurrency; @Nullable - protected final Column colAmountInBtc; + protected final Column colAmount; @Nullable - protected final MixedVolumeColumn colMixedAmount; + protected final Column colMixedAmount; @Nullable protected final Column colMinerTxFee; @Nullable @@ -94,7 +94,8 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder { @Nullable protected final Column colBisqTradeFee; @Nullable - protected final Column colTradeCost; + protected final Column colTradeCost; + //protected final Column colTradeCost; @Nullable protected final Column colIsPaymentSent; @Nullable @@ -124,7 +125,7 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder { this.colPrice = colSupplier.priceColumn.get(); this.colPriceDeviation = colSupplier.priceDeviationColumn.get(); this.colCurrency = colSupplier.currencyColumn.get(); - this.colAmountInBtc = colSupplier.amountInBtcColumn.get(); + this.colAmount = colSupplier.amountColumn.get(); this.colMixedAmount = colSupplier.mixedAmountColumn.get(); this.colMinerTxFee = colSupplier.minerTxFeeColumn.get(); this.colMixedTradeFee = colSupplier.mixedTradeFeeColumn.get(); @@ -145,6 +146,7 @@ abstract class AbstractTradeListBuilder extends AbstractTableBuilder { this.colTradeCost = colSupplier.tradeCostColumn.get(); this.colIsPaymentSent = colSupplier.paymentSentColumn.get(); this.colIsPaymentReceived = colSupplier.paymentReceivedColumn.get(); + //noinspection ConstantConditions this.colAltcoinReceiveAddressColumn = colSupplier.altcoinReceiveAddressColumn.get(); // BSQ swap trade detail specific columns @@ -167,6 +169,7 @@ protected void validate() { private final Supplier isTradeDetailTblBuilder = () -> tableType.equals(TRADE_DETAIL_TBL); protected final Predicate isFiatTrade = (t) -> isFiatOffer.test(t.getOffer()); + protected final Predicate isBsqTrade = (t) -> !isFiatOffer.test(t.getOffer()) && t.getOffer().getBaseCurrencyCode().equals("BSQ"); protected final Predicate isBsqSwapTrade = (t) -> t.getOffer().getIsBsqSwapOffer(); protected final Predicate isMyOffer = (t) -> t.getOffer().getIsMyOffer(); protected final Predicate isTaker = (t) -> t.getRole().toLowerCase().contains("taker"); @@ -180,15 +183,28 @@ protected void validate() { // Column Value Functions - protected final Function toAmount = (t) -> - isFiatTrade.test(t) - ? t.getTradeAmountAsLong() - : t.getTradeVolume(); + // Altcoin volumes from server are string representations of decimals. + // Converting them to longs ("sats") requires shifting the decimal points + // to left: 2 for BSQ, 8 for other altcoins. + protected final Function toAltcoinTradeVolumeAsLong = (t) -> + isBsqTrade.test(t) + ? new BigDecimal(t.getTradeVolume()).movePointRight(2).longValue() + : new BigDecimal(t.getTradeVolume()).movePointRight(8).longValue(); - protected final Function toTradeVolume = (t) -> + protected final Function toTradeVolumeAsString = (t) -> isFiatTrade.test(t) ? t.getTradeVolume() - : t.getTradeAmountAsLong(); + : formatSatoshis(t.getTradeAmountAsLong()); + + protected final Function toTradeVolumeAsLong = (t) -> + isFiatTrade.test(t) + ? Long.parseLong(t.getTradeVolume()) + : toAltcoinTradeVolumeAsLong.apply(t); + + protected final Function toTradeAmount = (t) -> + isFiatTrade.test(t) + ? t.getTradeAmountAsLong() + : toTradeVolumeAsLong.apply(t); protected final Function toMarket = (t) -> t.getOffer().getBaseCurrencyCode() + "/" @@ -199,16 +215,6 @@ protected void validate() { ? t.getOffer().getCounterCurrencyCode() : t.getOffer().getBaseCurrencyCode(); - - protected final Function toDisplayedVolumePrecision = (t) -> { - if (isFiatTrade.test(t)) { - return 0; - } else { - String currencyCode = toPaymentCurrencyCode.apply(t); - return currencyCode.equalsIgnoreCase("BSQ") ? 2 : 8; - } - }; - protected final Function toPriceDeviation = (t) -> t.getOffer().getUseMarketBasedPrice() ? formatToPercent(t.getOffer().getMarketPriceMargin()) diff --git a/cli/src/main/java/bisq/cli/table/builder/ClosedTradeTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/ClosedTradeTableBuilder.java index 261cddc1117..999b864abc0 100644 --- a/cli/src/main/java/bisq/cli/table/builder/ClosedTradeTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/ClosedTradeTableBuilder.java @@ -24,8 +24,8 @@ import bisq.cli.table.Table; -import bisq.cli.table.column.MixedPriceColumn; +@SuppressWarnings("ConstantConditions") class ClosedTradeTableBuilder extends AbstractTradeListBuilder { ClosedTradeTableBuilder(List protos) { @@ -37,10 +37,10 @@ public Table build() { return new Table(colTradeId, colCreateDate.asStringColumn(), colMarket, - colPrice.asStringColumn(), + colPrice.justify(), colPriceDeviation.justify(), - colAmountInBtc.asStringColumn(), - colMixedAmount.asStringColumn(), + colAmount.asStringColumn(), + colMixedAmount.justify(), colCurrency, colMinerTxFee.asStringColumn(), colMixedTradeFee.asStringColumn(), @@ -51,14 +51,14 @@ public Table build() { } private void populateColumns() { - trades.stream().forEachOrdered(t -> { + trades.forEach(t -> { colTradeId.addRow(t.getTradeId()); colCreateDate.addRow(t.getDate()); colMarket.addRow(toMarket.apply(t)); - ((MixedPriceColumn) colPrice).addRow(t.getTradePrice(), isFiatTrade.test(t)); + colPrice.addRow(t.getTradePrice()); colPriceDeviation.addRow(toPriceDeviation.apply(t)); - colAmountInBtc.addRow(t.getTradeAmountAsLong()); - colMixedAmount.addRow(t.getTradeVolume(), toDisplayedVolumePrecision.apply(t)); + colAmount.addRow(t.getTradeAmountAsLong()); + colMixedAmount.addRow(t.getTradeVolume()); colCurrency.addRow(toPaymentCurrencyCode.apply(t)); colMinerTxFee.addRow(toMyMinerTxFee.apply(t)); diff --git a/cli/src/main/java/bisq/cli/table/builder/FailedTradeTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/FailedTradeTableBuilder.java index 13b4399070a..6a10519154f 100644 --- a/cli/src/main/java/bisq/cli/table/builder/FailedTradeTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/FailedTradeTableBuilder.java @@ -24,11 +24,11 @@ import bisq.cli.table.Table; -import bisq.cli.table.column.MixedPriceColumn; /** * Builds a {@code bisq.cli.table.Table} from a list of {@code bisq.proto.grpc.TradeInfo} objects. */ +@SuppressWarnings("ConstantConditions") class FailedTradeTableBuilder extends AbstractTradeListBuilder { FailedTradeTableBuilder(List protos) { @@ -40,9 +40,9 @@ public Table build() { return new Table(colTradeId, colCreateDate.asStringColumn(), colMarket, - colPrice.asStringColumn(), - colAmountInBtc.asStringColumn(), - colMixedAmount.asStringColumn(), + colPrice.justify(), + colAmount.asStringColumn(), + colMixedAmount.justify(), colCurrency, colOfferType, colRole, @@ -50,13 +50,13 @@ public Table build() { } private void populateColumns() { - trades.stream().forEachOrdered(t -> { + trades.forEach(t -> { colTradeId.addRow(t.getTradeId()); colCreateDate.addRow(t.getDate()); colMarket.addRow(toMarket.apply(t)); - ((MixedPriceColumn) colPrice).addRow(t.getTradePrice(), isFiatTrade.test(t)); - colAmountInBtc.addRow(t.getTradeAmountAsLong()); - colMixedAmount.addRow(t.getTradeVolume(), toDisplayedVolumePrecision.apply(t)); + colPrice.addRow(t.getTradePrice()); + colAmount.addRow(t.getTradeAmountAsLong()); + colMixedAmount.addRow(t.getTradeVolume()); colCurrency.addRow(toPaymentCurrencyCode.apply(t)); colOfferType.addRow(toOfferType.apply(t)); colRole.addRow(t.getRole()); diff --git a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java index 5a86ce92a79..3ec7aa23c86 100644 --- a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java @@ -26,7 +26,6 @@ import javax.annotation.Nullable; -import static bisq.cli.CurrencyFormat.formatVolumeString; import static bisq.cli.table.builder.TableBuilderConstants.*; import static bisq.cli.table.builder.TableType.OFFER_TBL; import static bisq.cli.table.column.Column.JUSTIFICATION.LEFT; @@ -74,17 +73,16 @@ public Table build() { @SuppressWarnings("ConstantConditions") public Table buildFiatOfferTable(List offers) { @Nullable - Column colEnabled = enabledColumn.get(); // Not boolean: YES, NO, or PENDING + Column colEnabled = enabledColumn.get(); // Not boolean: "YES", "NO", or "PENDING" Column colFiatPrice = new StringColumn(format(COL_HEADER_DETAILED_PRICE, fiatTradeCurrency.get()), RIGHT); - Column colFiatVolume = new StringColumn(format("Temp Volume (%s)", fiatTradeCurrency.get()), NONE); - Column colMinFiatVolume = new StringColumn(format("Temp Min Volume (%s)", fiatTradeCurrency.get()), NONE); + Column colVolume = new StringColumn(format("Temp Volume (%s)", fiatTradeCurrency.get()), NONE); + Column colMinVolume = new StringColumn(format("Temp Min Volume (%s)", fiatTradeCurrency.get()), NONE); @Nullable Column colTriggerPrice = fiatTriggerPriceColumn.get(); // Populate columns with offer info. - //noinspection SimplifyStreamApiCallChains - offers.stream().forEachOrdered(o -> { + offers.forEach(o -> { if (colEnabled != null) colEnabled.addRow(toEnabled.apply(o)); @@ -92,10 +90,8 @@ public Table buildFiatOfferTable(List offers) { colFiatPrice.addRow(o.getPrice()); colMinAmount.addRow(o.getMinAmount()); colAmount.addRow(o.getAmount()); - - var volumePrecision = toOfferVolumePrecision.apply(o); - colMinFiatVolume.addRow(formatVolumeString(toBlankOrNonZeroValue.apply(o.getMinVolume()), volumePrecision)); - colFiatVolume.addRow(formatVolumeString(o.getVolume(), volumePrecision)); + colVolume.addRow(o.getVolume()); + colMinVolume.addRow(o.getMinVolume()); if (colTriggerPrice != null) colTriggerPrice.addRow(toBlankOrNonZeroValue.apply(o.getTriggerPrice())); @@ -110,8 +106,8 @@ public Table buildFiatOfferTable(List offers) { new ZippedStringColumns(format(COL_HEADER_VOLUME_RANGE, fiatTradeCurrency.get()), RIGHT, " - ", - colMinFiatVolume.asStringColumn(), - colFiatVolume.asStringColumn()); + colMinVolume.asStringColumn(), + colVolume.asStringColumn()); // Define and return the table instance with populated columns. @@ -141,15 +137,14 @@ public Table buildCryptoCurrencyOfferTable(List offers) { @Nullable Column colEnabled = enabledColumn.get(); // Not boolean: YES, NO, or PENDING Column colBtcPrice = new StringColumn(format(COL_HEADER_DETAILED_PRICE_OF_ALTCOIN, altcoinTradeCurrency.get()), RIGHT); - Column colBtcVolume = new StringColumn(format("Temp Volume (%s)", altcoinTradeCurrency.get()), NONE); - Column colMinBtcVolume = new StringColumn(format("Temp Min Volume (%s)", altcoinTradeCurrency.get()), NONE); + Column colVolume = new StringColumn(format("Temp Volume (%s)", altcoinTradeCurrency.get()), NONE); + Column colMinVolume = new StringColumn(format("Temp Min Volume (%s)", altcoinTradeCurrency.get()), NONE); @Nullable Column colTriggerPrice = altcoinTriggerPriceColumn.get(); // Populate columns with offer info. - //noinspection SimplifyStreamApiCallChains - offers.stream().forEachOrdered(o -> { + offers.forEach(o -> { if (colEnabled != null) colEnabled.addRow(toEnabled.apply(o)); @@ -157,9 +152,8 @@ public Table buildCryptoCurrencyOfferTable(List offers) { colBtcPrice.addRow(o.getPrice()); colAmount.addRow(o.getAmount()); colMinAmount.addRow(o.getMinAmount()); - var volumePrecision = toOfferVolumePrecision.apply(o); - colBtcVolume.addRow(formatVolumeString(o.getVolume(), volumePrecision)); - colMinBtcVolume.addRow(formatVolumeString(toBlankOrNonZeroValue.apply(o.getMinVolume()), volumePrecision)); + colVolume.addRow(o.getVolume()); + colMinVolume.addRow(o.getMinVolume()); if (colTriggerPrice != null) colTriggerPrice.addRow(toBlankOrNonZeroValue.apply(o.getTriggerPrice())); @@ -174,8 +168,8 @@ public Table buildCryptoCurrencyOfferTable(List offers) { new ZippedStringColumns(format(COL_HEADER_VOLUME_RANGE, altcoinTradeCurrency.get()), RIGHT, " - ", - colMinBtcVolume.asStringColumn(), - colBtcVolume.asStringColumn()); + colMinVolume.asStringColumn(), + colVolume.asStringColumn()); // Define and return the table instance with populated columns. @@ -211,18 +205,7 @@ public Table buildCryptoCurrencyOfferTable(List offers) { } } - // TODO Might want to move these three functions into superclass (if TradeTableBuilder needs them). private final Function toBlankOrNonZeroValue = (s) -> s.trim().equals("0") ? "" : s; - private final Function toOfferCurrencyCode = (o) -> isFiatOffer.test(o) - ? o.getCounterCurrencyCode() - : o.getBaseCurrencyCode(); - private final Function toOfferVolumePrecision = (o) -> { - if (isFiatOffer.test(o)) - return 0; - else - return toOfferCurrencyCode.apply(o).equals("BSQ") ? 2 : 8; - }; - private final Supplier firstOfferInList = () -> (OfferInfo) protos.get(0); private final Supplier isShowingMyOffers = () -> firstOfferInList.get().getIsMyOffer(); private final Supplier isShowingFiatOffers = () -> isFiatOffer.test(firstOfferInList.get()); diff --git a/cli/src/main/java/bisq/cli/table/builder/OpenTradeTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/OpenTradeTableBuilder.java index b9c3f7df5da..63a960d9b84 100644 --- a/cli/src/main/java/bisq/cli/table/builder/OpenTradeTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/OpenTradeTableBuilder.java @@ -24,11 +24,11 @@ import bisq.cli.table.Table; -import bisq.cli.table.column.MixedPriceColumn; /** * Builds a {@code bisq.cli.table.Table} from a list of {@code bisq.proto.grpc.TradeInfo} objects. */ +@SuppressWarnings("ConstantConditions") class OpenTradeTableBuilder extends AbstractTradeListBuilder { OpenTradeTableBuilder(List protos) { @@ -40,22 +40,22 @@ public Table build() { return new Table(colTradeId, colCreateDate.asStringColumn(), colMarket, - colPrice.asStringColumn(), - colAmountInBtc.asStringColumn(), - colMixedAmount.asStringColumn(), + colPrice.justify(), + colAmount.asStringColumn(), + colMixedAmount.justify(), colCurrency, colPaymentMethod, colRole); } private void populateColumns() { - trades.stream().forEachOrdered(t -> { + trades.forEach(t -> { colTradeId.addRow(t.getTradeId()); colCreateDate.addRow(t.getDate()); colMarket.addRow(toMarket.apply(t)); - ((MixedPriceColumn) colPrice).addRow(t.getTradePrice(), isFiatTrade.test(t)); - colAmountInBtc.addRow(t.getTradeAmountAsLong()); - colMixedAmount.addRow(t.getTradeVolume(), toDisplayedVolumePrecision.apply(t)); + colPrice.addRow(t.getTradePrice()); + colAmount.addRow(t.getTradeAmountAsLong()); + colMixedAmount.addRow(t.getTradeVolume()); colCurrency.addRow(toPaymentCurrencyCode.apply(t)); colPaymentMethod.addRow(t.getOffer().getPaymentMethodShortName()); colRole.addRow(t.getRole()); diff --git a/cli/src/main/java/bisq/cli/table/builder/TradeDetailTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/TradeDetailTableBuilder.java index 9d577ca1f6d..14dbef9bfb6 100644 --- a/cli/src/main/java/bisq/cli/table/builder/TradeDetailTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/TradeDetailTableBuilder.java @@ -77,12 +77,12 @@ private void populateBisqV1TradeColumns(TradeInfo trade) { colTradeId.addRow(trade.getShortId()); colRole.addRow(trade.getRole()); colPrice.addRow(trade.getTradePrice()); - colAmountInBtc.addRow(toAmount.apply(trade)); + colAmount.addRow(toTradeAmount.apply(trade)); colMinerTxFee.addRow(toMyMinerTxFee.apply(trade)); colBisqTradeFee.addRow(toMyMakerOrTakerFee.apply(trade)); colIsDepositPublished.addRow(trade.getIsDepositPublished()); colIsDepositConfirmed.addRow(trade.getIsDepositConfirmed()); - colTradeCost.addRow(toTradeVolume.apply(trade)); + colTradeCost.addRow(toTradeVolumeAsString.apply(trade)); colIsPaymentSent.addRow(trade.getIsFiatSent()); colIsPaymentReceived.addRow(trade.getIsFiatReceived()); colIsPayoutPublished.addRow(trade.getIsPayoutPublished()); @@ -95,10 +95,11 @@ private void populateBsqSwapTradeColumns(TradeInfo trade) { colTradeId.addRow(trade.getShortId()); colRole.addRow(trade.getRole()); colPrice.addRow(trade.getTradePrice()); - colAmountInBtc.addRow(toAmount.apply(trade)); + colAmount.addRow(toTradeAmount.apply(trade)); colMinerTxFee.addRow(toMyMinerTxFee.apply(trade)); colBisqTradeFee.addRow(toMyMakerOrTakerFee.apply(trade)); - colTradeCost.addRow(toTradeVolume.apply(trade)); + + colTradeCost.addRow(toTradeVolumeAsString.apply(trade)); var isCompleted = isCompletedBsqSwap.test(trade); status.addRow(isCompleted ? "COMPLETED" : "PENDING"); @@ -118,13 +119,13 @@ private List> getBisqV1TradeColumnList() { List> columns = new ArrayList<>() {{ add(colTradeId); add(colRole); - add(colPrice.asStringColumn()); - add(colAmountInBtc.asStringColumn()); + add(colPrice.justify()); + add(colAmount.asStringColumn()); add(colMinerTxFee.asStringColumn()); add(colBisqTradeFee.asStringColumn()); add(colIsDepositPublished.asStringColumn()); add(colIsDepositConfirmed.asStringColumn()); - add(colTradeCost.asStringColumn()); + add(colTradeCost.justify()); add(colIsPaymentSent.asStringColumn()); add(colIsPaymentReceived.asStringColumn()); add(colIsPayoutPublished.asStringColumn()); @@ -141,11 +142,11 @@ private List> getBsqSwapTradeColumnList(boolean isCompleted) { List> columns = new ArrayList<>() {{ add(colTradeId); add(colRole); - add(colPrice.asStringColumn()); - add(colAmountInBtc.asStringColumn()); + add(colPrice.justify()); + add(colAmount.asStringColumn()); add(colMinerTxFee.asStringColumn()); add(colBisqTradeFee.asStringColumn()); - add(colTradeCost.asStringColumn()); + add(colTradeCost.justify()); add(status); }}; diff --git a/cli/src/main/java/bisq/cli/table/builder/TradeTableColumnSupplier.java b/cli/src/main/java/bisq/cli/table/builder/TradeTableColumnSupplier.java index 9f3155fa2c1..ec9c51e2fec 100644 --- a/cli/src/main/java/bisq/cli/table/builder/TradeTableColumnSupplier.java +++ b/cli/src/main/java/bisq/cli/table/builder/TradeTableColumnSupplier.java @@ -36,24 +36,21 @@ import static bisq.cli.table.builder.TableType.FAILED_TRADES_TBL; import static bisq.cli.table.builder.TableType.OPEN_TRADES_TBL; import static bisq.cli.table.builder.TableType.TRADE_DETAIL_TBL; -import static bisq.cli.table.column.AltcoinColumn.DISPLAY_MODE.ALTCOIN_OFFER_VOLUME; +import static bisq.cli.table.column.AltcoinVolumeColumn.DISPLAY_MODE.ALTCOIN_VOLUME; +import static bisq.cli.table.column.AltcoinVolumeColumn.DISPLAY_MODE.BSQ_VOLUME; import static bisq.cli.table.column.Column.JUSTIFICATION.LEFT; import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; -import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.VOLUME; import static java.lang.String.format; -import bisq.cli.table.column.AltcoinColumn; +import bisq.cli.table.column.AltcoinVolumeColumn; import bisq.cli.table.column.BooleanColumn; import bisq.cli.table.column.BtcColumn; import bisq.cli.table.column.Column; -import bisq.cli.table.column.FiatColumn; import bisq.cli.table.column.Iso8601DateTimeColumn; import bisq.cli.table.column.LongColumn; -import bisq.cli.table.column.MixedPriceColumn; import bisq.cli.table.column.MixedTradeFeeColumn; -import bisq.cli.table.column.MixedVolumeColumn; import bisq.cli.table.column.SatoshiColumn; import bisq.cli.table.column.StringColumn; @@ -98,18 +95,16 @@ public TradeTableColumnSupplier(TableType tableType, List trades) { ? null : new StringColumn(COL_HEADER_MARKET); - private final Function> toDetailedPriceColumn = (t) -> { + private final Function> toDetailedPriceColumn = (t) -> { String colHeader = isFiatTrade.test(t) ? format(COL_HEADER_DETAILED_PRICE, t.getOffer().getCounterCurrencyCode()) : format(COL_HEADER_DETAILED_PRICE_OF_ALTCOIN, t.getOffer().getBaseCurrencyCode()); - return isFiatTrade.test(t) - ? new FiatColumn(colHeader) - : new AltcoinColumn(colHeader); + return new StringColumn(colHeader, RIGHT); }; - final Supplier> priceColumn = () -> isTradeDetailTblBuilder.get() + final Supplier> priceColumn = () -> isTradeDetailTblBuilder.get() ? toDetailedPriceColumn.apply(firstRow.get()) - : new MixedPriceColumn(COL_HEADER_PRICE); + : new StringColumn(COL_HEADER_PRICE, RIGHT); final Supplier> priceDeviationColumn = () -> isTradeDetailTblBuilder.get() ? null @@ -122,18 +117,21 @@ public TradeTableColumnSupplier(TableType tableType, List trades) { private final Function> toDetailedAmountColumn = (t) -> { String headerCurrencyCode = t.getOffer().getBaseCurrencyCode(); String colHeader = format(COL_HEADER_DETAILED_AMOUNT, headerCurrencyCode); + AltcoinVolumeColumn.DISPLAY_MODE displayMode = headerCurrencyCode.equals("BSQ") ? BSQ_VOLUME : ALTCOIN_VOLUME; return isFiatTrade.test(t) ? new SatoshiColumn(colHeader) - : new AltcoinColumn(colHeader, ALTCOIN_OFFER_VOLUME); + : new AltcoinVolumeColumn(colHeader, displayMode); }; - final Supplier> amountInBtcColumn = () -> isTradeDetailTblBuilder.get() + // Can be fiat, btc or altcoin amount represented as longs. Placing the decimal + // in the displayed string representation is done in the Column implementation. + final Supplier> amountColumn = () -> isTradeDetailTblBuilder.get() ? toDetailedAmountColumn.apply(firstRow.get()) : new BtcColumn(COL_HEADER_AMOUNT_IN_BTC); - final Supplier mixedAmountColumn = () -> isTradeDetailTblBuilder.get() + final Supplier mixedAmountColumn = () -> isTradeDetailTblBuilder.get() ? null - : new MixedVolumeColumn(COL_HEADER_AMOUNT); + : new StringColumn(COL_HEADER_AMOUNT, RIGHT); final Supplier> minerTxFeeColumn = () -> isTradeDetailTblBuilder.get() || isClosedTradeTblBuilder.get() ? new SatoshiColumn(COL_HEADER_TX_FEE) @@ -248,14 +246,12 @@ public TradeTableColumnSupplier(TableType tableType, List trades) { } }; - final Supplier> tradeCostColumn = () -> { + final Supplier> tradeCostColumn = () -> { if (isTradeDetailTblBuilder.get()) { TradeInfo t = firstRow.get(); String headerCurrencyCode = t.getOffer().getCounterCurrencyCode(); String colHeader = format(COL_HEADER_TRADE_BUYER_COST, headerCurrencyCode); - return isFiatTrade.test(t) - ? new FiatColumn(colHeader, VOLUME) - : new SatoshiColumn(colHeader); + return new StringColumn(colHeader, RIGHT); } else { return null; } diff --git a/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java b/cli/src/main/java/bisq/cli/table/column/AltcoinVolumeColumn.java similarity index 65% rename from cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java rename to cli/src/main/java/bisq/cli/table/column/AltcoinVolumeColumn.java index 79f4976bf5b..0db6c381f4b 100644 --- a/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java +++ b/cli/src/main/java/bisq/cli/table/column/AltcoinVolumeColumn.java @@ -17,43 +17,33 @@ package bisq.cli.table.column; +import java.math.BigDecimal; + import java.util.function.BiFunction; import java.util.stream.IntStream; -import static bisq.cli.CurrencyFormat.formatCryptoCurrencyPrice; -import static bisq.cli.CurrencyFormat.formatCryptoCurrencyVolume; -import static bisq.cli.table.column.AltcoinColumn.DISPLAY_MODE.ALTCOIN_PRICE; import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; /** - * For displaying altcoin values as volume, price, or optional trigger price - * with appropriate precision. + * For displaying altcoin volume with appropriate precision. */ -public class AltcoinColumn extends LongColumn { +public class AltcoinVolumeColumn extends LongColumn { public enum DISPLAY_MODE { - @Deprecated - ALTCOIN_OFFER_VOLUME, - ALTCOIN_PRICE, - @Deprecated - ALTCOIN_TRIGGER_PRICE + ALTCOIN_VOLUME, + BSQ_VOLUME, } private final DISPLAY_MODE displayMode; - // The default AltcoinColumn JUSTIFICATION is RIGHT. - // The default AltcoinColumn DISPLAY_MODE is ALTCOIN_PRICE. - public AltcoinColumn(String name) { - this(name, RIGHT, ALTCOIN_PRICE); - } - - public AltcoinColumn(String name, DISPLAY_MODE displayMode) { + // The default AltcoinVolumeColumn JUSTIFICATION is RIGHT. + public AltcoinVolumeColumn(String name, DISPLAY_MODE displayMode) { this(name, RIGHT, displayMode); } - public AltcoinColumn(String name, - JUSTIFICATION justification, - DISPLAY_MODE displayMode) { + public AltcoinVolumeColumn(String name, + JUSTIFICATION justification, + DISPLAY_MODE displayMode) { super(name, justification); this.displayMode = displayMode; } @@ -88,11 +78,10 @@ public StringColumn asStringColumn() { private final BiFunction toFormattedString = (value, displayMode) -> { switch (displayMode) { - case ALTCOIN_OFFER_VOLUME: - return value > 0 ? formatCryptoCurrencyVolume(value) : ""; - case ALTCOIN_PRICE: - case ALTCOIN_TRIGGER_PRICE: - return value > 0 ? formatCryptoCurrencyPrice(value) : ""; + case ALTCOIN_VOLUME: + return value > 0 ? new BigDecimal(value).movePointLeft(8).toString() : ""; + case BSQ_VOLUME: + return value > 0 ? new BigDecimal(value).movePointLeft(2).toString() : ""; default: throw new IllegalStateException("invalid display mode: " + displayMode); } diff --git a/cli/src/main/java/bisq/cli/table/column/FiatColumn.java b/cli/src/main/java/bisq/cli/table/column/FiatColumn.java index 81ebcb7fe58..d115ab82fe2 100644 --- a/cli/src/main/java/bisq/cli/table/column/FiatColumn.java +++ b/cli/src/main/java/bisq/cli/table/column/FiatColumn.java @@ -22,21 +22,16 @@ import static bisq.cli.CurrencyFormat.formatFiatVolume; import static bisq.cli.CurrencyFormat.formatPrice; import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; -import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.PRICE; -import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.TRIGGER_PRICE; +import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.FIAT_PRICE; /** - * For displaying fiat values as volume, price, or optional trigger price - * with appropriate precision. + * For displaying fiat volume or price with appropriate precision. */ public class FiatColumn extends LongColumn { public enum DISPLAY_MODE { - PRICE, - @Deprecated - TRIGGER_PRICE, - @Deprecated - VOLUME + FIAT_PRICE, + FIAT_VOLUME } private final DISPLAY_MODE displayMode; @@ -44,7 +39,7 @@ public enum DISPLAY_MODE { // The default FiatColumn JUSTIFICATION is RIGHT. // The default FiatColumn DISPLAY_MODE is PRICE. public FiatColumn(String name) { - this(name, RIGHT, PRICE); + this(name, RIGHT, FIAT_PRICE); } public FiatColumn(String name, DISPLAY_MODE displayMode) { @@ -62,11 +57,7 @@ public FiatColumn(String name, public void addRow(Long value) { rows.add(value); - String s; - if (displayMode.equals(TRIGGER_PRICE)) - s = value > 0 ? formatPrice(value) : ""; - else - s = displayMode.equals(PRICE) ? formatPrice(value) : formatFiatVolume(value); + String s = displayMode.equals(FIAT_PRICE) ? formatPrice(value) : formatFiatVolume(value); stringColumn.addRow(s); diff --git a/cli/src/main/java/bisq/cli/table/column/MixedPriceColumn.java b/cli/src/main/java/bisq/cli/table/column/MixedPriceColumn.java deleted file mode 100644 index d8beaf80feb..00000000000 --- a/cli/src/main/java/bisq/cli/table/column/MixedPriceColumn.java +++ /dev/null @@ -1,57 +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.cli.table.column; - -import static bisq.cli.CurrencyFormat.formatPrice; -import static bisq.cli.CurrencyFormat.formatSatoshis; -import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; - -/** - * For displaying a mix of fiat and altcoin prices with appropriate precision. - */ -public class MixedPriceColumn extends LongColumn { - - public MixedPriceColumn(String name) { - super(name, RIGHT); - } - - @Override - public void addRow(Long value) { - throw new UnsupportedOperationException("use public void addRow(Long value, boolean isFiat) instead"); - } - - public void addRow(Long value, boolean isFiat) { - rows.add(value); - - String s = isFiat ? formatPrice(value) : formatSatoshis(value); - stringColumn.addRow(s); - - if (isNewMaxWidth.test(s)) - maxWidth = s.length(); - } - - @Override - public String getRowAsFormattedString(int rowIndex) { - return getRow(rowIndex).toString(); - } - - @Override - public StringColumn asStringColumn() { - return stringColumn.justify(); - } -} diff --git a/cli/src/main/java/bisq/cli/table/column/MixedVolumeColumn.java b/cli/src/main/java/bisq/cli/table/column/MixedVolumeColumn.java deleted file mode 100644 index 1de2a24ecc9..00000000000 --- a/cli/src/main/java/bisq/cli/table/column/MixedVolumeColumn.java +++ /dev/null @@ -1,73 +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.cli.table.column; - -import static bisq.cli.CurrencyFormat.formatCryptoCurrencyVolume; -import static bisq.cli.CurrencyFormat.formatFiatVolume; -import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; - -/** - * For displaying a mix of fiat and altcoin volumes with appropriate precision. - */ -public class MixedVolumeColumn extends LongColumn { - - public MixedVolumeColumn(String name) { - super(name, RIGHT); - } - - @Override - public void addRow(Long value) { - throw new UnsupportedOperationException("use public void addRow(Long value, boolean isAltcoinVolume) instead"); - } - - @Deprecated - public void addRow(Long value, boolean isAltcoinVolume) { - rows.add(value); - - String s = isAltcoinVolume - ? formatCryptoCurrencyVolume(value) - : formatFiatVolume(value); - stringColumn.addRow(s); - - if (isNewMaxWidth.test(s)) - maxWidth = s.length(); - } - - public void addRow(Long value, int displayPrecision) { - rows.add(value); - - boolean isAltcoinVolume = displayPrecision > 0; - String s = isAltcoinVolume - ? formatCryptoCurrencyVolume(value, displayPrecision) - : formatFiatVolume(value); - stringColumn.addRow(s); - - if (isNewMaxWidth.test(s)) - maxWidth = s.length(); - } - - @Override - public String getRowAsFormattedString(int rowIndex) { - return getRow(rowIndex).toString(); - } - - @Override - public StringColumn asStringColumn() { - return stringColumn.justify(); - } -} From 543c573998b9766464aa4400967092b582aab92e Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 19 Feb 2022 15:17:38 -0300 Subject: [PATCH 18/41] Adjust apitest cases to TradeInfo .proto's price & volume type change --- .../java/bisq/apitest/method/offer/AbstractOfferTest.java | 4 ++-- .../java/bisq/apitest/method/offer/BsqSwapOfferTest.java | 8 +++++--- .../offer/CreateOfferUsingMarketPriceMarginTest.java | 2 +- .../java/bisq/apitest/method/offer/EditOfferTest.java | 2 +- .../java/bisq/apitest/method/trade/AbstractTradeTest.java | 2 +- .../bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java | 7 +++---- .../apitest/method/trade/BsqSwapSellBtcTradeTest.java | 2 +- .../bisq/apitest/method/trade/TakeBuyXMROfferTest.java | 2 +- .../bisq/apitest/method/trade/TakeSellXMROfferTest.java | 2 +- 9 files changed, 16 insertions(+), 15 deletions(-) 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 35a33c45c61..627afff6c52 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java @@ -162,12 +162,12 @@ public static void createXmrPaymentAccounts() { XMR, "44G4jWmSvTEfifSUZzTDnJVLPvYATmq9XhhtDqUof1BGCLceG82EQsVYG9Q9GN4bJcjbAJEc1JD1m5G7iK4UPZqACubV4Mq", false); - log.debug("Alices XMR Account: {}", alicesXmrAcct); + log.trace("Alices XMR Account: {}", alicesXmrAcct); bobsXmrAcct = bobClient.createCryptoCurrencyPaymentAccount("Bob's XMR Account", XMR, "4BDRhdSBKZqAXs3PuNTbMtaXBNqFj5idC2yMVnQj8Rm61AyKY8AxLTt9vGRJ8pwcG4EtpyD8YpGqdZWCZ2VZj6yVBN2RVKs", false); - log.debug("Bob's XMR Account: {}", bobsXmrAcct); + log.trace("Bob's XMR Account: {}", bobsXmrAcct); } @AfterAll diff --git a/apitest/src/test/java/bisq/apitest/method/offer/BsqSwapOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/BsqSwapOfferTest.java index 60e96ca3dea..7c2ff5e6f92 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/BsqSwapOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/BsqSwapOfferTest.java @@ -113,13 +113,15 @@ private void createBsqSwapOffer() { 1_000_000L, 1_000_000L, "0.00005"); - log.debug("BsqSwap Sell BSQ (Buy BTC) OFFER:\n{}", bsqSwapOffer); + log.debug("BsqSwap SELL BSQ (BUY BTC) Offer:\n{}", toOfferTable.apply(bsqSwapOffer)); var newOfferId = bsqSwapOffer.getId(); assertNotEquals("", newOfferId); assertEquals(BUY.name(), bsqSwapOffer.getDirection()); assertEquals("0.00005000", bsqSwapOffer.getPrice()); assertEquals(1_000_000L, bsqSwapOffer.getAmount()); assertEquals(1_000_000L, bsqSwapOffer.getMinAmount()); + assertEquals("200.00", bsqSwapOffer.getVolume()); + assertEquals("200.00", bsqSwapOffer.getMinVolume()); assertEquals(BSQ, bsqSwapOffer.getBaseCurrencyCode()); assertEquals(BTC, bsqSwapOffer.getCounterCurrencyCode()); @@ -142,7 +144,7 @@ private void testGetMyBsqSwapOffer(OfferInfo bsqSwapOffer) { if (numFetchAttempts >= 9) fail(format("Alice giving up on fetching her (my) bsq swap offer after %d attempts.", numFetchAttempts), ex); - sleep(1000); + sleep(1500); } } } @@ -162,7 +164,7 @@ private void testGetBsqSwapOffer(OfferInfo bsqSwapOffer) { if (numFetchAttempts > 9) fail(format("Bob gave up on fetching available bsq swap offer after %d attempts.", numFetchAttempts), ex); - sleep(1000); + sleep(1500); } } } 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 7ad241f50c0..64c3cf20cc8 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java @@ -320,7 +320,7 @@ private boolean isCalculatedPriceWithinErrorTolerance(double delta, actualDiffPct, mktPrice, scaledOfferPrice); - log.warn(offer.toString()); + log.trace(offer.toString()); } return true; diff --git a/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java index 55b041ed3c1..cf6fb51acf4 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java @@ -831,7 +831,7 @@ public void testEditBsqSwapOfferShouldThrowException() { 1_250_000L, 750_000L, "0.00005"); - log.debug("BsqSwap Buy BSQ (Buy BTC) offer:\n{}", originalOffer); + log.debug("BsqSwap BUY BSQ (SELL BTC) Offer:\n{}", toOfferTable.apply(originalOffer)); var newOfferId = originalOffer.getId(); assertNotEquals("", newOfferId); assertEquals(SELL.name(), originalOffer.getDirection()); 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 5ea52777c63..b4bc79ab53f 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java @@ -177,7 +177,7 @@ protected final void waitForSellerSeesPaymentInitiatedMessage(Logger log, TradeInfo trade = grpcClient.getTrade(tradeId); if (!isTradeInPaymentReceiptConfirmedStateAndPhase.test(trade)) { - fail(format("INVALID_PHASE for {}'s trade %s in STATE=%s PHASE=%s, cannot confirm payment received.", + fail(format("INVALID_PHASE for %s's trade %s in STATE=%s PHASE=%s, cannot confirm payment received.", userName, trade.getShortId(), trade.getState(), diff --git a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java index 1072b21fc96..9b4a687ea8f 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java @@ -26,7 +26,6 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; @@ -49,7 +48,7 @@ import bisq.apitest.method.offer.AbstractOfferTest; import bisq.cli.GrpcClient; -@Disabled +// @Disabled @Slf4j @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class BsqSwapBuyBtcTradeTest extends AbstractTradeTest { @@ -85,7 +84,7 @@ public void testAliceCreateBsqSwapBuyBtcOffer() { 1_000_000L, // 0.01 BTC 1_000_000L, "0.00005"); - log.debug("Pending BsqSwap Sell BSQ (Buy BTC) OFFER:\n{}", toOfferTable.apply(mySwapOffer)); + log.debug("Pending BsqSwap SELL BSQ (BUY BTC) Offer:\n{}", toOfferTable.apply(mySwapOffer)); var newOfferId = mySwapOffer.getId(); assertNotEquals("", newOfferId); assertEquals(OfferDirection.BUY.name(), mySwapOffer.getDirection()); @@ -98,7 +97,7 @@ public void testAliceCreateBsqSwapBuyBtcOffer() { genBtcBlocksThenWait(1, 2_500); mySwapOffer = aliceClient.getOffer(newOfferId); - log.debug("My fetched BsqSwap Sell BSQ (Buy BTC) OFFER:\n{}", toOfferTable.apply(mySwapOffer)); + log.debug("My fetched BsqSwap SELL BSQ (BUY BTC) Offer:\n{}", toOfferTable.apply(mySwapOffer)); assertNotEquals(0, mySwapOffer.getMakerFee()); runCliGetOffer(newOfferId); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapSellBtcTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapSellBtcTradeTest.java index d699428c844..50f78a4970d 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapSellBtcTradeTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapSellBtcTradeTest.java @@ -83,7 +83,7 @@ public void testAliceCreateBsqSwapSellBtcOffer() { 1_000_000L, // 0.01 BTC 1_000_000L, "0.00005"); - log.debug("Pending BsqSwap Buy BSQ (Sell BTC) OFFER:\n{}", toOfferTable.apply(mySwapOffer)); + log.debug("Pending BsqSwap BUY BSQ (SELL BTC) Offer:\n{}", toOfferTable.apply(mySwapOffer)); var newOfferId = mySwapOffer.getId(); assertNotEquals("", newOfferId); assertEquals(SELL.name(), mySwapOffer.getDirection()); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyXMROfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyXMROfferTest.java index 11f04fd890b..bb572976026 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyXMROfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyXMROfferTest.java @@ -80,7 +80,7 @@ public void testTakeAlicesSellBTCForXMROffer(final TestInfo testInfo) { getDefaultBuyerSecurityDepositAsPercent(), alicesXmrAcct.getId(), TRADE_FEE_CURRENCY_CODE); - log.debug("Alice's Buy XMR (Sell BTC) offer:\n{}", new TableBuilder(OFFER_TBL, alicesOffer).build()); + log.debug("Alice's BUY XMR (SELL BTC) Offer:\n{}", new TableBuilder(OFFER_TBL, alicesOffer).build()); genBtcBlocksThenWait(1, 5000); var offerId = alicesOffer.getId(); assertFalse(alicesOffer.getIsCurrencyForMakerFeeBtc()); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellXMROfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellXMROfferTest.java index ec048da8923..769d6dac8a0 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellXMROfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellXMROfferTest.java @@ -84,7 +84,7 @@ public void testTakeAlicesBuyBTCForXMROffer(final TestInfo testInfo) { alicesXmrAcct.getId(), TRADE_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); - log.debug("Alice's SELL XMR (Buy BTC) offer:\n{}", new TableBuilder(OFFER_TBL, alicesOffer).build()); + log.debug("Alice's SELL XMR (BUY BTC) Offer:\n{}", new TableBuilder(OFFER_TBL, alicesOffer).build()); genBtcBlocksThenWait(1, 4000); var offerId = alicesOffer.getId(); assertTrue(alicesOffer.getIsCurrencyForMakerFeeBtc()); From 5cc928a7e500952e59a54ca09c0defda1e952e4d Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 15:16:02 -0300 Subject: [PATCH 19/41] Disambiguate grpc.proto offer pct literal field names Rename double marketPriceMargin -> marketPriceMarginPct. Rename double buyerSecurityDeposit -> buyerSecurityDepositPct. --- proto/src/main/proto/grpc.proto | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 7d9b588a837..62672019305 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -172,7 +172,6 @@ message GetMyBsqSwapOffersReply { repeated OfferInfo bsqSwapOffers = 1; // The returned list of user's open BSQ swap offers. } -// TODO: Change some numeric fields to string to prevent loss of precision and/or ambiguity. message CreateBsqSwapOfferRequest { // The new BSQ swap offer's BUY (BTC) or SELL (BTC) direction. string direction = 1; @@ -188,7 +187,6 @@ message CreateBsqSwapOfferReply { OfferInfo bsqSwapOffer = 1; // The newly created BSQ swap offer. } -// TODO: Change some numeric fields to string to prevent loss of precision and/or ambiguity. message CreateOfferRequest { // The new offer's fiat or altcoin currency code. string currencyCode = 1; @@ -200,15 +198,13 @@ message CreateOfferRequest { // Whether the offer price is fixed, or market price margin based. bool useMarketBasedPrice = 4; // The offer's market price margin as a percentage above or below the current market BTC price, e.g., 2.50 represents 2.5%. - double marketPriceMargin = 5; + double marketPriceMarginPct = 5; // The amount of BTC to be traded, in satoshis. uint64 amount = 6; // The minimum amount of BTC to be traded, in satoshis. uint64 minAmount = 7; - // For a new BUY BTC offer, the offer maker's security deposit as a percentage of the BTC amount to be traded, e.g., 0.15 represents 15%. - // TODO: This parameter (where 0.## represents ##%) conflicts with marketPriceMargin (where #.## literally represents #.##%). - // Backward compat breaking change to buyerSecurityDeposit is needed to make it consistent with marketPriceMargin (or vice-versa). - double buyerSecurityDeposit = 8; + // A BUY BTC offer maker's security deposit as a percentage of the BTC amount to be traded, e.g., 15.00 represents 15%. + double buyerSecurityDepositPct = 8; // A market price margin based offer's trigger price is the market BTC price at which the offer is automatically disabled. // Disabled offers are never automatically enabled, they must be manually re-enabled. // A zero value indicates trigger price is not set. Trigger price does not apply to fixed price offers. @@ -231,8 +227,8 @@ message EditOfferRequest { string price = 2; // Whether the offer price is fixed, or market price margin based. bool useMarketBasedPrice = 3; - // The offer's new market price margin as a percentage above or below the current market BTC price. - double marketPriceMargin = 4; + // An offer's new market price margin as a percentage above or below the current market BTC price. + double marketPriceMarginPct = 4; // A market price margin based offer's trigger price is the market BTC price at which the offer is automatically disabled. // Disabled offers are never automatically enabled, they must be manually re-enabled. // A zero value indicates trigger price is not set. Trigger price does not apply to fixed price offers. @@ -281,7 +277,6 @@ message CancelOfferReply { // OfferInfo describes an offer to a client. It is derived from the heavier // Offer object in the daemon, which holds too much state to be sent to clients. -// TODO: Change some numeric fields to string to prevent loss of precision and/or ambiguity. message OfferInfo { // The offer's unique identifier. string id = 1; @@ -292,10 +287,8 @@ message OfferInfo { string price = 3; // Whether the offer price is fixed, or market price margin based. bool useMarketBasedPrice = 4; - // The offer's market price margin above or below the current market BTC price, represented as a decimal. - // 5% is represented as 0.05. - // TODO: Change to string type, and make consistent with Create & Edit Offer's marketPriceMargin params. - double marketPriceMargin = 5; + // The offer's market price margin above or below the current market BTC price, e.g., 5.00 represents 5%. + double marketPriceMarginPct = 5; // The offer's BTC amount in satoshis. Ten million satoshis is represented as 10000000. uint64 amount = 6; // The offer's minimum BTC amount in satoshis. One million satoshis is represented as 1000000. From 8408c093e0f4e0b1fef7ba488222d8c7af6accd8 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 15:18:37 -0300 Subject: [PATCH 20/41] Adjust GrpcOffersService to new .proto *Pct field names --- .../main/java/bisq/daemon/grpc/GrpcOffersService.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java index f49881e1713..18bb17bf048 100644 --- a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java +++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java @@ -125,9 +125,8 @@ public void getOffer(GetOfferRequest req, try { String offerId = req.getId(); Optional myOpenOffer = coreApi.findMyOpenOffer(offerId); - OfferInfo offerInfo = myOpenOffer.isPresent() - ? toMyOfferInfo(myOpenOffer.get()) - : toOfferInfo(coreApi.getOffer(offerId)); + OfferInfo offerInfo = myOpenOffer.map(OfferInfo::toMyOfferInfo) + .orElseGet(() -> toOfferInfo(coreApi.getOffer(offerId))); var reply = GetOfferReply.newBuilder() .setOffer(offerInfo.toProtoMessage()) .build(); @@ -278,10 +277,10 @@ public void createOffer(CreateOfferRequest req, req.getDirection(), req.getPrice(), req.getUseMarketBasedPrice(), - req.getMarketPriceMargin(), + req.getMarketPriceMarginPct(), req.getAmount(), req.getMinAmount(), - req.getBuyerSecurityDeposit(), + req.getBuyerSecurityDepositPct(), req.getTriggerPrice(), req.getPaymentAccountId(), req.getMakerFeeCurrencyCode(), @@ -307,7 +306,7 @@ public void editOffer(EditOfferRequest req, coreApi.editOffer(req.getId(), req.getPrice(), req.getUseMarketBasedPrice(), - req.getMarketPriceMargin(), + req.getMarketPriceMarginPct(), req.getTriggerPrice(), req.getEnable(), req.getEditType()); From 66c04bdf3d7def67fc52be0228ec10896bc2cc43 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 15:19:32 -0300 Subject: [PATCH 21/41] Adjust core.api to new .proto *Pct field names --- core/src/main/java/bisq/core/api/CoreApi.java | 4 ++-- .../java/bisq/core/api/CoreOffersService.java | 24 +++++++++++++++---- .../java/bisq/core/api/model/OfferInfo.java | 20 +++++++++------- .../api/model/builder/OfferInfoBuilder.java | 6 ++--- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java index 2587b51d60f..1294d2820e5 100644 --- a/core/src/main/java/bisq/core/api/CoreApi.java +++ b/core/src/main/java/bisq/core/api/CoreApi.java @@ -199,7 +199,7 @@ public void createAndPlaceOffer(String currencyCode, double marketPriceMargin, long amountAsLong, long minAmountAsLong, - double buyerSecurityDeposit, + double buyerSecurityDepositPct, String triggerPrice, String paymentAccountId, String makerFeeCurrencyCode, @@ -211,7 +211,7 @@ public void createAndPlaceOffer(String currencyCode, marketPriceMargin, amountAsLong, minAmountAsLong, - buyerSecurityDeposit, + buyerSecurityDepositPct, triggerPrice, paymentAccountId, makerFeeCurrencyCode, diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java index 03764b7d1e5..aacc59cc2bf 100644 --- a/core/src/main/java/bisq/core/api/CoreOffersService.java +++ b/core/src/main/java/bisq/core/api/CoreOffersService.java @@ -276,7 +276,7 @@ void createAndPlaceOffer(String currencyCode, double marketPriceMargin, long amountAsLong, long minAmountAsLong, - double buyerSecurityDeposit, + double buyerSecurityDepositPct, String triggerPrice, String paymentAccountId, String makerFeeCurrencyCode, @@ -296,6 +296,20 @@ void createAndPlaceOffer(String currencyCode, Coin amount = Coin.valueOf(amountAsLong); Coin minAmount = Coin.valueOf(minAmountAsLong); Coin useDefaultTxFee = Coin.ZERO; + + // Almost ready to call createOfferService.createAndGetOffer(), but first: + // + // For the buyer security deposit parameter, API clients pass a double as a + // percent literal, e.g., #.## (%), where "1.00 means 1% of the trade amount". + // Desktop (UI) clients convert the percent literal string input before passing + // a representation of a pct as a decimal, e.g., 0.##. + // See bisq.desktop.main.offer.bisq_v1.MutableOfferDataModel, where + // "Pct value of buyer security deposit, e.g., 0.01 means 1% of trade amount." + // + // The API client's percent literal is transformed now, to make sure the double + // passed into createOfferService.createAndGetOffer() is correctly scaled. + double scaledBuyerSecurityDepositPct = exactMultiply(buyerSecurityDepositPct, 0.01); + Offer offer = createOfferService.createAndGetOffer(offerId, direction, upperCaseCurrencyCode, @@ -305,7 +319,7 @@ void createAndPlaceOffer(String currencyCode, useDefaultTxFee, useMarketBasedPrice, exactMultiply(marketPriceMargin, 0.01), - buyerSecurityDeposit, + scaledBuyerSecurityDepositPct, paymentAccount); verifyPaymentAccountIsValidForNewOffer(offer, paymentAccount); @@ -314,7 +328,7 @@ void createAndPlaceOffer(String currencyCode, boolean useSavingsWallet = true; //noinspection ConstantConditions placeOffer(offer, - buyerSecurityDeposit, + scaledBuyerSecurityDepositPct, triggerPrice, useSavingsWallet, transaction -> resultHandler.accept(offer)); @@ -383,13 +397,13 @@ private void placeBsqSwapOffer(Offer offer, Runnable resultHandler) { } private void placeOffer(Offer offer, - double buyerSecurityDeposit, + double buyerSecurityDepositPct, String triggerPrice, boolean useSavingsWallet, Consumer resultHandler) { var triggerPriceAsLong = getMarketPriceAsLong(triggerPrice, offer.getCurrencyCode()); openOfferManager.placeOffer(offer, - buyerSecurityDeposit, + buyerSecurityDepositPct, useSavingsWallet, triggerPriceAsLong, resultHandler::accept, 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 48a15be9425..de155b86291 100644 --- a/core/src/main/java/bisq/core/api/model/OfferInfo.java +++ b/core/src/main/java/bisq/core/api/model/OfferInfo.java @@ -31,6 +31,7 @@ import lombok.Getter; import lombok.ToString; +import static bisq.common.util.MathUtils.exactMultiply; import static bisq.core.util.PriceUtil.reformatMarketPrice; import static bisq.core.util.VolumeUtil.formatVolume; import static java.util.Objects.requireNonNull; @@ -48,7 +49,7 @@ public class OfferInfo implements Payload { private final String direction; private final String price; private final boolean useMarketBasedPrice; - private final double marketPriceMargin; + private final double marketPriceMarginPct; private final long amount; private final long minAmount; private final String volume; @@ -83,7 +84,7 @@ public OfferInfo(OfferInfoBuilder builder) { this.direction = builder.getDirection(); this.price = builder.getPrice(); this.useMarketBasedPrice = builder.isUseMarketBasedPrice(); - this.marketPriceMargin = builder.getMarketPriceMargin(); + this.marketPriceMarginPct = builder.getMarketPriceMarginPct(); this.amount = builder.getAmount(); this.minAmount = builder.getMinAmount(); this.volume = builder.getVolume(); @@ -138,9 +139,9 @@ public static OfferInfo toMyOfferInfo(OpenOffer openOffer) { Optional optionalTriggerPrice = openOffer.getTriggerPrice() > 0 ? Optional.of(Price.valueOf(currencyCode, openOffer.getTriggerPrice())) : Optional.empty(); - var preciseTriggerPrice = optionalTriggerPrice.isPresent() - ? reformatMarketPrice(optionalTriggerPrice.get().toPlainString(), currencyCode) - : "0"; + var preciseTriggerPrice = optionalTriggerPrice + .map(value -> reformatMarketPrice(value.toPlainString(), currencyCode)) + .orElse("0"); return getBuilder(openOffer.getOffer(), true) .withTriggerPrice(preciseTriggerPrice) .withIsActivated(!openOffer.isDeactivated()) @@ -148,10 +149,13 @@ public static OfferInfo toMyOfferInfo(OpenOffer openOffer) { } private static OfferInfoBuilder getBuilder(Offer offer, boolean isMyOffer) { + // OfferInfo protos are passed to API client, and some field + // values are converted to displayable, unambiguous form. var currencyCode = offer.getCurrencyCode(); var preciseOfferPrice = reformatMarketPrice( requireNonNull(offer.getPrice()).toPlainString(), currencyCode); + var marketPriceMarginAsPctLiteral = exactMultiply(offer.getMarketPriceMargin(), 100); var roundedVolume = formatVolume(requireNonNull(offer.getVolume())); var roundedMinVolume = formatVolume(requireNonNull(offer.getMinVolume())); return new OfferInfoBuilder() @@ -159,7 +163,7 @@ private static OfferInfoBuilder getBuilder(Offer offer, boolean isMyOffer) { .withDirection(offer.getDirection().name()) .withPrice(preciseOfferPrice) .withUseMarketBasedPrice(offer.isUseMarketBasedPrice()) - .withMarketPriceMargin(offer.getMarketPriceMargin()) + .withMarketPriceMarginPct(marketPriceMarginAsPctLiteral) .withAmount(offer.getAmount().value) .withMinAmount(offer.getMinAmount().value) .withVolume(roundedVolume) @@ -207,7 +211,7 @@ public bisq.proto.grpc.OfferInfo toProtoMessage() { .setDirection(direction) .setPrice(price) .setUseMarketBasedPrice(useMarketBasedPrice) - .setMarketPriceMargin(marketPriceMargin) + .setMarketPriceMarginPct(marketPriceMarginPct) .setAmount(amount) .setMinAmount(minAmount) .setVolume(volume == null ? "0" : volume) @@ -244,7 +248,7 @@ public static OfferInfo fromProto(bisq.proto.grpc.OfferInfo proto) { .withDirection(proto.getDirection()) .withPrice(proto.getPrice()) .withUseMarketBasedPrice(proto.getUseMarketBasedPrice()) - .withMarketPriceMargin(proto.getMarketPriceMargin()) + .withMarketPriceMarginPct(proto.getMarketPriceMarginPct()) .withAmount(proto.getAmount()) .withMinAmount(proto.getMinAmount()) .withVolume(proto.getVolume()) diff --git a/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java b/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java index aadffccb6db..02e41e3fc49 100644 --- a/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java +++ b/core/src/main/java/bisq/core/api/model/builder/OfferInfoBuilder.java @@ -34,7 +34,7 @@ public final class OfferInfoBuilder { private String direction; private String price; private boolean useMarketBasedPrice; - private double marketPriceMargin; + private double marketPriceMarginPct; private long amount; private long minAmount; private String volume; @@ -82,8 +82,8 @@ public OfferInfoBuilder withUseMarketBasedPrice(boolean useMarketBasedPrice) { return this; } - public OfferInfoBuilder withMarketPriceMargin(double useMarketBasedPrice) { - this.marketPriceMargin = useMarketBasedPrice; + public OfferInfoBuilder withMarketPriceMarginPct(double marketPriceMarginPct) { + this.marketPriceMarginPct = marketPriceMarginPct; return this; } From d2ba39b28c1622be5ee7778231871ca33b2f5aa4 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 15:21:13 -0300 Subject: [PATCH 22/41] Adjust cli module to new .proto *Pct field names --- cli/src/main/java/bisq/cli/CliMain.java | 11 ++--- .../main/java/bisq/cli/CurrencyFormat.java | 11 ----- cli/src/main/java/bisq/cli/GrpcClient.java | 24 +++++----- .../cli/opts/AbstractMethodOptionParser.java | 9 ++++ .../cli/opts/CreateOfferOptionParser.java | 12 +++-- .../bisq/cli/opts/EditOfferOptionParser.java | 47 +++++++------------ .../cli/request/OffersServiceRequest.java | 26 +++++----- .../builder/AbstractTradeListBuilder.java | 2 +- .../java/bisq/cli/opts/OptionParsersTest.java | 2 +- 9 files changed, 66 insertions(+), 78 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index b5430e67d5f..cf70886d2da 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -43,7 +43,6 @@ import static bisq.cli.CurrencyFormat.formatInternalFiatPrice; import static bisq.cli.CurrencyFormat.formatTxFeeRateInfo; import static bisq.cli.CurrencyFormat.toSatoshis; -import static bisq.cli.CurrencyFormat.toSecurityDepositAsPct; import static bisq.cli.Method.*; import static bisq.cli.opts.OptLabel.*; import static bisq.cli.table.builder.TableType.*; @@ -346,7 +345,7 @@ public static void run(String[] args) { var useMarketBasedPrice = opts.isUsingMktPriceMargin(); var fixedPrice = opts.getFixedPrice(); var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal(); - var securityDeposit = isSwap ? 0.00 : toSecurityDepositAsPct(opts.getSecurityDeposit()); + var securityDepositPct = isSwap ? 0.00 : opts.getSecurityDepositPct(); var makerFeeCurrencyCode = opts.getMakerFeeCurrencyCode(); var triggerPrice = "0"; // Cannot be defined until the new offer is added to book. OfferInfo offer; @@ -363,7 +362,7 @@ public static void run(String[] args) { useMarketBasedPrice, fixedPrice, marketPriceMargin.doubleValue(), - securityDeposit, + securityDepositPct, paymentAcctId, makerFeeCurrencyCode, triggerPrice); @@ -387,14 +386,14 @@ public static void run(String[] args) { var opts = new EditOfferOptionParser(args).parse(); var fixedPrice = opts.getFixedPrice(); var isUsingMktPriceMargin = opts.isUsingMktPriceMargin(); - var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal(); + var marketPriceMarginPct = opts.getMktPriceMarginPct(); var triggerPrice = opts.getTriggerPrice(); var enable = opts.getEnableAsSignedInt(); var editOfferType = opts.getOfferEditType(); client.editOffer(offerId, fixedPrice, isUsingMktPriceMargin, - marketPriceMargin.doubleValue(), + marketPriceMarginPct, triggerPrice, enable, editOfferType); @@ -517,7 +516,7 @@ public static void run(String[] args) { ? client.getOpenTrades() : client.getTradeHistory(category); if (trades.isEmpty()) { - out.println(format("no %s trades found", category.name().toLowerCase())); + out.printf("no %s trades found%n", category.name().toLowerCase()); } else { var tableType = category.equals(OPEN) ? OPEN_TRADES_TBL diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java index d7cbc0b5e8b..16836d7eee4 100644 --- a/cli/src/main/java/bisq/cli/CurrencyFormat.java +++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java @@ -56,8 +56,6 @@ public class CurrencyFormat { static final BigDecimal BSQ_SATOSHI_DIVISOR = new BigDecimal(100); static final DecimalFormat BSQ_FORMAT = new DecimalFormat("###,###,###,##0.00", DECIMAL_FORMAT_SYMBOLS); - static final BigDecimal SECURITY_DEPOSIT_MULTIPLICAND = new BigDecimal("0.01"); - public static String formatSatoshis(String sats) { //noinspection BigDecimalMethodWithoutRoundingCalled return SATOSHI_FORMAT.format(new BigDecimal(sats).divide(SATOSHI_DIVISOR)); @@ -127,15 +125,6 @@ public static long toSatoshis(String btc) { } } - public static double toSecurityDepositAsPct(String securityDepositInput) { - try { - return new BigDecimal(securityDepositInput) - .multiply(SECURITY_DEPOSIT_MULTIPLICAND).doubleValue(); - } catch (NumberFormatException e) { - throw new IllegalArgumentException(format("'%s' is not a number", securityDepositInput)); - } - } - public static String formatFeeSatoshis(long sats) { return BTC_TX_FEE_FORMAT.format(BigDecimal.valueOf(sats)); } diff --git a/cli/src/main/java/bisq/cli/GrpcClient.java b/cli/src/main/java/bisq/cli/GrpcClient.java index 0b9557c58d7..bf9b20888da 100644 --- a/cli/src/main/java/bisq/cli/GrpcClient.java +++ b/cli/src/main/java/bisq/cli/GrpcClient.java @@ -162,7 +162,7 @@ public OfferInfo createFixedPricedOffer(String direction, long amount, long minAmount, String fixedPrice, - double securityDeposit, + double securityDepositPct, String paymentAcctId, String makerFeeCurrencyCode) { return offersServiceRequest.createOffer(direction, @@ -172,7 +172,7 @@ public OfferInfo createFixedPricedOffer(String direction, false, fixedPrice, 0.00, - securityDeposit, + securityDepositPct, paymentAcctId, makerFeeCurrencyCode, "0" /* no trigger price */); @@ -182,8 +182,8 @@ public OfferInfo createMarketBasedPricedOffer(String direction, String currencyCode, long amount, long minAmount, - double marketPriceMargin, - double securityDeposit, + double marketPriceMarginPct, + double securityDepositPct, String paymentAcctId, String makerFeeCurrencyCode, String triggerPrice) { @@ -193,8 +193,8 @@ public OfferInfo createMarketBasedPricedOffer(String direction, minAmount, true, "0", - marketPriceMargin, - securityDeposit, + marketPriceMarginPct, + securityDepositPct, paymentAcctId, makerFeeCurrencyCode, triggerPrice); @@ -206,8 +206,8 @@ public OfferInfo createOffer(String direction, long minAmount, boolean useMarketBasedPrice, String fixedPrice, - double marketPriceMargin, - double securityDeposit, + double marketPriceMarginPct, + double securityDepositPct, String paymentAcctId, String makerFeeCurrencyCode, String triggerPrice) { @@ -217,8 +217,8 @@ public OfferInfo createOffer(String direction, minAmount, useMarketBasedPrice, fixedPrice, - marketPriceMargin, - securityDeposit, + marketPriceMarginPct, + securityDepositPct, paymentAcctId, makerFeeCurrencyCode, triggerPrice); @@ -243,7 +243,7 @@ public void editOfferTriggerPrice(String offerId, String triggerPrice) { public void editOffer(String offerId, String price, boolean useMarketBasedPrice, - double marketPriceMargin, + double marketPriceMarginPct, String triggerPrice, int enable, EditType editType) { @@ -253,7 +253,7 @@ public void editOffer(String offerId, offersServiceRequest.editOffer(offerId, price, useMarketBasedPrice, - marketPriceMargin, + marketPriceMarginPct, triggerPrice, enable, editType); diff --git a/cli/src/main/java/bisq/cli/opts/AbstractMethodOptionParser.java b/cli/src/main/java/bisq/cli/opts/AbstractMethodOptionParser.java index 2bccab1d098..025a208a8e3 100644 --- a/cli/src/main/java/bisq/cli/opts/AbstractMethodOptionParser.java +++ b/cli/src/main/java/bisq/cli/opts/AbstractMethodOptionParser.java @@ -29,6 +29,7 @@ import lombok.Getter; import static bisq.cli.opts.OptLabel.OPT_HELP; +import static java.lang.String.format; @SuppressWarnings("unchecked") abstract class AbstractMethodOptionParser implements MethodOpts { @@ -65,6 +66,14 @@ public boolean isForHelp() { return options.has(helpOpt); } + protected void verifyStringIsValidDouble(String string) { + try { + Double.valueOf(string); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException(format("%s is not a number", string)); + } + } + protected final Predicate> valueNotSpecified = (opt) -> !options.hasArgument(opt) || options.valueOf(opt).isEmpty(); diff --git a/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java index 5c338434815..fab316f63d7 100644 --- a/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java +++ b/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java @@ -53,7 +53,7 @@ public class CreateOfferOptionParser extends AbstractMethodOptionParser implemen .withOptionalArg() .defaultsTo("0"); - final OptionSpec securityDepositOpt = parser.accepts(OPT_SECURITY_DEPOSIT, "maker security deposit (%)") + final OptionSpec securityDepositPctOpt = parser.accepts(OPT_SECURITY_DEPOSIT, "maker security deposit (%)") .withRequiredArg(); final OptionSpec makerFeeCurrencyCodeOpt = parser.accepts(OPT_FEE_CURRENCY, "maker fee currency code (bsq|btc)") @@ -95,7 +95,7 @@ public CreateOfferOptionParser parse() { if (options.has(mktPriceMarginOpt)) throw new IllegalArgumentException("cannot use a market price margin in bsq swap offer"); - if (options.has(securityDepositOpt)) + if (options.has(securityDepositPctOpt)) throw new IllegalArgumentException("cannot use a security deposit in bsq swap offer"); if (!options.has(fixedPriceOpt) || options.valueOf(fixedPriceOpt).isEmpty()) @@ -114,8 +114,10 @@ public CreateOfferOptionParser parse() { if (options.has(fixedPriceOpt) && options.valueOf(fixedPriceOpt).isEmpty()) throw new IllegalArgumentException("no fixed price specified"); - if (!options.has(securityDepositOpt) || options.valueOf(securityDepositOpt).isEmpty()) + if (!options.has(securityDepositPctOpt) || options.valueOf(securityDepositPctOpt).isEmpty()) throw new IllegalArgumentException("no security deposit specified"); + else + verifyStringIsValidDouble(options.valueOf(securityDepositPctOpt)); } return this; @@ -158,8 +160,8 @@ public String getFixedPrice() { return options.has(fixedPriceOpt) ? options.valueOf(fixedPriceOpt) : "0.00"; } - public String getSecurityDeposit() { - return options.valueOf(securityDepositOpt); + public double getSecurityDepositPct() { + return Double.valueOf(options.valueOf(securityDepositPctOpt)); } public String getMakerFeeCurrencyCode() { diff --git a/cli/src/main/java/bisq/cli/opts/EditOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/EditOfferOptionParser.java index 17afa982f76..0e0b2d61c5a 100644 --- a/cli/src/main/java/bisq/cli/opts/EditOfferOptionParser.java +++ b/cli/src/main/java/bisq/cli/opts/EditOfferOptionParser.java @@ -22,14 +22,11 @@ import joptsimple.OptionSpec; -import java.math.BigDecimal; - import static bisq.cli.opts.OptLabel.OPT_ENABLE; import static bisq.cli.opts.OptLabel.OPT_FIXED_PRICE; import static bisq.cli.opts.OptLabel.OPT_MKT_PRICE_MARGIN; import static bisq.cli.opts.OptLabel.OPT_TRIGGER_PRICE; import static bisq.proto.grpc.EditOfferRequest.EditType.*; -import static java.lang.String.format; @@ -45,7 +42,7 @@ public class EditOfferOptionParser extends OfferIdOptionParser implements Method .withOptionalArg() .defaultsTo("0"); - final OptionSpec mktPriceMarginOpt = parser.accepts(OPT_MKT_PRICE_MARGIN, + final OptionSpec mktPriceMarginPctOpt = parser.accepts(OPT_MKT_PRICE_MARGIN, "market btc price margin (%)") .withOptionalArg() .defaultsTo("0.00"); @@ -75,7 +72,7 @@ public EditOfferOptionParser parse() { // Super class will short-circuit parsing if help option is present. boolean hasNoEditDetails = !options.has(fixedPriceOpt) - && !options.has(mktPriceMarginOpt) + && !options.has(mktPriceMarginPctOpt) && !options.has(triggerPriceOpt) && !options.has(enableOpt); if (hasNoEditDetails) @@ -92,7 +89,7 @@ public EditOfferOptionParser parse() { // A single enable opt is a valid opt combo. boolean enableOptIsOnlyOpt = !options.has(fixedPriceOpt) - && !options.has(mktPriceMarginOpt) + && !options.has(mktPriceMarginPctOpt) && !options.has(triggerPriceOpt); if (enableOptIsOnlyOpt) { offerEditType = ACTIVATION_STATE_ONLY; @@ -107,7 +104,7 @@ public EditOfferOptionParser parse() { String fixedPriceAsString = options.valueOf(fixedPriceOpt); verifyStringIsValidDouble(fixedPriceAsString); - boolean fixedPriceOptIsOnlyOpt = !options.has(mktPriceMarginOpt) + boolean fixedPriceOptIsOnlyOpt = !options.has(mktPriceMarginPctOpt) && !options.has(triggerPriceOpt) && !options.has(enableOpt); if (fixedPriceOptIsOnlyOpt) { @@ -116,7 +113,7 @@ public EditOfferOptionParser parse() { } boolean fixedPriceOptAndEnableOptAreOnlyOpts = options.has(enableOpt) - && !options.has(mktPriceMarginOpt) + && !options.has(mktPriceMarginPctOpt) && !options.has(triggerPriceOpt); if (fixedPriceOptAndEnableOptAreOnlyOpts) { offerEditType = FIXED_PRICE_AND_ACTIVATION_STATE; @@ -124,15 +121,15 @@ public EditOfferOptionParser parse() { } } - if (options.has(mktPriceMarginOpt)) { - if (valueNotSpecified.test(mktPriceMarginOpt)) + if (options.has(mktPriceMarginPctOpt)) { + if (valueNotSpecified.test(mktPriceMarginPctOpt)) throw new IllegalArgumentException("no mkt price margin specified"); - String priceMarginAsString = options.valueOf(mktPriceMarginOpt); - if (priceMarginAsString.isEmpty()) + String priceMarginPctAsString = options.valueOf(mktPriceMarginPctOpt); + if (priceMarginPctAsString.isEmpty()) throw new IllegalArgumentException("no market price margin specified"); - verifyStringIsValidDouble(priceMarginAsString); + verifyStringIsValidDouble(priceMarginPctAsString); boolean mktPriceMarginOptIsOnlyOpt = !options.has(triggerPriceOpt) && !options.has(fixedPriceOpt) @@ -160,7 +157,7 @@ public EditOfferOptionParser parse() { verifyStringIsValidDouble(triggerPriceAsString); - boolean triggerPriceOptIsOnlyOpt = !options.has(mktPriceMarginOpt) + boolean triggerPriceOptIsOnlyOpt = !options.has(mktPriceMarginPctOpt) && !options.has(fixedPriceOpt) && !options.has(enableOpt); if (triggerPriceOptIsOnlyOpt) { @@ -168,7 +165,7 @@ public EditOfferOptionParser parse() { return this; } - boolean triggerPriceOptAndEnableOptAreOnlyOpts = !options.has(mktPriceMarginOpt) + boolean triggerPriceOptAndEnableOptAreOnlyOpts = !options.has(mktPriceMarginPctOpt) && !options.has(fixedPriceOpt) && options.has(enableOpt); if (triggerPriceOptAndEnableOptAreOnlyOpts) { @@ -177,18 +174,18 @@ public EditOfferOptionParser parse() { } } - if (options.has(mktPriceMarginOpt) && options.has(fixedPriceOpt)) + if (options.has(mktPriceMarginPctOpt) && options.has(fixedPriceOpt)) throw new IllegalArgumentException("cannot specify market price margin and fixed price"); if (options.has(fixedPriceOpt) && options.has(triggerPriceOpt)) throw new IllegalArgumentException("trigger price cannot be set on fixed price offers"); - if (options.has(mktPriceMarginOpt) && options.has(triggerPriceOpt) && !options.has(enableOpt)) { + if (options.has(mktPriceMarginPctOpt) && options.has(triggerPriceOpt) && !options.has(enableOpt)) { offerEditType = MKT_PRICE_MARGIN_AND_TRIGGER_PRICE; return this; } - if (options.has(mktPriceMarginOpt) && options.has(triggerPriceOpt) && options.has(enableOpt)) { + if (options.has(mktPriceMarginPctOpt) && options.has(triggerPriceOpt) && options.has(enableOpt)) { offerEditType = MKT_PRICE_MARGIN_AND_TRIGGER_PRICE_AND_ACTIVATION_STATE; return this; } @@ -220,14 +217,14 @@ public String getMktPriceMargin() { || offerEditType.equals(MKT_PRICE_MARGIN_AND_ACTIVATION_STATE) || offerEditType.equals(MKT_PRICE_MARGIN_AND_TRIGGER_PRICE) || offerEditType.equals(MKT_PRICE_MARGIN_AND_TRIGGER_PRICE_AND_ACTIVATION_STATE)) { - return isUsingMktPriceMargin() ? options.valueOf(mktPriceMarginOpt) : "0.00"; + return isUsingMktPriceMargin() ? options.valueOf(mktPriceMarginPctOpt) : "0.00"; } else { return "0.00"; } } - public BigDecimal getMktPriceMarginAsBigDecimal() { - return new BigDecimal(options.valueOf(mktPriceMarginOpt)); + public double getMktPriceMarginPct() { + return Double.parseDouble(options.valueOf(mktPriceMarginPctOpt)); } public boolean isUsingMktPriceMargin() { @@ -260,12 +257,4 @@ public Boolean isEnable() { public EditOfferRequest.EditType getOfferEditType() { return offerEditType; } - - private void verifyStringIsValidDouble(String string) { - try { - Double.valueOf(string); - } catch (NumberFormatException ex) { - throw new IllegalArgumentException(format("%s is not a number", string)); - } - } } diff --git a/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java b/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java index 5f900d770ca..65b62f05838 100644 --- a/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java +++ b/cli/src/main/java/bisq/cli/request/OffersServiceRequest.java @@ -82,7 +82,7 @@ public OfferInfo createFixedPricedOffer(String direction, long amount, long minAmount, String fixedPrice, - double securityDeposit, + double securityDepositPct, String paymentAcctId, String makerFeeCurrencyCode) { return createOffer(direction, @@ -92,7 +92,7 @@ public OfferInfo createFixedPricedOffer(String direction, false, fixedPrice, 0.00, - securityDeposit, + securityDepositPct, paymentAcctId, makerFeeCurrencyCode, "0" /* no trigger price */); @@ -104,8 +104,8 @@ public OfferInfo createOffer(String direction, long minAmount, boolean useMarketBasedPrice, String fixedPrice, - double marketPriceMargin, - double securityDeposit, + double marketPriceMarginPct, + double securityDepositPct, String paymentAcctId, String makerFeeCurrencyCode, String triggerPrice) { @@ -116,8 +116,8 @@ public OfferInfo createOffer(String direction, .setMinAmount(minAmount) .setUseMarketBasedPrice(useMarketBasedPrice) .setPrice(fixedPrice) - .setMarketPriceMargin(marketPriceMargin) - .setBuyerSecurityDeposit(securityDeposit) + .setMarketPriceMarginPct(marketPriceMarginPct) + .setBuyerSecurityDepositPct(securityDepositPct) .setPaymentAccountId(paymentAcctId) .setMakerFeeCurrencyCode(makerFeeCurrencyCode) .setTriggerPrice(triggerPrice) @@ -133,7 +133,7 @@ public void editOfferActivationState(String offerId, int enable) { editOffer(offerId, offerPrice, offer.getUseMarketBasedPrice(), - offer.getMarketPriceMargin(), + offer.getMarketPriceMarginPct(), offer.getTriggerPrice(), enable, ACTIVATION_STATE_ONLY); @@ -144,18 +144,18 @@ public void editOfferFixedPrice(String offerId, String rawPriceString) { editOffer(offerId, rawPriceString, false, - offer.getMarketPriceMargin(), + offer.getMarketPriceMarginPct(), offer.getTriggerPrice(), offer.getIsActivated() ? 1 : 0, FIXED_PRICE_ONLY); } - public void editOfferPriceMargin(String offerId, double marketPriceMargin) { + public void editOfferPriceMargin(String offerId, double marketPriceMarginPct) { var offer = getMyOffer(offerId); editOffer(offerId, "0.00", true, - marketPriceMargin, + marketPriceMarginPct, offer.getTriggerPrice(), offer.getIsActivated() ? 1 : 0, MKT_PRICE_MARGIN_ONLY); @@ -166,7 +166,7 @@ public void editOfferTriggerPrice(String offerId, String triggerPrice) { editOffer(offerId, "0.00", offer.getUseMarketBasedPrice(), - offer.getMarketPriceMargin(), + offer.getMarketPriceMarginPct(), triggerPrice, offer.getIsActivated() ? 1 : 0, TRIGGER_PRICE_ONLY); @@ -175,7 +175,7 @@ public void editOfferTriggerPrice(String offerId, String triggerPrice) { public void editOffer(String offerId, String scaledPriceString, boolean useMarketBasedPrice, - double marketPriceMargin, + double marketPriceMarginPct, String triggerPrice, int enable, EditOfferRequest.EditType editType) { @@ -186,7 +186,7 @@ public void editOffer(String offerId, .setId(offerId) .setPrice(scaledPriceString) .setUseMarketBasedPrice(useMarketBasedPrice) - .setMarketPriceMargin(marketPriceMargin) + .setMarketPriceMarginPct(marketPriceMarginPct) .setTriggerPrice(triggerPrice) .setEnable(enable) .setEditType(editType) diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java index 478210c232d..0195f9a47cb 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java @@ -217,7 +217,7 @@ protected void validate() { protected final Function toPriceDeviation = (t) -> t.getOffer().getUseMarketBasedPrice() - ? formatToPercent(t.getOffer().getMarketPriceMargin()) + ? formatToPercent(t.getOffer().getMarketPriceMarginPct()) : "N/A"; protected final Function toMyMinerTxFee = (t) -> { diff --git a/cli/src/test/java/bisq/cli/opts/OptionParsersTest.java b/cli/src/test/java/bisq/cli/opts/OptionParsersTest.java index 818b4c9d26e..70b004eb037 100644 --- a/cli/src/test/java/bisq/cli/opts/OptionParsersTest.java +++ b/cli/src/test/java/bisq/cli/opts/OptionParsersTest.java @@ -135,7 +135,7 @@ public void testValidCreateOfferOpts() { assertEquals("EUR", parser.getCurrencyCode()); assertEquals("0.125", parser.getAmount()); assertEquals("0.0", parser.getMktPriceMargin()); - assertEquals("25.0", parser.getSecurityDeposit()); + assertEquals(25.0, parser.getSecurityDepositPct()); } // createoffer (bsq swap) opt parser tests From 2febe6b3270e1141a2535150c827fded93c6fd70 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 15:22:40 -0300 Subject: [PATCH 23/41] Adjust apitest cases to new .proto *Pct field names --- .../java/bisq/apitest/method/MethodTest.java | 15 +++ .../method/offer/AbstractOfferTest.java | 18 ++- .../apitest/method/offer/CancelOfferTest.java | 3 +- .../method/offer/CreateBSQOffersTest.java | 11 +- .../offer/CreateOfferUsingFixedPriceTest.java | 7 +- ...CreateOfferUsingMarketPriceMarginTest.java | 23 ++-- .../method/offer/CreateXMROffersTest.java | 9 +- .../apitest/method/offer/EditOfferTest.java | 108 +++++++++--------- .../method/offer/ValidateCreateOfferTest.java | 7 +- .../method/trade/BsqSwapBuyBtcTradeTest.java | 3 +- .../method/trade/TakeBuyBSQOfferTest.java | 3 +- .../method/trade/TakeBuyBTCOfferTest.java | 3 +- ...keBuyBTCOfferWithNationalBankAcctTest.java | 3 +- .../method/trade/TakeBuyXMROfferTest.java | 3 +- .../method/trade/TakeSellBSQOfferTest.java | 3 +- .../method/trade/TakeSellBTCOfferTest.java | 3 +- .../method/trade/TakeSellXMROfferTest.java | 3 +- .../LongRunningOfferDeactivationTest.java | 5 +- .../java/bisq/apitest/scenario/OfferTest.java | 8 +- .../apitest/scenario/bot/RandomOffer.java | 6 +- 20 files changed, 128 insertions(+), 116 deletions(-) diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java index f01c4ecbf53..5ca04409449 100644 --- a/apitest/src/test/java/bisq/apitest/method/MethodTest.java +++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java @@ -30,7 +30,10 @@ import java.io.IOException; import java.io.PrintWriter; +import java.math.BigDecimal; + import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.slf4j.Logger; @@ -42,6 +45,7 @@ import static bisq.apitest.config.ApiTestRateMeterInterceptorConfig.getTestRateMeterInterceptorConfig; import static bisq.cli.table.builder.TableType.BSQ_BALANCE_TBL; import static bisq.cli.table.builder.TableType.BTC_BALANCE_TBL; +import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.stream; @@ -162,6 +166,17 @@ protected final bisq.core.payment.PaymentAccount createPaymentAccount(GrpcClient return bisq.core.payment.PaymentAccount.fromProto(paymentAccount, CORE_PROTO_RESOLVER); } + public static final Supplier defaultBuyerSecurityDepositPct = () -> { + var defaultPct = BigDecimal.valueOf(getDefaultBuyerSecurityDepositAsPercent()); + if (defaultPct.precision() != 2) + throw new IllegalStateException(format( + "Unexpected decimal precision, expected 2 but actual is %d%n." + + "Check for changes to Restrictions.getDefaultBuyerSecurityDepositAsPercent()", + defaultPct.precision())); + + return defaultPct.movePointRight(2).doubleValue(); + }; + public static String formatBalancesTbls(BalancesInfo allBalances) { StringBuilder balances = new StringBuilder(BTC).append("\n"); balances.append(new TableBuilder(BTC_BALANCE_TBL, allBalances.getBtc()).build()); 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 627afff6c52..627c1befe3b 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/AbstractOfferTest.java @@ -44,7 +44,6 @@ import static bisq.apitest.config.BisqAppConfig.bobdaemon; import static bisq.apitest.config.BisqAppConfig.seednode; import static bisq.cli.table.builder.TableType.OFFER_TBL; -import static bisq.common.util.MathUtils.exactMultiply; import static java.lang.String.format; import static java.lang.System.out; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -78,29 +77,28 @@ public abstract class AbstractOfferTest extends MethodTest { @BeforeAll public static void setUp() { + setUp(false); + } + + public static void setUp(boolean startSupportingAppsInDebugMode) { startSupportingApps(true, - false, + startSupportingAppsInDebugMode, bitcoind, seednode, arbdaemon, alicedaemon, bobdaemon); - initSwapPaymentAccounts(); createLegacyBsqPaymentAccounts(); } - // Mkt Price Margin value of offer returned from server is scaled down by 10^-2. - protected final Function scaledDownMktPriceMargin = (mktPriceMargin) -> - exactMultiply(mktPriceMargin, 0.01); - - protected final Function toOfferTable = (offer) -> + protected static final Function toOfferTable = (offer) -> new TableBuilder(OFFER_TBL, offer).build().toString(); - protected final Function, String> toOffersTable = (offers) -> + protected static final Function, String> toOffersTable = (offers) -> new TableBuilder(OFFER_TBL, offers).build().toString(); - protected String calcPriceAsString(double base, double delta, int precision) { + protected static String calcPriceAsString(double base, double delta, int precision) { var mathContext = new MathContext(precision); var priceAsBigDecimal = new BigDecimal(Double.toString(base), mathContext) .add(new BigDecimal(Double.toString(delta), mathContext)) diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java index d0ec6d86f1b..119427c0cf1 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CancelOfferTest.java @@ -33,7 +33,6 @@ import org.junit.jupiter.api.TestMethodOrder; import static bisq.apitest.config.ApiTestConfig.BSQ; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static org.junit.jupiter.api.Assertions.assertEquals; import static protobuf.OfferDirection.BUY; @@ -52,7 +51,7 @@ public class CancelOfferTest extends AbstractOfferTest { 10000000L, 10000000L, 0.00, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), paymentAccountId, BSQ, NO_TRIGGER_PRICE); diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java index 2b878c1803d..1807d1000b5 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateBSQOffersTest.java @@ -32,7 +32,6 @@ import static bisq.apitest.config.ApiTestConfig.BSQ; import static bisq.apitest.config.ApiTestConfig.BTC; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -63,7 +62,7 @@ public void testCreateBuy1BTCFor20KBSQOffer() { 100_000_000L, 100_000_000L, "0.00005", // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("Sell BSQ (Buy BTC) Offer:\n{}", toOfferTable.apply(newOffer)); @@ -114,7 +113,7 @@ public void testCreateSell1BTCFor20KBSQOffer() { 100_000_000L, 100_000_000L, "0.00005", // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("SELL 20K BSQ Offer:\n{}", toOfferTable.apply(newOffer)); @@ -165,7 +164,7 @@ public void testCreateBuyBTCWith1To2KBSQOffer() { 10_000_000L, 5_000_000L, "0.00005", // FIXED PRICE IN BTC sats FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("BUY 1-2K BSQ Offer:\n{}", toOfferTable.apply(newOffer)); @@ -216,7 +215,7 @@ public void testCreateSellBTCFor5To10KBSQOffer() { 50_000_000L, 25_000_000L, "0.00005", // FIXED PRICE IN BTC sats FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("SELL 5-10K BSQ Offer:\n{}", toOfferTable.apply(newOffer)); @@ -280,6 +279,6 @@ private void genBtcBlockAndWaitForOfferPreparation() { // Extra time is needed for the OfferUtils#isBsqForMakerFeeAvailable, which // can sometimes return an incorrect false value if the BsqWallet's // available confirmed balance is temporarily = zero during BSQ offer prep. - genBtcBlocksThenWait(1, 5000); + genBtcBlocksThenWait(1, 5_000); } } 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 794fb1310a8..7691a5e26d4 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingFixedPriceTest.java @@ -31,7 +31,6 @@ import static bisq.apitest.config.ApiTestConfig.BTC; import static bisq.apitest.config.ApiTestConfig.EUR; import static bisq.apitest.config.ApiTestConfig.USD; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -55,7 +54,7 @@ public void testCreateAUDBTCBuyOfferUsingFixedPrice16000() { 10_000_000L, 10_000_000L, "36000", - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), audAccount.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("Offer #1:\n{}", toOfferTable.apply(newOffer)); @@ -104,7 +103,7 @@ public void testCreateUSDBTCBuyOfferUsingFixedPrice100001234() { 10_000_000L, 10_000_000L, "30000.1234", - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), usdAccount.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("Offer #2:\n{}", toOfferTable.apply(newOffer)); @@ -153,7 +152,7 @@ public void testCreateEURBTCSellOfferUsingFixedPrice95001234() { 10_000_000L, 5_000_000L, "29500.1234", - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), eurAccount.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("Offer #3:\n{}", toOfferTable.apply(newOffer)); 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 64c3cf20cc8..fc61b5699dc 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateOfferUsingMarketPriceMarginTest.java @@ -38,7 +38,6 @@ import static bisq.common.util.MathUtils.roundDouble; import static bisq.common.util.MathUtils.scaleDownByPowerOf10; import static bisq.common.util.MathUtils.scaleUpByPowerOf10; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static java.lang.Math.abs; import static java.lang.String.format; import static java.math.RoundingMode.HALF_UP; @@ -65,13 +64,13 @@ public class CreateOfferUsingMarketPriceMarginTest extends AbstractOfferTest { @Order(1) public void testCreateUSDBTCBuyOffer5PctPriceMargin() { PaymentAccount usdAccount = createDummyF2FAccount(aliceClient, "US"); - double priceMarginPctInput = 5.00; + double priceMarginPctInput = 5.00d; var newOffer = aliceClient.createMarketBasedPricedOffer(BUY.name(), "usd", 10_000_000L, 10_000_000L, priceMarginPctInput, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), usdAccount.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); @@ -83,6 +82,7 @@ public void testCreateUSDBTCBuyOffer5PctPriceMargin() { assertNotEquals("", newOfferId); assertEquals(BUY.name(), newOffer.getDirection()); assertTrue(newOffer.getUseMarketBasedPrice()); + assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -97,6 +97,7 @@ public void testCreateUSDBTCBuyOffer5PctPriceMargin() { assertEquals(newOfferId, newOffer.getId()); assertEquals(BUY.name(), newOffer.getDirection()); assertTrue(newOffer.getUseMarketBasedPrice()); + assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -112,13 +113,13 @@ public void testCreateUSDBTCBuyOffer5PctPriceMargin() { @Order(2) public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() { PaymentAccount nzdAccount = createDummyF2FAccount(aliceClient, "NZ"); - double priceMarginPctInput = -2.00; + double priceMarginPctInput = -2.00d; // -2% var newOffer = aliceClient.createMarketBasedPricedOffer(BUY.name(), "nzd", 10_000_000L, 10_000_000L, priceMarginPctInput, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), nzdAccount.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); @@ -130,6 +131,7 @@ public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() { assertNotEquals("", newOfferId); assertEquals(BUY.name(), newOffer.getDirection()); assertTrue(newOffer.getUseMarketBasedPrice()); + assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -144,6 +146,7 @@ public void testCreateNZDBTCBuyOfferMinus2PctPriceMargin() { assertEquals(newOfferId, newOffer.getId()); assertEquals(BUY.name(), newOffer.getDirection()); assertTrue(newOffer.getUseMarketBasedPrice()); + assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(10_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -165,7 +168,7 @@ public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() { 10_000_000L, 5_000_000L, priceMarginPctInput, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), gbpAccount.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); @@ -177,6 +180,7 @@ public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() { assertNotEquals("", newOfferId); assertEquals(SELL.name(), newOffer.getDirection()); assertTrue(newOffer.getUseMarketBasedPrice()); + assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -191,6 +195,7 @@ public void testCreateGBPBTCSellOfferMinus1Point5PctPriceMargin() { assertEquals(newOfferId, newOffer.getId()); assertEquals(SELL.name(), newOffer.getDirection()); assertTrue(newOffer.getUseMarketBasedPrice()); + assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -212,7 +217,7 @@ public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() { 10_000_000L, 5_000_000L, priceMarginPctInput, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), brlAccount.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); @@ -224,6 +229,7 @@ public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() { assertNotEquals("", newOfferId); assertEquals(SELL.name(), newOffer.getDirection()); assertTrue(newOffer.getUseMarketBasedPrice()); + assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -238,6 +244,7 @@ public void testCreateBRLBTCSellOffer6Point55PctPriceMargin() { assertEquals(newOfferId, newOffer.getId()); assertEquals(SELL.name(), newOffer.getDirection()); assertTrue(newOffer.getUseMarketBasedPrice()); + assertEquals(priceMarginPctInput, newOffer.getMarketPriceMarginPct()); assertEquals(10_000_000, newOffer.getAmount()); assertEquals(5_000_000, newOffer.getMinAmount()); assertEquals(1_500_000, newOffer.getBuyerSecurityDeposit()); @@ -260,7 +267,7 @@ public void testCreateUSDBTCBuyOfferWithTriggerPrice() { 10_000_000L, 5_000_000L, 0.0, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), usdAccount.getId(), MAKER_FEE_CURRENCY_CODE, triggerPrice); diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java index 33fad708d85..64d46e279f9 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java @@ -33,7 +33,6 @@ import static bisq.apitest.config.ApiTestConfig.BSQ; import static bisq.apitest.config.ApiTestConfig.BTC; import static bisq.apitest.config.ApiTestConfig.XMR; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -66,7 +65,7 @@ public void testCreateFixedPriceBuy1BTCFor200KXMROffer() { 100_000_000L, 75_000_000L, "0.005", // FIXED PRICE IN BTC (satoshis) FOR 1 XMR - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("Sell XMR (Buy BTC) offer:\n{}", toOfferTable.apply(newOffer)); @@ -113,7 +112,7 @@ public void testCreateFixedPriceSell1BTCFor200KXMROffer() { 100_000_000L, 50_000_000L, "0.005", // FIXED PRICE IN BTC (satoshis) FOR 1 XMR - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), MAKER_FEE_CURRENCY_CODE); log.debug("Buy XMR (Sell BTC) offer:\n{}", toOfferTable.apply(newOffer)); @@ -162,7 +161,7 @@ public void testCreatePriceMarginBasedBuy1BTCOfferWithTriggerPrice() { 100_000_000L, 75_000_000L, priceMarginPctInput, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), MAKER_FEE_CURRENCY_CODE, triggerPrice); @@ -218,7 +217,7 @@ public void testCreatePriceMarginBasedSell1BTCOffer() { 100_000_000L, 50_000_000L, priceMarginPctInput, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), MAKER_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); diff --git a/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java b/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java index cf6fb51acf4..4e839924019 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/EditOfferTest.java @@ -38,7 +38,6 @@ import org.junit.jupiter.api.TestMethodOrder; import static bisq.apitest.config.ApiTestConfig.*; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.proto.grpc.EditOfferRequest.EditType.*; import static java.lang.String.format; import static org.junit.jupiter.api.Assertions.*; @@ -141,21 +140,21 @@ public void testSetTriggerPriceToNegativeValueShouldThrowException() { @Order(4) public void testEditMktPriceMargin() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("US"); - var originalMktPriceMargin = new BigDecimal("0.1").doubleValue(); + var originalMktPriceMarginPct = 0.1d; // 0.1% var originalOffer = createMktPricedOfferForEdit(SELL.name(), USD, paymentAcct.getId(), - originalMktPriceMargin, + originalMktPriceMarginPct, NO_TRIGGER_PRICE); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. - assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin()); + assertEquals(originalMktPriceMarginPct, originalOffer.getMarketPriceMarginPct()); // Edit the offer's price margin, nothing else. - var newMktPriceMargin = new BigDecimal("0.5").doubleValue(); + var newMktPriceMargin = 0.5d; // 0.5% aliceClient.editOfferPriceMargin(originalOffer.getId(), newMktPriceMargin); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited USD offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); + assertEquals(newMktPriceMargin, editedOffer.getMarketPriceMarginPct()); assertTrue(editedOffer.getUseMarketBasedPrice()); doSanityCheck(originalOffer, editedOffer); @@ -222,24 +221,23 @@ public void testEditFixedPriceAndDeactivation() { @Order(7) public void testEditMktPriceMarginAndDeactivation() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("US"); - - var originalMktPriceMargin = new BigDecimal("0.0").doubleValue(); + var originalMktPriceMarginPct = 0.00d; OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(), USD, paymentAcct.getId(), - originalMktPriceMargin, + originalMktPriceMarginPct, NO_TRIGGER_PRICE); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); - assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin()); + assertEquals(originalMktPriceMarginPct, originalOffer.getMarketPriceMarginPct()); // Edit the offer's price margin and trigger price, and deactivate it. - var newMktPriceMargin = new BigDecimal("1.50").doubleValue(); + var newMktPriceMarginPct = 1.50d; // 1.5% aliceClient.editOffer(originalOffer.getId(), "0.00", originalOffer.getUseMarketBasedPrice(), - newMktPriceMargin, + newMktPriceMarginPct, NO_TRIGGER_PRICE, DEACTIVATE_OFFER, MKT_PRICE_MARGIN_AND_ACTIVATION_STATE); @@ -247,7 +245,7 @@ public void testEditMktPriceMarginAndDeactivation() { genBtcBlocksThenWait(1, 2_500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited USD offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); + assertEquals(newMktPriceMarginPct, editedOffer.getMarketPriceMarginPct()); assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); assertFalse(editedOffer.getIsActivated()); assertTrue(editedOffer.getUseMarketBasedPrice()); @@ -259,27 +257,27 @@ public void testEditMktPriceMarginAndDeactivation() { @Order(8) public void testEditMktPriceMarginAndTriggerPriceAndDeactivation() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("US"); - var originalMktPriceMargin = new BigDecimal("0.0").doubleValue(); + var originalMktPriceMarginPct = 0.00d; var mktPriceAsDouble = aliceClient.getBtcPrice(USD); var originalTriggerPrice = calcPriceAsString(mktPriceAsDouble, -5_000.0000, 4); OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(), USD, paymentAcct.getId(), - originalMktPriceMargin, + originalMktPriceMarginPct, originalTriggerPrice); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. originalOffer = aliceClient.getOffer(originalOffer.getId()); - assertEquals(scaledDownMktPriceMargin.apply(originalMktPriceMargin), originalOffer.getMarketPriceMargin()); + assertEquals(originalMktPriceMarginPct, originalOffer.getMarketPriceMarginPct()); assertEquals(originalTriggerPrice, originalOffer.getTriggerPrice()); // Edit the offer's price margin and trigger price, and deactivate it. - var newMktPriceMargin = new BigDecimal("0.1").doubleValue(); + var newMktPriceMarginPct = 0.10d; // 0.1% var newTriggerPrice = calcPriceAsString(mktPriceAsDouble, -2_000.0000, 4); aliceClient.editOffer(originalOffer.getId(), "0.00", originalOffer.getUseMarketBasedPrice(), - newMktPriceMargin, + newMktPriceMarginPct, newTriggerPrice, DEACTIVATE_OFFER, MKT_PRICE_MARGIN_AND_TRIGGER_PRICE_AND_ACTIVATION_STATE); @@ -287,7 +285,7 @@ public void testEditMktPriceMarginAndTriggerPriceAndDeactivation() { genBtcBlocksThenWait(1, 2_500); OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited USD offer:\n{}", toOfferTable.apply(editedOffer)); - assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); + assertEquals(newMktPriceMarginPct, editedOffer.getMarketPriceMarginPct()); assertEquals(newTriggerPrice, editedOffer.getTriggerPrice()); assertFalse(editedOffer.getIsActivated()); @@ -298,22 +296,22 @@ public void testEditMktPriceMarginAndTriggerPriceAndDeactivation() { @Order(9) public void testEditingFixedPriceInMktPriceMarginBasedOfferShouldThrowException() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("US"); - var originalMktPriceMargin = new BigDecimal("0.0").doubleValue(); + var originalMktPriceMarginPct = 0.00d; var originalOffer = createMktPricedOfferForEdit(SELL.name(), USD, paymentAcct.getId(), - originalMktPriceMargin, + originalMktPriceMarginPct, NO_TRIGGER_PRICE); log.debug("Original USD offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. // Try to edit both the fixed price and mkt price margin. - var newMktPriceMargin = new BigDecimal("0.25").doubleValue(); + var newMktPriceMarginPct = 0.25d; // 0.25% var newFixedPrice = "50000.0000"; Throwable exception = assertThrows(StatusRuntimeException.class, () -> aliceClient.editOffer(originalOffer.getId(), newFixedPrice, originalOffer.getUseMarketBasedPrice(), - newMktPriceMargin, + newMktPriceMarginPct, NO_TRIGGER_PRICE, ACTIVATE_OFFER, MKT_PRICE_MARGIN_ONLY)); @@ -361,13 +359,13 @@ public void testChangeFixedPriceOfferToPriceMarginBasedOfferWithTriggerPrice() { genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. // Change the offer to mkt price based and set a trigger price. - var newMktPriceMargin = new BigDecimal("0.05").doubleValue(); + var newMktPriceMarginPct = 0.05d; // 0.05% var delta = 200_000.0000; // trigger price on buy offer is 200K above mkt price var newTriggerPrice = calcPriceAsString(mktPriceAsDouble, delta, 4); aliceClient.editOffer(originalOffer.getId(), "0.00", true, - newMktPriceMargin, + newMktPriceMarginPct, newTriggerPrice, ACTIVATE_OFFER, MKT_PRICE_MARGIN_AND_TRIGGER_PRICE); @@ -376,7 +374,7 @@ public void testChangeFixedPriceOfferToPriceMarginBasedOfferWithTriggerPrice() { OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited MXN offer:\n{}", toOfferTable.apply(editedOffer)); assertTrue(editedOffer.getUseMarketBasedPrice()); - assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); + assertEquals(newMktPriceMarginPct, editedOffer.getMarketPriceMarginPct()); assertEquals(newTriggerPrice, editedOffer.getTriggerPrice()); assertTrue(editedOffer.getIsActivated()); @@ -388,13 +386,13 @@ public void testChangeFixedPriceOfferToPriceMarginBasedOfferWithTriggerPrice() { public void testChangePriceMarginBasedOfferToFixedPriceOfferAndDeactivateIt() { PaymentAccount paymentAcct = getOrCreatePaymentAccount("GB"); double mktPriceAsDouble = aliceClient.getBtcPrice("GBP"); - var originalMktPriceMargin = new BigDecimal("0.25").doubleValue(); + var originalMktPriceMarginPct = new BigDecimal("0.25").doubleValue(); var delta = 1_000.0000; // trigger price on sell offer is 1K below mkt price var originalTriggerPriceAsLong = calcPriceAsString(mktPriceAsDouble, delta, 4); var originalOffer = createMktPricedOfferForEdit(SELL.name(), "GBP", paymentAcct.getId(), - originalMktPriceMargin, + originalMktPriceMarginPct, originalTriggerPriceAsLong); log.debug("Original GBP offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2_500); // Wait for entry into offer book. @@ -413,7 +411,7 @@ public void testChangePriceMarginBasedOfferToFixedPriceOfferAndDeactivateIt() { log.debug("Edited GBP offer:\n{}", toOfferTable.apply(editedOffer)); assertEquals(fixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); - assertEquals(0.00, editedOffer.getMarketPriceMargin()); + assertEquals(0.00, editedOffer.getMarketPriceMarginPct()); assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); assertFalse(editedOffer.getIsActivated()); } @@ -426,7 +424,7 @@ public void testChangeFixedPricedBsqOfferToPriceMarginBasedOfferShouldThrowExcep 100_000_000L, 100_000_000L, "0.00005", // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); @@ -453,7 +451,7 @@ public void testEditTriggerPriceOnFixedPriceBsqOfferShouldThrowException() { 100_000_000L, 100_000_000L, "0.00005", // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); @@ -482,7 +480,7 @@ public void testEditFixedPriceOnBsqOffer() { 100_000_000L, 100_000_000L, fixedPriceAsString, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); @@ -502,7 +500,7 @@ public void testEditFixedPriceOnBsqOffer() { assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertTrue(editedOffer.getIsActivated()); assertFalse(editedOffer.getUseMarketBasedPrice()); - assertEquals(0.00, editedOffer.getMarketPriceMargin()); + assertEquals(0.00, editedOffer.getMarketPriceMarginPct()); assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); } @@ -515,7 +513,7 @@ public void testDisableBsqOffer() { 100_000_000L, 100_000_000L, fixedPriceAsString, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); @@ -534,7 +532,7 @@ public void testDisableBsqOffer() { assertFalse(editedOffer.getIsActivated()); assertEquals(fixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); - assertEquals(0.00, editedOffer.getMarketPriceMargin()); + assertEquals(0.00, editedOffer.getMarketPriceMarginPct()); assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); } @@ -547,7 +545,7 @@ public void testEditFixedPriceAndDisableBsqOffer() { 100_000_000L, 100_000_000L, fixedPriceAsString, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); @@ -567,7 +565,7 @@ public void testEditFixedPriceAndDisableBsqOffer() { assertFalse(editedOffer.getIsActivated()); assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); - assertEquals(0.00, editedOffer.getMarketPriceMargin()); + assertEquals(0.00, editedOffer.getMarketPriceMarginPct()); assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); } @@ -604,7 +602,7 @@ public void testChangePriceMarginBasedXmrOfferWithTriggerPriceToFixedPricedAndDe log.debug("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); assertEquals(newFixedPriceAsString, editedOffer.getPrice()); assertFalse(editedOffer.getUseMarketBasedPrice()); - assertEquals(0.00, editedOffer.getMarketPriceMargin()); + assertEquals(0.00, editedOffer.getMarketPriceMarginPct()); assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); assertFalse(editedOffer.getIsActivated()); @@ -615,11 +613,11 @@ public void testChangePriceMarginBasedXmrOfferWithTriggerPriceToFixedPricedAndDe @Order(19) public void testEditTriggerPriceOnPriceMarginBasedXmrOffer() { createXmrPaymentAccounts(); - double mktPriceMargin = -0.075d; + double mktPriceMarginPct = -0.075d; OfferInfo originalOffer = createMktPricedOfferForEdit(SELL.name(), XMR, alicesXmrAcct.getId(), - mktPriceMargin, + mktPriceMarginPct, NO_TRIGGER_PRICE); log.debug("Pending XMR offer:\n{}", toOfferTable.apply(originalOffer)); genBtcBlocksThenWait(1, 2500); // Wait for entry into offer book. @@ -632,7 +630,7 @@ public void testEditTriggerPriceOnPriceMarginBasedXmrOffer() { aliceClient.editOffer(originalOffer.getId(), "0", true, - mktPriceMargin, + mktPriceMarginPct, triggerPrice, ACTIVATE_OFFER, TRIGGER_PRICE_ONLY); @@ -641,7 +639,7 @@ public void testEditTriggerPriceOnPriceMarginBasedXmrOffer() { OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.info("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); assertTrue(editedOffer.getUseMarketBasedPrice()); - assertEquals(scaledDownMktPriceMargin.apply(mktPriceMargin), editedOffer.getMarketPriceMargin()); + assertEquals(mktPriceMarginPct, editedOffer.getMarketPriceMarginPct()); assertEquals(triggerPrice, editedOffer.getTriggerPrice()); assertTrue(editedOffer.getIsActivated()); @@ -659,7 +657,7 @@ public void testChangeFixedPricedXmrOfferToPriceMarginBasedOfferWithTriggerPrice 100_000_000L, 50_000_000L, fixedPriceAsString, // FIXED PRICE IN BTC (satoshis) FOR 1 XMR - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), BSQ); log.debug("Pending XMR offer:\n{}", toOfferTable.apply(originalOffer)); @@ -669,13 +667,13 @@ public void testChangeFixedPricedXmrOfferToPriceMarginBasedOfferWithTriggerPrice log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); // Change the offer to mkt price based and set a trigger price. - var newMktPriceMargin = new BigDecimal("0.05").doubleValue(); + var newMktPriceMarginPct = 0.05d; // 0.05% var delta = -0.00100000; var newTriggerPrice = calcPriceAsString(mktPriceAsDouble, delta, 8); aliceClient.editOffer(originalOffer.getId(), "0.00", true, - newMktPriceMargin, + newMktPriceMarginPct, newTriggerPrice, ACTIVATE_OFFER, MKT_PRICE_MARGIN_AND_TRIGGER_PRICE); @@ -684,7 +682,7 @@ public void testChangeFixedPricedXmrOfferToPriceMarginBasedOfferWithTriggerPrice OfferInfo editedOffer = aliceClient.getOffer(originalOffer.getId()); log.debug("Edited XMR offer:\n{}", toOfferTable.apply(editedOffer)); assertTrue(editedOffer.getUseMarketBasedPrice()); - assertEquals(scaledDownMktPriceMargin.apply(newMktPriceMargin), editedOffer.getMarketPriceMargin()); + assertEquals(newMktPriceMarginPct, editedOffer.getMarketPriceMarginPct()); assertEquals(newTriggerPrice, editedOffer.getTriggerPrice()); assertTrue(editedOffer.getIsActivated()); @@ -700,7 +698,7 @@ public void testEditTriggerPriceOnFixedPriceXmrOfferShouldThrowException() { 100_000_000L, 25_000_000L, "0.007", // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), BSQ); log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); @@ -731,7 +729,7 @@ public void testEditFixedPriceOnXmrOffer() { 100_000_000L, 100_000_000L, fixedPriceAsString, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), BSQ); log.debug("Original BSQ offer:\n{}", toOfferTable.apply(originalOffer)); @@ -765,7 +763,7 @@ public void testDisableXmrOffer() { 100_000_000L, 50_000_000L, fixedPriceAsString, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), BSQ); log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); @@ -798,7 +796,7 @@ public void testEditFixedPriceAndDisableXmrOffer() { 100_000_000L, 100_000_000L, fixedPriceAsString, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), BSQ); log.debug("Original XMR offer:\n{}", toOfferTable.apply(originalOffer)); @@ -860,14 +858,14 @@ public void testEditBsqSwapOfferShouldThrowException() { private OfferInfo createMktPricedOfferForEdit(String direction, String currencyCode, String paymentAccountId, - double marketPriceMargin, + double marketPriceMarginPct, String triggerPrice) { return aliceClient.createMarketBasedPricedOffer(direction, currencyCode, AMOUNT, AMOUNT, - marketPriceMargin, - getDefaultBuyerSecurityDepositAsPercent(), + marketPriceMarginPct, + defaultBuyerSecurityDepositPct.get(), paymentAccountId, BSQ, triggerPrice); @@ -882,7 +880,7 @@ private OfferInfo createFixedPricedOfferForEdit(String direction, AMOUNT, AMOUNT, priceAsString, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), paymentAccountId, BSQ); } @@ -904,7 +902,7 @@ private void doSanityCheck(OfferInfo originalOffer, OfferInfo editedOffer) { private void assertMarketBasedPriceFieldsAreIgnored(OfferInfo editedOffer) { assertFalse(editedOffer.getUseMarketBasedPrice()); - assertEquals(0.00, editedOffer.getMarketPriceMargin()); + assertEquals(0.00, editedOffer.getMarketPriceMarginPct()); assertEquals(NO_TRIGGER_PRICE, editedOffer.getTriggerPrice()); } 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 cc8a02f33d9..48a8ccbbbb5 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/ValidateCreateOfferTest.java @@ -31,7 +31,6 @@ import static bisq.apitest.config.ApiTestConfig.BSQ; import static bisq.apitest.config.ApiTestConfig.BTC; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static java.lang.String.format; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -53,7 +52,7 @@ public void testAmtTooLargeShouldThrowException() { 100000000000L, // exceeds amount limit 100000000000L, "10000.0000", - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), usdAccount.getId(), BSQ)); assertEquals("UNKNOWN: An error occurred at task: ValidateOffer", exception.getMessage()); @@ -70,7 +69,7 @@ public void testNoMatchingEURPaymentAccountShouldThrowException() { 10000000L, 10000000L, "40000.0000", - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), chfAccount.getId(), BTC)); String expectedError = format("UNKNOWN: cannot create EUR offer with payment account %s", chfAccount.getId()); @@ -88,7 +87,7 @@ public void testNoMatchingCADPaymentAccountShouldThrowException() { 10000000L, 10000000L, "63000.0000", - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), audAccount.getId(), BTC)); String expectedError = format("UNKNOWN: cannot create CAD offer with payment account %s", audAccount.getId()); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java index 9b4a687ea8f..8dc20b54170 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/BsqSwapBuyBtcTradeTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; @@ -48,7 +49,7 @@ import bisq.apitest.method.offer.AbstractOfferTest; import bisq.cli.GrpcClient; -// @Disabled +@Disabled @Slf4j @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class BsqSwapBuyBtcTradeTest extends AbstractTradeTest { diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBSQOfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBSQOfferTest.java index 50bde49e244..503e5f41e30 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBSQOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBSQOfferTest.java @@ -30,7 +30,6 @@ import org.junit.jupiter.api.TestMethodOrder; import static bisq.apitest.config.ApiTestConfig.BSQ; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.core.trade.model.bisq_v1.Trade.Phase.PAYOUT_PUBLISHED; import static bisq.core.trade.model.bisq_v1.Trade.State.BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG; import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG; @@ -76,7 +75,7 @@ public void testTakeAlicesSellBTCForBSQOffer(final TestInfo testInfo) { 15_000_000L, 7_500_000L, "0.000035", // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), TRADE_FEE_CURRENCY_CODE); log.debug("Alice's BUY BSQ (SELL BTC) Offer:\n{}", toOfferTable.apply(alicesOffer)); 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 55487f740bd..9ec651b0813 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferTest.java @@ -32,7 +32,6 @@ import static bisq.apitest.config.ApiTestConfig.BSQ; import static bisq.apitest.config.ApiTestConfig.USD; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.core.trade.model.bisq_v1.Trade.Phase.PAYOUT_PUBLISHED; import static bisq.core.trade.model.bisq_v1.Trade.State.BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG; import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG; @@ -62,7 +61,7 @@ public void testTakeAlicesBuyOffer(final TestInfo testInfo) { 12_500_000L, 12_500_000L, // min-amount = amount 0.00, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesUsdAccount.getId(), TRADE_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferWithNationalBankAcctTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferWithNationalBankAcctTest.java index e0e2ee746bd..0049cb54911 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferWithNationalBankAcctTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyBTCOfferWithNationalBankAcctTest.java @@ -49,7 +49,6 @@ import org.junit.jupiter.api.TestMethodOrder; import static bisq.apitest.config.ApiTestConfig.BSQ; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.core.trade.model.bisq_v1.Trade.Phase.PAYOUT_PUBLISHED; import static bisq.core.trade.model.bisq_v1.Trade.State.BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG; import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG; @@ -94,7 +93,7 @@ public void testTakeAlicesBuyOffer(final TestInfo testInfo) { 1_000_000L, 1_000_000L, // min-amount = amount 0.00, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesPaymentAccount.getId(), TRADE_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyXMROfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyXMROfferTest.java index bb572976026..7ed209da5c1 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyXMROfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeBuyXMROfferTest.java @@ -32,7 +32,6 @@ import static bisq.apitest.config.ApiTestConfig.BSQ; import static bisq.apitest.config.ApiTestConfig.XMR; import static bisq.cli.table.builder.TableType.OFFER_TBL; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.core.trade.model.bisq_v1.Trade.Phase.PAYOUT_PUBLISHED; import static bisq.core.trade.model.bisq_v1.Trade.State.BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG; import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG; @@ -77,7 +76,7 @@ public void testTakeAlicesSellBTCForXMROffer(final TestInfo testInfo) { 15_000_000L, 7_500_000L, "0.00455500", // FIXED PRICE IN BTC (satoshis) FOR 1 XMR - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), TRADE_FEE_CURRENCY_CODE); log.debug("Alice's BUY XMR (SELL BTC) Offer:\n{}", new TableBuilder(OFFER_TBL, alicesOffer).build()); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBSQOfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBSQOfferTest.java index ac1f0569153..fcb79cee8ed 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBSQOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBSQOfferTest.java @@ -32,7 +32,6 @@ import static bisq.apitest.config.ApiTestConfig.BSQ; import static bisq.apitest.config.ApiTestConfig.BTC; import static bisq.cli.table.builder.TableType.OFFER_TBL; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.core.trade.model.bisq_v1.Trade.Phase.PAYOUT_PUBLISHED; import static bisq.core.trade.model.bisq_v1.Trade.Phase.WITHDRAWN; import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG; @@ -78,7 +77,7 @@ public void testTakeAlicesBuyBTCForBSQOffer(final TestInfo testInfo) { 15_000_000L, 7_500_000L, "0.000035", // FIXED PRICE IN BTC (satoshis) FOR 1 BSQ - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesLegacyBsqAcct.getId(), TRADE_FEE_CURRENCY_CODE); log.debug("Alice's SELL BSQ (BUY BTC) Offer:\n{}", new TableBuilder(OFFER_TBL, alicesOffer).build()); 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 9e205f5ef37..89735ef2c0e 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellBTCOfferTest.java @@ -32,7 +32,6 @@ import static bisq.apitest.config.ApiTestConfig.BTC; import static bisq.apitest.config.ApiTestConfig.USD; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.core.trade.model.bisq_v1.Trade.Phase.PAYOUT_PUBLISHED; import static bisq.core.trade.model.bisq_v1.Trade.Phase.WITHDRAWN; import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG; @@ -65,7 +64,7 @@ public void testTakeAlicesSellOffer(final TestInfo testInfo) { 12_500_000L, 12_500_000L, // min-amount = amount 0.00, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesUsdAccount.getId(), TRADE_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); diff --git a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellXMROfferTest.java b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellXMROfferTest.java index 769d6dac8a0..6ecc572c3d9 100644 --- a/apitest/src/test/java/bisq/apitest/method/trade/TakeSellXMROfferTest.java +++ b/apitest/src/test/java/bisq/apitest/method/trade/TakeSellXMROfferTest.java @@ -32,7 +32,6 @@ import static bisq.apitest.config.ApiTestConfig.BTC; import static bisq.apitest.config.ApiTestConfig.XMR; import static bisq.cli.table.builder.TableType.OFFER_TBL; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.core.trade.model.bisq_v1.Trade.Phase.PAYOUT_PUBLISHED; import static bisq.core.trade.model.bisq_v1.Trade.Phase.WITHDRAWN; import static bisq.core.trade.model.bisq_v1.Trade.State.SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG; @@ -80,7 +79,7 @@ public void testTakeAlicesBuyBTCForXMROffer(final TestInfo testInfo) { 20_000_000L, 10_500_000L, priceMarginPctInput, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), TRADE_FEE_CURRENCY_CODE, NO_TRIGGER_PRICE); diff --git a/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java b/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java index a27fa8174d4..00293fd5f93 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java +++ b/apitest/src/test/java/bisq/apitest/scenario/LongRunningOfferDeactivationTest.java @@ -31,7 +31,6 @@ import org.junit.jupiter.api.condition.EnabledIf; import static bisq.apitest.config.ApiTestConfig.BTC; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static java.lang.System.getenv; import static org.junit.jupiter.api.Assertions.fail; import static protobuf.OfferDirection.BUY; @@ -65,7 +64,7 @@ public void testSellOfferAutoDisable(final TestInfo testInfo) { 1_000_000, 1_000_000, 0.00, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), paymentAcct.getId(), BTC, triggerPrice); @@ -112,7 +111,7 @@ public void testBuyOfferAutoDisable(final TestInfo testInfo) { 1_000_000, 1_000_000, 0.00, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), paymentAcct.getId(), BTC, triggerPrice); diff --git a/apitest/src/test/java/bisq/apitest/scenario/OfferTest.java b/apitest/src/test/java/bisq/apitest/scenario/OfferTest.java index 2d6eef8cbe9..f9a0b4c7188 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/OfferTest.java +++ b/apitest/src/test/java/bisq/apitest/scenario/OfferTest.java @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; @@ -41,9 +42,14 @@ @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class OfferTest extends AbstractOfferTest { + @BeforeAll + public static void setUp() { + setUp(false); // Use setUp(true) for running API daemons in remote debug mode. + } + @Test @Order(1) - public void testAmtTooLargeShouldThrowException() { + public void testCreateOfferValidation() { ValidateCreateOfferTest test = new ValidateCreateOfferTest(); test.testAmtTooLargeShouldThrowException(); test.testNoMatchingEURPaymentAccountShouldThrowException(); diff --git a/apitest/src/test/java/bisq/apitest/scenario/bot/RandomOffer.java b/apitest/src/test/java/bisq/apitest/scenario/bot/RandomOffer.java index 5f6cf143d43..40afcadab95 100644 --- a/apitest/src/test/java/bisq/apitest/scenario/bot/RandomOffer.java +++ b/apitest/src/test/java/bisq/apitest/scenario/bot/RandomOffer.java @@ -33,10 +33,10 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import static bisq.apitest.method.offer.AbstractOfferTest.defaultBuyerSecurityDepositPct; import static bisq.cli.CurrencyFormat.formatInternalFiatPrice; import static bisq.cli.CurrencyFormat.formatSatoshis; import static bisq.common.util.MathUtils.scaleDownByPowerOf10; -import static bisq.core.btc.wallet.Restrictions.getDefaultBuyerSecurityDepositAsPercent; import static bisq.core.payment.payload.PaymentMethod.F2F_ID; import static java.lang.String.format; import static java.math.RoundingMode.HALF_UP; @@ -127,7 +127,7 @@ public RandomOffer create() throws InvalidRandomOfferException { amount, minAmount, priceMargin, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), feeCurrency, "0" /*no trigger price*/); } else { @@ -137,7 +137,7 @@ public RandomOffer create() throws InvalidRandomOfferException { amount, minAmount, fixedOfferPrice, - getDefaultBuyerSecurityDepositAsPercent(), + defaultBuyerSecurityDepositPct.get(), feeCurrency); } this.id = offer.getId(); From 8f93c27deb46cae00386c64b4e7435484513ae87 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 18:11:24 -0300 Subject: [PATCH 24/41] Fix CLI gettrades' Deviation column value format (do nothing) --- .../builder/AbstractTradeListBuilder.java | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java index 0195f9a47cb..07400e8f299 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java @@ -20,8 +20,6 @@ import bisq.proto.grpc.ContractInfo; import bisq.proto.grpc.TradeInfo; -import java.text.DecimalFormat; - import java.math.BigDecimal; import java.math.RoundingMode; @@ -215,9 +213,10 @@ protected void validate() { ? t.getOffer().getCounterCurrencyCode() : t.getOffer().getBaseCurrencyCode(); + protected final Function toPriceDeviation = (t) -> t.getOffer().getUseMarketBasedPrice() - ? formatToPercent(t.getOffer().getMarketPriceMarginPct()) + ? t.getOffer().getMarketPriceMarginPct() + "%" : "N/A"; protected final Function toMyMinerTxFee = (t) -> { @@ -307,19 +306,6 @@ protected void validate() { } }; - // TODO Move to bisq/cli/CurrencyFormat.java ? - - public static String formatToPercent(double value) { - DecimalFormat decimalFormat = new DecimalFormat("#.##"); - decimalFormat.setMinimumFractionDigits(2); - decimalFormat.setMaximumFractionDigits(2); - return formatToPercent(value, decimalFormat); - } - - public static String formatToPercent(double value, DecimalFormat decimalFormat) { - return decimalFormat.format(roundDouble(value * 100.0, 2)).replace(",", ".") + "%"; - } - public static double roundDouble(double value, int precision) { return roundDouble(value, precision, RoundingMode.HALF_UP); } From 23303187bea964fac9b556170535e3f7369d65d5 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 18:14:47 -0300 Subject: [PATCH 25/41] Change mktPriceMarginOpt name to mktPriceMarginPctOpt And validate the opt value. --- cli/src/main/java/bisq/cli/CliMain.java | 6 ++-- .../cli/opts/CreateOfferOptionParser.java | 28 +++++++++---------- .../java/bisq/cli/opts/OptionParsersTest.java | 4 +-- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index cf70886d2da..361fb1daa34 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -344,8 +344,8 @@ public static void run(String[] args) { var minAmount = toSatoshis(opts.getMinAmount()); var useMarketBasedPrice = opts.isUsingMktPriceMargin(); var fixedPrice = opts.getFixedPrice(); - var marketPriceMargin = opts.getMktPriceMarginAsBigDecimal(); - var securityDepositPct = isSwap ? 0.00 : opts.getSecurityDepositPct(); + var marketPriceMarginPct = opts.getMktPriceMarginPct(); + var securityDepositPct = isSwap ? 0.00d : opts.getSecurityDepositPct(); var makerFeeCurrencyCode = opts.getMakerFeeCurrencyCode(); var triggerPrice = "0"; // Cannot be defined until the new offer is added to book. OfferInfo offer; @@ -361,7 +361,7 @@ public static void run(String[] args) { minAmount, useMarketBasedPrice, fixedPrice, - marketPriceMargin.doubleValue(), + marketPriceMarginPct, securityDepositPct, paymentAcctId, makerFeeCurrencyCode, diff --git a/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java b/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java index fab316f63d7..40881891c85 100644 --- a/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java +++ b/cli/src/main/java/bisq/cli/opts/CreateOfferOptionParser.java @@ -20,8 +20,6 @@ import joptsimple.OptionSpec; -import java.math.BigDecimal; - import static bisq.cli.opts.OptLabel.*; import static java.lang.Boolean.FALSE; import static joptsimple.internal.Strings.EMPTY; @@ -45,7 +43,7 @@ public class CreateOfferOptionParser extends AbstractMethodOptionParser implemen final OptionSpec minAmountOpt = parser.accepts(OPT_MIN_AMOUNT, "minimum amount of btc to buy or sell") .withOptionalArg(); - final OptionSpec mktPriceMarginOpt = parser.accepts(OPT_MKT_PRICE_MARGIN, "market btc price margin (%)") + final OptionSpec mktPriceMarginPctOpt = parser.accepts(OPT_MKT_PRICE_MARGIN, "market btc price margin (%)") .withOptionalArg() .defaultsTo("0.00"); @@ -92,7 +90,7 @@ public CreateOfferOptionParser parse() { if (options.has(paymentAccountIdOpt)) throw new IllegalArgumentException("cannot use a payment account id in bsq swap offer"); - if (options.has(mktPriceMarginOpt)) + if (options.has(mktPriceMarginPctOpt)) throw new IllegalArgumentException("cannot use a market price margin in bsq swap offer"); if (options.has(securityDepositPctOpt)) @@ -105,11 +103,16 @@ public CreateOfferOptionParser parse() { if (!options.has(paymentAccountIdOpt) || options.valueOf(paymentAccountIdOpt).isEmpty()) throw new IllegalArgumentException("no payment account id specified"); - if (!options.has(mktPriceMarginOpt) && !options.has(fixedPriceOpt)) + if (!options.has(mktPriceMarginPctOpt) && !options.has(fixedPriceOpt)) throw new IllegalArgumentException("no market price margin or fixed price specified"); - if (options.has(mktPriceMarginOpt) && options.valueOf(mktPriceMarginOpt).isEmpty()) - throw new IllegalArgumentException("no market price margin specified"); + if (options.has(mktPriceMarginPctOpt)) { + var mktPriceMarginPctString = options.valueOf(mktPriceMarginPctOpt); + if (mktPriceMarginPctString.isEmpty()) + throw new IllegalArgumentException("no market price margin specified"); + else + verifyStringIsValidDouble(mktPriceMarginPctString); + } if (options.has(fixedPriceOpt) && options.valueOf(fixedPriceOpt).isEmpty()) throw new IllegalArgumentException("no fixed price specified"); @@ -144,16 +147,11 @@ public String getMinAmount() { } public boolean isUsingMktPriceMargin() { - return options.has(mktPriceMarginOpt); - } - - @SuppressWarnings("unused") - public String getMktPriceMargin() { - return isUsingMktPriceMargin() ? options.valueOf(mktPriceMarginOpt) : "0.00"; + return options.has(mktPriceMarginPctOpt); } - public BigDecimal getMktPriceMarginAsBigDecimal() { - return isUsingMktPriceMargin() ? new BigDecimal(options.valueOf(mktPriceMarginOpt)) : BigDecimal.ZERO; + public double getMktPriceMarginPct() { + return isUsingMktPriceMargin() ? Double.parseDouble(options.valueOf(mktPriceMarginPctOpt)) : 0.00d; } public String getFixedPrice() { diff --git a/cli/src/test/java/bisq/cli/opts/OptionParsersTest.java b/cli/src/test/java/bisq/cli/opts/OptionParsersTest.java index 70b004eb037..562214bdaff 100644 --- a/cli/src/test/java/bisq/cli/opts/OptionParsersTest.java +++ b/cli/src/test/java/bisq/cli/opts/OptionParsersTest.java @@ -126,7 +126,7 @@ public void testValidCreateOfferOpts() { "--" + OPT_DIRECTION + "=" + "BUY", "--" + OPT_CURRENCY_CODE + "=" + "EUR", "--" + OPT_AMOUNT + "=" + "0.125", - "--" + OPT_MKT_PRICE_MARGIN + "=" + "0.0", + "--" + OPT_MKT_PRICE_MARGIN + "=" + "3.15", "--" + OPT_SECURITY_DEPOSIT + "=" + "25.0" }; CreateOfferOptionParser parser = new CreateOfferOptionParser(args).parse(); @@ -134,7 +134,7 @@ public void testValidCreateOfferOpts() { assertEquals("BUY", parser.getDirection()); assertEquals("EUR", parser.getCurrencyCode()); assertEquals("0.125", parser.getAmount()); - assertEquals("0.0", parser.getMktPriceMargin()); + assertEquals(3.15d, parser.getMktPriceMarginPct()); assertEquals(25.0, parser.getSecurityDepositPct()); } From fade8bc0d9ed7370add0e156f6aa3e3a48ee4228 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 18:52:56 -0300 Subject: [PATCH 26/41] Show CLI gettrades' Deviation col-value with precision=2 (do something) --- .../java/bisq/cli/table/builder/AbstractTradeListBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java index 07400e8f299..970e074c759 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java @@ -35,6 +35,7 @@ import static bisq.cli.table.builder.TableBuilderConstants.COL_HEADER_BUYER_DEPOSIT; import static bisq.cli.table.builder.TableBuilderConstants.COL_HEADER_SELLER_DEPOSIT; import static bisq.cli.table.builder.TableType.TRADE_DETAIL_TBL; +import static java.lang.String.format; import static protobuf.OfferDirection.SELL; @@ -213,10 +214,9 @@ protected void validate() { ? t.getOffer().getCounterCurrencyCode() : t.getOffer().getBaseCurrencyCode(); - protected final Function toPriceDeviation = (t) -> t.getOffer().getUseMarketBasedPrice() - ? t.getOffer().getMarketPriceMarginPct() + "%" + ? format("%.2f%s", t.getOffer().getMarketPriceMarginPct(), "%") : "N/A"; protected final Function toMyMinerTxFee = (t) -> { From 5acef133abbe3a687534b9c133fa15dc3f6daa5e Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 19:01:50 -0300 Subject: [PATCH 27/41] Delete dead code --- .../builder/AbstractTradeListBuilder.java | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java index 970e074c759..c13852ac11d 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTradeListBuilder.java @@ -21,7 +21,6 @@ import bisq.proto.grpc.TradeInfo; import java.math.BigDecimal; -import java.math.RoundingMode; import java.util.List; import java.util.function.Function; @@ -305,25 +304,4 @@ protected void validate() { return ""; } }; - - public static double roundDouble(double value, int precision) { - return roundDouble(value, precision, RoundingMode.HALF_UP); - } - - @SuppressWarnings("SameParameterValue") - public static double roundDouble(double value, int precision, RoundingMode roundingMode) { - if (precision < 0) - throw new IllegalArgumentException(); - if (!Double.isFinite(value)) - throw new IllegalArgumentException("Expected a finite double, but found " + value); - - try { - BigDecimal bd = BigDecimal.valueOf(value); - bd = bd.setScale(precision, roundingMode); - return bd.doubleValue(); - } catch (Throwable t) { - t.printStackTrace(); // TODO throw pretty exception for CLI console - return 0; - } - } } From 8271920943063665df49f119853ff971cbfedc7f Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sun, 20 Feb 2022 20:20:33 -0300 Subject: [PATCH 28/41] New comments through "message TxInfo { ... }" --- proto/src/main/proto/grpc.proto | 204 ++++++++++++++++++-------------- 1 file changed, 118 insertions(+), 86 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 62672019305..ea4b2a99eea 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -47,11 +47,11 @@ service Help { } message GetMethodHelpRequest { - string methodName = 1; // CLI command name. + string methodName = 1; // The CLI command name. } message GetMethodHelpReply { - string methodHelp = 1; // Man page for CLI command. + string methodHelp = 1; // The man page for the CLI command. } /* @@ -96,7 +96,7 @@ service Offers { // Edit an open offer. rpc EditOffer (EditOfferRequest) returns (EditOfferReply) { } - // Cancel (remove) an open offer. + // Cancel an open offer; remove it from the offer book. rpc CancelOffer (CancelOfferRequest) returns (CancelOfferReply) { } } @@ -108,10 +108,10 @@ message GetOfferCategoryRequest { message GetOfferCategoryReply { enum OfferCategory { - UNKNOWN = 0; - FIAT = 1; - ALTCOIN = 2; - BSQ_SWAP = 3; + UNKNOWN = 0; // An invalid offer category probably indicates a software bug. + FIAT = 1; // Indicates offer is to BUY or SELL BTC with a fiat currency. + ALTCOIN = 2; // Indicates offer is to BUY or SELL BTC with an altcoin. + BSQ_SWAP = 3; // Indicates offer is to swap BTC for BSQ. } OfferCategory offerCategory = 1; } @@ -361,7 +361,7 @@ message AvailabilityResultWithDescription { * The PaymentAccounts service provides rpc methods for creating fiat and crypto currency payment accounts. */ service PaymentAccounts { - // Create a fiat payment account, providing details in a json form. + // Create a fiat payment account, providing details in a json form generated by rpc method GetPaymentAccountForm. rpc CreatePaymentAccount (CreatePaymentAccountRequest) returns (CreatePaymentAccountReply) { } // Get list of all saved fiat payment accounts. @@ -370,7 +370,7 @@ service PaymentAccounts { // Get list of all supported Bisq payment methods. rpc GetPaymentMethods (GetPaymentMethodsRequest) returns (GetPaymentMethodsReply) { } - // Get a json template file for a supported Bisq payment method. + // Get a json template file for a supported Bisq payment method. Fill in the form and call rpc method CreatePaymentAccount. rpc GetPaymentAccountForm (GetPaymentAccountFormRequest) returns (GetPaymentAccountFormReply) { } // Create a crypto currency (altcoin) payment account. @@ -382,51 +382,52 @@ service PaymentAccounts { } message CreatePaymentAccountRequest { - string paymentAccountForm = 1; + string paymentAccountForm = 1; // File path of filled json payment account form. } message CreatePaymentAccountReply { - PaymentAccount paymentAccount = 1; + PaymentAccount paymentAccount = 1; // The new payment account. } message GetPaymentAccountsRequest { } message GetPaymentAccountsReply { - repeated PaymentAccount paymentAccounts = 1; + repeated PaymentAccount paymentAccounts = 1; // All user's saved payment accounts. } message GetPaymentMethodsRequest { } message GetPaymentMethodsReply { - repeated PaymentMethod paymentMethods = 1; + repeated PaymentMethod paymentMethods = 1; // Ids of all supported Bisq fiat payment methods. } message GetPaymentAccountFormRequest { - string paymentMethodId = 1; + string paymentMethodId = 1; // Payment method id determining content of the requested payment account form. } message GetPaymentAccountFormReply { + // An empty payment account json form to be filled out and passed to rpc method CreatePaymentAccount. string paymentAccountFormJson = 1; } message CreateCryptoCurrencyPaymentAccountRequest { - string accountName = 1; - string currencyCode = 2; - string address = 3; - bool tradeInstant = 4; + string accountName = 1; // The name of the altcoin payment account. Uniqueness is not enforced. + string currencyCode = 2; // The altcoin currency code. + string address = 3; // The altcoin receiving address. + bool tradeInstant = 4; // Whether the altcoin payment account is an instant account or not. } message CreateCryptoCurrencyPaymentAccountReply { - PaymentAccount paymentAccount = 1; + PaymentAccount paymentAccount = 1; // The new altcoin payment account. } message GetCryptoCurrencyPaymentMethodsRequest { } message GetCryptoCurrencyPaymentMethodsReply { - repeated PaymentMethod paymentMethods = 1; + repeated PaymentMethod paymentMethods = 1; // Ids of all supported Bisq altcoin payment methods. } service Price { @@ -436,11 +437,11 @@ service Price { } message MarketPriceRequest { - string currencyCode = 1; + string currencyCode = 1; // The three letter currency code. } message MarketPriceReply { - double price = 1; + double price = 1; // The most recently available market price. } /* @@ -476,22 +477,22 @@ message StopReply { * The Trades service provides rpc methods for taking, executing, and listing trades. */ service Trades { - // Get an open trade with a trade-id. + // Get a currently open trade. rpc GetTrade (GetTradeRequest) returns (GetTradeReply) { } - // Get all open or historical trades. + // Get currently open, or historical trades (closed or failed). rpc GetTrades (GetTradesRequest) returns (GetTradesReply) { } // Take an open offer. rpc TakeOffer (TakeOfferRequest) returns (TakeOfferReply) { } - // Send a 'payment started' message to a trading peer (seller). + // Send a 'payment started' message to a trading peer (the BTC seller). rpc ConfirmPaymentStarted (ConfirmPaymentStartedRequest) returns (ConfirmPaymentStartedReply) { } - // Send a 'payment received' message to a trading peer (buyer). + // Send a 'payment received' message to a trading peer (the BTC buyer). rpc ConfirmPaymentReceived (ConfirmPaymentReceivedRequest) returns (ConfirmPaymentReceivedReply) { } - // Close a completed trade (moves it to trade history). + // Close a completed trade; move it to trade history. rpc CloseTrade (CloseTradeRequest) returns (CloseTradeReply) { } // Fail an open trade. @@ -506,173 +507,204 @@ service Trades { } message TakeOfferRequest { - string offerId = 1; - string paymentAccountId = 2; - string takerFeeCurrencyCode = 3; + string offerId = 1; // The unique identifier of the offer being taken. + string paymentAccountId = 2; // The unique identifier of the payment account used to take offer.. + string takerFeeCurrencyCode = 3; // The code of the currency (BSQ or BTC) used to pay the taker's Bisq trade fee. } message TakeOfferReply { - TradeInfo trade = 1; - AvailabilityResultWithDescription failureReason = 2; + TradeInfo trade = 1; // The new trade. + AvailabilityResultWithDescription failureReason = 2; // The reason the offer could not be taken. } message ConfirmPaymentStartedRequest { - string tradeId = 1; + string tradeId = 1; // The unique identifier of the open trade. } message ConfirmPaymentStartedReply { } message ConfirmPaymentReceivedRequest { - string tradeId = 1; + string tradeId = 1; // The unique identifier of the open trade. } message ConfirmPaymentReceivedReply { } message GetTradeRequest { - string tradeId = 1; + string tradeId = 1; // The unique identifier of the trade. } message GetTradeReply { - TradeInfo trade = 1; + TradeInfo trade = 1; // The unique identifier of the trade. } message GetTradesRequest { + // Rpc method GetTrades parameter determining what category of trade list is is being requested. enum Category { - OPEN = 0; - CLOSED = 1; - FAILED = 2; + OPEN = 0; // Get all currently open trades. + CLOSED = 1; // Get all completed trades. + FAILED = 2; // Get all failed trades. } Category category = 1; } message GetTradesReply { - repeated TradeInfo trades = 1; + repeated TradeInfo trades = 1; // All trades for GetTradesRequest.Category. } message CloseTradeRequest { - string tradeId = 1; + string tradeId = 1; // The unique identifier of the trade. } message CloseTradeReply { } message FailTradeRequest { - string tradeId = 1; + string tradeId = 1; // The unique identifier of the trade. } message FailTradeReply { } message UnFailTradeRequest { - string tradeId = 1; + string tradeId = 1; // The unique identifier of the trade. } message UnFailTradeReply { } message WithdrawFundsRequest { - string tradeId = 1; - string address = 2; - string memo = 3; + string tradeId = 1; // The unique identifier of the trade. + string address = 2; // The receiver's bitcoin wallet address. + string memo = 3; // An optional memo saved with the sent btc transaction. } message WithdrawFundsReply { } message TradeInfo { + // The original offer. OfferInfo offer = 1; + // The unique identifier of the trade. string tradeId = 2; + // An abbreviation of unique identifier of the trade. It cannot be used as parameter to rpc methods GetTrade, + // ConfirmPaymentStarted, CloseTrade, etc., but it may be useful while interacting with support or trading peers. string shortId = 3; + // The creation date of the trade as a long: the number of milliseconds that have elapsed since January 1, 1970. uint64 date = 4; + // A brief description of the user's role in the trade, i.e., an offer maker or taker, a BTC buyer or seller. string role = 5; + // Whether the offer taker's Bisq trade fee was paid in BTC or not (BSQ). bool isCurrencyForTakerFeeBtc = 6; + // The bitcoin miner transaction fee in satoshis. uint64 txFeeAsLong = 7; + // The offer taker's Bisq trade fee in satoshis. uint64 takerFeeAsLong = 8; + // The bitcoin transaction id for offer taker's Bisq trade fee. string takerFeeTxId = 9; + // The bitcoin transaction id for the offer taker's security deposit. string depositTxId = 10; + // The bitcoin transaction id for trade payout. string payoutTxId = 11; + // The trade payout amount in satoshis. uint64 tradeAmountAsLong = 12; // For fiat trades: the fiat price for 1 BTC to 4 decimal places, e.g., 41000.50 EUR is "41000.5000". // For altcoin trades: the altcoin price for 1 BTC to 8 decimal places, e.g., 0.5 BTC is "0.50000000". string tradePrice = 13; + // The trading peer's node address. string tradingPeerNodeAddress = 14; + // The internal state of the trade. (TODO Needs more explanation.) string state = 15; + // The internal phase of the trade. (TODO Needs more explanation.) string phase = 16; + // How much of the trade protocol's time limit has elapsed. (TODO Needs more explanation.) string tradePeriodState = 17; + // Whether the trade's security deposit bitcoin transaction has been broadcast, or not. bool isDepositPublished = 18; + // Whether the trade's security deposit bitcoin transaction has been confirmed at least once, or not. bool isDepositConfirmed = 19; + // Whether the trade's 'start payment' message has been sent by the BTC buyer, or not. + // (TODO Rename field to isPaymentSent because payment could be made in altcoin.) bool isFiatSent = 20; + // Whether the trade's 'payment received' message has been sent by the BTC seller, or not. + // (TODO Rename field to isPaymentReceived because payment could be made in altcoin.) bool isFiatReceived = 21; + // Whether the trade's payout bitcoin transaction has been confirmed at least once, or not. bool isPayoutPublished = 22; + // Whether the trade's payout has been completed and the trade is now closed, or not. + // (TODO Rename field to isClosed, or isCompleted because payment could be made in altcoin.) bool isWithdrawn = 23; + // The entire trade contract as a json string. string contractAsJson = 24; + // The summary of the trade contract. ContractInfo contract = 25; // The volume of currency traded for BTC. string tradeVolume = 26; + // The details specific to the BSQ swap trade. If the trade is not a BSQ swap, this field should be ignored. BsqSwapTradeInfo bsqSwapTradeInfo = 28; // Needed by open/closed/failed trade list items. string closingStatus = 29; } message ContractInfo { - string buyerNodeAddress = 1; - string sellerNodeAddress = 2; - string mediatorNodeAddress = 3; - string refundAgentNodeAddress = 4; - bool isBuyerMakerAndSellerTaker = 5; - string makerAccountId = 6; - string takerAccountId = 7; - PaymentAccountPayloadInfo makerPaymentAccountPayload = 8; - PaymentAccountPayloadInfo takerPaymentAccountPayload = 9; - string makerPayoutAddressString = 10; - string takerPayoutAddressString = 11; - uint64 lockTime = 12; + string buyerNodeAddress = 1; // The BTC buyer peer's node address. + string sellerNodeAddress = 2; // The BTC seller peer's node address. + string mediatorNodeAddress = 3; // If the trade was disputed, the Bisq mediator's node address. + string refundAgentNodeAddress = 4; // If a trade refund was requested, the Bisq refund agent's node address. + bool isBuyerMakerAndSellerTaker = 5; // Whether the BTC buyer created the original offer, or not. + string makerAccountId = 6; // The offer maker's payment account id. + string takerAccountId = 7; // The offer taker's payment account id. + PaymentAccountPayloadInfo makerPaymentAccountPayload = 8; // A summary of the offer maker's payment account. + PaymentAccountPayloadInfo takerPaymentAccountPayload = 9; // A summary of the offer taker's payment account. + string makerPayoutAddressString = 10; // The offer maker's BTC payout address. + string takerPayoutAddressString = 11; // The offer taker's BTC payout address. + uint64 lockTime = 12; // TODO } /* * BSQ Swap protocol specific fields not common to Bisq v1 trade protocol fields. */ message BsqSwapTradeInfo { - string txId = 1; - uint64 bsqTradeAmount = 2; - uint64 btcTradeAmount = 3; - uint64 bsqMakerTradeFee = 4; - uint64 bsqTakerTradeFee = 5; - uint64 txFeePerVbyte = 6; - string makerBsqAddress = 7; - string makerBtcAddress = 8; - string takerBsqAddress = 9; - string takerBtcAddress = 10; - uint64 numConfirmations = 11; - string errorMessage = 12; - uint64 payout = 13; - uint64 swapPeerPayout = 14; + string txId = 1; // The BSQ swap's bitcoin transaction id. + uint64 bsqTradeAmount = 2; // The amount of BSQ swapped in satoshis. + uint64 btcTradeAmount = 3; // The amount of BTC swapped in satoshis. + uint64 bsqMakerTradeFee = 4; // The swap offer maker's BSQ trade fee. + uint64 bsqTakerTradeFee = 5; // The swap offer taker's BSQ trade fee. + uint64 txFeePerVbyte = 6; // The swap transaction's bitcoin transaction id. + string makerBsqAddress = 7; // The swap offer maker's BSQ wallet address. + string makerBtcAddress = 8; // The swap offer maker's BTC wallet address. + string takerBsqAddress = 9; // The swap offer taker's BSQ wallet address. + string takerBtcAddress = 10; // The swap offer taker's BTC wallet address. + uint64 numConfirmations = 11; // The confirmations count for the completed swap's bitcoin transaction. + string errorMessage = 12; // An explanation for a failure to complete the swap. + uint64 payout = 13; // The amount of the user's payout in satoshis. (TODO explanation about miner fee vs trade fee) + uint64 swapPeerPayout = 14; // The amount of the peer's payout in satoshis. (TODO explanation about miner fee vs trade fee) } message PaymentAccountPayloadInfo { - string id = 1; - string paymentMethodId = 2; - string address = 3; + string id = 1; // The unique identifier of the payment account. + string paymentMethodId = 2; // The unique identifier of the payment method. + string address = 3; // The optional altcoin wallet address associated with the (altcoin) payment account. } message TxFeeRateInfo { - bool useCustomTxFeeRate = 1; - uint64 customTxFeeRate = 2; - uint64 feeServiceRate = 3; + bool useCustomTxFeeRate = 1; // Whether the daemon's custom btc transaction fee rate preference is set, or not. + uint64 customTxFeeRate = 2; // The daemon's custom btc transaction fee rate preference, in sats/byte. + uint64 feeServiceRate = 3; // The Bisq network's most recently available btc transaction fee rate, in sats/byte. + // The date of the most recent Bisq network fee rate request as a long: the number of milliseconds that have elapsed since January 1, 1970. uint64 lastFeeServiceRequestTs = 4; - uint64 minFeeServiceRate = 5; + uint64 minFeeServiceRate = 5; // The Bisq network's minimum btc transaction fee rate, in sats/byte. } message TxInfo { - string txId = 1; - uint64 inputSum = 2; - uint64 outputSum = 3; - uint64 fee = 4; - int32 size = 5; - bool isPending = 6; - string memo = 7; + string txId = 1; // The bitcoin transaction id. + uint64 inputSum = 2; // The sum of the bitcoin transactions input values in satoshis. + uint64 outputSum = 3; // The sum of the bitcoin transactions output values in satoshis. + uint64 fee = 4; // The bitcoin transaction's miner fee in satoshis. + int32 size = 5; // The bitcoin transaction's size in bytes. + bool isPending = 6; // Whether the bitcoin transaction has been confirmed at least one time, or not. + string memo = 7; // An optional memo associated with the bitcoin transaction. } /* From fcd9c7e4d30bd868f695e0d86a2876fefcfca617 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Mon, 21 Feb 2022 07:48:02 -0300 Subject: [PATCH 29/41] Finish 1st full pass of documenting grpc.proto for API reference site --- proto/src/main/proto/grpc.proto | 117 ++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 43 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index ea4b2a99eea..4a5840d215e 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -713,7 +713,7 @@ message TxInfo { * an encryption password on a a wallet, and unlocking / locking an encrypted wallet. */ service Wallets { - // Get current BSQ and BTC balances. + // Get the Bisq wallet's current BSQ and BTC balances. rpc GetBalances (GetBalancesRequest) returns (GetBalancesReply) { } // Get BTC balance for a wallet address. @@ -722,95 +722,112 @@ service Wallets { // Get an unused BSQ wallet address. rpc GetUnusedBsqAddress (GetUnusedBsqAddressRequest) returns (GetUnusedBsqAddressReply) { } - // Send BSQ to an address. + // Send an amount of BSQ to an external address. rpc SendBsq (SendBsqRequest) returns (SendBsqReply) { } - // Send BSQ to an address. + // Send an amount of BTC to an external address. rpc SendBtc (SendBtcRequest) returns (SendBtcReply) { } - // Verify a specific amount of BSQ was received by a BSQ wallet address. (TODO change method name?) + // Verify a specific amount of BSQ was received by a BSQ wallet address. + // This is a problematic way of verifying BSQ payment has been received for a v1 trade protocol BSQ-BTC trade, + // which has been solved by the introduction of BSQ swap trades, which use a different, unused BSQ address for each trade. rpc VerifyBsqSentToAddress (VerifyBsqSentToAddressRequest) returns (VerifyBsqSentToAddressReply) { } - // Get most recently available BTC network tx fee, or custom fee rate if set. + // Get the most recently available Bisq network's bitcoin miner transaction fee rate, or custom fee rate if set. rpc GetTxFeeRate (GetTxFeeRateRequest) returns (GetTxFeeRateReply) { } - // Set custom tx fee rate. + // Set the Bisq daemon's custom bitcoin miner transaction fee rate, in sats/byte.. rpc SetTxFeeRatePreference (SetTxFeeRatePreferenceRequest) returns (SetTxFeeRatePreferenceReply) { } - // Remove custom tx fee rate, revert to using BTC network tx fee rate. + // Remove the custom bitcoin miner transaction fee rate; revert to the Bisq network's bitcoin miner transaction fee rate. rpc UnsetTxFeeRatePreference (UnsetTxFeeRatePreferenceRequest) returns (UnsetTxFeeRatePreferenceReply) { } - // Get a BTC tx with a transaction-id. + // Get a bitcoin transaction summary. rpc GetTransaction (GetTransactionRequest) returns (GetTransactionReply) { } - // Get all BTC receiving address in the wallet. + // Get all bitcoin receiving address in the Bisq BTC wallet. rpc GetFundingAddresses (GetFundingAddressesRequest) returns (GetFundingAddressesReply) { } - // Set wallet encryption password. + // Set the Bisq wallet's encryption password for a time period in seconds. An unlocked wallet will automatically + // lock itself after the timeout period has expired, or a LockWallet request has been made, whichever is first. + // An unlocked wallet's timeout setting can be overridden by subsequent SetWalletPassword calls. rpc SetWalletPassword (SetWalletPasswordRequest) returns (SetWalletPasswordReply) { } - // Remove wallet encryption password. + // Remove the encryption password from the Bisq wallet. rpc RemoveWalletPassword (RemoveWalletPasswordRequest) returns (RemoveWalletPasswordReply) { } - // Lock unlocked, encrypted wallet. + // Lock an encrypted Bisq wallet before the UnlockWallet rpc method's timeout period has expired. rpc LockWallet (LockWalletRequest) returns (LockWalletReply) { } - // Unlock encrypted wallet before executing wallet sensitive methods: - // createoffer, takeoffer, getbalances, etc. + // Unlock a Bisq encrypted wallet before calling wallet sensitive rpc methods: CreateOffer, TakeOffer, GetBalances, etc. rpc UnlockWallet (UnlockWalletRequest) returns (UnlockWalletReply) { } } message GetBalancesRequest { - string currencyCode = 1; + string currencyCode = 1; // The Bisq wallet currency (BSQ or BTC) for the balances request. } message GetBalancesReply { - BalancesInfo balances = 1; + BalancesInfo balances = 1; // The summary of Bisq wallet's BSQ and BTC balances. } message GetAddressBalanceRequest { - string address = 1; + string address = 1; // The BTC wallet address being queried. } message GetAddressBalanceReply { - AddressBalanceInfo addressBalanceInfo = 1; + AddressBalanceInfo addressBalanceInfo = 1; // The BTC wallet address with its balance summary. } message GetUnusedBsqAddressRequest { } message GetUnusedBsqAddressReply { - string address = 1; + string address = 1; // The BSQ wallet's unused address. } message SendBsqRequest { + // The external BSQ wallet address. string address = 1; + // The amount being sent to the external BSQ wallet address, as a string in "#######,##" format. string amount = 2; + // An optional bitcoin miner transaction fee rate, in sats/byte. If not defined, Bisq will revert + // to the custom transaction fee rate preference, if set, else the common Bisq network fee rate. string txFeeRate = 3; } message SendBsqReply { + // The summary of a bitcoin transaction. (BSQ is a colored coin, and transacted on the bitcoin blockchain.) TxInfo txInfo = 1; } message SendBtcRequest { + // The external bitcoin address. string address = 1; + // The amount of BTC to send to the external address, as a string in "##.########" (BTC unit) format. string amount = 2; + // An optional bitcoin miner transaction fee rate, in sats/byte. If not defined, Bisq will revert + // to the custom transaction fee rate preference, if set, else the common Bisq network fee rate. string txFeeRate = 3; + // An optional memo associated with the bitcoin transaction. string memo = 4; } message SendBtcReply { - TxInfo txInfo = 1; + TxInfo txInfo = 1; // The summary of a bitcoin transaction. } message VerifyBsqSentToAddressRequest { - string address = 1; - string amount = 2; + string address = 1; // The internal BSQ wallet address. + string amount = 2; // The amount supposedly sent to the BSQ wallet address, as a string in "#######,##" format. } message VerifyBsqSentToAddressReply { + // Whether a specific BSQ wallet address has received a specific amount of BSQ. If the same address has received + // the same amount of BSQ more than once, a true value does not indicate payment has been made for a v1 protocol + // BSQ-BTC trade. This BSQ payment verification problem is solved with BSQ swaps, which use a different BSQ + // address for each swap transaction. bool isAmountReceived = 1; } @@ -818,7 +835,7 @@ message GetTxFeeRateRequest { } message GetTxFeeRateReply { - TxFeeRateInfo txFeeRateInfo = 1; + TxFeeRateInfo txFeeRateInfo = 1; // The summary of the most recently available bitcoin transaction fee rates. } message SetTxFeeRatePreferenceRequest { @@ -826,14 +843,14 @@ message SetTxFeeRatePreferenceRequest { } message SetTxFeeRatePreferenceReply { - TxFeeRateInfo txFeeRateInfo = 1; + TxFeeRateInfo txFeeRateInfo = 1; // The summary of the most recently available bitcoin transaction fee rates. } message UnsetTxFeeRatePreferenceRequest { } message UnsetTxFeeRatePreferenceReply { - TxFeeRateInfo txFeeRateInfo = 1; + TxFeeRateInfo txFeeRateInfo = 1; // The summary of the most recently available bitcoin transaction fee rates. } message GetTransactionRequest { @@ -841,26 +858,26 @@ message GetTransactionRequest { } message GetTransactionReply { - TxInfo txInfo = 1; + TxInfo txInfo = 1; // The summary of a bitcoin transaction. } message GetFundingAddressesRequest { } message GetFundingAddressesReply { - repeated AddressBalanceInfo addressBalanceInfo = 1; + repeated AddressBalanceInfo addressBalanceInfo = 1; // The list of BTC wallet addresses with their balances. } message SetWalletPasswordRequest { - string password = 1; - string newPassword = 2; + string password = 1; // The new password for encrypting an unencrypted Bisq wallet. + string newPassword = 2; // The new password for encrypting an already encrypted Bisq wallet (a password override). } message SetWalletPasswordReply { } message RemoveWalletPasswordRequest { - string password = 1; + string password = 1; // The Bisq wallet's current encryption password. } message RemoveWalletPasswordReply { @@ -873,43 +890,57 @@ message LockWalletReply { } message UnlockWalletRequest { - string password = 1; - uint64 timeout = 2; + string password = 1; // The Bisq wallet's encryption password. + uint64 timeout = 2; // The Bisq wallet unlock time period, in seconds. } message UnlockWalletReply { } -/* Field names are shortened for readability's sake, i.e., -* balancesInfo.getBtc().getAvailableBalance() is cleaner than -* balancesInfo.getBtcBalanceInfo().getAvailableBalance(). -*/ message BalancesInfo { - BsqBalanceInfo bsq = 1; - BtcBalanceInfo btc = 2; + BsqBalanceInfo bsq = 1; // BSQ wallet balance information. + BtcBalanceInfo btc = 2; // BTC wallet balance information. } message BsqBalanceInfo { + // The BSQ amount currently available to send to other addresses at the user's discretion, in satoshis. uint64 availableConfirmedBalance = 1; + // The BSQ amount currently being used in a send transaction, in satoshis. Unverified BSQ balances are not spendable, + // but are often quickly returned to the availableConfirmedBalance as soon as the send transaction has been broadcast. + // (TODO Clarify meaning of unverifiedBalance.) uint64 unverifiedBalance = 2; + // The BSQ transaction change amount tied up in an unconfirmed transaction, remaining unspendable until the change + // is returned to the availableConfirmedBalance. + // (TODO Clarify meaning of unverifiedBalance.) uint64 unconfirmedChangeBalance = 3; + // The locked BSQ amount held by DAO voting transaction. uint64 lockedForVotingBalance = 4; + // The locked BSQ amount held by DAO bonding transaction. uint64 lockupBondsBalance = 5; + // The BSQ amount received during a time-based DAO bonding release transaction. + // (TODO Clarify meaning of unlockingBondsBalance.) uint64 unlockingBondsBalance = 6; } message BtcBalanceInfo { + // The BTC amount currently available to send to other addresses at the user's discretion, in satoshis. uint64 availableBalance = 1; + // The BTC amount currently reserved to cover open offers' security deposits, and BTC sellers' payout amounts, + // in satoshis. Reserved funds are not spendable, but are recoverable by users. When a user cancels an offer + // funds reserved for that offer are returned to the availableBalance. uint64 reservedBalance = 2; + // The sum of availableBalance + reservedBalance, in satoshis. uint64 totalAvailableBalance = 3; + // The BTC amount being locked to cover the security deposits and BTC seller's pending trade payouts. Locked + // funds are not recoverable until a trade is completed, when security deposits are returned to the availableBalance. uint64 lockedBalance = 4; } message AddressBalanceInfo { - string address = 1; - int64 balance = 2; - int64 numConfirmations = 3; - bool isAddressUnused = 4; + string address = 1; // The bitcoin wallet address. + int64 balance = 2; // The address' BTC balance in satoshis. + int64 numConfirmations = 3; // The number of confirmations for the most recent transaction referencing the output address. + bool isAddressUnused = 4; // Whether the bitcoin address has ever been used, or not. } service GetVersion { @@ -922,5 +953,5 @@ message GetVersionRequest { } message GetVersionReply { - string version = 1; + string version = 1; // The version of the Bisq software release. } From 9f013bd6c249575486035e2b88b56c820208e744 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Mon, 21 Feb 2022 08:00:31 -0300 Subject: [PATCH 30/41] Fix errors in comments --- proto/src/main/proto/grpc.proto | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 4a5840d215e..0d0c995a92a 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -699,8 +699,8 @@ message TxFeeRateInfo { message TxInfo { string txId = 1; // The bitcoin transaction id. - uint64 inputSum = 2; // The sum of the bitcoin transactions input values in satoshis. - uint64 outputSum = 3; // The sum of the bitcoin transactions output values in satoshis. + uint64 inputSum = 2; // The sum of the bitcoin transaction's input values in satoshis. + uint64 outputSum = 3; // The sum of the bitcoin transaction's output values in satoshis. uint64 fee = 4; // The bitcoin transaction's miner fee in satoshis. int32 size = 5; // The bitcoin transaction's size in bytes. bool isPending = 6; // Whether the bitcoin transaction has been confirmed at least one time, or not. @@ -733,7 +733,7 @@ service Wallets { // which has been solved by the introduction of BSQ swap trades, which use a different, unused BSQ address for each trade. rpc VerifyBsqSentToAddress (VerifyBsqSentToAddressRequest) returns (VerifyBsqSentToAddressReply) { } - // Get the most recently available Bisq network's bitcoin miner transaction fee rate, or custom fee rate if set. + // Get the Bisq network's most recently available bitcoin miner transaction fee rate, or custom fee rate if set. rpc GetTxFeeRate (GetTxFeeRateRequest) returns (GetTxFeeRateReply) { } // Set the Bisq daemon's custom bitcoin miner transaction fee rate, in sats/byte.. @@ -745,12 +745,10 @@ service Wallets { // Get a bitcoin transaction summary. rpc GetTransaction (GetTransactionRequest) returns (GetTransactionReply) { } - // Get all bitcoin receiving address in the Bisq BTC wallet. + // Get all bitcoin receiving addresses in the Bisq BTC wallet. rpc GetFundingAddresses (GetFundingAddressesRequest) returns (GetFundingAddressesReply) { } - // Set the Bisq wallet's encryption password for a time period in seconds. An unlocked wallet will automatically - // lock itself after the timeout period has expired, or a LockWallet request has been made, whichever is first. - // An unlocked wallet's timeout setting can be overridden by subsequent SetWalletPassword calls. + // Set the Bisq wallet's encryption password. rpc SetWalletPassword (SetWalletPasswordRequest) returns (SetWalletPasswordReply) { } // Remove the encryption password from the Bisq wallet. @@ -759,7 +757,10 @@ service Wallets { // Lock an encrypted Bisq wallet before the UnlockWallet rpc method's timeout period has expired. rpc LockWallet (LockWalletRequest) returns (LockWalletReply) { } - // Unlock a Bisq encrypted wallet before calling wallet sensitive rpc methods: CreateOffer, TakeOffer, GetBalances, etc. + // Unlock a Bisq encrypted wallet before calling wallet sensitive rpc methods: CreateOffer, TakeOffer, GetBalances, + // etc., for a timeout period in seconds. An unlocked wallet will automatically lock itself after the timeout + // period has expired, or a LockWallet request has been made, whichever is first. An unlocked wallet's timeout + // setting can be overridden by subsequent SetWalletPassword calls. rpc UnlockWallet (UnlockWalletRequest) returns (UnlockWalletReply) { } } From 6e566603945a9c65690964bad8a0af2679e64c17 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Mon, 21 Feb 2022 08:09:42 -0300 Subject: [PATCH 31/41] Fix comment error --- proto/src/main/proto/grpc.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 0d0c995a92a..4a1723f6814 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -760,7 +760,7 @@ service Wallets { // Unlock a Bisq encrypted wallet before calling wallet sensitive rpc methods: CreateOffer, TakeOffer, GetBalances, // etc., for a timeout period in seconds. An unlocked wallet will automatically lock itself after the timeout // period has expired, or a LockWallet request has been made, whichever is first. An unlocked wallet's timeout - // setting can be overridden by subsequent SetWalletPassword calls. + // setting can be overridden by subsequent UnlockWallet calls. rpc UnlockWallet (UnlockWalletRequest) returns (UnlockWalletReply) { } } From 464c5a81c99e288b0ae3dde3831a4276150df0e1 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Mon, 21 Feb 2022 08:13:13 -0300 Subject: [PATCH 32/41] Be consistent in use of apostrophe --- proto/src/main/proto/grpc.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 4a1723f6814..1595202ac34 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -892,7 +892,7 @@ message LockWalletReply { message UnlockWalletRequest { string password = 1; // The Bisq wallet's encryption password. - uint64 timeout = 2; // The Bisq wallet unlock time period, in seconds. + uint64 timeout = 2; // The Bisq wallet's unlock time period, in seconds. } message UnlockWalletReply { From 5e754a25a131ddb2d6edc6258e07d2631c902d44 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 24 Feb 2022 08:28:36 -0300 Subject: [PATCH 33/41] Fix comment --- .../java/bisq/apitest/method/offer/CreateXMROffersTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java b/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java index 64d46e279f9..cb9db33a145 100644 --- a/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java +++ b/apitest/src/test/java/bisq/apitest/method/offer/CreateXMROffersTest.java @@ -64,7 +64,7 @@ public void testCreateFixedPriceBuy1BTCFor200KXMROffer() { XMR, 100_000_000L, 75_000_000L, - "0.005", // FIXED PRICE IN BTC (satoshis) FOR 1 XMR + "0.005", // FIXED PRICE IN BTC FOR 1 XMR defaultBuyerSecurityDepositPct.get(), alicesXmrAcct.getId(), MAKER_FEE_CURRENCY_CODE); From 66c04134fcffbc940138c0bc54841c03088a2ce5 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 25 Feb 2022 18:51:07 -0300 Subject: [PATCH 34/41] Check offer exists before trying to take it This was overlooked in tests, but client might use a bad offer-id param. --- .../bisq/daemon/grpc/GrpcTradesService.java | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java index 9331e154cef..904d406e04f 100644 --- a/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java +++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java @@ -20,6 +20,7 @@ import bisq.core.api.CoreApi; import bisq.core.api.model.CanceledTradeInfo; import bisq.core.api.model.TradeInfo; +import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; import bisq.core.trade.model.TradeModel; import bisq.core.trade.model.bisq_v1.Trade; @@ -93,31 +94,37 @@ public void takeOffer(TakeOfferRequest req, responseObserver, exceptionHandler, log); - - if (coreApi.isBsqSwapOffer(req.getOfferId(), false)) { - coreApi.takeBsqSwapOffer(req.getOfferId(), - bsqSwapTrade -> { - var reply = buildTakeOfferReply(bsqSwapTrade); - responseObserver.onNext(reply); - responseObserver.onCompleted(); - }, - errorMessage -> { - if (!errorMessageHandler.isErrorHandled()) - errorMessageHandler.handleErrorMessage(errorMessage); - }); - } else { - coreApi.takeOffer(req.getOfferId(), - req.getPaymentAccountId(), - req.getTakerFeeCurrencyCode(), - trade -> { - var reply = buildTakeOfferReply(trade); - responseObserver.onNext(reply); - responseObserver.onCompleted(); - }, - errorMessage -> { - if (!errorMessageHandler.isErrorHandled()) - errorMessageHandler.handleErrorMessage(errorMessage); - }); + try { + // Make sure the offer exists before trying to take it. + Offer offer = coreApi.getOffer(req.getOfferId()); + + if (offer.isBsqSwapOffer()) { + coreApi.takeBsqSwapOffer(offer.getId(), + bsqSwapTrade -> { + var reply = buildTakeOfferReply(bsqSwapTrade); + responseObserver.onNext(reply); + responseObserver.onCompleted(); + }, + errorMessage -> { + if (!errorMessageHandler.isErrorHandled()) + errorMessageHandler.handleErrorMessage(errorMessage); + }); + } else { + coreApi.takeOffer(offer.getId(), + req.getPaymentAccountId(), + req.getTakerFeeCurrencyCode(), + trade -> { + var reply = buildTakeOfferReply(trade); + responseObserver.onNext(reply); + responseObserver.onCompleted(); + }, + errorMessage -> { + if (!errorMessageHandler.isErrorHandled()) + errorMessageHandler.handleErrorMessage(errorMessage); + }); + } + } catch (Throwable cause) { + exceptionHandler.handleException(log, cause, responseObserver); } } From c0631eb31fd3d189d520b2a9ccc23a2db61203e2 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 25 Feb 2022 20:51:55 -0300 Subject: [PATCH 35/41] Fix file/merge conflict --- proto/src/main/proto/grpc.proto | 2 -- 1 file changed, 2 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index cbe6a4701ac..1595202ac34 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -172,7 +172,6 @@ message GetMyBsqSwapOffersReply { repeated OfferInfo bsqSwapOffers = 1; // The returned list of user's open BSQ swap offers. } -// TODO: Change some numeric fields to string to prevent loss of precision and/or ambiguity. message CreateBsqSwapOfferRequest { // The new BSQ swap offer's BUY (BTC) or SELL (BTC) direction. string direction = 1; @@ -188,7 +187,6 @@ message CreateBsqSwapOfferReply { OfferInfo bsqSwapOffer = 1; // The newly created BSQ swap offer. } -// TODO: Change some numeric fields to string to prevent loss of precision and/or ambiguity. message CreateOfferRequest { // The new offer's fiat or altcoin currency code. string currencyCode = 1; From ab8a3433c36b20b57aa7e15319b7e3f71e5e483b Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 26 Feb 2022 14:27:52 -0300 Subject: [PATCH 36/41] Use a zero fixed-price if useMarketBasedPrice=true The CLI and apitest cases always pass "0", but java & python clients might pass an empty string. This change avoids number formatting & scaling problems when clients pass an empty string in the price parameter. --- core/src/main/java/bisq/core/api/CoreApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java index 1294d2820e5..073d3075dea 100644 --- a/core/src/main/java/bisq/core/api/CoreApi.java +++ b/core/src/main/java/bisq/core/api/CoreApi.java @@ -206,7 +206,7 @@ public void createAndPlaceOffer(String currencyCode, Consumer resultHandler) { coreOffersService.createAndPlaceOffer(currencyCode, directionAsString, - price, + useMarketBasedPrice ? "0" : price, useMarketBasedPrice, marketPriceMargin, amountAsLong, From fcd2bcd34f977140bcc1290a2ec86a0ffbcc18eb Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 26 Feb 2022 15:13:21 -0300 Subject: [PATCH 37/41] Allow editoffer clients to pass empty string for price parameter The client may have passed an empty string for the price parameter, if only enabling or disabling the offer. If so, validate with new price = old price. --- core/src/main/java/bisq/core/api/EditOfferValidator.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/bisq/core/api/EditOfferValidator.java b/core/src/main/java/bisq/core/api/EditOfferValidator.java index 977b7a738e7..f3b90e7f1eb 100644 --- a/core/src/main/java/bisq/core/api/EditOfferValidator.java +++ b/core/src/main/java/bisq/core/api/EditOfferValidator.java @@ -68,7 +68,12 @@ class EditOfferValidator { int newEnable, EditOfferRequest.EditType editType) { this.currentlyOpenOffer = currentlyOpenOffer; - this.newPrice = newPrice; + // The client may have passed an empty string for the price parameter + // if only enabling or disabling the offer. If so, validate with new + // price = old price. + this.newPrice = editType.equals(ACTIVATION_STATE_ONLY) + ? currentlyOpenOffer.getOffer().getPrice().toString() + : newPrice; // The client cannot determine what offer.isUseMarketBasedPrice should be // when editType = ACTIVATION_STATE_ONLY. Override newIsUseMarketBasedPrice // param for the ACTIVATION_STATE_ONLY case. From aa6f5305552647a9b6a0485c537de95eb8d1e1ed Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 26 Feb 2022 15:26:24 -0300 Subject: [PATCH 38/41] Revert "Allow editoffer clients to pass empty string for price parameter" This reverts commit fcd2bcd34f977140bcc1290a2ec86a0ffbcc18eb. --- core/src/main/java/bisq/core/api/EditOfferValidator.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/core/src/main/java/bisq/core/api/EditOfferValidator.java b/core/src/main/java/bisq/core/api/EditOfferValidator.java index f3b90e7f1eb..977b7a738e7 100644 --- a/core/src/main/java/bisq/core/api/EditOfferValidator.java +++ b/core/src/main/java/bisq/core/api/EditOfferValidator.java @@ -68,12 +68,7 @@ class EditOfferValidator { int newEnable, EditOfferRequest.EditType editType) { this.currentlyOpenOffer = currentlyOpenOffer; - // The client may have passed an empty string for the price parameter - // if only enabling or disabling the offer. If so, validate with new - // price = old price. - this.newPrice = editType.equals(ACTIVATION_STATE_ONLY) - ? currentlyOpenOffer.getOffer().getPrice().toString() - : newPrice; + this.newPrice = newPrice; // The client cannot determine what offer.isUseMarketBasedPrice should be // when editType = ACTIVATION_STATE_ONLY. Override newIsUseMarketBasedPrice // param for the ACTIVATION_STATE_ONLY case. From b9040029916e8ff3f0c5e0051d5169f9303c490b Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 26 Feb 2022 17:17:42 -0300 Subject: [PATCH 39/41] Avoid number formatting problems if clients pass empty (default) str params --- core/src/main/java/bisq/core/api/EditOfferValidator.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/bisq/core/api/EditOfferValidator.java b/core/src/main/java/bisq/core/api/EditOfferValidator.java index 977b7a738e7..e6123e14bd8 100644 --- a/core/src/main/java/bisq/core/api/EditOfferValidator.java +++ b/core/src/main/java/bisq/core/api/EditOfferValidator.java @@ -68,7 +68,7 @@ class EditOfferValidator { int newEnable, EditOfferRequest.EditType editType) { this.currentlyOpenOffer = currentlyOpenOffer; - this.newPrice = newPrice; + this.newPrice = newPrice.isBlank() ? "0" : newPrice; // The client cannot determine what offer.isUseMarketBasedPrice should be // when editType = ACTIVATION_STATE_ONLY. Override newIsUseMarketBasedPrice // param for the ACTIVATION_STATE_ONLY case. @@ -78,12 +78,12 @@ class EditOfferValidator { ? currentlyOpenOffer.getOffer().isUseMarketBasedPrice() : newIsUseMarketBasedPrice; this.newMarketPriceMargin = newMarketPriceMargin; - this.newTriggerPrice = newTriggerPrice; + this.newTriggerPrice = newTriggerPrice.isBlank() ? "0" : newTriggerPrice; this.newEnable = newEnable; this.editType = editType; - this.isZeroEditedFixedPriceString = new BigDecimal(newPrice).doubleValue() == 0; - this.isZeroEditedTriggerPrice = new BigDecimal(newTriggerPrice).equals(ZERO); + this.isZeroEditedFixedPriceString = new BigDecimal(this.newPrice).doubleValue() == 0; + this.isZeroEditedTriggerPrice = new BigDecimal(this.newTriggerPrice).equals(ZERO); } EditOfferValidator validate() { From c20f2568d4d1e8ea859772c4233f1be8478d1759 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 26 Feb 2022 17:43:17 -0300 Subject: [PATCH 40/41] Allow clients to pass empty string for minAmount param --- core/src/main/java/bisq/core/api/CoreOffersService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java index aacc59cc2bf..4fdd8495738 100644 --- a/core/src/main/java/bisq/core/api/CoreOffersService.java +++ b/core/src/main/java/bisq/core/api/CoreOffersService.java @@ -259,7 +259,7 @@ void createAndPlaceBsqSwapOffer(String directionAsString, String offerId = getRandomOfferId(); OfferDirection direction = OfferDirection.valueOf(directionAsString.toUpperCase()); Coin amount = Coin.valueOf(amountAsLong); - Coin minAmount = Coin.valueOf(minAmountAsLong); + Coin minAmount = minAmountAsLong == 0 ? amount : Coin.valueOf(minAmountAsLong); Price price = Price.valueOf(currencyCode, priceStringToLong(priceAsString, currencyCode)); openBsqSwapOfferService.requestNewOffer(offerId, direction, @@ -294,7 +294,7 @@ void createAndPlaceOffer(String currencyCode, OfferDirection direction = OfferDirection.valueOf(directionAsString.toUpperCase()); Price price = Price.valueOf(upperCaseCurrencyCode, priceStringToLong(priceAsString, upperCaseCurrencyCode)); Coin amount = Coin.valueOf(amountAsLong); - Coin minAmount = Coin.valueOf(minAmountAsLong); + Coin minAmount = minAmountAsLong == 0 ? amount : Coin.valueOf(minAmountAsLong); Coin useDefaultTxFee = Coin.ZERO; // Almost ready to call createOfferService.createAndGetOffer(), but first: From f14806ea1f377dae49bc27e116ec8bc6d5c4861a Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Sat, 26 Feb 2022 17:43:17 -0300 Subject: [PATCH 41/41] Let minAmount param be optional --- core/src/main/java/bisq/core/api/CoreOffersService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java index aacc59cc2bf..4fdd8495738 100644 --- a/core/src/main/java/bisq/core/api/CoreOffersService.java +++ b/core/src/main/java/bisq/core/api/CoreOffersService.java @@ -259,7 +259,7 @@ void createAndPlaceBsqSwapOffer(String directionAsString, String offerId = getRandomOfferId(); OfferDirection direction = OfferDirection.valueOf(directionAsString.toUpperCase()); Coin amount = Coin.valueOf(amountAsLong); - Coin minAmount = Coin.valueOf(minAmountAsLong); + Coin minAmount = minAmountAsLong == 0 ? amount : Coin.valueOf(minAmountAsLong); Price price = Price.valueOf(currencyCode, priceStringToLong(priceAsString, currencyCode)); openBsqSwapOfferService.requestNewOffer(offerId, direction, @@ -294,7 +294,7 @@ void createAndPlaceOffer(String currencyCode, OfferDirection direction = OfferDirection.valueOf(directionAsString.toUpperCase()); Price price = Price.valueOf(upperCaseCurrencyCode, priceStringToLong(priceAsString, upperCaseCurrencyCode)); Coin amount = Coin.valueOf(amountAsLong); - Coin minAmount = Coin.valueOf(minAmountAsLong); + Coin minAmount = minAmountAsLong == 0 ? amount : Coin.valueOf(minAmountAsLong); Coin useDefaultTxFee = Coin.ZERO; // Almost ready to call createOfferService.createAndGetOffer(), but first: