Fix API editoffer bug: set fixed-price=0 on margin offers

This is causing erroneous PRICE_OUT_OF_TOLERANCE errors when trying
to take offers having (fixed) price!=0, and isUsingMktPriceMargin=true
in the payload.

The API daemon editoffer's treatment of (fixed) price and
isUsingMktPriceMargin flag in the API has been inconsistent with the UI.

With this change:  when isUsingMktPriceMargin=true, (fixed) price is
set to 0 on the server.  API clients, however, still must show the
calculated price when isUsingMktPriceMargin=true, making this fix hard
to test in the client.  The server will now throw an exception if
(fixed) price and isUsingMktPriceMargin flag in the API are not
properly set in the API server.

This fix is intended to prevent issues such as
https://github.com/bisq-network/bisq/issues/6170 from happening for
this reason.  The offer maker edited offers with API, creating
inconsistent state described above.  It is hoped the user's offers
can be fixed by editing them in the UI.

Based on `master`.
This commit is contained in:
ghubstan 2022-05-14 18:14:49 -03:00
parent a1eedafce7
commit 381985ec3a
No known key found for this signature in database
GPG Key ID: E35592D6800A861E
3 changed files with 25 additions and 12 deletions

View File

@ -464,22 +464,35 @@ class CoreOffersService {
// in OfferPayload.
Offer offer = openOffer.getOffer();
String currencyCode = offer.getCurrencyCode();
boolean isEditingPrice = editType.equals(FIXED_PRICE_ONLY) || editType.equals(FIXED_PRICE_AND_ACTIVATION_STATE);
Price editedPrice;
if (isEditingPrice) {
editedPrice = Price.valueOf(currencyCode, priceStringToLong(editedPriceAsString, currencyCode));
boolean isUsingMktPriceMargin = editOfferValidator.isEditingUseMktPriceMarginFlag.test(offer, editType);
boolean isEditingFixedPrice = editType.equals(FIXED_PRICE_ONLY) || editType.equals(FIXED_PRICE_AND_ACTIVATION_STATE);
Price editedFixedPrice;
if (isEditingFixedPrice) {
editedFixedPrice = Price.valueOf(currencyCode, priceStringToLong(editedPriceAsString, currencyCode));
} else {
editedPrice = offer.getPrice();
// When isUsingMktPriceMargin=true, (fixed) price must be set to 0 on the server.
// The client, however, still must show the calculated price when
// isUsingMktPriceMargin=true.
editedFixedPrice = isUsingMktPriceMargin ? Price.valueOf(currencyCode, 0) : offer.getPrice();
}
boolean isUsingMktPriceMargin = editOfferValidator.isEditingUseMktPriceMarginFlag.test(offer, editType);
// If isUsingMktPriceMargin=true, throw exception if new fixed-price != 0.
// If isUsingMktPriceMargin=false, throw exception if new fixed-price == 0.
if (isUsingMktPriceMargin && editedFixedPrice.getValue() != 0)
throw new IllegalStateException(
format("Fixed price on mkt price margin based offer %s must be set to 0 in server.",
offer.getId()));
else if (!isUsingMktPriceMargin && editedFixedPrice.getValue() == 0)
throw new IllegalStateException(
format("Fixed price on fixed price offer %s cannot be 0.", offer.getId()));
boolean isEditingMktPriceMargin = editOfferValidator.isEditingMktPriceMargin.test(editType);
double newMarketPriceMargin = isEditingMktPriceMargin
? exactMultiply(editedMarketPriceMargin, 0.01)
: offer.getMarketPriceMargin();
MutableOfferPayloadFields mutableOfferPayloadFields = new MutableOfferPayloadFields(
Objects.requireNonNull(editedPrice).getValue(),
Objects.requireNonNull(editedFixedPrice).getValue(),
isUsingMktPriceMargin ? newMarketPriceMargin : 0.00,
isUsingMktPriceMargin,
offer.getBaseCurrencyCode(),

View File

@ -420,7 +420,7 @@ public class OfferUtil {
original.getOwnerNodeAddress(),
original.getPubKeyRing(),
original.getDirection(),
mutableOfferPayloadFields.getPrice(),
mutableOfferPayloadFields.getFixedPrice(),
mutableOfferPayloadFields.getMarketPriceMargin(),
mutableOfferPayloadFields.isUseMarketBasedPrice(),
original.getAmount(),

View File

@ -32,7 +32,7 @@ import javax.annotation.Nullable;
@Setter
public final class MutableOfferPayloadFields {
private final long price;
private final long fixedPrice; // Must be 0 when marketPriceMargin = true (on server).
private final double marketPriceMargin;
private final boolean useMarketBasedPrice;
private final String baseCurrencyCode;
@ -69,7 +69,7 @@ public final class MutableOfferPayloadFields {
offerPayload.getExtraDataMap());
}
public MutableOfferPayloadFields(long price,
public MutableOfferPayloadFields(long fixedPrice,
double marketPriceMargin,
boolean useMarketBasedPrice,
String baseCurrencyCode,
@ -83,7 +83,7 @@ public final class MutableOfferPayloadFields {
@Nullable String bankId,
@Nullable List<String> acceptedBankIds,
@Nullable Map<String, String> extraDataMap) {
this.price = price;
this.fixedPrice = fixedPrice;
this.marketPriceMargin = marketPriceMargin;
this.useMarketBasedPrice = useMarketBasedPrice;
this.baseCurrencyCode = baseCurrencyCode;
@ -102,7 +102,7 @@ public final class MutableOfferPayloadFields {
@Override
public String toString() {
return "MutableOfferPayloadFields{" + "\n" +
" price=" + price + "\n" +
" fixedPrice=" + fixedPrice + "\n" +
", marketPriceMargin=" + marketPriceMargin + "\n" +
", useMarketBasedPrice=" + useMarketBasedPrice + "\n" +
", baseCurrencyCode='" + baseCurrencyCode + '\'' + "\n" +