Type-safe CFeeRate class
Use CFeeRate instead of an int64_t for quantities that are fee-per-size. Helps prevent unit-conversion mismatches between the wallet, relaying, and mining code.
This commit is contained in:
@@ -453,7 +453,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||
|
||||
CTxOut txout(amount, (CScript)vector<unsigned char>(24, 0));
|
||||
txDummy.vout.push_back(txout);
|
||||
if (txout.IsDust(CTransaction::nMinRelayTxFee))
|
||||
if (txout.IsDust(CTransaction::minRelayTxFee))
|
||||
fDust = true;
|
||||
}
|
||||
}
|
||||
@@ -525,7 +525,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||
sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority);
|
||||
|
||||
// Fee
|
||||
int64_t nFee = nTransactionFee * (1 + (int64_t)nBytes / 1000);
|
||||
int64_t nFee = payTxFee.GetFee(nBytes);
|
||||
|
||||
// Min Fee
|
||||
int64_t nMinFee = GetMinFee(txDummy, nBytes, AllowFree(dPriority), GMF_SEND);
|
||||
@@ -536,26 +536,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||
{
|
||||
nChange = nAmount - nPayFee - nPayAmount;
|
||||
|
||||
// if sub-cent change is required, the fee must be raised to at least CTransaction::nMinTxFee
|
||||
if (nPayFee < CTransaction::nMinTxFee && nChange > 0 && nChange < CENT)
|
||||
{
|
||||
if (nChange < CTransaction::nMinTxFee) // change < 0.0001 => simply move all change to fees
|
||||
{
|
||||
nPayFee += nChange;
|
||||
nChange = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
nChange = nChange + nPayFee - CTransaction::nMinTxFee;
|
||||
nPayFee = CTransaction::nMinTxFee;
|
||||
}
|
||||
}
|
||||
|
||||
// Never create dust outputs; if we would, just add the dust to the fee.
|
||||
if (nChange > 0 && nChange < CENT)
|
||||
{
|
||||
CTxOut txout(nChange, (CScript)vector<unsigned char>(24, 0));
|
||||
if (txout.IsDust(CTransaction::nMinRelayTxFee))
|
||||
if (txout.IsDust(CTransaction::minRelayTxFee))
|
||||
{
|
||||
nPayFee += nChange;
|
||||
nChange = 0;
|
||||
@@ -610,19 +595,19 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||
|
||||
// tool tips
|
||||
QString toolTip1 = tr("This label turns red, if the transaction size is greater than 1000 bytes.") + "<br /><br />";
|
||||
toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CTransaction::nMinTxFee)) + "<br /><br />";
|
||||
toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CTransaction::minTxFee.GetFeePerK())) + "<br /><br />";
|
||||
toolTip1 += tr("Can vary +/- 1 byte per input.");
|
||||
|
||||
QString toolTip2 = tr("Transactions with higher priority are more likely to get included into a block.") + "<br /><br />";
|
||||
toolTip2 += tr("This label turns red, if the priority is smaller than \"medium\".") + "<br /><br />";
|
||||
toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CTransaction::nMinTxFee));
|
||||
toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CTransaction::minTxFee.GetFeePerK()));
|
||||
|
||||
QString toolTip3 = tr("This label turns red, if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT)) + "<br /><br />";
|
||||
toolTip3 += tr("This means a fee of at least %1 is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CTransaction::nMinTxFee)) + "<br /><br />";
|
||||
toolTip3 += tr("This means a fee of at least %1 is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CTransaction::minTxFee.GetFeePerK())) + "<br /><br />";
|
||||
toolTip3 += tr("Amounts below 0.546 times the minimum relay fee are shown as dust.");
|
||||
|
||||
QString toolTip4 = tr("This label turns red, if the change is smaller than %1.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT)) + "<br /><br />";
|
||||
toolTip4 += tr("This means a fee of at least %1 is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CTransaction::nMinTxFee));
|
||||
toolTip4 += tr("This means a fee of at least %1 is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CTransaction::minTxFee.GetFeePerK()));
|
||||
|
||||
l5->setToolTip(toolTip1);
|
||||
l6->setToolTip(toolTip2);
|
||||
|
||||
@@ -210,7 +210,7 @@ bool isDust(const QString& address, qint64 amount)
|
||||
CTxDestination dest = CBitcoinAddress(address.toStdString()).Get();
|
||||
CScript script; script.SetDestination(dest);
|
||||
CTxOut txOut(amount, script);
|
||||
return txOut.IsDust(CTransaction::nMinRelayTxFee);
|
||||
return txOut.IsDust(CTransaction::minRelayTxFee);
|
||||
}
|
||||
|
||||
QString HtmlEscape(const QString& str, bool fMultiLine)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "monitoreddatamapper.h"
|
||||
#include "optionsmodel.h"
|
||||
|
||||
#include "main.h" // for CTransaction::nMinTxFee and MAX_SCRIPTCHECK_THREADS
|
||||
#include "main.h" // for CTransaction::minTxFee and MAX_SCRIPTCHECK_THREADS
|
||||
#include "netbase.h"
|
||||
#include "txdb.h" // for -dbcache defaults
|
||||
|
||||
@@ -101,7 +101,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
|
||||
#endif
|
||||
|
||||
ui->unit->setModel(new BitcoinUnits(this));
|
||||
ui->transactionFee->setSingleStep(CTransaction::nMinTxFee);
|
||||
ui->transactionFee->setSingleStep(CTransaction::minTxFee.GetFeePerK());
|
||||
|
||||
/* Widget-to-option mapper */
|
||||
mapper = new MonitoredDataMapper(this);
|
||||
|
||||
@@ -94,7 +94,7 @@ void OptionsModel::Init()
|
||||
#ifdef ENABLE_WALLET
|
||||
if (!settings.contains("nTransactionFee"))
|
||||
settings.setValue("nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE);
|
||||
nTransactionFee = settings.value("nTransactionFee").toLongLong(); // if -paytxfee is set, this will be overridden later in init.cpp
|
||||
payTxFee = CFeeRate(settings.value("nTransactionFee").toLongLong()); // if -paytxfee is set, this will be overridden later in init.cpp
|
||||
if (mapArgs.count("-paytxfee"))
|
||||
addOverriddenOption("-paytxfee");
|
||||
|
||||
@@ -187,15 +187,16 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
||||
return settings.value("nSocksVersion", 5);
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
case Fee:
|
||||
// Attention: Init() is called before nTransactionFee is set in AppInit2()!
|
||||
case Fee: {
|
||||
// Attention: Init() is called before payTxFee is set in AppInit2()!
|
||||
// To ensure we can change the fee on-the-fly update our QSetting when
|
||||
// opening OptionsDialog, which queries Fee via the mapper.
|
||||
if (nTransactionFee != settings.value("nTransactionFee").toLongLong())
|
||||
settings.setValue("nTransactionFee", (qint64)nTransactionFee);
|
||||
// Todo: Consider to revert back to use just nTransactionFee here, if we don't want
|
||||
if (!(payTxFee == CFeeRate(settings.value("nTransactionFee").toLongLong(), 1000)))
|
||||
settings.setValue("nTransactionFee", (qint64)payTxFee.GetFeePerK());
|
||||
// Todo: Consider to revert back to use just payTxFee here, if we don't want
|
||||
// -paytxfee to update our QSettings!
|
||||
return settings.value("nTransactionFee");
|
||||
}
|
||||
case SpendZeroConfChange:
|
||||
return settings.value("bSpendZeroConfChange");
|
||||
#endif
|
||||
@@ -284,12 +285,14 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
||||
}
|
||||
break;
|
||||
#ifdef ENABLE_WALLET
|
||||
case Fee: // core option - can be changed on-the-fly
|
||||
case Fee: { // core option - can be changed on-the-fly
|
||||
// Todo: Add is valid check and warn via message, if not
|
||||
nTransactionFee = value.toLongLong();
|
||||
settings.setValue("nTransactionFee", (qint64)nTransactionFee);
|
||||
qint64 nTransactionFee = value.toLongLong();
|
||||
payTxFee = CFeeRate(nTransactionFee, 1000);
|
||||
settings.setValue("nTransactionFee", nTransactionFee);
|
||||
emit transactionFeeChanged(nTransactionFee);
|
||||
break;
|
||||
}
|
||||
case SpendZeroConfChange:
|
||||
if (settings.value("bSpendZeroConfChange") != value) {
|
||||
settings.setValue("bSpendZeroConfChange", value);
|
||||
|
||||
@@ -551,7 +551,7 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
||||
|
||||
// Extract and check amounts
|
||||
CTxOut txOut(sendingTo.second, sendingTo.first);
|
||||
if (txOut.IsDust(CTransaction::nMinRelayTxFee)) {
|
||||
if (txOut.IsDust(CTransaction::minRelayTxFee)) {
|
||||
emit message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).")
|
||||
.arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
|
||||
@@ -231,12 +231,6 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||
return AmountExceedsBalance;
|
||||
}
|
||||
|
||||
if((total + nTransactionFee) > nBalance)
|
||||
{
|
||||
transaction.setTransactionFee(nTransactionFee);
|
||||
return SendCoinsReturn(AmountWithFeeExceedsBalance);
|
||||
}
|
||||
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user