From 0580e7317944fe2d1a4c8c1fd309d451343f1720 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 16 Feb 2017 15:43:38 -0500 Subject: [PATCH] Use new tx and trade fees. UI improvements, remove trade fee from provider data --- .../main/java/io/bitsquare/btc/FeePolicy.java | 26 +---- .../bitsquare/btc/provider/fee/FeeData.java | 6 +- .../btc/provider/fee/FeeProvider.java | 3 +- .../btc/provider/fee/FeeService.java | 98 +++++++++++-------- .../dao/blockchain/SquBlockchainService.java | 10 +- .../createoffer/CreateOfferDataModel.java | 24 +++-- .../offer/createoffer/CreateOfferView.java | 7 +- .../createoffer/CreateOfferViewModel.java | 23 +++-- .../offer/takeoffer/TakeOfferDataModel.java | 34 ++++--- .../main/offer/takeoffer/TakeOfferView.java | 9 +- .../offer/takeoffer/TakeOfferViewModel.java | 26 +++-- .../overlays/windows/TradeDetailsWindow.java | 4 +- .../java/io/bitsquare/gui/util/GUIUtil.java | 6 ++ .../resources/i18n/displayStrings.properties | 2 +- .../provider/fee/FeeRequestService.java | 7 +- .../fee/providers/BtcFeesProvider.java | 3 +- 16 files changed, 164 insertions(+), 124 deletions(-) diff --git a/core/src/main/java/io/bitsquare/btc/FeePolicy.java b/core/src/main/java/io/bitsquare/btc/FeePolicy.java index c5ca6c00ba..62c063d8af 100644 --- a/core/src/main/java/io/bitsquare/btc/FeePolicy.java +++ b/core/src/main/java/io/bitsquare/btc/FeePolicy.java @@ -31,28 +31,8 @@ public class FeePolicy { // https://estimatefee.appspot.com/ // Average values are 10-100 satoshis/byte in january 2016 // Average values are 60-140 satoshis/byte in february 2017 - // - // Our trade transactions have a fixed set of inputs and outputs making the size very predictable - // (as long the user does not do multiple funding transactions) - // - // trade fee tx: 226 bytes // 221 satoshi/byte - // deposit tx: 336 bytes // 148 satoshi/byte - // payout tx: 371 bytes // 134 satoshi/byte - // disputed payout tx: 408 bytes // 122 satoshi/byte - // We set a fixed fee to make the needed amounts in the trade predictable. - // We use 0.0005 BTC (0.5 EUR @ 1000 EUR/BTC) which is for our tx sizes about 120-220 satoshi/byte - // We cannot make that user defined as it need to be the same for both users, so we can only change that in - // software updates - // TODO before Beta we should get a good future proof guess as a change causes incompatible versions - - // For non trade transactions (withdrawal) we use the default fee calculation - // To avoid issues with not getting into full blocks, we increase the fee/kb to 30 satoshi/byte - // The user can change that in the preferences - // The BitcoinJ fee calculation use kb so a tx size < 1kb will still pay the fee for a kb tx. - // Our payout tx has about 370 bytes so we get a fee/kb value of about 90 satoshi/byte making it high priority - // Other payout transactions (E.g. arbitrators many collected transactions) will go with 30 satoshi/byte if > 1kb - private static Coin NON_TRADE_FEE_PER_KB = Coin.valueOf(40_000); // 0.0004 BTC about 0.16 EUR @ 400 EUR/BTC + private static Coin NON_TRADE_FEE_PER_KB = Coin.valueOf(150_000); public static void setNonTradeFeePerKb(Coin nonTradeFeePerKb) { NON_TRADE_FEE_PER_KB = nonTradeFeePerKb; @@ -62,4 +42,8 @@ public class FeePolicy { return NON_TRADE_FEE_PER_KB; } + public static Coin getDefaultSecurityDeposit() { + return Coin.valueOf(3_000_000); + } + } diff --git a/core/src/main/java/io/bitsquare/btc/provider/fee/FeeData.java b/core/src/main/java/io/bitsquare/btc/provider/fee/FeeData.java index 4b09b9f7f0..cf926c3063 100644 --- a/core/src/main/java/io/bitsquare/btc/provider/fee/FeeData.java +++ b/core/src/main/java/io/bitsquare/btc/provider/fee/FeeData.java @@ -7,12 +7,8 @@ public class FeeData { private static final Logger log = LoggerFactory.getLogger(FeeData.class); public final long txFeePerByte; - public final long createOfferFee; - public final long takeOfferFee; - public FeeData(long txFeePerByte, long createOfferFee, long takeOfferFee) { + public FeeData(long txFeePerByte) { this.txFeePerByte = txFeePerByte; - this.createOfferFee = createOfferFee; - this.takeOfferFee = takeOfferFee; } } diff --git a/core/src/main/java/io/bitsquare/btc/provider/fee/FeeProvider.java b/core/src/main/java/io/bitsquare/btc/provider/fee/FeeProvider.java index 0276da4878..b5b0896208 100644 --- a/core/src/main/java/io/bitsquare/btc/provider/fee/FeeProvider.java +++ b/core/src/main/java/io/bitsquare/btc/provider/fee/FeeProvider.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +//TODO use protobuffer instead of json public class FeeProvider extends HttpClientProvider { private static final Logger log = LoggerFactory.getLogger(FeeProvider.class); @@ -28,7 +29,7 @@ public class FeeProvider extends HttpClientProvider { tsMap.put("bitcoinFeesTs", ((Double) linkedTreeMap.get("bitcoinFeesTs")).longValue()); LinkedTreeMap dataMap = (LinkedTreeMap) linkedTreeMap.get("data"); - FeeData feeData = new FeeData(dataMap.get("txFee").longValue(), dataMap.get("createOfferFee").longValue(), dataMap.get("takeOfferFee").longValue()); + FeeData feeData = new FeeData(dataMap.get("txFee").longValue()); return new Tuple2<>(tsMap, feeData); } diff --git a/core/src/main/java/io/bitsquare/btc/provider/fee/FeeService.java b/core/src/main/java/io/bitsquare/btc/provider/fee/FeeService.java index 4875265819..79b5289743 100644 --- a/core/src/main/java/io/bitsquare/btc/provider/fee/FeeService.java +++ b/core/src/main/java/io/bitsquare/btc/provider/fee/FeeService.java @@ -21,7 +21,6 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.SettableFuture; import com.google.inject.Inject; -import io.bitsquare.app.Log; import io.bitsquare.btc.provider.ProvidersRepository; import io.bitsquare.common.UserThread; import io.bitsquare.common.handlers.FaultHandler; @@ -33,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nullable; +import java.time.Instant; import java.util.Map; import static com.google.common.base.Preconditions.checkNotNull; @@ -40,22 +40,28 @@ import static com.google.common.base.Preconditions.checkNotNull; public class FeeService { private static final Logger log = LoggerFactory.getLogger(FeeService.class); - public static final long MIN_TX_FEE = 40; // satoshi/byte - public static final long MAX_TX_FEE = 200; - public static final long DEFAULT_TX_FEE = 100; + public static final long MIN_TX_FEE = 60; // satoshi/byte + public static final long MAX_TX_FEE = 300; + public static final long DEFAULT_TX_FEE = 150; - public static final long MIN_CREATE_OFFER_FEE = 10_000; - public static final long MAX_CREATE_OFFER_FEE = 500_000; - public static final long DEFAULT_CREATE_OFFER_FEE = 30_000; + public static final long MIN_CREATE_OFFER_FEE_IN_BTC = 10_000; + public static final long MAX_CREATE_OFFER_FEE_IN_BTC = 500_000; + public static final long DEFAULT_CREATE_OFFER_FEE_IN_BTC = 30_000; // excluded mining fee - public static final long MIN_TAKE_OFFER_FEE = 10_000; - public static final long MAX_TAKE_OFFER_FEE = 1000_000; - public static final long DEFAULT_TAKE_OFFER_FEE = 80_000; + public static final long MIN_TAKE_OFFER_FEE_IN_BTC = 10_000; + public static final long MAX_TAKE_OFFER_FEE_IN_BTC = 1000_000; + public static final long DEFAULT_TAKE_OFFER_FEE_IN_BTC = 30_000; // excluded mining fee + + // 0.00216 btc is for 3 x tx fee for taker -> about 2 EUR! + + public static final long MIN_PAUSE_BETWEEN_REQUESTS_IN_MIN = 10; private final FeeProvider feeProvider; + @Nullable private FeeData feeData; private Map timeStampMap; private long epochInSecondAtLastRequest; + private long lastRequest; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -65,7 +71,6 @@ public class FeeService { public FeeService(HttpClient httpClient, ProvidersRepository providersRepository) { this.feeProvider = new FeeProvider(httpClient, providersRepository.getBaseUrl()); - feeData = new FeeData(DEFAULT_TX_FEE, DEFAULT_CREATE_OFFER_FEE, DEFAULT_TAKE_OFFER_FEE); } public void onAllServicesInitialized() { @@ -73,30 +78,39 @@ public class FeeService { } public void requestFees(@Nullable Runnable resultHandler, @Nullable FaultHandler faultHandler) { - //TODO add throttle - Log.traceCall(); - FeeRequest feeRequest = new FeeRequest(); - SettableFuture, FeeData>> future = feeRequest.getFees(feeProvider); - Futures.addCallback(future, new FutureCallback, FeeData>>() { - @Override - public void onSuccess(@Nullable Tuple2, FeeData> result) { - UserThread.execute(() -> { - checkNotNull(result, "Result must not be null at getFees"); - timeStampMap = result.first; - epochInSecondAtLastRequest = timeStampMap.get("bitcoinFeesTs"); - feeData = result.second; - if (resultHandler != null) - resultHandler.run(); - }); - } + long now = Instant.now().getEpochSecond(); + if (feeData == null || now - lastRequest > MIN_PAUSE_BETWEEN_REQUESTS_IN_MIN * 60) { + lastRequest = now; + FeeRequest feeRequest = new FeeRequest(); + SettableFuture, FeeData>> future = feeRequest.getFees(feeProvider); + Futures.addCallback(future, new FutureCallback, FeeData>>() { + @Override + public void onSuccess(@Nullable Tuple2, FeeData> result) { + UserThread.execute(() -> { + checkNotNull(result, "Result must not be null at getFees"); + timeStampMap = result.first; + epochInSecondAtLastRequest = timeStampMap.get("bitcoinFeesTs"); + feeData = result.second; + log.info("Tx fee: txFeePerByte=" + feeData.txFeePerByte); + if (resultHandler != null) + resultHandler.run(); + }); + } - @Override - public void onFailure(@NotNull Throwable throwable) { - log.warn("Could not load fees. " + throwable.toString()); - if (faultHandler != null) - UserThread.execute(() -> faultHandler.handleFault("Could not load fees", throwable)); - } - }); + @Override + public void onFailure(@NotNull Throwable throwable) { + log.warn("Could not load fees. " + throwable.toString()); + if (faultHandler != null) + UserThread.execute(() -> faultHandler.handleFault("Could not load fees", throwable)); + } + }); + } else { + log.debug("We got a requestFees called again before min pause of {} minutes has passed.", MIN_PAUSE_BETWEEN_REQUESTS_IN_MIN); + UserThread.execute(() -> { + if (resultHandler != null) + resultHandler.run(); + }); + } } public Coin getTxFee(int sizeInBytes) { @@ -104,16 +118,20 @@ public class FeeService { } public Coin getTxFeePerByte() { - log.info("txFeePerByte = " + feeData.txFeePerByte); - return Coin.valueOf(feeData.txFeePerByte); + if (feeData != null) + return Coin.valueOf(feeData.txFeePerByte); + else + return Coin.valueOf(DEFAULT_TX_FEE); } - public Coin getCreateOfferFee() { - return Coin.valueOf(feeData.createOfferFee); + // TODO we will get that from the DAO voting + public Coin getCreateOfferFeeInBtc() { + return Coin.valueOf(DEFAULT_CREATE_OFFER_FEE_IN_BTC); } - public Coin getTakeOfferFee() { - return Coin.valueOf(feeData.takeOfferFee); + // TODO we will get that from the DAO voting + public Coin getTakeOfferFeeInBtc() { + return Coin.valueOf(DEFAULT_TAKE_OFFER_FEE_IN_BTC); } public Coin getCreateCompensationRequestFee() { diff --git a/core/src/main/java/io/bitsquare/dao/blockchain/SquBlockchainService.java b/core/src/main/java/io/bitsquare/dao/blockchain/SquBlockchainService.java index eddde502bd..a85dea4124 100644 --- a/core/src/main/java/io/bitsquare/dao/blockchain/SquBlockchainService.java +++ b/core/src/main/java/io/bitsquare/dao/blockchain/SquBlockchainService.java @@ -73,18 +73,18 @@ abstract public class SquBlockchainService { String genesisTxId) throws SquBlockchainException { try { - log.info("blockCount=" + chainHeadHeight); + //log.info("blockCount=" + chainHeadHeight); long startTs = System.currentTimeMillis(); for (int blockHeight = genesisBlockHeight; blockHeight <= chainHeadHeight; blockHeight++) { Block block = requestBlock(blockHeight); - log.info("blockHeight=" + blockHeight); + //log.info("blockHeight=" + blockHeight); parseBlock(new SquBlock(block.getTx(), block.getHeight()), genesisBlockHeight, genesisTxId, utxoByTxIdMap); } printUtxoMap(utxoByTxIdMap); - log.info("Took {} ms", System.currentTimeMillis() - startTs); + // log.info("Took {} ms", System.currentTimeMillis() - startTs); } catch (BitcoindException | CommunicationException e) { throw new SquBlockchainException(e.getMessage(), e); } @@ -157,7 +157,7 @@ abstract public class SquBlockchainService { for (SquTransaction transaction : connectedTxs) { verifyTransaction(transaction, blockHeight, utxoByTxIdMap); } - log.info("orphanTxs " + orphanTxs); + //log.info("orphanTxs " + orphanTxs); if (!orphanTxs.isEmpty() && recursions < maxRecursions) resolveConnectedTxs(orphanTxs, utxoByTxIdMap, blockHeight, ++recursions, maxRecursions); } @@ -286,6 +286,6 @@ abstract public class SquBlockchainService { .append(a.getValue().toString()).append("}\n"); }); }); - log.info(sb.toString()); + //log.info(sb.toString()); } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferDataModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferDataModel.java index 08f677f7bd..b08eec824a 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferDataModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferDataModel.java @@ -22,6 +22,7 @@ import io.bitsquare.app.DevFlags; import io.bitsquare.app.Version; import io.bitsquare.arbitration.Arbitrator; import io.bitsquare.btc.AddressEntry; +import io.bitsquare.btc.FeePolicy; import io.bitsquare.btc.listeners.BalanceListener; import io.bitsquare.btc.provider.fee.FeeService; import io.bitsquare.btc.provider.price.PriceFeedService; @@ -143,8 +144,8 @@ class CreateOfferDataModel extends ActivatableDataModel { useMarketBasedPrice.set(preferences.getUsePercentageBasedPrice()); - // TODO add ui for editing - securityDepositAsCoin = Coin.valueOf(1_000_000); + // TODO add ui for editing, use preferences + securityDepositAsCoin = FeePolicy.getDefaultSecurityDeposit(); balanceListener = new BalanceListener(getAddressEntry().getAddress()) { @Override @@ -255,14 +256,14 @@ class CreateOfferDataModel extends ActivatableDataModel { // not too many inputs. // trade fee tx: 226 bytes (1 input) - 374 bytes (2 inputs) - feeService.requestFees(() -> { - createOfferFeeAsCoin = feeService.getCreateOfferFee(); - txFeeAsCoin = feeService.getTxFee(400); - calculateTotalToPay(); - }, null); - createOfferFeeAsCoin = feeService.getCreateOfferFee(); + // Set the default values (in rare cases if the fee request was not done yet we get the hard coded default values) + // But offer creation happens usually after that so we should have already the value from the estimation service. txFeeAsCoin = feeService.getTxFee(400); + createOfferFeeAsCoin = feeService.getCreateOfferFeeInBtc(); + + // We request to get the actual estimated fee + requestTxFee(); calculateVolume(); calculateTotalToPay(); @@ -419,6 +420,13 @@ class CreateOfferDataModel extends ActivatableDataModel { this.marketPriceMargin = marketPriceMargin; } + void requestTxFee() { + feeService.requestFees(() -> { + txFeeAsCoin = feeService.getTxFee(400); + createOfferFeeAsCoin = feeService.getCreateOfferFeeInBtc(); + calculateTotalToPay(); + }, null); + } /////////////////////////////////////////////////////////////////////////////////////////// // Getters diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java index 857968c0d9..f52f5292ff 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java @@ -334,7 +334,7 @@ public class CreateOfferView extends ActivatableViewAndModel { - //TODO update doubleTxFeeAsCoin and txFeeAsCoin in view with binding - takerFeeAsCoin = feeService.getTakeOfferFee(); - txFeeAsCoin = feeService.getTxFee(400); - totalTxFeeAsCoin = txFeeAsCoin.multiply(3); - calculateTotalToPay(); - }, null); + // disputed payout tx: 408 bytes - takerFeeAsCoin = feeService.getTakeOfferFee(); + // Set the default values (in rare cases if the fee request was not done yet we get the hard coded default values) + // But the "take offer" happens usually after that so we should have already the value from the estimation service. + takerFeeAsCoin = feeService.getTakeOfferFeeInBtc(); txFeeAsCoin = feeService.getTxFee(400); totalTxFeeAsCoin = txFeeAsCoin.multiply(3); + // We request to get the actual estimated fee + requestTxFee(); + calculateVolume(); calculateTotalToPay(); @@ -244,6 +242,15 @@ class TakeOfferDataModel extends ActivatableDataModel { priceFeedService.setCurrencyCode(offer.getCurrencyCode()); } + void requestTxFee() { + feeService.requestFees(() -> { + takerFeeAsCoin = feeService.getTakeOfferFeeInBtc(); + txFeeAsCoin = feeService.getTxFee(400); + totalTxFeeAsCoin = txFeeAsCoin.multiply(3); + calculateTotalToPay(); + }, null); + } + void onTabSelected(boolean isSelected) { this.isTabSelected = isSelected; if (!preferences.getUseStickyMarketPrice() && isTabSelected) @@ -258,11 +265,12 @@ class TakeOfferDataModel extends ActivatableDataModel { // errorMessageHandler is used only in the check availability phase. As soon we have a trade we write the error msg in the trade object as we want to // have it persisted as well. void onTakeOffer(TradeResultHandler tradeResultHandler) { + Coin fundsNeededForTrade = totalToPayAsCoin.get().subtract(takerFeeAsCoin).subtract(txFeeAsCoin); tradeManager.onTakeOffer(amountAsCoin.get(), txFeeAsCoin, takerFeeAsCoin, tradePrice.getValue(), - totalToPayAsCoin.get().subtract(takerFeeAsCoin).subtract(txFeeAsCoin), + fundsNeededForTrade, offer, paymentAccount.getId(), useSavingsWallet, @@ -460,6 +468,10 @@ class TakeOfferDataModel extends ActivatableDataModel { return totalTxFeeAsCoin; } + public Coin getTxFeeAsCoin() { + return txFeeAsCoin; + } + public AddressEntry getAddressEntry() { return addressEntry; } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java index 507bab08a5..9ca19f47ae 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java @@ -340,7 +340,7 @@ public class TakeOfferView extends ActivatableViewAndModel im } public void onShowPayFundsScreen() { + dataModel.requestTxFee(); showPayFundsScreenDisplayed.set(true); updateSpinnerInfo(); } @@ -569,22 +571,26 @@ class TakeOfferViewModel extends ActivatableWithDataModel im return amountDescription; } - String getAmount() { + String getTradeAmount() { return formatter.formatCoinWithCode(dataModel.amountAsCoin.get()); } - String getTakerFee() { - return formatter.formatCoinWithCode(dataModel.getTakerFeeAsCoin()); - } - - String getNetworkFee() { - return formatter.formatCoinWithCode(dataModel.getTotalTxFeeAsCoin()); - } - public String getSecurityDeposit() { - return formatter.formatCoinWithCode(dataModel.getSecurityDepositAsCoin()); + return formatter.formatCoinWithCode(dataModel.getSecurityDepositAsCoin()) + + GUIUtil.getPercentageOfTradeAmount(dataModel.getSecurityDepositAsCoin(), dataModel.amountAsCoin.get(), formatter); } + public String getTakerFee() { + return formatter.formatCoinWithCode(dataModel.getTakerFeeAsCoin()) + + GUIUtil.getPercentageOfTradeAmount(dataModel.getTakerFeeAsCoin(), dataModel.amountAsCoin.get(), formatter); + } + + public String getTxFee() { + return formatter.formatCoinWithCode(dataModel.getTotalTxFeeAsCoin()) + + GUIUtil.getPercentageOfTradeAmount(dataModel.getTotalTxFeeAsCoin(), dataModel.amountAsCoin.get(), formatter); + } + + public PaymentMethod getPaymentMethod() { return dataModel.getPaymentMethod(); } diff --git a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java index ebf6c00dfc..6fef003e7c 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java +++ b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java @@ -18,7 +18,6 @@ package io.bitsquare.gui.main.overlays.windows; import io.bitsquare.arbitration.DisputeManager; -import io.bitsquare.btc.FeePolicy; import io.bitsquare.gui.components.TextFieldWithCopyIcon; import io.bitsquare.gui.main.MainView; import io.bitsquare.gui.main.overlays.Overlay; @@ -131,7 +130,7 @@ public class TradeDetailsWindow extends Overlay { addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId())); // second group - rows = 5; + rows = 6; PaymentAccountContractData buyerPaymentAccountContractData = null; PaymentAccountContractData sellerPaymentAccountContractData = null; @@ -173,6 +172,7 @@ public class TradeDetailsWindow extends Overlay { addLabelTextFieldWithCopyIcon(gridPane, rowIndex, "Trade ID:", trade.getId(), Layout.FIRST_ROW_AND_GROUP_DISTANCE); addLabelTextField(gridPane, ++rowIndex, "Trade date:", formatter.formatDateTime(trade.getDate())); addLabelTextField(gridPane, ++rowIndex, "Security deposit:", formatter.formatCoinWithCode(offer.getSecurityDeposit())); + addLabelTextField(gridPane, ++rowIndex, "Tx fee:", formatter.formatCoinWithCode(trade.getTxFee())); addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Selected arbitrator:", trade.getArbitratorNodeAddress().getFullAddress()); if (trade.getTradingPeerNodeAddress() != null) diff --git a/gui/src/main/java/io/bitsquare/gui/util/GUIUtil.java b/gui/src/main/java/io/bitsquare/gui/util/GUIUtil.java index 4ed97307a9..13d2a2d0bb 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/GUIUtil.java +++ b/gui/src/main/java/io/bitsquare/gui/util/GUIUtil.java @@ -39,6 +39,7 @@ import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import javafx.stage.Stage; import javafx.util.StringConverter; +import org.bitcoinj.core.Coin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -300,4 +301,9 @@ public class GUIUtil { e.printStackTrace(); } } + + public static String getPercentageOfTradeAmount(Coin fee, Coin tradeAmount, BSFormatter formatter) { + return " (" + formatter.formatToPercentWithSymbol((double) fee.value / (double) tradeAmount.value) + + " of trade amount)"; + } } diff --git a/gui/src/main/resources/i18n/displayStrings.properties b/gui/src/main/resources/i18n/displayStrings.properties index 28a38280d7..555494dd3f 100644 --- a/gui/src/main/resources/i18n/displayStrings.properties +++ b/gui/src/main/resources/i18n/displayStrings.properties @@ -180,7 +180,7 @@ takeOffer.fundsBox.sell.info=For every offer there is a dedicated trade wallet. takeOffer.fundsBox.tradeAmount=Amount to sell: takeOffer.fundsBox.securityDeposit=Security deposit: takeOffer.fundsBox.offerFee=Take offer fee: -takeOffer.fundsBox.networkFee=Mining fee: +takeOffer.fundsBox.networkFee=Mining fees (3x): takeOffer.fundsBox.total=Total: takeOffer.fundsBox.showAdvanced=Show advanced settings takeOffer.fundsBox.hideAdvanced=Hide advanced settings diff --git a/provider/src/main/java/io/bitsquare/provider/fee/FeeRequestService.java b/provider/src/main/java/io/bitsquare/provider/fee/FeeRequestService.java index b439516288..11d915cc6d 100644 --- a/provider/src/main/java/io/bitsquare/provider/fee/FeeRequestService.java +++ b/provider/src/main/java/io/bitsquare/provider/fee/FeeRequestService.java @@ -32,6 +32,7 @@ import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; +//TODO use protobuffer instead of json public class FeeRequestService { private static final Logger log = LoggerFactory.getLogger(FeeRequestService.class); @@ -47,10 +48,7 @@ public class FeeRequestService { public FeeRequestService() throws IOException { btcFeesProvider = new BtcFeesProvider(); - allFeesMap.put("txFee", FeeService.DEFAULT_TX_FEE); - allFeesMap.put("createOfferFee", FeeService.DEFAULT_CREATE_OFFER_FEE); - allFeesMap.put("takeOfferFee", FeeService.DEFAULT_TAKE_OFFER_FEE); - + writeToJson(); startRequests(); } @@ -101,5 +99,4 @@ public class FeeRequestService { public String getJson() { return json; } - } diff --git a/provider/src/main/java/io/bitsquare/provider/fee/providers/BtcFeesProvider.java b/provider/src/main/java/io/bitsquare/provider/fee/providers/BtcFeesProvider.java index 2e5efa58ec..4a899f5816 100644 --- a/provider/src/main/java/io/bitsquare/provider/fee/providers/BtcFeesProvider.java +++ b/provider/src/main/java/io/bitsquare/provider/fee/providers/BtcFeesProvider.java @@ -12,6 +12,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +//TODO use protobuffer instead of json public class BtcFeesProvider { private static final Logger log = LoggerFactory.getLogger(BtcFeesProvider.class); @@ -23,7 +24,7 @@ public class BtcFeesProvider { public Long getFee() throws IOException, HttpException { String response = httpClient.requestWithGET("recommended", "User-Agent", ""); - log.debug("Get recommended fee response: " + response); + log.info("Get recommended fee response: " + response); Map map = new HashMap<>(); LinkedTreeMap treeMap = new Gson().fromJson(response, LinkedTreeMap.class); treeMap.entrySet().stream().forEach(e -> map.put(e.getKey(), e.getValue().longValue()));