From a082fd4a843734a454ee8392e39a96ad10cd6f71 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:17:10 +0100 Subject: [PATCH 01/10] Add fee fields to filter --- .../main/java/bisq/core/filter/Filter.java | 58 ++++++++++++++++--- .../resources/i18n/displayStrings.properties | 6 +- .../core/user/UserPayloadModelVOTest.java | 4 ++ .../core/util/FeeReceiverSelectorTest.java | 4 ++ .../main/overlays/windows/FilterWindow.java | 31 +++++++++- proto/src/main/proto/pb.proto | 4 ++ 6 files changed, 97 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/bisq/core/filter/Filter.java b/core/src/main/java/bisq/core/filter/Filter.java index 0a684cd9e92..3af0b8c832e 100644 --- a/core/src/main/java/bisq/core/filter/Filter.java +++ b/core/src/main/java/bisq/core/filter/Filter.java @@ -109,6 +109,13 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload { // See ProofOfWorkTest for more info. private final int powDifficulty; + // Added at v 1.8.0 + // BSQ fee gets updated in proposals repo (e.g. https://github.com/bisq-network/proposals/issues/345) + private final long makerFeeBtc; + private final long takerFeeBtc; + private final long makerFeeBsq; + private final long takerFeeBsq; + // After we have created the signature from the filter data we clone it and apply the signature static Filter cloneWithSig(Filter filter, String signatureAsBase64) { return new Filter(filter.getBannedOfferIds(), @@ -140,7 +147,11 @@ static Filter cloneWithSig(Filter filter, String signatureAsBase64) { filter.isDisableMempoolValidation(), filter.isDisableApi(), filter.isDisablePowMessage(), - filter.getPowDifficulty()); + filter.getPowDifficulty(), + filter.getMakerFeeBtc(), + filter.getTakerFeeBtc(), + filter.getMakerFeeBsq(), + filter.getTakerFeeBsq()); } // Used for signature verification as we created the sig without the signatureAsBase64 field we set it to null again @@ -174,7 +185,11 @@ static Filter cloneWithoutSig(Filter filter) { filter.isDisableMempoolValidation(), filter.isDisableApi(), filter.isDisablePowMessage(), - filter.getPowDifficulty()); + filter.getPowDifficulty(), + filter.getMakerFeeBtc(), + filter.getTakerFeeBtc(), + filter.getMakerFeeBsq(), + filter.getTakerFeeBsq()); } public Filter(List bannedOfferIds, @@ -203,7 +218,11 @@ public Filter(List bannedOfferIds, boolean disableMempoolValidation, boolean disableApi, boolean disablePowMessage, - int powDifficulty) { + int powDifficulty, + long makerFeeBtc, + long takerFeeBtc, + long makerFeeBsq, + long takerFeeBsq) { this(bannedOfferIds, nodeAddressesBannedFromTrading, bannedPaymentAccounts, @@ -233,7 +252,11 @@ public Filter(List bannedOfferIds, disableMempoolValidation, disableApi, disablePowMessage, - powDifficulty); + powDifficulty, + makerFeeBtc, + takerFeeBtc, + makerFeeBsq, + takerFeeBsq); } @@ -271,7 +294,11 @@ public Filter(List bannedOfferIds, boolean disableMempoolValidation, boolean disableApi, boolean disablePowMessage, - int powDifficulty) { + int powDifficulty, + long makerFeeBtc, + long takerFeeBtc, + long makerFeeBsq, + long takerFeeBsq) { this.bannedOfferIds = bannedOfferIds; this.nodeAddressesBannedFromTrading = nodeAddressesBannedFromTrading; this.bannedPaymentAccounts = bannedPaymentAccounts; @@ -302,6 +329,10 @@ public Filter(List bannedOfferIds, this.disableApi = disableApi; this.disablePowMessage = disablePowMessage; this.powDifficulty = powDifficulty; + this.makerFeeBtc = makerFeeBtc; + this.takerFeeBtc = takerFeeBtc; + this.makerFeeBsq = makerFeeBsq; + this.takerFeeBsq = takerFeeBsq; // ownerPubKeyBytes can be null when called from tests if (ownerPubKeyBytes != null) { @@ -344,7 +375,11 @@ public protobuf.StoragePayload toProtoMessage() { .setDisableMempoolValidation(disableMempoolValidation) .setDisableApi(disableApi) .setDisablePowMessage(disablePowMessage) - .setPowDifficulty(powDifficulty); + .setPowDifficulty(powDifficulty) + .setMakerFeeBtc(makerFeeBtc) + .setTakerFeeBtc(takerFeeBtc) + .setMakerFeeBsq(makerFeeBsq) + .setTakerFeeBsq(takerFeeBsq); Optional.ofNullable(signatureAsBase64).ifPresent(builder::setSignatureAsBase64); Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraData); @@ -357,7 +392,6 @@ public static Filter fromProto(protobuf.Filter proto) { .map(PaymentAccountFilter::fromProto) .collect(Collectors.toList()); - return new Filter(ProtoUtil.protocolStringListToList(proto.getBannedOfferIdsList()), ProtoUtil.protocolStringListToList(proto.getNodeAddressesBannedFromTradingList()), bannedPaymentAccountsList, @@ -387,7 +421,11 @@ public static Filter fromProto(protobuf.Filter proto) { proto.getDisableMempoolValidation(), proto.getDisableApi(), proto.getDisablePowMessage(), - proto.getPowDifficulty() + proto.getPowDifficulty(), + proto.getMakerFeeBtc(), + proto.getTakerFeeBtc(), + proto.getMakerFeeBsq(), + proto.getTakerFeeBsq() ); } @@ -435,6 +473,10 @@ public String toString() { ",\n disableApi=" + disableApi + ",\n disablePowMessage=" + disablePowMessage + ",\n powDifficulty=" + powDifficulty + + ",\n makerFeeBtc=" + makerFeeBtc + + ",\n takerFeeBtc=" + takerFeeBtc + + ",\n makerFeeBsq=" + makerFeeBsq + + ",\n takerFeeBsq=" + takerFeeBsq + "\n}"; } } diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 85f0c9c9262..ca65add598a 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -2780,6 +2780,10 @@ filterWindow.disableApi=Disable API filterWindow.disableMempoolValidation=Disable Mempool Validation filterWindow.disablePowMessage=Disable messages requiring Proof of Work filterWindow.powDifficulty=Proof of work difficulty (BSQ swap offers) +filterWindow.makerFeeBtc=Min. BTC maker fee (e.g. 0.001) +filterWindow.takerFeeBtc=Min. BTC taker fee (e.g. 0.007) +filterWindow.makerFeeBsq=Min. BSQ maker fee (e.g. 15.14) +filterWindow.takerFeeBsq=Min. BSQ taker fee (e.g. 105.97) offerDetailsWindow.minBtcAmount=Min. BTC amount offerDetailsWindow.min=(min. {0}) @@ -3417,7 +3421,7 @@ payment.swift.account=Account No. (or IBAN) payment.swift.use.intermediary=Use Intermediary Bank payment.swift.showPaymentInfo=Show Payment Information... payment.account.owner.address=Account owner address -payment.transferwiseUsd.address= (must be US-based, consider using bank address) +payment.transferwiseUsd.address=(must be US-based, consider using bank address) payment.amazon.site=Buy giftcard at payment.ask=Ask in Trader Chat diff --git a/core/src/test/java/bisq/core/user/UserPayloadModelVOTest.java b/core/src/test/java/bisq/core/user/UserPayloadModelVOTest.java index e6340678eae..3c953583027 100644 --- a/core/src/test/java/bisq/core/user/UserPayloadModelVOTest.java +++ b/core/src/test/java/bisq/core/user/UserPayloadModelVOTest.java @@ -71,6 +71,10 @@ public void testRoundtripFull() { false, false, false, + 0, + 0, + 0, + 0, 0)); vo.setRegisteredArbitrator(ArbitratorTest.getArbitratorMock()); diff --git a/core/src/test/java/bisq/core/util/FeeReceiverSelectorTest.java b/core/src/test/java/bisq/core/util/FeeReceiverSelectorTest.java index 4d38a1487a2..2dcbd5b1a19 100644 --- a/core/src/test/java/bisq/core/util/FeeReceiverSelectorTest.java +++ b/core/src/test/java/bisq/core/util/FeeReceiverSelectorTest.java @@ -132,6 +132,10 @@ private static Filter filterWithReceivers(List btcFeeReceiverAddresses) false, false, false, + 0, + 0, + 0, + 0, 0); } } diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/FilterWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/FilterWindow.java index a2fe76adb90..d393de487df 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/FilterWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/FilterWindow.java @@ -26,11 +26,17 @@ import bisq.core.filter.FilterManager; import bisq.core.filter.PaymentAccountFilter; import bisq.core.locale.Res; +import bisq.core.util.FormattingUtils; +import bisq.core.util.ParsingUtils; +import bisq.core.util.coin.BsqFormatter; +import bisq.core.util.coin.CoinFormatter; import bisq.common.UserThread; import bisq.common.app.DevEnv; import bisq.common.config.Config; +import org.bitcoinj.core.Coin; + import com.google.inject.Inject; import javax.inject.Named; @@ -63,13 +69,19 @@ public class FilterWindow extends Overlay { private final FilterManager filterManager; + private final BsqFormatter bsqFormatter; + private final CoinFormatter btcFormatter; private final boolean useDevPrivilegeKeys; private ScrollPane scrollPane; @Inject public FilterWindow(FilterManager filterManager, + BsqFormatter bsqFormatter, + @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter, @Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) { this.filterManager = filterManager; + this.bsqFormatter = bsqFormatter; + this.btcFormatter = btcFormatter; this.useDevPrivilegeKeys = useDevPrivilegeKeys; type = Type.Attention; } @@ -178,6 +190,14 @@ private void addContent() { InputTextField powDifficultyTF = addInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.powDifficulty")); powDifficultyTF.setText("0"); + InputTextField makerFeeBtcTF = addInputTextField(gridPane, ++rowIndex, + Res.get("filterWindow.makerFeeBtc")); + InputTextField takerFeeBtcTF = addInputTextField(gridPane, ++rowIndex, + Res.get("filterWindow.takerFeeBtc")); + InputTextField makerFeeBsqTF = addInputTextField(gridPane, ++rowIndex, + Res.get("filterWindow.makerFeeBsq")); + InputTextField takerFeeBsqTF = addInputTextField(gridPane, ++rowIndex, + Res.get("filterWindow.takerFeeBsq")); Filter filter = filterManager.getDevFilter(); if (filter != null) { @@ -207,6 +227,11 @@ private void addContent() { disableApiCheckBox.setSelected(filter.isDisableApi()); disablePowMessage.setSelected(filter.isDisablePowMessage()); powDifficultyTF.setText(String.valueOf(filter.getPowDifficulty())); + + makerFeeBtcTF.setText(btcFormatter.formatCoin(Coin.valueOf(filter.getMakerFeeBtc()))); + takerFeeBtcTF.setText(btcFormatter.formatCoin(Coin.valueOf(filter.getTakerFeeBtc()))); + makerFeeBsqTF.setText(bsqFormatter.formatBSQSatoshis(filter.getMakerFeeBsq())); + takerFeeBsqTF.setText(bsqFormatter.formatBSQSatoshis(filter.getTakerFeeBsq())); } Button removeFilterMessageButton = new AutoTooltipButton(Res.get("filterWindow.remove")); @@ -244,7 +269,11 @@ private void addContent() { disableMempoolValidationCheckBox.isSelected(), disableApiCheckBox.isSelected(), disablePowMessage.isSelected(), - Integer.parseInt(powDifficultyTF.getText()) + Integer.parseInt(powDifficultyTF.getText()), + ParsingUtils.parseToCoin(makerFeeBtcTF.getText(), btcFormatter).value, + ParsingUtils.parseToCoin(takerFeeBtcTF.getText(), btcFormatter).value, + ParsingUtils.parseToCoin(makerFeeBsqTF.getText(), bsqFormatter).value, + ParsingUtils.parseToCoin(takerFeeBsqTF.getText(), bsqFormatter).value ); // We remove first the old filter diff --git a/proto/src/main/proto/pb.proto b/proto/src/main/proto/pb.proto index e305174798c..724fdf7d60f 100644 --- a/proto/src/main/proto/pb.proto +++ b/proto/src/main/proto/pb.proto @@ -770,6 +770,10 @@ message Filter { bool disable_mempool_validation = 28; bool disable_pow_message = 29; int32 pow_difficulty = 30; + int64 maker_fee_btc = 31; + int64 taker_fee_btc = 32; + int64 maker_fee_bsq = 33; + int64 taker_fee_bsq = 34; } // Deprecated From 65285e2c6963f124d92dd008e61ead625b9cd2c9 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:24:36 +0100 Subject: [PATCH 02/10] Add filterManager to filterManager (will be used in follow-up commits) --- .../bisq/core/provider/mempool/MempoolService.java | 6 +++--- .../bisq/core/provider/mempool/TxValidator.java | 13 ++++++++++--- .../bisq/core/provider/mempool/TxValidatorTest.java | 4 +++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/MempoolService.java b/core/src/main/java/bisq/core/provider/mempool/MempoolService.java index 9a347d8e00d..1ef55a60e58 100644 --- a/core/src/main/java/bisq/core/provider/mempool/MempoolService.java +++ b/core/src/main/java/bisq/core/provider/mempool/MempoolService.java @@ -93,7 +93,7 @@ public boolean canRequestBeMade(OfferPayload offerPayload) { public void validateOfferMakerTx(OfferPayload offerPayload, Consumer resultHandler) { validateOfferMakerTx(new TxValidator(daoStateService, offerPayload.getOfferFeePaymentTxId(), Coin.valueOf(offerPayload.getAmount()), - offerPayload.isCurrencyForMakerFeeBtc()), resultHandler); + offerPayload.isCurrencyForMakerFeeBtc(), filterManager), resultHandler); } public void validateOfferMakerTx(TxValidator txValidator, Consumer resultHandler) { @@ -107,7 +107,7 @@ public void validateOfferMakerTx(TxValidator txValidator, Consumer public void validateOfferTakerTx(Trade trade, Consumer resultHandler) { validateOfferTakerTx(new TxValidator(daoStateService, trade.getTakerFeeTxId(), trade.getAmount(), - trade.isCurrencyForTakerFeeBtc()), resultHandler); + trade.isCurrencyForTakerFeeBtc(), filterManager), resultHandler); } public void validateOfferTakerTx(TxValidator txValidator, Consumer resultHandler) { @@ -120,7 +120,7 @@ public void validateOfferTakerTx(TxValidator txValidator, Consumer } public void checkTxIsConfirmed(String txId, Consumer resultHandler) { - TxValidator txValidator = new TxValidator(daoStateService, txId); + TxValidator txValidator = new TxValidator(daoStateService, txId, filterManager); if (!isServiceSupported()) { UserThread.runAfter(() -> resultHandler.accept(txValidator.endResult("mempool request not supported, bypassing", true)), 1); return; diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 7a70f543633..9b827502c0a 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -19,6 +19,7 @@ import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.DaoStateService; +import bisq.core.filter.FilterManager; import bisq.common.util.Tuple2; @@ -49,6 +50,7 @@ public class TxValidator { private final static long BLOCK_TOLERANCE = 599999L; // allow really old offers with weird fee addresses private final DaoStateService daoStateService; + private final FilterManager filterManager; private final List errorList; private final String txId; private Coin amount; @@ -59,20 +61,25 @@ public class TxValidator { @Setter private String jsonTxt; - - public TxValidator(DaoStateService daoStateService, String txId, Coin amount, @Nullable Boolean isFeeCurrencyBtc) { + public TxValidator(DaoStateService daoStateService, + String txId, + Coin amount, + @Nullable Boolean isFeeCurrencyBtc, + FilterManager filterManager) { this.daoStateService = daoStateService; this.txId = txId; this.amount = amount; this.isFeeCurrencyBtc = isFeeCurrencyBtc; + this.filterManager = filterManager; this.errorList = new ArrayList<>(); this.jsonTxt = ""; } - public TxValidator(DaoStateService daoStateService, String txId) { + public TxValidator(DaoStateService daoStateService, String txId, FilterManager filterManager) { this.daoStateService = daoStateService; this.txId = txId; this.chainHeight = (long) daoStateService.getChainHeight(); + this.filterManager = filterManager; this.errorList = new ArrayList<>(); this.jsonTxt = ""; } diff --git a/core/src/test/java/bisq/core/provider/mempool/TxValidatorTest.java b/core/src/test/java/bisq/core/provider/mempool/TxValidatorTest.java index d3c68c61456..8cdea1cd98a 100644 --- a/core/src/test/java/bisq/core/provider/mempool/TxValidatorTest.java +++ b/core/src/test/java/bisq/core/provider/mempool/TxValidatorTest.java @@ -19,6 +19,7 @@ import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.DaoStateService; +import bisq.core.filter.FilterManager; import bisq.core.trade.DelayedPayoutAddressProvider; import bisq.core.util.FeeReceiverSelector; import bisq.core.util.ParsingUtils; @@ -204,7 +205,8 @@ private TxValidator createTxValidator(String offerData) { when(mockedDaoStateService.getParamValueAsCoin(Mockito.any(Param.class), Mockito.anyInt())).thenAnswer(mockGetFeeRate); when(mockedDaoStateService.getParamValueAsCoin(Mockito.any(Param.class), Mockito.anyString())).thenAnswer(mockGetParamValueAsCoin); when(mockedDaoStateService.getParamChangeList(Mockito.any())).thenAnswer(mockGetParamChangeList); - TxValidator txValidator = new TxValidator(mockedDaoStateService, txId, Coin.valueOf(amount), isCurrencyForMakerFeeBtc); + FilterManager filterManager = mock(FilterManager.class); + TxValidator txValidator = new TxValidator(mockedDaoStateService, txId, Coin.valueOf(amount), isCurrencyForMakerFeeBtc, filterManager); return txValidator; } catch (RuntimeException ignore) { // If input format is not as expected we ignore entry From e57c6820014790ce30f8778059118997df984403 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:28:52 +0100 Subject: [PATCH 03/10] Add blockHeightAtOfferCreation to TxValidator Used in case of maker fee validation --- .../core/provider/mempool/MempoolService.java | 2 +- .../core/provider/mempool/TxValidator.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/MempoolService.java b/core/src/main/java/bisq/core/provider/mempool/MempoolService.java index 1ef55a60e58..6f62d31b531 100644 --- a/core/src/main/java/bisq/core/provider/mempool/MempoolService.java +++ b/core/src/main/java/bisq/core/provider/mempool/MempoolService.java @@ -93,7 +93,7 @@ public boolean canRequestBeMade(OfferPayload offerPayload) { public void validateOfferMakerTx(OfferPayload offerPayload, Consumer resultHandler) { validateOfferMakerTx(new TxValidator(daoStateService, offerPayload.getOfferFeePaymentTxId(), Coin.valueOf(offerPayload.getAmount()), - offerPayload.isCurrencyForMakerFeeBtc(), filterManager), resultHandler); + offerPayload.isCurrencyForMakerFeeBtc(), offerPayload.getBlockHeightAtOfferCreation(), filterManager), resultHandler); } public void validateOfferMakerTx(TxValidator txValidator, Consumer resultHandler) { diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 9b827502c0a..042791451ca 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -51,6 +51,7 @@ public class TxValidator { private final DaoStateService daoStateService; private final FilterManager filterManager; + private long blockHeightAtOfferCreation; // Only set for maker. private final List errorList; private final String txId; private Coin amount; @@ -75,6 +76,22 @@ public TxValidator(DaoStateService daoStateService, this.jsonTxt = ""; } + public TxValidator(DaoStateService daoStateService, + String txId, + Coin amount, + @Nullable Boolean isFeeCurrencyBtc, + long blockHeightAtOfferCreation, + FilterManager filterManager) { + this.daoStateService = daoStateService; + this.txId = txId; + this.amount = amount; + this.isFeeCurrencyBtc = isFeeCurrencyBtc; + this.blockHeightAtOfferCreation = blockHeightAtOfferCreation; + this.filterManager = filterManager; + this.errorList = new ArrayList<>(); + this.jsonTxt = ""; + } + public TxValidator(DaoStateService daoStateService, String txId, FilterManager filterManager) { this.daoStateService = daoStateService; this.txId = txId; @@ -306,10 +323,16 @@ private static long getTxConfirms(String jsonTxt, long chainHeight) { // we want the block height applicable for calculating the appropriate expected trading fees // if the tx is not yet confirmed, use current block tip, if tx is confirmed use the block it was confirmed at. private long getBlockHeightForFeeCalculation(String jsonTxt) { + // For the maker we set the blockHeightAtOfferCreation from the offer + if (blockHeightAtOfferCreation > 0) { + return blockHeightAtOfferCreation; + } + long txBlockHeight = getTxBlockHeight(jsonTxt); if (txBlockHeight > 0) { return txBlockHeight; } + return daoStateService.getChainHeight(); } From b427795e4c1f91d93f4e2c75dfe4e78b0f636068 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:32:28 +0100 Subject: [PATCH 04/10] Extract minFeeParam Cleanup --- .../bisq/core/provider/mempool/TxValidator.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 042791451ca..5e0a3b75008 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -47,7 +47,7 @@ @Getter public class TxValidator { private final static double FEE_TOLERANCE = 0.95; // we expect fees to be at least 95% of target - private final static long BLOCK_TOLERANCE = 599999L; // allow really old offers with weird fee addresses + private final static long BLOCK_TOLERANCE = 599999; // allow really old offers with weird fee addresses private final DaoStateService daoStateService; private final FilterManager filterManager; @@ -195,9 +195,11 @@ private boolean checkFeeAmountBTC(String jsonTxt, Coin tradeAmount, boolean isMa } long feeValue = jsonFeeValue.getAsLong(); log.debug("BTC fee: {}", feeValue); + + Param minFeeParam = isMaker ? Param.MIN_MAKER_FEE_BTC : Param.MIN_TAKER_FEE_BTC; Coin expectedFee = getFeeHistorical(tradeAmount, isMaker ? getMakerFeeRateBtc(blockHeight) : getTakerFeeRateBtc(blockHeight), - isMaker ? Param.MIN_MAKER_FEE_BTC : Param.MIN_TAKER_FEE_BTC); + minFeeParam); double leniencyCalc = feeValue / (double) expectedFee.getValue(); String description = "Expected BTC fee: " + expectedFee.toString() + " sats , actual fee paid: " + Coin.valueOf(feeValue).toString() + " sats"; if (expectedFee.getValue() == feeValue) { @@ -211,7 +213,7 @@ private boolean checkFeeAmountBTC(String jsonTxt, Coin tradeAmount, boolean isMa return true; } else if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), isMaker ? Param.DEFAULT_MAKER_FEE_BTC : Param.DEFAULT_TAKER_FEE_BTC, - isMaker ? Param.MIN_MAKER_FEE_BTC : Param.MIN_TAKER_FEE_BTC)) { + minFeeParam)) { log.info("Leniency rule: the fee matches a different DAO parameter {}", description); return true; } else { @@ -236,9 +238,10 @@ private boolean checkFeeAmountBSQ(String jsonTxt, Coin tradeAmount, boolean isMa if (jsonVIn0Value == null || jsonFeeValue == null) { throw new JsonSyntaxException("vin/vout missing data"); } + Param minFeeParam = isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ; Coin expectedFee = getFeeHistorical(tradeAmount, isMaker ? getMakerFeeRateBsq(blockHeight) : getTakerFeeRateBsq(blockHeight), - isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ); + minFeeParam); long feeValue = jsonVIn0Value.getAsLong() - jsonFeeValue.getAsLong(); // if the first output (BSQ) is greater than the first input (BSQ) include the second input (presumably BSQ) if (jsonFeeValue.getAsLong() > jsonVIn0Value.getAsLong()) { @@ -387,7 +390,10 @@ private Coin getTakerFeeRateBtc(long blockHeight) { // implements leniency rule of accepting old DAO rate parameters: https://github.com/bisq-network/bisq/issues/5329#issuecomment-803223859 // We iterate over all past dao param values and if one of those matches we consider it valid. That covers the non-in-sync cases. - private boolean feeExistsUsingDifferentDaoParam(Coin tradeAmount, Coin actualFeeValue, Param defaultFeeParam, Param minFeeParam) { + private boolean feeExistsUsingDifferentDaoParam(Coin tradeAmount, + Coin actualFeeValue, + Param defaultFeeParam, + Param minFeeParam) { for (Coin daoHistoricalRate : daoStateService.getParamChangeList(defaultFeeParam)) { if (actualFeeValue.equals(getFeeHistorical(tradeAmount, daoHistoricalRate, minFeeParam))) { return true; From c88addef1663a7fc29e62a62cf093c9791d381dd Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:34:03 +0100 Subject: [PATCH 05/10] Break up if else clauses (helps for improvements in later commits) --- .../core/provider/mempool/TxValidator.java | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 5e0a3b75008..529dc5e13ef 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -205,22 +205,28 @@ private boolean checkFeeAmountBTC(String jsonTxt, Coin tradeAmount, boolean isMa if (expectedFee.getValue() == feeValue) { log.debug("The fee matched what we expected"); return true; - } else if (expectedFee.getValue() < feeValue) { + } + + if (expectedFee.getValue() < feeValue) { log.info("The fee was more than what we expected: " + description); return true; - } else if (leniencyCalc > FEE_TOLERANCE) { + } + + if (leniencyCalc > FEE_TOLERANCE) { log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", FEE_TOLERANCE, leniencyCalc, description); return true; - } else if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), + } + + if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), isMaker ? Param.DEFAULT_MAKER_FEE_BTC : Param.DEFAULT_TAKER_FEE_BTC, minFeeParam)) { log.info("Leniency rule: the fee matches a different DAO parameter {}", description); return true; - } else { - String feeUnderpaidMessage = "UNDERPAID. " + description; - errorList.add(feeUnderpaidMessage); - log.info(feeUnderpaidMessage); } + + String feeUnderpaidMessage = "UNDERPAID. " + description; + errorList.add(feeUnderpaidMessage); + log.info(feeUnderpaidMessage); return false; } @@ -258,21 +264,27 @@ private boolean checkFeeAmountBSQ(String jsonTxt, Coin tradeAmount, boolean isMa if (expectedFee.getValue() == feeValue) { log.debug("The fee matched what we expected"); return true; - } else if (expectedFee.getValue() < feeValue) { + } + + if (expectedFee.getValue() < feeValue) { log.info("The fee was more than what we expected. " + description); return true; - } else if (leniencyCalc > FEE_TOLERANCE) { + } + + if (leniencyCalc > FEE_TOLERANCE) { log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", FEE_TOLERANCE, leniencyCalc, description); return true; - } else if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), + } + + if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), isMaker ? Param.DEFAULT_MAKER_FEE_BSQ : Param.DEFAULT_TAKER_FEE_BSQ, isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ)) { log.info("Leniency rule: the fee matches a different DAO parameter {}", description); return true; - } else { - errorList.add(description); - log.info(description); } + + errorList.add(description); + log.info(description); return false; } From 1027b9d7fe0af9ad6153c44d5a393bfe64383769 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:36:46 +0100 Subject: [PATCH 06/10] Extract vars Cleanups --- .../core/provider/mempool/TxValidator.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 529dc5e13ef..08a99c8b734 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -200,26 +200,27 @@ private boolean checkFeeAmountBTC(String jsonTxt, Coin tradeAmount, boolean isMa Coin expectedFee = getFeeHistorical(tradeAmount, isMaker ? getMakerFeeRateBtc(blockHeight) : getTakerFeeRateBtc(blockHeight), minFeeParam); - double leniencyCalc = feeValue / (double) expectedFee.getValue(); String description = "Expected BTC fee: " + expectedFee.toString() + " sats , actual fee paid: " + Coin.valueOf(feeValue).toString() + " sats"; - if (expectedFee.getValue() == feeValue) { + + long expectedFeeAsLong = expectedFee.getValue(); + if (expectedFeeAsLong == feeValue) { log.debug("The fee matched what we expected"); return true; } - if (expectedFee.getValue() < feeValue) { + if (expectedFeeAsLong < feeValue) { log.info("The fee was more than what we expected: " + description); return true; } + double leniencyCalc = feeValue / (double) expectedFeeAsLong; if (leniencyCalc > FEE_TOLERANCE) { log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", FEE_TOLERANCE, leniencyCalc, description); return true; } - if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), - isMaker ? Param.DEFAULT_MAKER_FEE_BTC : Param.DEFAULT_TAKER_FEE_BTC, - minFeeParam)) { + Param defaultFeeParam = isMaker ? Param.DEFAULT_MAKER_FEE_BTC : Param.DEFAULT_TAKER_FEE_BTC; + if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), defaultFeeParam, minFeeParam)) { log.info("Leniency rule: the fee matches a different DAO parameter {}", description); return true; } @@ -258,27 +259,28 @@ private boolean checkFeeAmountBSQ(String jsonTxt, Coin tradeAmount, boolean isMa feeValue += jsonVIn1Value.getAsLong(); } log.debug("BURNT BSQ maker fee: {} BSQ ({} sats)", (double) feeValue / 100.0, feeValue); - double leniencyCalc = feeValue / (double) expectedFee.getValue(); + long expectedFeeAsLong = expectedFee.getValue(); String description = String.format("Expected fee: %.2f BSQ, actual fee paid: %.2f BSQ", - (double) expectedFee.getValue() / 100.0, (double) feeValue / 100.0); - if (expectedFee.getValue() == feeValue) { + (double) expectedFeeAsLong / 100.0, (double) feeValue / 100.0); + + if (expectedFeeAsLong == feeValue) { log.debug("The fee matched what we expected"); return true; } - if (expectedFee.getValue() < feeValue) { + if (expectedFeeAsLong < feeValue) { log.info("The fee was more than what we expected. " + description); return true; } + double leniencyCalc = feeValue / (double) expectedFeeAsLong; if (leniencyCalc > FEE_TOLERANCE) { log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", FEE_TOLERANCE, leniencyCalc, description); return true; } - if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), - isMaker ? Param.DEFAULT_MAKER_FEE_BSQ : Param.DEFAULT_TAKER_FEE_BSQ, - isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ)) { + Param defaultFeeParam = isMaker ? Param.DEFAULT_MAKER_FEE_BSQ : Param.DEFAULT_TAKER_FEE_BSQ; + if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), defaultFeeParam, minFeeParam)) { log.info("Leniency rule: the fee matches a different DAO parameter {}", description); return true; } From 2e137459dc21130a50e614c89ee63e496227ab8c Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:44:31 +0100 Subject: [PATCH 07/10] Add check for fee from filter That check is done if: - If we are after activation time - If filter is available - If value in filter is > 0 The check compares the paid fee and the fee value from filter and requires that paid fee is > 70% of filter value. See comments in code for more background. --- .../core/provider/mempool/TxValidator.java | 84 ++++++++++++++++++- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 08a99c8b734..9e3df5d2f02 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -22,6 +22,7 @@ import bisq.core.filter.FilterManager; import bisq.common.util.Tuple2; +import bisq.common.util.Utilities; import org.bitcoinj.core.Coin; @@ -32,7 +33,10 @@ import com.google.gson.JsonSyntaxException; import java.util.ArrayList; +import java.util.Date; +import java.util.GregorianCalendar; import java.util.List; +import java.util.Optional; import lombok.Getter; import lombok.Setter; @@ -46,6 +50,7 @@ @Slf4j @Getter public class TxValidator { + private static final Date USE_FEE_FROM_FILTER_ACTIVATION_DATE = Utilities.getUTCDate(2022, GregorianCalendar.JANUARY, 1); private final static double FEE_TOLERANCE = 0.95; // we expect fees to be at least 95% of target private final static long BLOCK_TOLERANCE = 599999; // allow really old offers with weird fee addresses @@ -200,9 +205,11 @@ private boolean checkFeeAmountBTC(String jsonTxt, Coin tradeAmount, boolean isMa Coin expectedFee = getFeeHistorical(tradeAmount, isMaker ? getMakerFeeRateBtc(blockHeight) : getTakerFeeRateBtc(blockHeight), minFeeParam); - String description = "Expected BTC fee: " + expectedFee.toString() + " sats , actual fee paid: " + Coin.valueOf(feeValue).toString() + " sats"; + Coin feeValueAsCoin = Coin.valueOf(feeValue); long expectedFeeAsLong = expectedFee.getValue(); + String description = "Expected BTC fee: " + expectedFee + " sats , actual fee paid: " + + feeValueAsCoin + " sats"; if (expectedFeeAsLong == feeValue) { log.debug("The fee matched what we expected"); return true; @@ -215,12 +222,23 @@ private boolean checkFeeAmountBTC(String jsonTxt, Coin tradeAmount, boolean isMa double leniencyCalc = feeValue / (double) expectedFeeAsLong; if (leniencyCalc > FEE_TOLERANCE) { - log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", FEE_TOLERANCE, leniencyCalc, description); + log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", + FEE_TOLERANCE, leniencyCalc, description); return true; } + Optional maybeTestFeeFromFilter = maybeTestFeeFromFilter(tradeAmount, + isMaker, + feeValueAsCoin, + minFeeParam, + true, + description); + if (maybeTestFeeFromFilter.isPresent()) { + return maybeTestFeeFromFilter.get(); + } + Param defaultFeeParam = isMaker ? Param.DEFAULT_MAKER_FEE_BTC : Param.DEFAULT_TAKER_FEE_BTC; - if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), defaultFeeParam, minFeeParam)) { + if (feeExistsUsingDifferentDaoParam(tradeAmount, feeValueAsCoin, defaultFeeParam, minFeeParam)) { log.info("Leniency rule: the fee matches a different DAO parameter {}", description); return true; } @@ -278,6 +296,17 @@ private boolean checkFeeAmountBSQ(String jsonTxt, Coin tradeAmount, boolean isMa log.info("Leniency rule: the fee was low, but above {} of what was expected {} {}", FEE_TOLERANCE, leniencyCalc, description); return true; } + Coin feeValueAsCoin = Coin.valueOf(feeValue); + + Optional maybeTestFeeFromFilter = maybeTestFeeFromFilter(tradeAmount, + isMaker, + feeValueAsCoin, + minFeeParam, + false, + description); + if (maybeTestFeeFromFilter.isPresent()) { + return maybeTestFeeFromFilter.get(); + } Param defaultFeeParam = isMaker ? Param.DEFAULT_MAKER_FEE_BSQ : Param.DEFAULT_TAKER_FEE_BSQ; if (feeExistsUsingDifferentDaoParam(tradeAmount, Coin.valueOf(feeValue), defaultFeeParam, minFeeParam)) { @@ -402,6 +431,55 @@ private Coin getTakerFeeRateBtc(long blockHeight) { return daoStateService.getParamValueAsCoin(Param.DEFAULT_TAKER_FEE_BTC, (int) blockHeight); } + private Optional maybeTestFeeFromFilter(Coin tradeAmount, + boolean isMaker, + Coin feeValueAsCoin, + Param minFeeParam, + boolean isBtcFee, + String description) { + if (new Date().before(USE_FEE_FROM_FILTER_ACTIVATION_DATE)) { + return Optional.empty(); + } + return getFeeFromFilter(isMaker, isBtcFee) + .map(feeFromFilter -> { + boolean isValid = testWithFeeFromFilter(tradeAmount, feeValueAsCoin, feeFromFilter, minFeeParam); + if (!isValid) { + log.warn("Fee does not match fee from filter. Fee from filter={}. {}", feeFromFilter, description); + } + return isValid; + }); + } + + private Optional getFeeFromFilter(boolean isMaker, boolean isBtcFee) { + return Optional.ofNullable(filterManager.getFilter()) + .map(filter -> { + Coin value; + if (isMaker) { + value = isBtcFee ? + Coin.valueOf(filter.getMakerFeeBtc()) : + Coin.valueOf(filter.getMakerFeeBsq()); + } else { + value = isBtcFee ? + Coin.valueOf(filter.getTakerFeeBtc()) : + Coin.valueOf(filter.getTakerFeeBsq()); + } + return value; + }) + .filter(Coin::isPositive); + } + + private boolean testWithFeeFromFilter(Coin tradeAmount, + Coin actualFeeValue, + Coin feeFromFilter, + Param minFeeParam) { + long actualFeeAsLong = actualFeeValue.value; + long feeFromFilterAsLong = getFeeHistorical(tradeAmount, feeFromFilter, minFeeParam).value; + double deviation = actualFeeAsLong / (double) feeFromFilterAsLong; + // It can be that the filter has not been updated immediately after DAO param change, so we need a tolerance + // Common change rate is 15-20% + return deviation > 0.7; + } + // implements leniency rule of accepting old DAO rate parameters: https://github.com/bisq-network/bisq/issues/5329#issuecomment-803223859 // We iterate over all past dao param values and if one of those matches we consider it valid. That covers the non-in-sync cases. private boolean feeExistsUsingDifferentDaoParam(Coin tradeAmount, From 5928b448430b6e282cdfec8e47ced8480e26b705 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:48:07 +0100 Subject: [PATCH 08/10] Use genesis height in maybeTestFeeFromFilter instead of 0 --- .../src/main/java/bisq/core/provider/mempool/TxValidator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 9e3df5d2f02..614278bc80e 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -491,8 +491,8 @@ private boolean feeExistsUsingDifferentDaoParam(Coin tradeAmount, return true; } } - // finally check the default rate used when we ask for the fee rate at block height 0 (it is hard coded in the Param enum) - Coin defaultRate = daoStateService.getParamValueAsCoin(defaultFeeParam, 0); + // Finally, check the default rate used when we ask for the fee rate at genesis block height (it is hard coded in the Param enum) + Coin defaultRate = daoStateService.getParamValueAsCoin(defaultFeeParam, daoStateService.getGenesisBlockHeight()); return actualFeeValue.equals(getFeeHistorical(tradeAmount, defaultRate, minFeeParam)); } From b00d317e889fb44f77640e046a7a91a6c2311689 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Sun, 14 Nov 2021 14:49:03 +0100 Subject: [PATCH 09/10] Rename getFeeHistorical to calculateFee --- .../java/bisq/core/provider/mempool/TxValidator.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 614278bc80e..6aa147bc7ca 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -202,7 +202,7 @@ private boolean checkFeeAmountBTC(String jsonTxt, Coin tradeAmount, boolean isMa log.debug("BTC fee: {}", feeValue); Param minFeeParam = isMaker ? Param.MIN_MAKER_FEE_BTC : Param.MIN_TAKER_FEE_BTC; - Coin expectedFee = getFeeHistorical(tradeAmount, + Coin expectedFee = calculateFee(tradeAmount, isMaker ? getMakerFeeRateBtc(blockHeight) : getTakerFeeRateBtc(blockHeight), minFeeParam); @@ -264,7 +264,7 @@ private boolean checkFeeAmountBSQ(String jsonTxt, Coin tradeAmount, boolean isMa throw new JsonSyntaxException("vin/vout missing data"); } Param minFeeParam = isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ; - Coin expectedFee = getFeeHistorical(tradeAmount, + Coin expectedFee = calculateFee(tradeAmount, isMaker ? getMakerFeeRateBsq(blockHeight) : getTakerFeeRateBsq(blockHeight), minFeeParam); long feeValue = jsonVIn0Value.getAsLong() - jsonFeeValue.getAsLong(); @@ -405,7 +405,7 @@ private static long getTxBlockHeight(String jsonTxt) { return 0L; // in mempool, not confirmed yet } - private Coin getFeeHistorical(Coin amount, Coin feeRatePerBtc, Param minFeeParam) { + private Coin calculateFee(Coin amount, Coin feeRatePerBtc, Param minFeeParam) { double feePerBtcAsDouble = (double) feeRatePerBtc.value; double amountAsDouble = amount != null ? (double) amount.value : 0; double btcAsDouble = (double) Coin.COIN.value; @@ -473,7 +473,7 @@ private boolean testWithFeeFromFilter(Coin tradeAmount, Coin feeFromFilter, Param minFeeParam) { long actualFeeAsLong = actualFeeValue.value; - long feeFromFilterAsLong = getFeeHistorical(tradeAmount, feeFromFilter, minFeeParam).value; + long feeFromFilterAsLong = calculateFee(tradeAmount, feeFromFilter, minFeeParam).value; double deviation = actualFeeAsLong / (double) feeFromFilterAsLong; // It can be that the filter has not been updated immediately after DAO param change, so we need a tolerance // Common change rate is 15-20% @@ -487,13 +487,13 @@ private boolean feeExistsUsingDifferentDaoParam(Coin tradeAmount, Param defaultFeeParam, Param minFeeParam) { for (Coin daoHistoricalRate : daoStateService.getParamChangeList(defaultFeeParam)) { - if (actualFeeValue.equals(getFeeHistorical(tradeAmount, daoHistoricalRate, minFeeParam))) { + if (actualFeeValue.equals(calculateFee(tradeAmount, daoHistoricalRate, minFeeParam))) { return true; } } // Finally, check the default rate used when we ask for the fee rate at genesis block height (it is hard coded in the Param enum) Coin defaultRate = daoStateService.getParamValueAsCoin(defaultFeeParam, daoStateService.getGenesisBlockHeight()); - return actualFeeValue.equals(getFeeHistorical(tradeAmount, defaultRate, minFeeParam)); + return actualFeeValue.equals(calculateFee(tradeAmount, defaultRate, minFeeParam)); } public TxValidator endResult(String title, boolean status) { From f17c2e12340fb0deb5b02cf101fd0b18880bfa92 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Mon, 15 Nov 2021 13:05:40 +0100 Subject: [PATCH 10/10] Rename method --- .../core/provider/mempool/TxValidator.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java index 6aa147bc7ca..2533a7ca627 100644 --- a/core/src/main/java/bisq/core/provider/mempool/TxValidator.java +++ b/core/src/main/java/bisq/core/provider/mempool/TxValidator.java @@ -227,14 +227,14 @@ private boolean checkFeeAmountBTC(String jsonTxt, Coin tradeAmount, boolean isMa return true; } - Optional maybeTestFeeFromFilter = maybeTestFeeFromFilter(tradeAmount, + Optional result = maybeCheckAgainstFeeFromFilter(tradeAmount, isMaker, feeValueAsCoin, minFeeParam, true, description); - if (maybeTestFeeFromFilter.isPresent()) { - return maybeTestFeeFromFilter.get(); + if (result.isPresent()) { + return result.get(); } Param defaultFeeParam = isMaker ? Param.DEFAULT_MAKER_FEE_BTC : Param.DEFAULT_TAKER_FEE_BTC; @@ -298,7 +298,7 @@ private boolean checkFeeAmountBSQ(String jsonTxt, Coin tradeAmount, boolean isMa } Coin feeValueAsCoin = Coin.valueOf(feeValue); - Optional maybeTestFeeFromFilter = maybeTestFeeFromFilter(tradeAmount, + Optional maybeTestFeeFromFilter = maybeCheckAgainstFeeFromFilter(tradeAmount, isMaker, feeValueAsCoin, minFeeParam, @@ -431,12 +431,12 @@ private Coin getTakerFeeRateBtc(long blockHeight) { return daoStateService.getParamValueAsCoin(Param.DEFAULT_TAKER_FEE_BTC, (int) blockHeight); } - private Optional maybeTestFeeFromFilter(Coin tradeAmount, - boolean isMaker, - Coin feeValueAsCoin, - Param minFeeParam, - boolean isBtcFee, - String description) { + private Optional maybeCheckAgainstFeeFromFilter(Coin tradeAmount, + boolean isMaker, + Coin feeValueAsCoin, + Param minFeeParam, + boolean isBtcFee, + String description) { if (new Date().before(USE_FEE_FROM_FILTER_ACTIVATION_DATE)) { return Optional.empty(); }