Move util code from UI to core

Move code to OfferUtil and PaymentAccountUtil to avoid code duplication
once http-API gets merged
This commit is contained in:
Manfred Karrer 2019-01-12 00:14:55 +01:00
parent 6e753a29f7
commit 3c35f46b64
No known key found for this signature in database
GPG Key ID: 401250966A6B2C46
5 changed files with 159 additions and 67 deletions

View File

@ -20,18 +20,25 @@ package bisq.core.offer;
import bisq.core.app.BisqEnvironment;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.Restrictions;
import bisq.core.filter.FilterManager;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.monetary.Price;
import bisq.core.monetary.Volume;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.F2FAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.MarketPrice;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.statistics.ReferralIdService;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.CoinUtil;
import bisq.network.p2p.P2PService;
import bisq.common.util.MathUtils;
import org.bitcoinj.core.Coin;
@ -39,6 +46,8 @@ import org.bitcoinj.utils.Fiat;
import com.google.common.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
@ -46,6 +55,7 @@ import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* This class holds utility methods for the creation of an Offer.
@ -309,4 +319,62 @@ public class OfferUtil {
}
return Res.get("feeOptionWindow.fee", fee, feeInFiatAsString);
}
public static Map<String, String> getExtraDataMap(AccountAgeWitnessService accountAgeWitnessService,
ReferralIdService referralIdService,
PaymentAccount paymentAccount,
String currencyCode) {
Map<String, String> extraDataMap = null;
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
extraDataMap = new HashMap<>();
final String myWitnessHashAsHex = accountAgeWitnessService.getMyWitnessHashAsHex(paymentAccount.getPaymentAccountPayload());
extraDataMap.put(OfferPayload.ACCOUNT_AGE_WITNESS_HASH, myWitnessHashAsHex);
}
if (referralIdService.getOptionalReferralId().isPresent()) {
if (extraDataMap == null)
extraDataMap = new HashMap<>();
extraDataMap.put(OfferPayload.REFERRAL_ID, referralIdService.getOptionalReferralId().get());
}
if (paymentAccount instanceof F2FAccount) {
if (extraDataMap == null)
extraDataMap = new HashMap<>();
extraDataMap.put(OfferPayload.F2F_CITY, ((F2FAccount) paymentAccount).getCity());
extraDataMap.put(OfferPayload.F2F_EXTRA_INFO, ((F2FAccount) paymentAccount).getExtraInfo());
}
return extraDataMap;
}
public static void validateOfferData(FilterManager filterManager,
P2PService p2PService,
Coin buyerSecurityDepositAsCoin,
PaymentAccount paymentAccount,
String currencyCode,
Coin makerFeeAsCoin) {
checkNotNull(makerFeeAsCoin, "makerFee must not be null");
checkNotNull(p2PService.getAddress(), "Address must not be null");
checkArgument(buyerSecurityDepositAsCoin.compareTo(Restrictions.getMaxBuyerSecurityDeposit()) <= 0,
"securityDeposit must be not exceed " +
Restrictions.getMaxBuyerSecurityDeposit().toFriendlyString());
checkArgument(buyerSecurityDepositAsCoin.compareTo(Restrictions.getMinBuyerSecurityDeposit()) >= 0,
"securityDeposit must be not be less than " +
Restrictions.getMinBuyerSecurityDeposit().toFriendlyString());
checkArgument(!filterManager.isCurrencyBanned(currencyCode),
Res.get("offerbook.warning.currencyBanned"));
checkArgument(!filterManager.isPaymentMethodBanned(paymentAccount.getPaymentMethod()),
Res.get("offerbook.warning.paymentMethodBanned"));
}
// TODO no code duplication found in UI code (added for API)
/* public static Coin getFundsNeededForOffer(Coin tradeAmount, Coin buyerSecurityDeposit, OfferPayload.Direction direction) {
boolean buyOffer = isBuyOffer(direction);
Coin needed = buyOffer ? buyerSecurityDeposit : Restrictions.getSellerSecurityDeposit();
if (!buyOffer)
needed = needed.add(tradeAmount);
return needed;
}*/
}

View File

