mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-22 14:42:37 +01:00
Further speedups of TradeStatistics3.isValid
Use a Map to speed up 'PaymentMethod.getPaymentMethod', called from 'isValid', instead of scanning the payment method list every invocation. Make the list immutable to ensure the map never goes stale, which is OK since no code modified it outside PaymentMethod's static initialisation. Also speed up the global accessor 'TradeLimits.getMaxTradeLimit', by caching the DAO param value in a volatile field, cleared upon each new block arrival. Furthermore, speed up 'TradeLimits.getFirstMonthRiskBasedTradeLimit' by simplifying the rounding logic to avoid a pass through the (rather slow) BigDecimal type.
This commit is contained in:
parent
4bc1d299e5
commit
277b170e3c
2 changed files with 31 additions and 25 deletions
|
@ -19,9 +19,9 @@ package bisq.core.payment;
|
||||||
|
|
||||||
import bisq.core.dao.governance.param.Param;
|
import bisq.core.dao.governance.param.Param;
|
||||||
import bisq.core.dao.governance.period.PeriodService;
|
import bisq.core.dao.governance.period.PeriodService;
|
||||||
|
import bisq.core.dao.state.DaoStateListener;
|
||||||
import bisq.core.dao.state.DaoStateService;
|
import bisq.core.dao.state.DaoStateService;
|
||||||
|
import bisq.core.dao.state.model.blockchain.Block;
|
||||||
import bisq.common.util.MathUtils;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
public class TradeLimits {
|
public class TradeLimits implements DaoStateListener {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Getter
|
@Getter
|
||||||
private static TradeLimits INSTANCE;
|
private static TradeLimits INSTANCE;
|
||||||
|
@ -45,10 +45,14 @@ public class TradeLimits {
|
||||||
private final DaoStateService daoStateService;
|
private final DaoStateService daoStateService;
|
||||||
private final PeriodService periodService;
|
private final PeriodService periodService;
|
||||||
|
|
||||||
|
private volatile Coin cachedMaxTradeLimit;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TradeLimits(DaoStateService daoStateService, PeriodService periodService) {
|
public TradeLimits(DaoStateService daoStateService, PeriodService periodService) {
|
||||||
this.daoStateService = daoStateService;
|
this.daoStateService = daoStateService;
|
||||||
this.periodService = periodService;
|
this.periodService = periodService;
|
||||||
|
|
||||||
|
daoStateService.addDaoStateListener(this);
|
||||||
INSTANCE = this;
|
INSTANCE = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +62,10 @@ public class TradeLimits {
|
||||||
// guice.
|
// guice.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onParseBlockCompleteAfterBatchProcessing(Block block) {
|
||||||
|
cachedMaxTradeLimit = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default trade limits defined as statics in PaymentMethod are only used until the DAO
|
* The default trade limits defined as statics in PaymentMethod are only used until the DAO
|
||||||
|
@ -67,7 +75,11 @@ public class TradeLimits {
|
||||||
* @return the maximum trade limit set by the DAO.
|
* @return the maximum trade limit set by the DAO.
|
||||||
*/
|
*/
|
||||||
public Coin getMaxTradeLimit() {
|
public Coin getMaxTradeLimit() {
|
||||||
return daoStateService.getParamValueAsCoin(Param.MAX_TRADE_LIMIT, periodService.getChainHeight());
|
Coin limit = cachedMaxTradeLimit;
|
||||||
|
if (limit == null) {
|
||||||
|
cachedMaxTradeLimit = limit = daoStateService.getParamValueAsCoin(Param.MAX_TRADE_LIMIT, periodService.getChainHeight());
|
||||||
|
}
|
||||||
|
return limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We possibly rounded value for the first month gets multiplied by 4 to get the trade limit after the account
|
// We possibly rounded value for the first month gets multiplied by 4 to get the trade limit after the account
|
||||||
|
@ -98,8 +110,6 @@ public class TradeLimits {
|
||||||
long smallestLimit = maxLimit / (4 * riskFactor); // e.g. 100000000 / 32 = 3125000
|
long smallestLimit = maxLimit / (4 * riskFactor); // e.g. 100000000 / 32 = 3125000
|
||||||
// We want to avoid more than 4 decimal places (100000000 / 32 = 3125000 or 1 BTC / 32 = 0.03125 BTC).
|
// We want to avoid more than 4 decimal places (100000000 / 32 = 3125000 or 1 BTC / 32 = 0.03125 BTC).
|
||||||
// We want rounding to 0.0313 BTC
|
// We want rounding to 0.0313 BTC
|
||||||
double decimalForm = MathUtils.scaleDownByPowerOf10((double) smallestLimit, 8);
|
return ((smallestLimit + 5000L) / 10000L) * 10000L;
|
||||||
double rounded = MathUtils.roundDouble(decimalForm, 4);
|
|
||||||
return MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(rounded, 8));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,13 @@ import bisq.common.proto.persistable.PersistablePayload;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Comparator;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -196,8 +198,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
||||||
|
|
||||||
// The limit and duration assignment must not be changed as that could break old offers (if amount would be higher
|
// The limit and duration assignment must not be changed as that could break old offers (if amount would be higher
|
||||||
// than new trade limit) and violate the maker expectation when he created the offer (duration).
|
// than new trade limit) and violate the maker expectation when he created the offer (duration).
|
||||||
@Getter
|
private static final List<PaymentMethod> PAYMENT_METHODS = Stream.of(
|
||||||
private final static List<PaymentMethod> paymentMethods = new ArrayList<>(Arrays.asList(
|
|
||||||
// EUR
|
// EUR
|
||||||
SEPA = new PaymentMethod(SEPA_ID, 6 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
|
SEPA = new PaymentMethod(SEPA_ID, 6 * DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
|
||||||
SEPA_INSTANT = new PaymentMethod(SEPA_INSTANT_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
|
SEPA_INSTANT = new PaymentMethod(SEPA_INSTANT_ID, DAY, DEFAULT_TRADE_LIMIT_HIGH_RISK),
|
||||||
|
@ -277,18 +278,15 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
||||||
BLOCK_CHAINS_INSTANT = new PaymentMethod(BLOCK_CHAINS_INSTANT_ID, TimeUnit.HOURS.toMillis(1), DEFAULT_TRADE_LIMIT_VERY_LOW_RISK),
|
BLOCK_CHAINS_INSTANT = new PaymentMethod(BLOCK_CHAINS_INSTANT_ID, TimeUnit.HOURS.toMillis(1), DEFAULT_TRADE_LIMIT_VERY_LOW_RISK),
|
||||||
// BsqSwap
|
// BsqSwap
|
||||||
BSQ_SWAP = new PaymentMethod(BSQ_SWAP_ID, 1, DEFAULT_TRADE_LIMIT_VERY_LOW_RISK)
|
BSQ_SWAP = new PaymentMethod(BSQ_SWAP_ID, 1, DEFAULT_TRADE_LIMIT_VERY_LOW_RISK)
|
||||||
));
|
).sorted(Comparator.comparing(
|
||||||
|
m -> m.id.equals(CLEAR_X_CHANGE_ID) ? "ZELLE" : m.id)
|
||||||
|
).collect(Collectors.toUnmodifiableList());
|
||||||
|
|
||||||
static {
|
private static final Map<String, PaymentMethod> PAYMENT_METHOD_MAP = PAYMENT_METHODS.stream()
|
||||||
paymentMethods.sort((o1, o2) -> {
|
.collect(Collectors.toUnmodifiableMap(m -> m.id, m -> m));
|
||||||
String id1 = o1.getId();
|
|
||||||
if (id1.equals(CLEAR_X_CHANGE_ID))
|
public static List<PaymentMethod> getPaymentMethods() {
|
||||||
id1 = "ZELLE";
|
return PAYMENT_METHODS;
|
||||||
String id2 = o2.getId();
|
|
||||||
if (id2.equals(CLEAR_X_CHANGE_ID))
|
|
||||||
id2 = "ZELLE";
|
|
||||||
return id1.compareTo(id2);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PaymentMethod getDummyPaymentMethod(String id) {
|
public static PaymentMethod getDummyPaymentMethod(String id) {
|
||||||
|
@ -371,9 +369,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable<Payme
|
||||||
|
|
||||||
// We look up only our active payment methods not retired ones.
|
// We look up only our active payment methods not retired ones.
|
||||||
public static Optional<PaymentMethod> getActivePaymentMethod(String id) {
|
public static Optional<PaymentMethod> getActivePaymentMethod(String id) {
|
||||||
return paymentMethods.stream()
|
return Optional.ofNullable(PAYMENT_METHOD_MAP.get(id));
|
||||||
.filter(e -> e.getId().equals(id))
|
|
||||||
.findFirst();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Coin getMaxTradeLimitAsCoin(String currencyCode) {
|
public Coin getMaxTradeLimitAsCoin(String currencyCode) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue