Skip to content

Commit

Permalink
Implement rounding options for "Pay-By-Mail" payment type
Browse files Browse the repository at this point in the history
  • Loading branch information
wp07e committed Jul 2, 2024
1 parent 438e8d4 commit 2a4d224
Show file tree
Hide file tree
Showing 26 changed files with 260 additions and 46 deletions.
12 changes: 8 additions & 4 deletions core/src/main/java/haveno/core/api/CoreApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,8 @@ public void postOffer(String currencyCode,
boolean reserveExactAmount,
String paymentAccountId,
Consumer<Offer> resultHandler,
ErrorMessageHandler errorMessageHandler) {
ErrorMessageHandler errorMessageHandler,
int roundTo) {
coreOffersService.postOffer(currencyCode,
directionAsString,
priceAsString,
Expand All @@ -433,7 +434,8 @@ public void postOffer(String currencyCode,
reserveExactAmount,
paymentAccountId,
resultHandler,
errorMessageHandler);
errorMessageHandler,
roundTo);
}

public Offer editOffer(String offerId,
Expand All @@ -445,7 +447,8 @@ public Offer editOffer(String offerId,
BigInteger amount,
BigInteger minAmount,
double buyerSecurityDeposit,
PaymentAccount paymentAccount) {
PaymentAccount paymentAccount,
Integer roundTo) {
return coreOffersService.editOffer(offerId,
currencyCode,
direction,
Expand All @@ -455,7 +458,8 @@ public Offer editOffer(String offerId,
amount,
minAmount,
buyerSecurityDeposit,
paymentAccount);
paymentAccount,
roundTo);
}

public void cancelOffer(String id, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
Expand Down
12 changes: 8 additions & 4 deletions core/src/main/java/haveno/core/api/CoreOffersService.java
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ void postOffer(String currencyCode,
boolean reserveExactAmount,
String paymentAccountId,
Consumer<Offer> resultHandler,
ErrorMessageHandler errorMessageHandler) {
ErrorMessageHandler errorMessageHandler,
int roundTo) {
coreWalletsService.verifyWalletsAreAvailable();
coreWalletsService.verifyEncryptedWalletIsUnlocked();

Expand All @@ -200,7 +201,8 @@ void postOffer(String currencyCode,
useMarketBasedPrice,
exactMultiply(marketPriceMargin, 0.01),
securityDeposit,
paymentAccount);
paymentAccount,
roundTo);

verifyPaymentAccountIsValidForNewOffer(offer, paymentAccount);

Expand All @@ -224,7 +226,8 @@ Offer editOffer(String offerId,
BigInteger amount,
BigInteger minAmount,
double buyerSecurityDeposit,
PaymentAccount paymentAccount) {
PaymentAccount paymentAccount,
Integer roundTo) {
return createOfferService.createAndGetOffer(offerId,
direction,
currencyCode.toUpperCase(),
Expand All @@ -234,7 +237,8 @@ Offer editOffer(String offerId,
useMarketBasedPrice,
exactMultiply(marketPriceMargin, 0.01),
buyerSecurityDeposit,
paymentAccount);
paymentAccount,
roundTo);
}

void cancelOffer(String id, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
Expand Down
9 changes: 7 additions & 2 deletions core/src/main/java/haveno/core/api/model/OfferInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public class OfferInfo implements Payload {
@Nullable
private final String splitOutputTxHash;
private final long splitOutputTxFee;
private final int roundTo;

public OfferInfo(OfferInfoBuilder builder) {
this.id = builder.getId();
Expand Down Expand Up @@ -111,6 +112,7 @@ public OfferInfo(OfferInfoBuilder builder) {
this.arbitratorSigner = builder.getArbitratorSigner();
this.splitOutputTxHash = builder.getSplitOutputTxHash();
this.splitOutputTxFee = builder.getSplitOutputTxFee();
this.roundTo = builder.getRoundTo();
}

public static OfferInfo toOfferInfo(Offer offer) {
Expand Down Expand Up @@ -177,7 +179,8 @@ private static OfferInfoBuilder getBuilder(Offer offer) {
.withPubKeyRing(offer.getOfferPayload().getPubKeyRing().toString())
.withVersionNumber(offer.getOfferPayload().getVersionNr())
.withProtocolVersion(offer.getOfferPayload().getProtocolVersion())
.withArbitratorSigner(offer.getOfferPayload().getArbitratorSigner() == null ? null : offer.getOfferPayload().getArbitratorSigner().getFullAddress());
.withArbitratorSigner(offer.getOfferPayload().getArbitratorSigner() == null ? null : offer.getOfferPayload().getArbitratorSigner().getFullAddress())
.withRoundTo(offer.getRoundTo());
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -215,7 +218,8 @@ public haveno.proto.grpc.OfferInfo toProtoMessage() {
.setPubKeyRing(pubKeyRing)
.setVersionNr(versionNumber)
.setProtocolVersion(protocolVersion)
.setSplitOutputTxFee(splitOutputTxFee);
.setSplitOutputTxFee(splitOutputTxFee)
.setRoundTo(roundTo);
Optional.ofNullable(arbitratorSigner).ifPresent(builder::setArbitratorSigner);
Optional.ofNullable(splitOutputTxHash).ifPresent(builder::setSplitOutputTxHash);
return builder.build();
Expand Down Expand Up @@ -255,6 +259,7 @@ public static OfferInfo fromProto(haveno.proto.grpc.OfferInfo proto) {
.withArbitratorSigner(proto.getArbitratorSigner())
.withSplitOutputTxHash(proto.getSplitOutputTxHash())
.withSplitOutputTxFee(proto.getSplitOutputTxFee())
.withRoundTo(proto.getRoundTo())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public final class OfferInfoBuilder {
private String arbitratorSigner;
private String splitOutputTxHash;
private long splitOutputTxFee;
private int roundTo;

public OfferInfoBuilder withId(String id) {
this.id = id;
Expand Down Expand Up @@ -223,7 +224,7 @@ public OfferInfoBuilder withArbitratorSigner(String arbitratorSigner) {
this.arbitratorSigner = arbitratorSigner;
return this;
}

public OfferInfoBuilder withSplitOutputTxHash(String splitOutputTxHash) {
this.splitOutputTxHash = splitOutputTxHash;
return this;
Expand All @@ -234,6 +235,11 @@ public OfferInfoBuilder withSplitOutputTxFee(long splitOutputTxFee) {
return this;
}

public OfferInfoBuilder withRoundTo(int roundTo) {
this.roundTo = roundTo;
return this;
}

public OfferInfo build() {
return new OfferInfo(this);
}
Expand Down
8 changes: 6 additions & 2 deletions core/src/main/java/haveno/core/offer/CreateOfferService.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,14 @@ public Offer createAndGetOffer(String offerId,
boolean useMarketBasedPrice,
double marketPriceMargin,
double securityDepositAsDouble,
PaymentAccount paymentAccount) {
PaymentAccount paymentAccount,
Integer roundTo) {

log.info("create and get offer with offerId={}, " +
"currencyCode={}, " +
"direction={}, " +
"fixedPrice={}, " +
"roundTo={}, " +
"useMarketBasedPrice={}, " +
"marketPriceMargin={}, " +
"amount={}, " +
Expand All @@ -118,6 +120,7 @@ public Offer createAndGetOffer(String offerId,
currencyCode,
direction,
fixedPrice == null ? null : fixedPrice.getValue(),
roundTo,
useMarketBasedPrice,
marketPriceMargin,
amount,
Expand Down Expand Up @@ -216,7 +219,8 @@ public Offer createAndGetOffer(String offerId,
Version.TRADE_PROTOCOL_VERSION,
null,
null,
null);
null,
roundTo);
Offer offer = new Offer(offerPayload);
offer.setPriceFeedService(priceFeedService);
return offer;
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/haveno/core/offer/Offer.java
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ public BigInteger getMinAmount() {
return BigInteger.valueOf(offerPayload.getMinAmount());
}

public Integer getRoundTo() {
return offerPayload.getRoundTo();
}

public boolean isRange() {
return offerPayload.getAmount() != offerPayload.getMinAmount();
}
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/haveno/core/offer/OfferBookService.java
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@ private void doDumpStatistics() {
offer.getId(),
offer.isUseMarketBasedPrice(),
offer.getMarketPriceMarginPct(),
offer.getPaymentMethod()
offer.getPaymentMethod(),
offer.getRoundTo()
);
} catch (Throwable t) {
// In case an offer was corrupted with null values we ignore it
Expand Down
7 changes: 6 additions & 1 deletion core/src/main/java/haveno/core/offer/OfferForJson.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import haveno.core.monetary.Volume;
import haveno.core.payment.payload.PaymentMethod;
import haveno.core.trade.HavenoUtils;
import lombok.Getter;
import org.bitcoinj.utils.MonetaryFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -47,6 +48,8 @@ public class OfferForJson {
public final double marketPriceMargin;
public final String paymentMethod;
public final String id;
@Getter
public final int roundTo;

// primaryMarket fields are based on industry standard where primaryMarket is always in the focus (in the app BTC is always in the focus - will be changed in a larger refactoring once)
public String currencyPair;
Expand Down Expand Up @@ -81,7 +84,8 @@ public OfferForJson(OfferDirection direction,
String id,
boolean useMarketBasedPrice,
double marketPriceMargin,
PaymentMethod paymentMethod) {
PaymentMethod paymentMethod,
Integer roundTo) {

this.direction = direction;
this.currencyCode = currencyCode;
Expand All @@ -93,6 +97,7 @@ public OfferForJson(OfferDirection direction,
this.useMarketBasedPrice = useMarketBasedPrice;
this.marketPriceMargin = marketPriceMargin;
this.paymentMethod = paymentMethod.getId();
this.roundTo = roundTo;

setDisplayStrings();
}
Expand Down
16 changes: 12 additions & 4 deletions core/src/main/java/haveno/core/offer/OfferPayload.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
@Setter
@Nullable
protected List<String> reserveTxKeyImages;
protected final int roundTo;

// Keys for extra map
// Only set for traditional offers
Expand Down Expand Up @@ -198,7 +199,8 @@ public OfferPayload(String id,
int protocolVersion,
@Nullable NodeAddress arbitratorSigner,
@Nullable byte[] arbitratorSignature,
@Nullable List<String> reserveTxKeyImages) {
@Nullable List<String> reserveTxKeyImages,
int roundTo) {
this.id = id;
this.date = date;
this.ownerNodeAddress = ownerNodeAddress;
Expand Down Expand Up @@ -237,6 +239,7 @@ public OfferPayload(String id,
this.upperClosePrice = upperClosePrice;
this.isPrivateOffer = isPrivateOffer;
this.hashOfChallenge = hashOfChallenge;
this.roundTo = roundTo;
}

public byte[] getHash() {
Expand Down Expand Up @@ -287,7 +290,8 @@ public byte[] getSignatureHash() {
protocolVersion,
arbitratorSigner,
null,
reserveTxKeyImages
reserveTxKeyImages,
roundTo
);

return signee.getHash();
Expand Down Expand Up @@ -368,7 +372,8 @@ public protobuf.StoragePayload toProtoMessage() {
.setLowerClosePrice(lowerClosePrice)
.setUpperClosePrice(upperClosePrice)
.setIsPrivateOffer(isPrivateOffer)
.setProtocolVersion(protocolVersion);
.setProtocolVersion(protocolVersion)
.setRoundTo(roundTo);
Optional.ofNullable(ownerNodeAddress).ifPresent(e -> builder.setOwnerNodeAddress(ownerNodeAddress.toProtoMessage()));
Optional.ofNullable(countryCode).ifPresent(builder::setCountryCode);
Optional.ofNullable(bankId).ifPresent(builder::setBankId);
Expand Down Expand Up @@ -429,7 +434,8 @@ public static OfferPayload fromProto(protobuf.OfferPayload proto) {
proto.getProtocolVersion(),
proto.hasArbitratorSigner() ? NodeAddress.fromProto(proto.getArbitratorSigner()) : null,
ProtoUtil.byteArrayOrNullFromProto(proto.getArbitratorSignature()),
proto.getReserveTxKeyImagesList() == null ? null : new ArrayList<String>(proto.getReserveTxKeyImagesList()));
proto.getReserveTxKeyImagesList() == null ? null : new ArrayList<String>(proto.getReserveTxKeyImagesList()),
proto.getRoundTo());
}

@Override
Expand Down Expand Up @@ -474,6 +480,7 @@ public String toString() {
",\r\n hashOfChallenge='" + hashOfChallenge + '\'' +
",\r\n arbitratorSigner=" + arbitratorSigner +
",\r\n arbitratorSignature=" + Utilities.bytesAsHexString(arbitratorSignature) +
",\r\n roundTo=" + roundTo +
"\r\n} ";
}

Expand Down Expand Up @@ -515,6 +522,7 @@ public JsonElement serialize(OfferPayload offerPayload, Type type, JsonSerializa
object.add("protocolVersion", context.serialize(offerPayload.getProtocolVersion()));
object.add("arbitratorSigner", context.serialize(offerPayload.getArbitratorSigner()));
object.add("arbitratorSignature", context.serialize(offerPayload.getArbitratorSignature()));
object.add("roundTo", context.serialize(offerPayload.getRoundTo()));
return object;
}
}
Expand Down
7 changes: 4 additions & 3 deletions core/src/main/java/haveno/core/offer/OpenOfferManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ private void doCancelOffer(@NotNull OpenOffer openOffer) {
Offer offer = openOffer.getOffer();
offer.setState(Offer.State.REMOVED);
openOffer.setState(OpenOffer.State.CANCELED);
removeOpenOffer(openOffer);
removeOpenOffer(openOffer);
closedTradableManager.add(openOffer); // TODO: don't add these to closed tradables?
xmrWalletService.resetAddressEntriesForOpenOffer(offer.getId());
requestPersistence();
Expand Down Expand Up @@ -893,7 +893,7 @@ private void processScheduledOffers(TransactionResultHandler resultHandler, // T
}

private void processUnpostedOffer(List<OpenOffer> openOffers, OpenOffer openOffer, TransactionResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {

// skip if already processing
if (openOffer.isProcessing()) {
resultHandler.handleResult(null);
Expand Down Expand Up @@ -1642,7 +1642,8 @@ private void maybeUpdatePersistedOffers() {
protocolVersion,
originalOfferPayload.getArbitratorSigner(),
originalOfferPayload.getArbitratorSignature(),
originalOfferPayload.getReserveTxKeyImages());
originalOfferPayload.getReserveTxKeyImages(),
originalOfferPayload.getRoundTo());

// Save states from original data to use for the updated
Offer.State originalOfferState = originalOffer.getState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme

// Cryptos
BLOCK_CHAINS = new PaymentMethod(BLOCK_CHAINS_ID, DAY, DEFAULT_TRADE_LIMIT_VERY_LOW_RISK, Arrays.asList()),

// Cryptos with 1 hour trade period
BLOCK_CHAINS_INSTANT = new PaymentMethod(BLOCK_CHAINS_INSTANT_ID, TimeUnit.HOURS.toMillis(1), DEFAULT_TRADE_LIMIT_VERY_LOW_RISK, Arrays.asList())
);
Expand Down Expand Up @@ -597,6 +597,10 @@ public static boolean isRoundedForAtmCash(String id) {
id.equals(PaymentMethod.HAL_CASH_ID);
}

public static boolean isRoundedForPBMCash(String id) {
return id.equals(PaymentMethod.PAY_BY_MAIL_ID);
}

public static boolean isFixedPriceOnly(String id) {
return id.equals(PaymentMethod.CASH_AT_ATM_ID) ||
id.equals(PaymentMethod.HAL_CASH_ID);
Expand Down
Loading

0 comments on commit 2a4d224

Please sign in to comment.