@ -150,6 +150,10 @@ public abstract class PaymentAccount implements PersistablePayload {
return null;
}
public long getMaxTradePeriod() {
return paymentMethod.getMaxTradePeriod();
}
protected abstract PaymentAccountPayload createPayload();
public void setSalt(byte[] salt) {

View File

@ -17,18 +17,23 @@
package bisq.core.payment;
import bisq.core.locale.Country;
import bisq.core.offer.Offer;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
@Slf4j
public class PaymentAccountUtil {
public static boolean isAnyPaymentAccountValidForOffer(Offer offer, Collection<PaymentAccount> paymentAccounts) {
@ -65,4 +70,66 @@ public class PaymentAccountUtil {
PaymentAccounts accounts = new PaymentAccounts(paymentAccounts, service);
return Optional.ofNullable(accounts.getOldestPaymentAccountForOffer(offer));
}
@Nullable
public static ArrayList<String> getAcceptedCountryCodes(PaymentAccount paymentAccount) {
ArrayList<String> acceptedCountryCodes = null;
if (paymentAccount instanceof SepaAccount) {
acceptedCountryCodes = new ArrayList<>(((SepaAccount) paymentAccount).getAcceptedCountryCodes());
} else if (paymentAccount instanceof SepaInstantAccount) {
acceptedCountryCodes = new ArrayList<>(((SepaInstantAccount) paymentAccount).getAcceptedCountryCodes());
} else if (paymentAccount instanceof CountryBasedPaymentAccount) {
acceptedCountryCodes = new ArrayList<>();
Country country = ((CountryBasedPaymentAccount) paymentAccount).getCountry();
if (country != null)
acceptedCountryCodes.add(country.code);
}
return acceptedCountryCodes;
}
@Nullable
public static List<String> getAcceptedBanks(PaymentAccount paymentAccount) {
List<String> acceptedBanks = null;
if (paymentAccount instanceof SpecificBanksAccount) {
acceptedBanks = new ArrayList<>(((SpecificBanksAccount) paymentAccount).getAcceptedBanks());
} else if (paymentAccount instanceof SameBankAccount) {
acceptedBanks = new ArrayList<>();
acceptedBanks.add(((SameBankAccount) paymentAccount).getBankId());
}
return acceptedBanks;
}
@Nullable
public static String getBankId(PaymentAccount paymentAccount) {
return paymentAccount instanceof BankAccount ? ((BankAccount) paymentAccount).getBankId() : null;
}
@Nullable
public static String getCountryCode(PaymentAccount paymentAccount) {
// That is optional and set to null if not supported (AltCoins, OKPay,...)
if (paymentAccount instanceof CountryBasedPaymentAccount) {
Country country = (((CountryBasedPaymentAccount) paymentAccount)).getCountry();
return country != null ? country.code : null;
}
return null;
}
// TODO no code duplication found in UI code (added for API)
// That is optional and set to null if not supported (AltCoins, OKPay,...)
/* public static String getCountryCode(PaymentAccount paymentAccount) {
if (paymentAccount instanceof CountryBasedPaymentAccount) {
Country country = ((CountryBasedPaymentAccount) paymentAccount).getCountry();
return country != null ? country.code : null;
} else {
return null;
}
}*/
// TODO no code duplication found in UI code (added for API)
/*public static long getMaxTradeLimit(AccountAgeWitnessService accountAgeWitnessService, PaymentAccount paymentAccount, String currencyCode) {
if (paymentAccount != null)
return accountAgeWitnessService.getMyTradeLimit(paymentAccount, currencyCode);
else
return 0;
}*/
}

View File

@ -156,7 +156,7 @@ public abstract class PaymentMethodForm {
}
protected void addLimitations(boolean isDisplayForm) {
long hours = paymentAccount.getPaymentMethod().getMaxTradePeriod() / 3600_000;
long hours = paymentAccount.getMaxTradePeriod() / 3600_000;
final TradeCurrency tradeCurrency;
if (paymentAccount.getSingleTradeCurrency() != null)

View File

@ -37,15 +37,9 @@ import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.BankAccount;
import bisq.core.payment.CountryBasedPaymentAccount;
import bisq.core.payment.F2FAccount;
import bisq.core.payment.HalCashAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.SameBankAccount;
import bisq.core.payment.SepaAccount;
import bisq.core.payment.SepaInstantAccount;
import bisq.core.payment.SpecificBanksAccount;
import bisq.core.payment.PaymentAccountUtil;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.handlers.TransactionResultHandler;
@ -83,9 +77,7 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.SetChangeListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -323,34 +315,13 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
long amount = this.amount.get() != null ? this.amount.get().getValue() : 0L;
long minAmount = this.minAmount.get() != null ? this.minAmount.get().getValue() : 0L;
ArrayList<String> acceptedCountryCodes = null;
if (paymentAccount instanceof SepaAccount) {
acceptedCountryCodes = new ArrayList<>(((SepaAccount) paymentAccount).getAcceptedCountryCodes());
} else if (paymentAccount instanceof SepaInstantAccount) {
acceptedCountryCodes = new ArrayList<>(((SepaInstantAccount) paymentAccount).getAcceptedCountryCodes());
} else if (paymentAccount instanceof CountryBasedPaymentAccount) {
acceptedCountryCodes = new ArrayList<>();
acceptedCountryCodes.add(((CountryBasedPaymentAccount) paymentAccount).getCountry().code);
}
ArrayList<String> acceptedBanks = null;
if (paymentAccount instanceof SpecificBanksAccount) {
acceptedBanks = new ArrayList<>(((SpecificBanksAccount) paymentAccount).getAcceptedBanks());
} else if (paymentAccount instanceof SameBankAccount) {
acceptedBanks = new ArrayList<>();
acceptedBanks.add(((SameBankAccount) paymentAccount).getBankId());
}
String bankId = paymentAccount instanceof BankAccount ? ((BankAccount) paymentAccount).getBankId() : null;
// That is optional and set to null if not supported (AltCoins, OKPay,...)
String countryCode = paymentAccount instanceof CountryBasedPaymentAccount ? ((CountryBasedPaymentAccount) paymentAccount).getCountry().code : null;
checkNotNull(p2PService.getAddress(), "Address must not be null");
checkNotNull(getMakerFee(), "makerFee must not be null");
List<String> acceptedCountryCodes = PaymentAccountUtil.getAcceptedCountryCodes(paymentAccount);
List<String> acceptedBanks = PaymentAccountUtil.getAcceptedBanks(paymentAccount);
String bankId = PaymentAccountUtil.getBankId(paymentAccount);
String countryCode = PaymentAccountUtil.getCountryCode(paymentAccount);
long maxTradeLimit = getMaxTradeLimit();
long maxTradePeriod = paymentAccount.getPaymentMethod().getMaxTradePeriod();
long maxTradePeriod = paymentAccount.getMaxTradePeriod();
// reserved for future use cases
// Use null values if not set
@ -360,38 +331,20 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
long lowerClosePrice = 0;
long upperClosePrice = 0;
String hashOfChallenge = null;
Map<String, String> extraDataMap = null;
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
extraDataMap = new HashMap<>();
final String myWitnessHashAsHex = accountAgeWitnessService.getMyWitnessHashAsHex(paymentAccount.getPaymentAccountPayload());
extraDataMap.put(OfferPayload.ACCOUNT_AGE_WITNESS_HASH, myWitnessHashAsHex);
}
if (referralIdService.getOptionalReferralId().isPresent()) {
if (extraDataMap == null)
extraDataMap = new HashMap<>();
extraDataMap.put(OfferPayload.REFERRAL_ID, referralIdService.getOptionalReferralId().get());
}
if (paymentAccount instanceof F2FAccount) {
if (extraDataMap == null)
extraDataMap = new HashMap<>();
extraDataMap.put(OfferPayload.F2F_CITY, ((F2FAccount) paymentAccount).getCity());
extraDataMap.put(OfferPayload.F2F_EXTRA_INFO, ((F2FAccount) paymentAccount).getExtraInfo());
}
Coin buyerSecurityDepositAsCoin = buyerSecurityDeposit.get();
checkArgument(buyerSecurityDepositAsCoin.compareTo(Restrictions.getMaxBuyerSecurityDeposit()) <= 0,
"securityDeposit must be not exceed " +
Restrictions.getMaxBuyerSecurityDeposit().toFriendlyString());
checkArgument(buyerSecurityDepositAsCoin.compareTo(Restrictions.getMinBuyerSecurityDeposit()) >= 0,
"securityDeposit must be not be less than " +
Restrictions.getMinBuyerSecurityDeposit().toFriendlyString());
Coin makerFeeAsCoin = getMakerFee();
checkArgument(!filterManager.isCurrencyBanned(currencyCode),
Res.get("offerbook.warning.currencyBanned"));
checkArgument(!filterManager.isPaymentMethodBanned(paymentAccount.getPaymentMethod()),
Res.get("offerbook.warning.paymentMethodBanned"));
Map<String, String> extraDataMap = OfferUtil.getExtraDataMap(accountAgeWitnessService,
referralIdService,
paymentAccount,
currencyCode);
OfferUtil.validateOfferData(filterManager,
p2PService,
buyerSecurityDepositAsCoin,
paymentAccount,
currencyCode,
makerFeeAsCoin);
OfferPayload offerPayload = new OfferPayload(offerId,
new Date().getTime(),
@ -417,7 +370,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
Version.VERSION,
btcWalletService.getLastBlockSeenHeight(),
txFeeFromFeeService.value,
getMakerFee().value,
makerFeeAsCoin.value,
isCurrencyForMakerFeeBtc(),
buyerSecurityDepositAsCoin.value,
sellerSecurityDeposit.value,