Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User can set custom tx fee to override FeeService estimated fee #4231

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions core/src/main/java/bisq/core/btc/wallet/BtcWalletService.java
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ public Transaction completePreparedBsqTx(Transaction preparedBsqTx, boolean useC
// typical size for a tx with 2 inputs
int txSizeWithUnsignedInputs = 203;
// If useCustomTxFee we allow overriding the estimated fee from preferences
Coin txFeePerByte = useCustomTxFee ? getTxFeeForWithdrawalPerByte() : feeService.getTxFeePerByte();
Coin txFeePerByte = useCustomTxFee ? getTxFeePerByte() : feeService.getTxFeePerByte();
// In case there are no change outputs we force a change by adding min dust to the BTC input
Coin forcedChangeValue = Coin.ZERO;

Expand Down Expand Up @@ -785,7 +785,7 @@ public void doubleSpendTransaction(String txId, Runnable resultHandler, ErrorMes
int txSize = 0;
Transaction tx;
SendRequest sendRequest;
Coin txFeeForWithdrawalPerByte = getTxFeeForWithdrawalPerByte();
Coin txFeeForWithdrawalPerByte = getTxFeePerByte();
do {
counter++;
fee = txFeeForWithdrawalPerByte.multiply(txSize);
Expand Down Expand Up @@ -902,7 +902,7 @@ public Transaction getFeeEstimationTransaction(String fromAddress,
int counter = 0;
int txSize = 0;
Transaction tx;
Coin txFeeForWithdrawalPerByte = getTxFeeForWithdrawalPerByte();
Coin txFeeForWithdrawalPerByte = getTxFeePerByte();
do {
counter++;
fee = txFeeForWithdrawalPerByte.multiply(txSize);
Expand Down Expand Up @@ -949,7 +949,7 @@ public Transaction getFeeEstimationTransactionForMultipleAddresses(Set<String> f
int counter = 0;
int txSize = 0;
Transaction tx;
Coin txFeeForWithdrawalPerByte = getTxFeeForWithdrawalPerByte();
Coin txFeeForWithdrawalPerByte = getTxFeePerByte();
do {
counter++;
fee = txFeeForWithdrawalPerByte.multiply(txSize);
Expand All @@ -974,7 +974,7 @@ public Transaction getFeeEstimationTransactionForMultipleAddresses(Set<String> f
}

private boolean feeEstimationNotSatisfied(int counter, Transaction tx) {
long targetFee = getTxFeeForWithdrawalPerByte().multiply(tx.bitcoinSerialize().length).value;
long targetFee = getTxFeePerByte().multiply(tx.bitcoinSerialize().length).value;
return counter < 10 &&
(tx.getFee().value < targetFee ||
tx.getFee().value - targetFee > 1000);
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/java/bisq/core/btc/wallet/WalletService.java
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,9 @@ public Coin getBalance(TransactionOutput output) {
return getBalanceForAddress(getAddressFromOutput(output));
}

public Coin getTxFeeForWithdrawalPerByte() {
Coin fee = (preferences.isUseCustomWithdrawalTxFee()) ?
Coin.valueOf(preferences.getWithdrawalTxFeeInBytes()) :
public Coin getTxFeePerByte() {
Coin fee = (preferences.isUseCustomTxFee()) ?
Coin.valueOf(preferences.getTxFeePerByte()) :
feeService.getTxFeePerByte();
log.info("tx fee = " + fee.toFriendlyString());
return fee;
Expand Down Expand Up @@ -491,7 +491,7 @@ public void emptyWallet(String toAddress,
throws InsufficientMoneyException, AddressFormatException {
SendRequest sendRequest = SendRequest.emptyWallet(Address.fromBase58(params, toAddress));
sendRequest.fee = Coin.ZERO;
sendRequest.feePerKb = getTxFeeForWithdrawalPerByte().multiply(1000);
sendRequest.feePerKb = getTxFeePerByte().multiply(1000);
sendRequest.aesKey = aesKey;
Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
printTx("empty wallet", sendResult.tx);
Expand Down
21 changes: 20 additions & 1 deletion core/src/main/java/bisq/core/provider/fee/FeeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import bisq.core.dao.governance.param.Param;
import bisq.core.dao.governance.period.PeriodService;
import bisq.core.dao.state.DaoStateService;
import bisq.core.user.Preferences;

import bisq.common.UserThread;
import bisq.common.config.Config;
Expand Down Expand Up @@ -93,6 +94,7 @@ public static Coin getMinTakerFee(boolean currencyForFeeIsBtc) {

private final FeeProvider feeProvider;
private final IntegerProperty feeUpdateCounter = new SimpleIntegerProperty(0);
private final Preferences preferences;
private long txFeePerByte = BTC_DEFAULT_TX_FEE;
private Map<String, Long> timeStampMap;
private long lastRequest;
Expand All @@ -105,8 +107,12 @@ public static Coin getMinTakerFee(boolean currencyForFeeIsBtc) {
///////////////////////////////////////////////////////////////////////////////////////////

@Inject
public FeeService(FeeProvider feeProvider, DaoStateService daoStateService, PeriodService periodService) {
public FeeService(FeeProvider feeProvider,
DaoStateService daoStateService,
PeriodService periodService,
Preferences preferences) {
this.feeProvider = feeProvider;
this.preferences = preferences;
FeeService.daoStateService = daoStateService;
FeeService.periodService = periodService;
}
Expand Down Expand Up @@ -135,6 +141,19 @@ public void requestFees(Runnable resultHandler) {
}

public void requestFees(@Nullable Runnable resultHandler, @Nullable FaultHandler faultHandler) {

// If the user set a custom fee, use that one and skip querying the external fee API endpoint
if (preferences.isUseCustomTxFee()) {
txFeePerByte = preferences.getTxFeePerByte();
log.info("Using custom tx fee: {} sats/vByte", txFeePerByte);

if (resultHandler != null)
resultHandler.run();

return;
}

// If user did not set a custom fee in their preferences, then query the fee API endpoint
long now = Instant.now().getEpochSecond();
// We all requests only each 2 minutes
if (now - lastRequest > MIN_PAUSE_BETWEEN_REQUESTS_IN_MIN * 60) {
Expand Down
18 changes: 9 additions & 9 deletions core/src/main/java/bisq/core/user/Preferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -494,13 +494,13 @@ public void setBitcoinNodes(String bitcoinNodes) {
persist();
}

public void setUseCustomWithdrawalTxFee(boolean useCustomWithdrawalTxFee) {
prefPayload.setUseCustomWithdrawalTxFee(useCustomWithdrawalTxFee);
public void setUseCustomTxFee(boolean useCustomTxFee) {
prefPayload.setUseCustomTxFee(useCustomTxFee);
persist();
}

public void setWithdrawalTxFeeInBytes(long withdrawalTxFeeInBytes) {
prefPayload.setWithdrawalTxFeeInBytes(withdrawalTxFeeInBytes);
public void setTxFeeInBytes(long txFeeInBytes) {
prefPayload.setTxFeePerByte(txFeeInBytes);
persist();
}

Expand Down Expand Up @@ -772,8 +772,8 @@ public List<String> getBridgeAddresses() {
return prefPayload.getBridgeAddresses();
}

public long getWithdrawalTxFeeInBytes() {
return Math.max(prefPayload.getWithdrawalTxFeeInBytes(), Config.baseCurrencyNetwork().getDefaultMinFeePerByte());
public long getTxFeePerByte() {
return Math.max(prefPayload.getTxFeePerByte(), Config.baseCurrencyNetwork().getDefaultMinFeePerByte());
}

public boolean isDaoFullNode() {
Expand Down Expand Up @@ -881,9 +881,9 @@ private interface ExcludesDelegateMethods {

void setBitcoinNodes(String bitcoinNodes);

void setUseCustomWithdrawalTxFee(boolean useCustomWithdrawalTxFee);
void setUseCustomTxFee(boolean useCustomTxFee);

void setWithdrawalTxFeeInBytes(long withdrawalTxFeeInBytes);
void getTxFeePerByte(long txFeePerByte);

void setSelectedPaymentAccountForCreateOffer(@Nullable PaymentAccount paymentAccount);

Expand Down Expand Up @@ -929,7 +929,7 @@ private interface ExcludesDelegateMethods {

List<String> getBridgeAddresses();

long getWithdrawalTxFeeInBytes();
long getTxFeePerByte();

void setUseStandbyMode(boolean useStandbyMode);

Expand Down
12 changes: 6 additions & 6 deletions core/src/main/java/bisq/core/user/PreferencesPayload.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ public final class PreferencesPayload implements UserThreadMappedPersistableEnve
private boolean showOwnOffersInOfferBook = true;
@Nullable
private TradeCurrency preferredTradeCurrency;
private long withdrawalTxFeeInBytes = 100;
private boolean useCustomWithdrawalTxFee = false;
private long txFeePerByte = 100;
private boolean useCustomTxFee = false;
private double maxPriceDistanceInPercent = 0.3;
@Nullable
private String offerBookChartScreenCurrencyCode;
Expand Down Expand Up @@ -158,8 +158,8 @@ public Message toProtoMessage() {
.setTacAccepted(tacAccepted)
.setUseTorForBitcoinJ(useTorForBitcoinJ)
.setShowOwnOffersInOfferBook(showOwnOffersInOfferBook)
.setWithdrawalTxFeeInBytes(withdrawalTxFeeInBytes)
.setUseCustomWithdrawalTxFee(useCustomWithdrawalTxFee)
.setTxFeePerByte(txFeePerByte)
.setUseCustomTxFee(useCustomTxFee)
.setMaxPriceDistanceInPercent(maxPriceDistanceInPercent)
.setTradeStatisticsTickUnitIndex(tradeStatisticsTickUnitIndex)
.setResyncSpvRequested(resyncSpvRequested)
Expand Down Expand Up @@ -234,8 +234,8 @@ public static PreferencesPayload fromProto(protobuf.PreferencesPayload proto, Co
proto.getUseTorForBitcoinJ(),
proto.getShowOwnOffersInOfferBook(),
proto.hasPreferredTradeCurrency() ? TradeCurrency.fromProto(proto.getPreferredTradeCurrency()) : null,
proto.getWithdrawalTxFeeInBytes(),
proto.getUseCustomWithdrawalTxFee(),
proto.getTxFeePerByte(),
proto.getUseCustomTxFee(),
proto.getMaxPriceDistanceInPercent(),
ProtoUtil.stringOrNullFromProto(proto.getOfferBookChartScreenCurrencyCode()),
ProtoUtil.stringOrNullFromProto(proto.getTradeChartsScreenCurrencyCode()),
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,7 @@ setting.preferences.explorer.bsq=BSQ block explorer
setting.preferences.deviation=Max. deviation from market price
setting.preferences.avoidStandbyMode=Avoid standby mode
setting.preferences.deviationToLarge=Values higher than {0}% are not allowed.
setting.preferences.txFee=Withdrawal transaction fee (satoshis/byte)
setting.preferences.txFee=Transaction fee (satoshis/byte)
setting.preferences.useCustomValue=Use custom value
setting.preferences.txFeeMin=Transaction fee must be at least {0} satoshis/byte
setting.preferences.txFeeTooLarge=Your input is above any reasonable value (>5000 satoshis/byte). Transaction fee is usually in the range of 50-400 satoshis/byte.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,34 +259,34 @@ private void initializeGeneralOptions() {
useCustomFee = tuple.third;

useCustomFeeCheckboxListener = (observable, oldValue, newValue) -> {
preferences.setUseCustomWithdrawalTxFee(newValue);
preferences.setUseCustomTxFee(newValue);
transactionFeeInputTextField.setEditable(newValue);
if (!newValue) {
transactionFeeInputTextField.setText(String.valueOf(feeService.getTxFeePerByte().value));
try {
preferences.setWithdrawalTxFeeInBytes(feeService.getTxFeePerByte().value);
preferences.setTxFeeInBytes(feeService.getTxFeePerByte().value);
} catch (Exception e) {
e.printStackTrace();
}
}

preferences.setUseCustomWithdrawalTxFee(newValue);
preferences.setUseCustomTxFee(newValue);
};

transactionFeeFocusedListener = (o, oldValue, newValue) -> {
if (oldValue && !newValue) {
String estimatedFee = String.valueOf(feeService.getTxFeePerByte().value);
try {
int withdrawalTxFeePerByte = Integer.parseInt(transactionFeeInputTextField.getText());
int txFeePerByte = Integer.parseInt(transactionFeeInputTextField.getText());
final long minFeePerByte = Config.baseCurrencyNetwork().getDefaultMinFeePerByte();
if (withdrawalTxFeePerByte < minFeePerByte) {
if (txFeePerByte < minFeePerByte) {
new Popup().warning(Res.get("setting.preferences.txFeeMin", minFeePerByte)).show();
transactionFeeInputTextField.setText(estimatedFee);
} else if (withdrawalTxFeePerByte > 5000) {
} else if (txFeePerByte > 5000) {
new Popup().warning(Res.get("setting.preferences.txFeeTooLarge")).show();
transactionFeeInputTextField.setText(estimatedFee);
} else {
preferences.setWithdrawalTxFeeInBytes(withdrawalTxFeePerByte);
preferences.setTxFeeInBytes(txFeePerByte);
}
} catch (NumberFormatException t) {
log.error(t.toString());
Expand Down Expand Up @@ -661,11 +661,11 @@ private void activateGeneralOptions() {
selectBaseCurrencyNetworkComboBox.setOnAction(e -> onSelectNetwork());
selectBaseCurrencyNetworkComboBox.getSelectionModel().select(BaseCurrencyNetwork.CURRENT_VALUE);*/

boolean useCustomWithdrawalTxFee = preferences.isUseCustomWithdrawalTxFee();
useCustomFee.setSelected(useCustomWithdrawalTxFee);
boolean useCustomTxFee = preferences.isUseCustomTxFee();
useCustomFee.setSelected(useCustomTxFee);

transactionFeeInputTextField.setEditable(useCustomWithdrawalTxFee);
if (!useCustomWithdrawalTxFee) {
transactionFeeInputTextField.setEditable(useCustomTxFee);
if (!useCustomTxFee) {
transactionFeeInputTextField.setText(String.valueOf(feeService.getTxFeePerByte().value));
feeService.feeUpdateCounterProperty().addListener(transactionFeeChangeListener);
}
Expand Down Expand Up @@ -780,8 +780,8 @@ public BlockChainExplorer fromString(String string) {
}

private Coin getTxFeeForWithdrawalPerByte() {
Coin fee = (preferences.isUseCustomWithdrawalTxFee()) ?
Coin.valueOf(preferences.getWithdrawalTxFeeInBytes()) :
Coin fee = (preferences.isUseCustomTxFee()) ?
Coin.valueOf(preferences.getTxFeePerByte()) :
feeService.getTxFeePerByte();
log.info("tx fee = " + fee.toFriendlyString());
return fee;
Expand Down
4 changes: 2 additions & 2 deletions proto/src/main/proto/pb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1508,8 +1508,8 @@ message PreferencesPayload {
bool use_tor_for_bitcoin_j = 12;
bool show_own_offers_in_offer_book = 13;
TradeCurrency preferred_trade_currency = 14;
int64 withdrawal_tx_fee_in_bytes = 15;
bool use_custom_withdrawal_tx_fee = 16;
int64 tx_fee_per_byte = 15;
bool use_custom_tx_fee = 16;
double max_price_distance_in_percent = 17;
string offer_book_chart_screen_currency_code = 18;
string trade_charts_screen_currency_code = 19;
Expand Down