Merge pull request #6544 from jmacxx/fix_withdrawal_fee_estimation

Fix withdrawal fee calculation & the min relay fee problem.
This commit is contained in:
Alejandro García 2023-01-28 19:25:06 +00:00 committed by GitHub
commit f43b5fe04b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 10 additions and 19 deletions

View file

@ -289,6 +289,7 @@ class CoreWalletsService {
// See WithdrawalView # onWithdraw (and refactor). // See WithdrawalView # onWithdraw (and refactor).
Transaction feeEstimationTransaction = Transaction feeEstimationTransaction =
btcWalletService.getFeeEstimationTransactionForMultipleAddresses(fromAddresses, btcWalletService.getFeeEstimationTransactionForMultipleAddresses(fromAddresses,
address,
receiverAmount, receiverAmount,
txFeePerVbyte); txFeePerVbyte);
if (feeEstimationTransaction == null) if (feeEstimationTransaction == null)

View file

@ -1056,13 +1056,7 @@ public class BtcWalletService extends WalletService {
} }
public Transaction getFeeEstimationTransactionForMultipleAddresses(Set<String> fromAddresses, public Transaction getFeeEstimationTransactionForMultipleAddresses(Set<String> fromAddresses,
Coin amount) String toAddress,
throws AddressFormatException, AddressEntryException, InsufficientFundsException {
Coin txFeeForWithdrawalPerVbyte = getTxFeeForWithdrawalPerVbyte();
return getFeeEstimationTransactionForMultipleAddresses(fromAddresses, amount, txFeeForWithdrawalPerVbyte);
}
public Transaction getFeeEstimationTransactionForMultipleAddresses(Set<String> fromAddresses,
Coin amount, Coin amount,
Coin txFeeForWithdrawalPerVbyte) Coin txFeeForWithdrawalPerVbyte)
throws AddressFormatException, AddressEntryException, InsufficientFundsException { throws AddressFormatException, AddressEntryException, InsufficientFundsException {
@ -1090,11 +1084,7 @@ public class BtcWalletService extends WalletService {
do { do {
counter++; counter++;
fee = txFeeForWithdrawalPerVbyte.multiply(txVsize); fee = txFeeForWithdrawalPerVbyte.multiply(txVsize);
// We use a dummy address for the output SendRequest sendRequest = getSendRequestForMultipleAddresses(fromAddresses, toAddress, amount, fee, null, aesKey);
// We don't know here whether the output is segwit or not but we don't care too much because the size of
// a segwit ouput is just 3 byte smaller than the size of a legacy ouput.
final String dummyReceiver = SegwitAddress.fromKey(params, new ECKey()).toString();
SendRequest sendRequest = getSendRequestForMultipleAddresses(fromAddresses, dummyReceiver, amount, fee, null, aesKey);
wallet.completeTx(sendRequest); wallet.completeTx(sendRequest);
tx = sendRequest.tx; tx = sendRequest.tx;
txVsize = tx.getVsize(); txVsize = tx.getVsize();
@ -1113,14 +1103,14 @@ public class BtcWalletService extends WalletService {
} }
private boolean feeEstimationNotSatisfied(int counter, Transaction tx) { private boolean feeEstimationNotSatisfied(int counter, Transaction tx) {
return feeEstimationNotSatisfied(counter, tx, getTxFeeForWithdrawalPerVbyte()); return feeEstimationNotSatisfied(counter, tx.getFee().value, tx.getVsize(), getTxFeeForWithdrawalPerVbyte());
} }
private boolean feeEstimationNotSatisfied(int counter, Transaction tx, Coin txFeeForWithdrawalPerVbyte) { private boolean feeEstimationNotSatisfied(int counter, long txFee, long txVsize, Coin txFeeForWithdrawalPerVbyte) {
long targetFee = txFeeForWithdrawalPerVbyte.multiply(tx.getVsize()).value; long targetFee = txFeeForWithdrawalPerVbyte.multiply(txVsize).value;
long higherThanTargetFee = txFee - targetFee;
return counter < 10 && return counter < 10 &&
(tx.getFee().value < targetFee || (txFee < targetFee || higherThanTargetFee > 1000);
tx.getFee().value - targetFee > 1000);
} }
public int getEstimatedFeeTxVsize(List<Coin> outputValues, Coin txFee) public int getEstimatedFeeTxVsize(List<Coin> outputValues, Coin txFee)

View file

@ -406,9 +406,9 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
final Coin sendersAmount; final Coin sendersAmount;
// We do not know sendersAmount if senderPaysFee is true. We repeat fee calculation after first attempt if senderPaysFee is true. // We do not know sendersAmount if senderPaysFee is true. We repeat fee calculation after first attempt if senderPaysFee is true.
Transaction feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(fromAddresses, amountAsCoin, feeRate); Transaction feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(fromAddresses, withdrawToAddress, amountAsCoin, feeRate);
if (feeExcluded && feeEstimationTransaction != null) { if (feeExcluded && feeEstimationTransaction != null) {
feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(fromAddresses, amountAsCoin.add(feeEstimationTransaction.getFee()), feeRate); feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(fromAddresses, withdrawToAddress, amountAsCoin.add(feeEstimationTransaction.getFee()), feeRate);
} }
checkNotNull(feeEstimationTransaction, "feeEstimationTransaction must not be null"); checkNotNull(feeEstimationTransaction, "feeEstimationTransaction must not be null");