From 9180ca61f672fe9acdf09e9fe0f1b26dacb378b6 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 8 Jan 2021 11:14:16 -0300 Subject: [PATCH 1/7] Fix two CLI option parsing bugs - Fix bug locating index of method name in String[] args. - Make createoffer method's security-deposit param format consistent with UI's. When creating an offer, the CLI should take "15.0", not "0.15" as a 15% security deposit. This is consistent with the UI, and the CLI's mkt-price-margin input format. --- cli/src/main/java/bisq/cli/CliMain.java | 5 +++-- .../main/java/bisq/cli/CurrencyFormat.java | 11 ++++++++++ .../java/bisq/cli/NegativeNumberOptions.java | 22 +++++++++++++++---- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index 9fc3acbb477..6df23f9b730 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -78,6 +78,7 @@ import static bisq.cli.CurrencyFormat.formatTxFeeRateInfo; import static bisq.cli.CurrencyFormat.toSatoshis; +import static bisq.cli.CurrencyFormat.toSecurityDepositAsPct; import static bisq.cli.NegativeNumberOptions.hasNegativeNumberOptions; import static bisq.cli.TableFormat.*; import static java.lang.String.format; @@ -376,7 +377,7 @@ public static void run(String[] args) { else fixedPrice = nonOptionArgs.get(7); - var securityDeposit = new BigDecimal(nonOptionArgs.get(8)); + var securityDeposit = toSecurityDepositAsPct(nonOptionArgs.get(8)); var makerFeeCurrencyCode = nonOptionArgs.size() == 10 ? nonOptionArgs.get(9) : "btc"; @@ -389,7 +390,7 @@ public static void run(String[] args) { .setUseMarketBasedPrice(useMarketBasedPrice) .setPrice(fixedPrice) .setMarketPriceMargin(marketPriceMargin.doubleValue()) - .setBuyerSecurityDeposit(securityDeposit.doubleValue()) + .setBuyerSecurityDeposit(securityDeposit) .setPaymentAccountId(paymentAcctId) .setMakerFeeCurrencyCode(makerFeeCurrencyCode) .build(); diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java index 515c5fba127..c5ea5a497b0 100644 --- a/cli/src/main/java/bisq/cli/CurrencyFormat.java +++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java @@ -43,6 +43,8 @@ public class CurrencyFormat { static final BigDecimal BSQ_SATOSHI_DIVISOR = new BigDecimal(100); static final DecimalFormat BSQ_FORMAT = new DecimalFormat("###,###,###,##0.00"); + static final BigDecimal SECURITY_DEPOSIT_MULTIPLICAND = new BigDecimal("0.01"); + @SuppressWarnings("BigDecimalMethodWithoutRoundingCalled") public static String formatSatoshis(long sats) { return BTC_FORMAT.format(BigDecimal.valueOf(sats).divide(SATOSHI_DIVISOR)); @@ -99,6 +101,15 @@ static long toSatoshis(String btc) { } } + 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)); + } + } + @SuppressWarnings("BigDecimalMethodWithoutRoundingCalled") private static String formatFeeSatoshis(long sats) { return BTC_TX_FEE_FORMAT.format(BigDecimal.valueOf(sats).divide(SATOSHI_DIVISOR)); diff --git a/cli/src/main/java/bisq/cli/NegativeNumberOptions.java b/cli/src/main/java/bisq/cli/NegativeNumberOptions.java index a152b6e327e..6623f9ad150 100644 --- a/cli/src/main/java/bisq/cli/NegativeNumberOptions.java +++ b/cli/src/main/java/bisq/cli/NegativeNumberOptions.java @@ -27,6 +27,7 @@ import java.util.function.Predicate; import static java.util.Arrays.stream; +import static java.util.stream.IntStream.range; class NegativeNumberOptions { @@ -35,13 +36,13 @@ class NegativeNumberOptions { String[] removeNegativeNumberOptions(String[] args) { // Cache any negative number params that will be rejected by the parser. // This should be called before command line parsing. - for (int i = 1; i < args.length; i++) { - // Start at i=1; args[0] is the method name. + int skipped = getIndexOfMethodInArgs(args); + for (int i = skipped; i < args.length; i++) { if (isNegativeNumber.test(args[i])) { String param = args[i]; - negativeNumberParams.put(i - 1, new BigDecimal(param).toString()); + negativeNumberParams.put(i - skipped, new BigDecimal(param).toString()); // Substitute a zero placeholder at the index containing the - // negative number option value. + // negative number positional option value. args[i] = "0"; } } @@ -80,4 +81,17 @@ static boolean hasNegativeNumberOptions(String[] args) { } return false; }; + + private int getIndexOfMethodInArgs(String[] args) { + // The first argument that does not start with '-' or '--' is the method name. + // Skip over the --password=xyz [--host=s --port=n] options. + int skipped = range(0, args.length) + .filter(i -> !args[i].startsWith("-")) + .findFirst() + .orElse(-1); + if (skipped >= 0) + return skipped; + else + throw new IllegalArgumentException("required --password option not found"); + } } From cc0855497e387d1b4341b1c2c3a320a395d7328b Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 8 Jan 2021 12:51:48 -0300 Subject: [PATCH 2/7] Add @Singleton annotation --- core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java | 2 ++ .../main/java/bisq/core/api/CorePaymentAccountsService.java | 2 ++ core/src/main/java/bisq/core/api/CorePriceService.java | 3 ++- core/src/main/java/bisq/core/api/CoreWalletsService.java | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java b/core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java index 725044c21e7..7b060834a93 100644 --- a/core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java +++ b/core/src/main/java/bisq/core/api/CoreDisputeAgentsService.java @@ -32,6 +32,7 @@ import org.bitcoinj.core.ECKey; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Date; import java.util.List; @@ -49,6 +50,7 @@ import static java.net.InetAddress.getLoopbackAddress; import static java.util.Arrays.asList; +@Singleton @Slf4j class CoreDisputeAgentsService { diff --git a/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java b/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java index d3084363de9..095bf2d1f2d 100644 --- a/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java +++ b/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java @@ -24,6 +24,7 @@ import bisq.core.user.User; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; @@ -34,6 +35,7 @@ import lombok.extern.slf4j.Slf4j; +@Singleton @Slf4j class CorePaymentAccountsService { diff --git a/core/src/main/java/bisq/core/api/CorePriceService.java b/core/src/main/java/bisq/core/api/CorePriceService.java index b8a32e73596..9eb4069dfe9 100644 --- a/core/src/main/java/bisq/core/api/CorePriceService.java +++ b/core/src/main/java/bisq/core/api/CorePriceService.java @@ -21,6 +21,7 @@ import bisq.core.provider.price.PriceFeedService; import javax.inject.Inject; +import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @@ -28,7 +29,7 @@ import static java.lang.String.format; import static java.util.Objects.requireNonNull; - +@Singleton @Slf4j class CorePriceService { diff --git a/core/src/main/java/bisq/core/api/CoreWalletsService.java b/core/src/main/java/bisq/core/api/CoreWalletsService.java index c107259ff98..0ef5a22d2fd 100644 --- a/core/src/main/java/bisq/core/api/CoreWalletsService.java +++ b/core/src/main/java/bisq/core/api/CoreWalletsService.java @@ -56,6 +56,7 @@ import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Singleton; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -83,6 +84,7 @@ import static java.lang.String.format; import static java.util.concurrent.TimeUnit.SECONDS; +@Singleton @Slf4j class CoreWalletsService { From 9ae1a29f23c2571b83ccd4ecaeb945d651ce9c19 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 8 Jan 2021 13:22:01 -0300 Subject: [PATCH 3/7] Integrate new protection tools into api's offer & trade services - Injected OfferFilter into CoreOffersService and CoreTradesService. The filter constrains 'getoffer(s)' results to offers an api user can take, as the first part of ongoing protection tools / api integration. - Created a new CoreContext singleton. Initially, lets Core*Services know if the user is using the api -- isApiUser=true if the current thread's name is "BisqDaemonMain" or the name contains "grpc". We do this anticipating future :desktop dependencies on the core api, and we don't pass hardcoded isApiUser=true params to lower level domain objects. We cannot check BisqDaemonMain.class.getSimpleName() because :core cannot have a circular dependency on :daemon, but there is probably a better way to do this than depending on the thread name set in BisqDaemonMain#configUserThread(). - Added @Singleton annotation to all Core*Service classes. --- .../main/java/bisq/core/api/CoreContext.java | 39 +++++++++++++++++++ .../java/bisq/core/api/CoreOffersService.java | 13 ++++++- .../java/bisq/core/api/CoreTradesService.java | 9 ++++- 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/bisq/core/api/CoreContext.java diff --git a/core/src/main/java/bisq/core/api/CoreContext.java b/core/src/main/java/bisq/core/api/CoreContext.java new file mode 100644 index 00000000000..6b958b2b831 --- /dev/null +++ b/core/src/main/java/bisq/core/api/CoreContext.java @@ -0,0 +1,39 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.api; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import lombok.extern.slf4j.Slf4j; + +import static java.lang.Thread.currentThread; + +@Singleton +@Slf4j +class CoreContext { + + @Inject + public CoreContext() { + } + + public boolean isApiUser() { + String threadName = currentThread().getName(); + return threadName.equals("BisqDaemonMain") || threadName.contains("grpc"); + } +} diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java index cba594362db..01ceb129502 100644 --- a/core/src/main/java/bisq/core/api/CoreOffersService.java +++ b/core/src/main/java/bisq/core/api/CoreOffersService.java @@ -22,6 +22,7 @@ import bisq.core.offer.CreateOfferService; import bisq.core.offer.Offer; import bisq.core.offer.OfferBookService; +import bisq.core.offer.OfferFilter; import bisq.core.offer.OfferUtil; import bisq.core.offer.OpenOfferManager; import bisq.core.payment.PaymentAccount; @@ -34,6 +35,7 @@ import org.bitcoinj.utils.Fiat; import javax.inject.Inject; +import javax.inject.Singleton; import java.math.BigDecimal; @@ -54,6 +56,7 @@ import static java.lang.String.format; import static java.util.Comparator.comparing; +@Singleton @Slf4j class CoreOffersService { @@ -63,28 +66,35 @@ class CoreOffersService { private final KeyRing keyRing; private final CreateOfferService createOfferService; private final OfferBookService offerBookService; + private final OfferFilter offerFilter; private final OpenOfferManager openOfferManager; private final OfferUtil offerUtil; private final User user; + private final boolean isApiUser; @Inject - public CoreOffersService(KeyRing keyRing, + public CoreOffersService(CoreContext coreContext, + KeyRing keyRing, CreateOfferService createOfferService, OfferBookService offerBookService, + OfferFilter offerFilter, OpenOfferManager openOfferManager, OfferUtil offerUtil, User user) { this.keyRing = keyRing; this.createOfferService = createOfferService; this.offerBookService = offerBookService; + this.offerFilter = offerFilter; this.openOfferManager = openOfferManager; this.offerUtil = offerUtil; this.user = user; + this.isApiUser = coreContext.isApiUser(); } Offer getOffer(String id) { return offerBookService.getOffers().stream() .filter(o -> o.getId().equals(id)) + .filter(o -> offerFilter.canTakeOffer(o, isApiUser).isValid()) .findAny().orElseThrow(() -> new IllegalStateException(format("offer with id '%s' not found", id))); } @@ -100,6 +110,7 @@ Offer getMyOffer(String id) { List getOffers(String direction, String currencyCode) { return offerBookService.getOffers().stream() .filter(o -> offerMatchesDirectionAndCurrency(o, direction, currencyCode)) + .filter(o -> offerFilter.canTakeOffer(o, isApiUser).isValid()) .sorted(priceComparator(direction)) .collect(Collectors.toList()); } diff --git a/core/src/main/java/bisq/core/api/CoreTradesService.java b/core/src/main/java/bisq/core/api/CoreTradesService.java index b15ad6f48b8..83fc421bbf6 100644 --- a/core/src/main/java/bisq/core/api/CoreTradesService.java +++ b/core/src/main/java/bisq/core/api/CoreTradesService.java @@ -35,6 +35,7 @@ import org.bitcoinj.core.Coin; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Optional; import java.util.function.Consumer; @@ -44,6 +45,7 @@ import static bisq.core.btc.model.AddressEntry.Context.TRADE_PAYOUT; import static java.lang.String.format; +@Singleton @Slf4j class CoreTradesService { @@ -59,9 +61,11 @@ class CoreTradesService { private final TradeManager tradeManager; private final TradeUtil tradeUtil; private final User user; + private final boolean isApiUser; @Inject - public CoreTradesService(CoreWalletsService coreWalletsService, + public CoreTradesService(CoreContext coreContext, + CoreWalletsService coreWalletsService, BtcWalletService btcWalletService, OfferUtil offerUtil, ClosedTradableManager closedTradableManager, @@ -77,6 +81,7 @@ public CoreTradesService(CoreWalletsService coreWalletsService, this.tradeManager = tradeManager; this.tradeUtil = tradeUtil; this.user = user; + this.isApiUser = coreContext.isApiUser(); } void takeOffer(Offer offer, @@ -108,7 +113,7 @@ void takeOffer(Offer offer, offer, paymentAccountId, useSavingsWallet, - true, + isApiUser, resultHandler::accept, errorMessage -> { log.error(errorMessage); From 0c6005ed2dd0858b4bb7f09016223b3d52375058 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Mon, 11 Jan 2021 14:36:51 -0300 Subject: [PATCH 4/7] Stub out support for OpenOffer's triggerPrice in api This is a feature that will not be included in api v1, but partial support is added in this change to the server. CLI will pass a default triggerPrice of 0 (unused) with the createoffer command. When fully implemented, an optional trigger-price param will be added to the CLI's createoffer method, and the value will only be visible to offer owners. New enableoffer and disableoffer methods will also need to be added. --- cli/src/main/java/bisq/cli/CliMain.java | 1 + core/src/main/java/bisq/core/api/CoreApi.java | 7 ++++++ .../java/bisq/core/api/CoreOffersService.java | 14 +++++++++-- .../java/bisq/core/api/model/OfferInfo.java | 25 ++++++++++++++++--- .../bisq/daemon/grpc/GrpcOffersService.java | 5 +++- proto/src/main/proto/grpc.proto | 22 ++++++++-------- 6 files changed, 58 insertions(+), 16 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index 6df23f9b730..1105f7ea872 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -391,6 +391,7 @@ public static void run(String[] args) { .setPrice(fixedPrice) .setMarketPriceMargin(marketPriceMargin.doubleValue()) .setBuyerSecurityDeposit(securityDeposit) + .setTriggerPrice(0) // TODO Support optional trigger price. .setPaymentAccountId(paymentAcctId) .setMakerFeeCurrencyCode(makerFeeCurrencyCode) .build(); diff --git a/core/src/main/java/bisq/core/api/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java index 6c57f20c7f1..bbd12b7ccbd 100644 --- a/core/src/main/java/bisq/core/api/CoreApi.java +++ b/core/src/main/java/bisq/core/api/CoreApi.java @@ -24,6 +24,7 @@ import bisq.core.monetary.Price; import bisq.core.offer.Offer; import bisq.core.offer.OfferPayload; +import bisq.core.offer.OpenOffer; import bisq.core.payment.PaymentAccount; import bisq.core.payment.payload.PaymentMethod; import bisq.core.trade.Trade; @@ -120,6 +121,10 @@ public List getMyOffers(String direction, String currencyCode) { return coreOffersService.getMyOffers(direction, currencyCode); } + public OpenOffer getMyOpenOffer(String id) { + return coreOffersService.getMyOpenOffer(id); + } + public void createAnPlaceOffer(String currencyCode, String directionAsString, String priceAsString, @@ -128,6 +133,7 @@ public void createAnPlaceOffer(String currencyCode, long amountAsLong, long minAmountAsLong, double buyerSecurityDeposit, + long triggerPrice, String paymentAccountId, String makerFeeCurrencyCode, Consumer resultHandler) { @@ -139,6 +145,7 @@ public void createAnPlaceOffer(String currencyCode, amountAsLong, minAmountAsLong, buyerSecurityDeposit, + triggerPrice, paymentAccountId, makerFeeCurrencyCode, resultHandler); diff --git a/core/src/main/java/bisq/core/api/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java index 01ceb129502..455cb398c86 100644 --- a/core/src/main/java/bisq/core/api/CoreOffersService.java +++ b/core/src/main/java/bisq/core/api/CoreOffersService.java @@ -24,6 +24,7 @@ import bisq.core.offer.OfferBookService; import bisq.core.offer.OfferFilter; import bisq.core.offer.OfferUtil; +import bisq.core.offer.OpenOffer; import bisq.core.offer.OpenOfferManager; import bisq.core.payment.PaymentAccount; import bisq.core.user.User; @@ -123,6 +124,13 @@ List getMyOffers(String direction, String currencyCode) { .collect(Collectors.toList()); } + OpenOffer getMyOpenOffer(String id) { + return openOfferManager.getOpenOfferById(id) + .filter(open -> open.getOffer().isMyOffer(keyRing)) + .orElseThrow(() -> + new IllegalStateException(format("openoffer with id '%s' not found", id))); + } + // Create and place new offer. void createAndPlaceOffer(String currencyCode, String directionAsString, @@ -132,6 +140,7 @@ void createAndPlaceOffer(String currencyCode, long amountAsLong, long minAmountAsLong, double buyerSecurityDeposit, + long triggerPrice, String paymentAccountId, String makerFeeCurrencyCode, Consumer resultHandler) { @@ -163,6 +172,7 @@ void createAndPlaceOffer(String currencyCode, //noinspection ConstantConditions placeOffer(offer, buyerSecurityDeposit, + triggerPrice, useSavingsWallet, transaction -> resultHandler.accept(offer)); } @@ -204,13 +214,13 @@ void cancelOffer(String id) { private void placeOffer(Offer offer, double buyerSecurityDeposit, + long triggerPrice, boolean useSavingsWallet, Consumer resultHandler) { - // TODO add support for triggerPrice parameter. If value is 0 it is interpreted as not used. Its an optional value openOfferManager.placeOffer(offer, buyerSecurityDeposit, useSavingsWallet, - 0, + triggerPrice, resultHandler::accept, log::error); 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 dd3b4859ddd..2314cb43086 100644 --- a/core/src/main/java/bisq/core/api/model/OfferInfo.java +++ b/core/src/main/java/bisq/core/api/model/OfferInfo.java @@ -46,8 +46,9 @@ public class OfferInfo implements Payload { private final long volume; private final long minVolume; private final long buyerSecurityDeposit; + private final long triggerPrice; private final boolean isCurrencyForMakerFeeBtc; - private final String paymentAccountId; // only used when creating offer + private final String paymentAccountId; private final String paymentMethodId; private final String paymentMethodShortName; // For fiat offer the baseCurrencyCode is BTC and the counterCurrencyCode is the fiat currency @@ -68,6 +69,7 @@ public OfferInfo(OfferInfoBuilder builder) { this.volume = builder.volume; this.minVolume = builder.minVolume; this.buyerSecurityDeposit = builder.buyerSecurityDeposit; + this.triggerPrice = builder.triggerPrice; this.isCurrencyForMakerFeeBtc = builder.isCurrencyForMakerFeeBtc; this.paymentAccountId = builder.paymentAccountId; this.paymentMethodId = builder.paymentMethodId; @@ -79,6 +81,16 @@ public OfferInfo(OfferInfoBuilder builder) { } public static OfferInfo toOfferInfo(Offer offer) { + return getOfferInfoBuilder(offer).build(); + } + + public static OfferInfo toOfferInfo(Offer offer, long triggerPrice) { + // The Offer does not have a triggerPrice attribute, so we get + // the base OfferInfoBuilder, then add the OpenOffer's triggerPrice. + return getOfferInfoBuilder(offer).withTriggerPrice(triggerPrice).build(); + } + + private static OfferInfo.OfferInfoBuilder getOfferInfoBuilder(Offer offer) { return new OfferInfo.OfferInfoBuilder() .withId(offer.getId()) .withDirection(offer.getDirection().name()) @@ -97,8 +109,7 @@ public static OfferInfo toOfferInfo(Offer offer) { .withBaseCurrencyCode(offer.getOfferPayload().getBaseCurrencyCode()) .withCounterCurrencyCode(offer.getOfferPayload().getCounterCurrencyCode()) .withDate(offer.getDate().getTime()) - .withState(offer.getState().name()) - .build(); + .withState(offer.getState().name()); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -118,6 +129,7 @@ public bisq.proto.grpc.OfferInfo toProtoMessage() { .setVolume(volume) .setMinVolume(minVolume) .setBuyerSecurityDeposit(buyerSecurityDeposit) + .setTriggerPrice(triggerPrice) .setIsCurrencyForMakerFeeBtc(isCurrencyForMakerFeeBtc) .setPaymentAccountId(paymentAccountId) .setPaymentMethodId(paymentMethodId) @@ -142,6 +154,7 @@ public static OfferInfo fromProto(bisq.proto.grpc.OfferInfo proto) { .withVolume(proto.getVolume()) .withMinVolume(proto.getMinVolume()) .withBuyerSecurityDeposit(proto.getBuyerSecurityDeposit()) + .withTriggerPrice(proto.getTriggerPrice()) .withIsCurrencyForMakerFeeBtc(proto.getIsCurrencyForMakerFeeBtc()) .withPaymentAccountId(proto.getPaymentAccountId()) .withPaymentMethodId(proto.getPaymentMethodId()) @@ -170,6 +183,7 @@ public static class OfferInfoBuilder { private long volume; private long minVolume; private long buyerSecurityDeposit; + private long triggerPrice; private boolean isCurrencyForMakerFeeBtc; private String paymentAccountId; private String paymentMethodId; @@ -229,6 +243,11 @@ public OfferInfoBuilder withBuyerSecurityDeposit(long buyerSecurityDeposit) { return this; } + public OfferInfoBuilder withTriggerPrice(long triggerPrice) { + this.triggerPrice = triggerPrice; + return this; + } + public OfferInfoBuilder withIsCurrencyForMakerFeeBtc(boolean isCurrencyForMakerFeeBtc) { this.isCurrencyForMakerFeeBtc = isCurrencyForMakerFeeBtc; return this; diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java index e92d05863f1..a0bef9ee3b3 100644 --- a/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java +++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java @@ -20,6 +20,7 @@ import bisq.core.api.CoreApi; import bisq.core.api.model.OfferInfo; import bisq.core.offer.Offer; +import bisq.core.offer.OpenOffer; import bisq.proto.grpc.CancelOfferReply; import bisq.proto.grpc.CancelOfferRequest; @@ -78,8 +79,9 @@ public void getMyOffer(GetMyOfferRequest req, StreamObserver responseObserver) { try { Offer offer = coreApi.getMyOffer(req.getId()); + OpenOffer openOffer = coreApi.getMyOpenOffer(req.getId()); var reply = GetMyOfferReply.newBuilder() - .setOffer(toOfferInfo(offer).toProtoMessage()) + .setOffer(toOfferInfo(offer, openOffer.getTriggerPrice()).toProtoMessage()) .build(); responseObserver.onNext(reply); responseObserver.onCompleted(); @@ -139,6 +141,7 @@ public void createOffer(CreateOfferRequest req, req.getAmount(), req.getMinAmount(), req.getBuyerSecurityDeposit(), + req.getTriggerPrice(), req.getPaymentAccountId(), req.getMakerFeeCurrencyCode(), offer -> { diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index b2532d8b48a..3ac2ea4bf61 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -102,8 +102,9 @@ message CreateOfferRequest { uint64 amount = 6; uint64 minAmount = 7; double buyerSecurityDeposit = 8; - string paymentAccountId = 9; - string makerFeeCurrencyCode = 10; + uint64 triggerPrice = 9; + string paymentAccountId = 10; + string makerFeeCurrencyCode = 11; } message CreateOfferReply { @@ -128,14 +129,15 @@ message OfferInfo { uint64 volume = 8; uint64 minVolume = 9; uint64 buyerSecurityDeposit = 10; - bool isCurrencyForMakerFeeBtc = 11; - string paymentAccountId = 12; - string paymentMethodId = 13; - string paymentMethodShortName = 14; - string baseCurrencyCode = 15; - string counterCurrencyCode = 16; - uint64 date = 17; - string state = 18; + uint64 triggerPrice = 11; + bool isCurrencyForMakerFeeBtc = 12; + string paymentAccountId = 13; + string paymentMethodId = 14; + string paymentMethodShortName = 15; + string baseCurrencyCode = 16; + string counterCurrencyCode = 17; + uint64 date = 18; + string state = 19; } /////////////////////////////////////////////////////////////////////////////////////////// From f1a6783c15d75b3c9f5f00044f5d1d26cf5f53ed Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Mon, 11 Jan 2021 14:56:47 -0300 Subject: [PATCH 5/7] Display fiat ccy code in upper case --- cli/src/main/java/bisq/cli/TableFormat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main/java/bisq/cli/TableFormat.java b/cli/src/main/java/bisq/cli/TableFormat.java index a23b7a022d8..1323bf2dc20 100644 --- a/cli/src/main/java/bisq/cli/TableFormat.java +++ b/cli/src/main/java/bisq/cli/TableFormat.java @@ -125,7 +125,7 @@ static String formatOfferTable(List offerInfo, String fiatCurrency) { + 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, fiatCurrency, fiatCurrency); + String headerLine = format(headersFormat, fiatCurrency.toUpperCase(), fiatCurrency.toUpperCase()); String colDataFormat = "%-" + (COL_HEADER_DIRECTION.length() + COL_HEADER_DELIMITER.length()) + "s" // left + "%" + (COL_HEADER_PRICE.length() - 1) + "s" // rt justify to end of hdr From 9a4e3111930c4007a6cd0d4b4087a1e51f8dede9 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Wed, 13 Jan 2021 09:31:34 -0300 Subject: [PATCH 6/7] Fix file conflict The createoffer trigger price was defined as the 0 default value in the gRPC request object (causing the file conflict with the main branch). This line can be removed because a protobuf long's default value is 0. --- cli/src/main/java/bisq/cli/CliMain.java | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index 1105f7ea872..6df23f9b730 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -391,7 +391,6 @@ public static void run(String[] args) { .setPrice(fixedPrice) .setMarketPriceMargin(marketPriceMargin.doubleValue()) .setBuyerSecurityDeposit(securityDeposit) - .setTriggerPrice(0) // TODO Support optional trigger price. .setPaymentAccountId(paymentAcctId) .setMakerFeeCurrencyCode(makerFeeCurrencyCode) .build(); From 0e779a4bf63e66778630dc179a83df747087085d Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Wed, 13 Jan 2021 19:55:49 -0300 Subject: [PATCH 7/7] Inject CoreContext into server, then set isApiUser=true Do not set isApiUser=true based on hardcoded thread name ;-( For requested change https://github.com/bisq-network/bisq/pull/5065#pullrequestreview-567708569 --- core/src/main/java/bisq/core/api/CoreContext.java | 15 +++++++-------- .../main/java/bisq/daemon/grpc/GrpcServer.java | 6 +++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/bisq/core/api/CoreContext.java b/core/src/main/java/bisq/core/api/CoreContext.java index 6b958b2b831..dece76bc063 100644 --- a/core/src/main/java/bisq/core/api/CoreContext.java +++ b/core/src/main/java/bisq/core/api/CoreContext.java @@ -20,20 +20,19 @@ import javax.inject.Inject; import javax.inject.Singleton; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import static java.lang.Thread.currentThread; - @Singleton @Slf4j -class CoreContext { +public class CoreContext { + + @Getter + @Setter + private boolean isApiUser; @Inject public CoreContext() { } - - public boolean isApiUser() { - String threadName = currentThread().getName(); - return threadName.equals("BisqDaemonMain") || threadName.contains("grpc"); - } } diff --git a/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java index b72f0eafe08..589645d77dd 100644 --- a/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java +++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java @@ -17,6 +17,8 @@ package bisq.daemon.grpc; +import bisq.core.api.CoreContext; + import bisq.common.UserThread; import bisq.common.config.Config; @@ -44,7 +46,8 @@ public class GrpcServer { private final Server server; @Inject - public GrpcServer(Config config, + public GrpcServer(CoreContext coreContext, + Config config, PasswordAuthInterceptor passwordAuthInterceptor, GrpcDisputeAgentsService disputeAgentsService, GrpcOffersService offersService, @@ -66,6 +69,7 @@ public GrpcServer(Config config, .addService(walletsService) .intercept(passwordAuthInterceptor) .build(); + coreContext.setApiUser(true); } public void start() {