From 6f1057a7660f82c9c99c17f923a0d01b2036b69e Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 13:28:14 -0300 Subject: [PATCH 01/30] Include unmerged API NPE fix to FeeService class (see PR #6052) --- core/src/main/java/bisq/core/provider/fee/FeeService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/bisq/core/provider/fee/FeeService.java b/core/src/main/java/bisq/core/provider/fee/FeeService.java index e118d5f602f..ccb1da9670b 100644 --- a/core/src/main/java/bisq/core/provider/fee/FeeService.java +++ b/core/src/main/java/bisq/core/provider/fee/FeeService.java @@ -82,7 +82,7 @@ private static Coin getFeeFromParamAsCoin(Param param) { private static Coin getFilterFromParamAsCoin(Param param) { Coin filterVal = Coin.ZERO; - if (filterManager != null) { + if (filterManager != null && filterManager.getFilter() != null) { if (param == Param.DEFAULT_MAKER_FEE_BTC) { filterVal = Coin.valueOf(filterManager.getFilter().getMakerFeeBtc()); } else if (param == Param.DEFAULT_TAKER_FEE_BTC) { From 4596960191e5db3d61c20b36b8871d8a8a0e1a53 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 13:31:17 -0300 Subject: [PATCH 02/30] Prepare API Offers .proto defs for significant changes This commit adds comments to grpc.proto to be pulled into a new API reference doc. Some of the comments highlight issues to be resolved in following PRs. The main focus is on documenting gRPC Offers service definitions in grpc.proto: - Comment each field in the Offers service's messages. - Add TODO comments about fixing field defs with usability & consistency problems. Other API reference doc related changes to grpc.proto: - Comment each gRPC service's rpc method definitions, however briefly. - Improve some existing rpc method comments. --- proto/src/main/proto/grpc.proto | 224 ++++++++++++++++++++++---------- 1 file changed, 153 insertions(+), 71 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index b5530a890a2..0d4b0efc45d 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -22,79 +22,75 @@ option java_package = "bisq.proto.grpc"; option java_multiple_files = true; /* -* DisputeAgents service is provided for development, and can only be used when running in regtest mode. +* The DisputeAgents service is provided for development only; it can only be used when running in regtest mode. */ service DisputeAgents { - // Register regtest / dev mode dispute agents. Does not work if running on mainnet. + // Register regtest / dev mode dispute agents. Does not work when running on mainnet. rpc RegisterDisputeAgent (RegisterDisputeAgentRequest) returns (RegisterDisputeAgentReply) { } } -/* -* Register a dispute agent using a registration key. -*/ message RegisterDisputeAgentRequest { + // One of "mediator" or "refundagent". Development / test arbitrators can only be registered in the UI. string disputeAgentType = 1; + // Private developer (only) registration key. string registrationKey = 2; } message RegisterDisputeAgentReply { } - -/* -* CLI command help service. -*/ service Help { - // Returns CLI command help in man page format. + // Returns a CLI command man page. rpc GetMethodHelp (GetMethodHelpRequest) returns (GetMethodHelpReply) { } } message GetMethodHelpRequest { - string methodName = 1; + string methodName = 1; // CLI command name. } message GetMethodHelpReply { - string methodHelp = 1; + string methodHelp = 1; // Man page for CLI command. } - /* -* Offers service provides rpc methods for creating, editing, listing, and cancelling Bisq offers. +* The Offers service provides rpc methods for creating, editing, listing, and cancelling Bisq offers. */ service Offers { - // Get offer category, one of FIAT, ALTCOIN, or BSQ_SWAP. + // Get an offer's category, one of FIAT, ALTCOIN, or BSQ_SWAP. This information is needed before an offer + // can be taken, and is used by a client to determine what kind of offer to take: a v1 FIAT or ALTCOIN offer, + // or a BSQ swap offer. V1 and BSQ swap trades are handled differently in the API daemon. rpc GetOfferCategory (GetOfferCategoryRequest) returns (GetOfferCategoryReply) { } - // Get available BSQ swap offer with offer-id. + // Get the available BSQ swap offer with offer-id. rpc GetBsqSwapOffer (GetOfferRequest) returns (GetBsqSwapOfferReply) { } - // Get version 1 protocol offer with offer-id. + // Get the v1 protocol offer with offer-id. rpc GetOffer (GetOfferRequest) returns (GetOfferReply) { } - // Get my BSQ swap offer with offer-id. + // Get user's BSQ swap offer with offer-id. rpc GetMyBsqSwapOffer (GetMyOfferRequest) returns (GetMyBsqSwapOfferReply) { } - // Get my open version 1 protocol offer with offer-id. Deprecated since 27-Dec-2021 (v1.8.0). + // Get my open v1 protocol offer with offer-id. Deprecated since 27-Dec-2021 (v1.8.0). Use GetOffer. rpc GetMyOffer (GetMyOfferRequest) returns (GetMyOfferReply) { } - // Get available BSQ swap offers with direction BUY or SELL. + // Get all available BSQ swap offers with a BUY (BTC) or SELL (BTC) direction. rpc GetBsqSwapOffers (GetBsqSwapOffersRequest) returns (GetBsqSwapOffersReply) { } - // Get available version 1 protocol offers with direction BUY or SELL. + // Get all available v1 protocol offers with a BUY (BTC) or SELL (BTC) direction. rpc GetOffers (GetOffersRequest) returns (GetOffersReply) { } - // Get my BSQ swap offers with direction BUY or SELL. + // Get all user's BSQ swap offers with a BUY (BTC) or SELL (BTC) direction. rpc GetMyBsqSwapOffers (GetBsqSwapOffersRequest) returns (GetMyBsqSwapOffersReply) { } - // Get my open version 1 protocol offers with direction BUY or SELL. + // Get all user's open v1 protocol offers with a BUY (BTC) or SELL (BTC) direction. rpc GetMyOffers (GetMyOffersRequest) returns (GetMyOffersReply) { } // Create a BSQ swap offer. rpc CreateBsqSwapOffer (CreateBsqSwapOfferRequest) returns (CreateBsqSwapOfferReply) { } - // Create a version 1 protocol offer. + // Create a v1 protocol offer. rpc CreateOffer (CreateOfferRequest) returns (CreateOfferReply) { } // Edit an open offer. @@ -106,8 +102,8 @@ service Offers { } message GetOfferCategoryRequest { - string id = 1; - bool isMyOffer = 2; + string id = 1; // The offer's unique identifier. + bool isMyOffer = 2; // Whether the offer was created by the user or not. } message GetOfferCategoryReply { @@ -121,113 +117,154 @@ message GetOfferCategoryReply { } message GetBsqSwapOfferReply { - OfferInfo bsqSwapOffer = 1; + OfferInfo bsqSwapOffer = 1; // The returned BSQ swap offer. } message GetOfferRequest { - string id = 1; + string id = 1; // The offer's unique identifier. } message GetOfferReply { - OfferInfo offer = 1; + OfferInfo offer = 1; // The returned v1 protocol offer. } message GetMyBsqSwapOfferReply { - OfferInfo bsqSwapOffer = 1; + OfferInfo bsqSwapOffer = 1; // The returned BSQ swap offer. } -// @Deprecated since 27-Dec-2021 (v1.8.0) +// Deprecated with rpc method GetMyOffer since 27-Dec-2021 (v1.8.0). message GetMyOfferRequest { - string id = 1; + string id = 1; // The offer's unique identifier. } -// @Deprecated since 27-Dec-2021 (v1.8.0) +// Deprecated with rpc method GetMyOffer since 27-Dec-2021 (v1.8.0). message GetMyOfferReply { - OfferInfo offer = 1; + OfferInfo offer = 1; // The returned v1 protocol offer. } message GetOffersRequest { - string direction = 1; - string currencyCode = 2; + string direction = 1; // The offer's BUY (BTC) or SELL (BTC) direction. + string currencyCode = 2; // The offer's fiat or altcoin currency code. } message GetOffersReply { - repeated OfferInfo offers = 1; + repeated OfferInfo offers = 1; // The returned list of available offers. } message GetBsqSwapOffersRequest { - string direction = 1; + string direction = 1; // The BSQ swap offer's BUY (BTC) or SELL (BTC) direction. } message GetBsqSwapOffersReply { - repeated OfferInfo bsqSwapOffers = 1; + repeated OfferInfo bsqSwapOffers = 1; // The returned list of available BSQ swap offers. } message GetMyOffersRequest { - string direction = 1; - string currencyCode = 2; + string direction = 1; // The offers' BUY (BTC) or SELL (BTC) direction. + string currencyCode = 2; // The offer's fiat or altcoin currency code. } message GetMyOffersReply { - repeated OfferInfo offers = 1; + repeated OfferInfo offers = 1; // The returned list of user's open offers. } message GetMyBsqSwapOffersReply { - repeated OfferInfo bsqSwapOffers = 1; + repeated OfferInfo bsqSwapOffers = 1; // The returned list of user's open BSQ swap offers. } +// TODO: Use string for all number fields, in order to eliminate loss of precision or ambiguity. message CreateBsqSwapOfferRequest { + // The new BSQ swap offer's BUY (BTC) or SELL (BTC) direction. string direction = 1; + // The amount of BTC to be traded as a long representing satoshi units. uint64 amount = 2; + // The minimum amount of BTC to be traded as a long representing satoshi units. uint64 minAmount = 3; + // The fixed price of the offer as a string representing BTC units, e.g., "0.00005" or "0.00005000". string price = 4; } message CreateBsqSwapOfferReply { - OfferInfo bsqSwapOffer = 1; + OfferInfo bsqSwapOffer = 1; // The newly created BSQ swap offer. } +// TODO: Use string for all number fields, in order to eliminate loss of precision or ambiguity. message CreateOfferRequest { + // The new offer's fiat or altcoin currency code. string currencyCode = 1; + // The new v1 protocol offer's BUY (BTC) or SELL (BTC) direction. string direction = 2; + // For fiat offers: a string representing the rounded, fixed fiat price of the offer, e.g., "45000", not "45000". + // For altcoin offers: a string representing the fixed BTC price of the offer, e.g., "0.00005". string price = 3; + // 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; + // 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; + // 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; + // 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. string makerFeeCurrencyCode = 11; } message CreateOfferReply { - OfferInfo offer = 1; + OfferInfo offer = 1; // The newly created v1 protocol offer. } message EditOfferRequest { + // The edited offer's unique identifier. string id = 1; + // For fiat offers: a string representing the new rounded, fixed fiat price of the offer, e.g., "45000", not "45000". + // For altcoin offers: a string representing the new fixed BTC price of the offer, e.g., "0.00005". 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; + // For market price margin based offer, the current market BTC price at which the offer is automatically disabled. uint64 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 // 0 = disable // 1 = enable sint32 enable = 6; - // The EditType constricts what offer details can be modified and simplifies param validation. + // The EditType determines and constricts what offer details can + // be modified by the request, simplifying param validation. enum EditType { - ACTIVATION_STATE_ONLY = 0; - FIXED_PRICE_ONLY = 1; - FIXED_PRICE_AND_ACTIVATION_STATE = 2; - MKT_PRICE_MARGIN_ONLY = 3; - MKT_PRICE_MARGIN_AND_ACTIVATION_STATE = 4; - TRIGGER_PRICE_ONLY = 5; - TRIGGER_PRICE_AND_ACTIVATION_STATE = 6; - MKT_PRICE_MARGIN_AND_TRIGGER_PRICE = 7; - MKT_PRICE_MARGIN_AND_TRIGGER_PRICE_AND_ACTIVATION_STATE = 8; - } + // Edit only the offer's activation state (enabled or disabled). + ACTIVATION_STATE_ONLY = 0; + // Edit only the offer's fixed price. + FIXED_PRICE_ONLY = 1; + // Edit only the offer's fixed price and activation state. + FIXED_PRICE_AND_ACTIVATION_STATE = 2; + // Edit only the offer's market price margin. + MKT_PRICE_MARGIN_ONLY = 3; + // Edit only the offer's market price margin and activation state. + MKT_PRICE_MARGIN_AND_ACTIVATION_STATE = 4; + // Edit only the market price margin based offer's trigger price. + TRIGGER_PRICE_ONLY = 5; + // Edit only the market price margin based offer's trigger price and activation state. + TRIGGER_PRICE_AND_ACTIVATION_STATE = 6; + // Edit only the offer's market price margin and trigger price. + MKT_PRICE_MARGIN_AND_TRIGGER_PRICE = 7; + // Edit only the offer's market price margin, trigger price, and activation state. + MKT_PRICE_MARGIN_AND_TRIGGER_PRICE_AND_ACTIVATION_STATE = 8; + } + // Tell the daemon precisely what is being edited. EditType editType = 7; } @@ -235,53 +272,106 @@ message EditOfferReply { } message CancelOfferRequest { - string id = 1; + string id = 1; // The canceled offer's unique identifier. } 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: Use string for all number fields, in order to eliminate loss of precision or ambiguity. message OfferInfo { + // The offer's unique identifier. 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; + // 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 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. 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; + // 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; + // 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. string paymentAccountId = 13; + // The unique identifier of the payment method used to create the offer. string paymentMethodId = 14; + // The short description of the payment method used to create the offer. string paymentMethodShortName = 15; + // For fiat offers, the baseCurrencyCode is BTC, and the counterCurrencyCode is the fiat currency code. + // For altcoin offers it is the opposite, the baseCurrencyCode is the altcoin code and the counterCurrencyCode is BTC. string baseCurrencyCode = 16; + // For fiat offers, the baseCurrencyCode is BTC, and the counterCurrencyCode is the fiat currency code. + // For altcoin offers it is the opposite, the baseCurrencyCode is the altcoin code and the counterCurrencyCode is BTC. string counterCurrencyCode = 17; + // The creation date of the offer as a long: the number of milliseconds that have elapsed since January 1, 1970. uint64 date = 18; + // The internal state of the offer, e.g., AVAILABLE, NOT_AVAILABLE, REMOVED, etc. string state = 19; + // A long representing the BTC seller's security deposit in satoshis. uint64 sellerSecurityDeposit = 20; + // The bitcoin transaction id of the offer maker's fee payment. string offerFeePaymentTxId = 21; + // The bitcoin transaction fee (amount) for the offer maker's fee payment transaction, in satoshis. uint64 txFee = 22; + // The offer maker's Bisq trade fee amount in satoshis. uint64 makerFee = 23; + // Whether the offer is currently enabled or not. bool isActivated = 24; + // Whether the offer was created by the user or not. bool isMyOffer = 25; + // Whether the newly created offer was created by the user or not. bool isMyPendingOffer = 26; + // Whether the offer is a BSQ swap offer or not (v1 protocol offer). bool isBsqSwapOffer = 27; + // The offer creator's Tor onion address. string ownerNodeAddress = 28; + // The offer creator's public key ring as a string. string pubKeyRing = 29; + // The Bisq software version used to create the offer. string versionNr = 30; + // The bitcoin protocol version used to create the offer. int32 protocolVersion = 31; } +// An offer's current availability status. message AvailabilityResultWithDescription { + // An offer's current status as an eum. AvailabilityResult availabilityResult = 1; + // A user friendly description of an offer's current availability status. string description = 2; } /* -* PaymentAccounts service provides rpc methods for creating fiat and crypto currency payment accounts. +* 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. @@ -352,11 +442,8 @@ message GetCryptoCurrencyPaymentMethodsReply { repeated PaymentMethod paymentMethods = 1; } -/* -* Price service comment. -*/ service Price { - // Get current market price for a crypto currency. + // Get the current market price for a crypto currency. rpc GetMarketPrice (MarketPriceRequest) returns (MarketPriceReply) { } } @@ -385,9 +472,6 @@ message GetTradeStatisticsReply { repeated TradeStatistics3 TradeStatistics = 1; } -/* -* ShutdownServer service comment. -*/ service ShutdownServer { // Shut down a local Bisq daemon. rpc Stop (StopRequest) returns (StopReply) { @@ -397,11 +481,12 @@ service ShutdownServer { message StopRequest { } + message StopReply { } /* -* Trades service provides rpc methods for taking, executing, and listing trades. +* The Trades service provides rpc methods for taking, executing, and listing trades. */ service Trades { // Get an open trade with a trade-id. @@ -601,7 +686,7 @@ message TxInfo { } /* -* Wallets service provides rpc methods for basic wallet operations such as checking balances, +* The Wallets service provides rpc methods for basic wallet operations such as checking balances, * sending BTC or BSQ to external wallets, checking transaction fee rates, setting or unsetting * an encryption password on a a wallet, and unlocking / locking an encrypted wallet. */ @@ -805,11 +890,8 @@ message AddressBalanceInfo { bool isAddressUnused = 4; } -/* -* GetVersion service provides the local Bisq daemon's version. -*/ service GetVersion { - // Get current Bisq version number. + // Get the current Bisq version number. rpc GetVersion (GetVersionRequest) returns (GetVersionReply) { } } From ddd3ec3243a869c79d8e723f5cafbd9d562aaa37 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Thu, 17 Feb 2022 13:39:06 -0300 Subject: [PATCH 03/30] Fix comment about changing "all" number fields to string We will consider each problematic number field one at a time. Note: changing field types in following commits will break the API's backward compatibility, but devs agree it's OK since it is still in beta. --- proto/src/main/proto/grpc.proto | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index 0d4b0efc45d..f39ce446bb5 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -172,7 +172,7 @@ message GetMyBsqSwapOffersReply { repeated OfferInfo bsqSwapOffers = 1; // The returned list of user's open BSQ swap offers. } -// TODO: Use string for all number fields, in order to eliminate loss of precision or ambiguity. +// 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 +188,7 @@ message CreateBsqSwapOfferReply { OfferInfo bsqSwapOffer = 1; // The newly created BSQ swap offer. } -// TODO: Use string for all number fields, in order to eliminate loss of precision or ambiguity. +// 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; @@ -280,7 +280,7 @@ 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: Use string for all number fields, in order to eliminate loss of precision or ambiguity. +// 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; 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 04/30] 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 05/30] 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 06/30] 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 07/30] 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 08/30] 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 09/30] 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 10/30] 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 11/30] 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 12/30] 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 13/30] 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 14/30] 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 15/30] 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 16/30] 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 17/30] 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 18/30] 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 19/30] 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 20/30] 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 21/30] 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 22/30] 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 23/30] 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 24/30] 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 25/30] 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 26/30] 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 27/30] 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 28/30] 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 29/30] 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 30/30] 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; - } - } }