Merge pull request #5200
c1c9d5b
[Qt] Add Smartfee to GUI (Cozz Lovan)e7876b2
[Wallet] Prevent user from paying a non-sense fee (Cozz Lovan)ed3e5e4
[Wallet] Add global boolean whether to pay at least the custom fee (default=true) (Cozz Lovan)0ed9675
[Wallet] Add global boolean whether to send free transactions (default=true) (Cozz Lovan)
This commit is contained in:
commit
b7fe9cd04c
|
@ -290,6 +290,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n";
|
||||
strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
|
||||
strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
|
||||
strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n";
|
||||
strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n";
|
||||
strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)"), 1) + "\n";
|
||||
strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
|
||||
|
@ -704,6 +705,7 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
}
|
||||
nTxConfirmTarget = GetArg("-txconfirmtarget", 1);
|
||||
bSpendZeroConfChange = GetArg("-spendzeroconfchange", true);
|
||||
fSendFreeTransactions = GetArg("-sendfreetransactions", false);
|
||||
|
||||
std::string strWalletFile = GetArg("-wallet", "wallet.dat");
|
||||
#endif // ENABLE_WALLET
|
||||
|
|
|
@ -221,6 +221,12 @@ void BitcoinAmountField::clear()
|
|||
unit->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void BitcoinAmountField::setEnabled(bool fEnabled)
|
||||
{
|
||||
amount->setEnabled(fEnabled);
|
||||
unit->setEnabled(fEnabled);
|
||||
}
|
||||
|
||||
bool BitcoinAmountField::validate()
|
||||
{
|
||||
bool valid = false;
|
||||
|
|
|
@ -48,6 +48,9 @@ public:
|
|||
/** Make field empty and ready for new input. */
|
||||
void clear();
|
||||
|
||||
/** Enable/Disable. */
|
||||
void setEnabled(bool fEnabled);
|
||||
|
||||
/** Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907),
|
||||
in these cases we have to set it up manually.
|
||||
*/
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <QDialogButtonBox>
|
||||
#include <QFlags>
|
||||
#include <QIcon>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
|
@ -130,10 +131,22 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) :
|
|||
|
||||
// default view is sorted by amount desc
|
||||
sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder);
|
||||
|
||||
// restore list mode and sortorder as a convenience feature
|
||||
QSettings settings;
|
||||
if (settings.contains("nCoinControlMode") && !settings.value("nCoinControlMode").toBool())
|
||||
ui->radioTreeMode->click();
|
||||
if (settings.contains("nCoinControlSortColumn") && settings.contains("nCoinControlSortOrder"))
|
||||
sortView(settings.value("nCoinControlSortColumn").toInt(), ((Qt::SortOrder)settings.value("nCoinControlSortOrder").toInt()));
|
||||
}
|
||||
|
||||
CoinControlDialog::~CoinControlDialog()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("nCoinControlMode", ui->radioListMode->isChecked());
|
||||
settings.setValue("nCoinControlSortColumn", sortColumn);
|
||||
settings.setValue("nCoinControlSortOrder", (int)sortOrder);
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
@ -290,19 +303,19 @@ void CoinControlDialog::clipboardAmount()
|
|||
// copy label "Fee" to clipboard
|
||||
void CoinControlDialog::clipboardFee()
|
||||
{
|
||||
GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")));
|
||||
GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", ""));
|
||||
}
|
||||
|
||||
// copy label "After fee" to clipboard
|
||||
void CoinControlDialog::clipboardAfterFee()
|
||||
{
|
||||
GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")));
|
||||
GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", ""));
|
||||
}
|
||||
|
||||
// copy label "Bytes" to clipboard
|
||||
void CoinControlDialog::clipboardBytes()
|
||||
{
|
||||
GUIUtil::setClipboard(ui->labelCoinControlBytes->text());
|
||||
GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", ""));
|
||||
}
|
||||
|
||||
// copy label "Priority" to clipboard
|
||||
|
@ -320,7 +333,7 @@ void CoinControlDialog::clipboardLowOutput()
|
|||
// copy label "Change" to clipboard
|
||||
void CoinControlDialog::clipboardChange()
|
||||
{
|
||||
GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")));
|
||||
GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", ""));
|
||||
}
|
||||
|
||||
// treeview: sort
|
||||
|
@ -402,26 +415,22 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
|
|||
}
|
||||
|
||||
// return human readable label for priority number
|
||||
QString CoinControlDialog::getPriorityLabel(const CTxMemPool& pool, double dPriority)
|
||||
QString CoinControlDialog::getPriorityLabel(double dPriority, double mempoolEstimatePriority)
|
||||
{
|
||||
// confirmations -> textual description
|
||||
typedef std::map<unsigned int, QString> PriorityDescription;
|
||||
const static PriorityDescription priorityDescriptions = boost::assign::map_list_of
|
||||
(1, tr("highest"))(2, tr("higher"))(3, tr("high"))
|
||||
(5, tr("medium-high"))(6, tr("medium"))
|
||||
(10, tr("low-medium"))(15, tr("low"))
|
||||
(20, tr("lower"));
|
||||
double dPriorityMedium = mempoolEstimatePriority;
|
||||
|
||||
BOOST_FOREACH(const PriorityDescription::value_type& i, priorityDescriptions)
|
||||
{
|
||||
double p = mempool.estimatePriority(i.first);
|
||||
if (p > 0 && dPriority >= p) return i.second;
|
||||
}
|
||||
// Note: if mempool hasn't accumulated enough history (estimatePriority
|
||||
// returns -1) we're conservative and classify as "lowest"
|
||||
if (mempool.estimatePriority(nTxConfirmTarget) <= 0 && AllowFree(dPriority))
|
||||
return ">=" + tr("medium");
|
||||
return tr("lowest");
|
||||
if (dPriorityMedium <= 0)
|
||||
dPriorityMedium = AllowFreeThreshold(); // not enough data, back to hard-coded
|
||||
|
||||
if (dPriority / 1000000 > dPriorityMedium) return tr("highest");
|
||||
else if (dPriority / 100000 > dPriorityMedium) return tr("higher");
|
||||
else if (dPriority / 10000 > dPriorityMedium) return tr("high");
|
||||
else if (dPriority / 1000 > dPriorityMedium) return tr("medium-high");
|
||||
else if (dPriority > dPriorityMedium) return tr("medium");
|
||||
else if (dPriority * 10 > dPriorityMedium) return tr("low-medium");
|
||||
else if (dPriority * 100 > dPriorityMedium) return tr("low");
|
||||
else if (dPriority * 1000 > dPriorityMedium) return tr("lower");
|
||||
else return tr("lowest");
|
||||
}
|
||||
|
||||
// shows count of locked unspent outputs
|
||||
|
@ -470,6 +479,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
double dPriorityInputs = 0;
|
||||
unsigned int nQuantity = 0;
|
||||
int nQuantityUncompressed = 0;
|
||||
bool fAllowFree = false;
|
||||
|
||||
vector<COutPoint> vCoinControl;
|
||||
vector<COutput> vOutputs;
|
||||
|
@ -522,24 +532,22 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here
|
||||
|
||||
// Priority
|
||||
double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget);
|
||||
dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority)
|
||||
sPriorityLabel = CoinControlDialog::getPriorityLabel(mempool, dPriority);
|
||||
sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority);
|
||||
|
||||
// Voluntary Fee
|
||||
nPayFee = payTxFee.GetFee(max((unsigned int)1000, nBytes));
|
||||
|
||||
// Min Fee
|
||||
if (nPayFee == 0)
|
||||
{
|
||||
// Fee
|
||||
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
||||
|
||||
double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
|
||||
if (dPriorityNeeded <= 0 && !AllowFree(dPriority)) // not enough mempool history: never send free
|
||||
dPriorityNeeded = std::numeric_limits<double>::max();
|
||||
// Allow free?
|
||||
double dPriorityNeeded = mempoolEstimatePriority;
|
||||
if (dPriorityNeeded <= 0)
|
||||
dPriorityNeeded = AllowFreeThreshold(); // not enough data, back to hard-coded
|
||||
fAllowFree = (dPriority >= dPriorityNeeded);
|
||||
|
||||
if (nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE && dPriority >= dPriorityNeeded)
|
||||
if (fSendFreeTransactions)
|
||||
if (fAllowFree && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
|
||||
nPayFee = 0;
|
||||
}
|
||||
|
||||
if (nPayAmount > 0)
|
||||
{
|
||||
|
@ -595,7 +603,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
l6->setText(sPriorityLabel); // Priority
|
||||
l7->setText(fDust ? tr("yes") : tr("no")); // Dust
|
||||
l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change
|
||||
if (nPayFee > 0)
|
||||
if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000))
|
||||
{
|
||||
l3->setText("~" + l3->text());
|
||||
l4->setText("~" + l4->text());
|
||||
|
@ -605,7 +613,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
|
||||
// turn labels "red"
|
||||
l5->setStyleSheet((nBytes >= MAX_FREE_TRANSACTION_CREATE_SIZE) ? "color:red;" : "");// Bytes >= 1000
|
||||
l6->setStyleSheet((dPriority > 0 && !AllowFree(dPriority)) ? "color:red;" : ""); // Priority < "medium"
|
||||
l6->setStyleSheet((dPriority > 0 && !fAllowFree) ? "color:red;" : ""); // Priority < "medium"
|
||||
l7->setStyleSheet((fDust) ? "color:red;" : ""); // Dust = "yes"
|
||||
|
||||
// tool tips
|
||||
|
@ -620,7 +628,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
QString toolTip3 = tr("This label turns red, if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546)));
|
||||
|
||||
// how many satoshis the estimated fee can vary per byte we guess wrong
|
||||
double dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), std::max(payTxFee.GetFeePerK(), mempool.estimateFee(nTxConfirmTarget).GetFeePerK())) / 1000;
|
||||
double dFeeVary;
|
||||
if (payTxFee.GetFeePerK() > 0)
|
||||
dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), payTxFee.GetFeePerK()) / 1000;
|
||||
else
|
||||
dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), mempool.estimateFee(nTxConfirmTarget).GetFeePerK()) / 1000;
|
||||
QString toolTip4 = tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
|
||||
|
||||
l3->setToolTip(toolTip4);
|
||||
|
@ -656,6 +668,7 @@ void CoinControlDialog::updateView()
|
|||
QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
|
||||
|
||||
int nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
|
||||
double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget);
|
||||
|
||||
map<QString, vector<COutput> > mapCoins;
|
||||
model->listCoins(mapCoins);
|
||||
|
@ -745,7 +758,7 @@ void CoinControlDialog::updateView()
|
|||
|
||||
// priority
|
||||
double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10
|
||||
itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(mempool, dPriority));
|
||||
itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority));
|
||||
itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPriority), 20, " "));
|
||||
dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1);
|
||||
nInputSum += nInputSize;
|
||||
|
@ -778,7 +791,7 @@ void CoinControlDialog::updateView()
|
|||
itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")");
|
||||
itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum));
|
||||
itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " "));
|
||||
itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(mempool, dPrioritySum));
|
||||
itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum, mempoolEstimatePriority));
|
||||
itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPrioritySum), 20, " "));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
|
||||
// static because also called from sendcoinsdialog
|
||||
static void updateLabels(WalletModel*, QDialog*);
|
||||
static QString getPriorityLabel(const CTxMemPool& pool, double);
|
||||
static QString getPriorityLabel(double dPriority, double mempoolEstimatePriority);
|
||||
|
||||
static QList<CAmount> payAmounts;
|
||||
static CCoinControl *coinControl;
|
||||
|
|
|
@ -137,65 +137,6 @@
|
|||
<string>W&allet</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Wallet">
|
||||
<item>
|
||||
<widget class="QLabel" name="transactionFeeInfoLabel">
|
||||
<property name="text">
|
||||
<string>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1_Wallet">
|
||||
<item>
|
||||
<widget class="QLabel" name="transactionFeeLabel">
|
||||
<property name="text">
|
||||
<string>Pay transaction &fee</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>transactionFee</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="BitcoinAmountField" name="transactionFee"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_1_Wallet">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Wallet">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
|
@ -225,6 +166,19 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Wallet">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabNetwork">
|
||||
|
@ -632,12 +586,6 @@
|
|||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BitcoinAmountField</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>bitcoinamountfield.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QValidatedLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>850</width>
|
||||
<height>400</height>
|
||||
<height>526</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Send Coins</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0,0">
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
|
@ -617,7 +617,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>830</width>
|
||||
<height>178</height>
|
||||
<height>68</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
|
||||
|
@ -657,6 +657,590 @@
|
|||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frameFee">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee1">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee2" stretch="0,0,0">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFee1">
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee7">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacerSmartFee">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>4</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutSmartFee">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFeeHeadline">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-weight:bold;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Transaction Fee:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFeeMinimized">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonChooseFee">
|
||||
<property name="text">
|
||||
<string>Choose...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonMinimizeFee">
|
||||
<property name="toolTip">
|
||||
<string>collapse fee-settings</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Minimize</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frameFeeSelection">
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee12">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayoutFee">
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item row="1" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee8">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFee13">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioCustomPerKilobyte">
|
||||
<property name="toolTip">
|
||||
<string>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>per kilobyte</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupCustomFee</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioCustomAtLeast">
|
||||
<property name="toolTip">
|
||||
<string>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>total at least</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupCustomFee</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="BitcoinAmountField" name="customFee"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFee8">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxMinimumFee">
|
||||
<property name="toolTip">
|
||||
<string>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelMinFeeWarning">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(read the tooltip)</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee4" stretch="0,1">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioSmartFee">
|
||||
<property name="text">
|
||||
<string>Recommended:</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupFee</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee9" stretch="0,1">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioCustomFee">
|
||||
<property name="text">
|
||||
<string>Custom:</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupFee</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee3" stretch="0,0,1">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFee12">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelSmartFee">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFeeEstimation">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelSmartFee2">
|
||||
<property name="text">
|
||||
<string>(Smart fee not initialized yet. This usually takes a few blocks...)</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFee9">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee6">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelSmartFee3">
|
||||
<property name="text">
|
||||
<string>Confirmation time:</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutFee5">
|
||||
<property name="rightMargin">
|
||||
<number>30</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSlider" name="sliderSmartFee">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFee10">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelSmartFeeNormal">
|
||||
<property name="text">
|
||||
<string>normal</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelSmartFeeFast">
|
||||
<property name="text">
|
||||
<string>fast</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayoutFee5" stretch="0,0,0">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxFreeTx">
|
||||
<property name="text">
|
||||
<string>Send as zero-fee transaction if possible</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFreeTx">
|
||||
<property name="text">
|
||||
<string>(confirmation may take longer)</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacerFee5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacerFee2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacerFee">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>800</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
|
@ -787,9 +1371,19 @@
|
|||
<extends>QLineEdit</extends>
|
||||
<header>qvalidatedlineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>BitcoinAmountField</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>bitcoinamountfield.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="groupFee"/>
|
||||
<buttongroup name="groupCustomFee"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
|
|
@ -105,9 +105,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
|
|||
#endif
|
||||
|
||||
ui->unit->setModel(new BitcoinUnits(this));
|
||||
#ifdef ENABLE_WALLET
|
||||
ui->transactionFee->setSingleStep(CWallet::minTxFee.GetFeePerK());
|
||||
#endif
|
||||
|
||||
/* Widget-to-option mapper */
|
||||
mapper = new QDataWidgetMapper(this);
|
||||
|
@ -139,16 +136,11 @@ void OptionsDialog::setModel(OptionsModel *model)
|
|||
strLabel = tr("none");
|
||||
ui->overriddenByCommandLineLabel->setText(strLabel);
|
||||
|
||||
connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
|
||||
mapper->setModel(model);
|
||||
setMapper();
|
||||
mapper->toFirst();
|
||||
}
|
||||
|
||||
/* update the display unit, to not use the default ("BTC") */
|
||||
updateDisplayUnit();
|
||||
|
||||
/* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */
|
||||
|
||||
/* Main */
|
||||
|
@ -172,7 +164,6 @@ void OptionsDialog::setMapper()
|
|||
mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
|
||||
|
||||
/* Wallet */
|
||||
mapper->addMapping(ui->transactionFee, OptionsModel::Fee);
|
||||
mapper->addMapping(ui->spendZeroConfChange, OptionsModel::SpendZeroConfChange);
|
||||
mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures);
|
||||
|
||||
|
@ -264,15 +255,6 @@ void OptionsDialog::clearStatusLabel()
|
|||
ui->statusLabel->clear();
|
||||
}
|
||||
|
||||
void OptionsDialog::updateDisplayUnit()
|
||||
{
|
||||
if(model)
|
||||
{
|
||||
/* Update transactionFee with the current unit */
|
||||
ui->transactionFee->setDisplayUnit(model->getDisplayUnit());
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort)
|
||||
{
|
||||
Q_UNUSED(nProxyPort);
|
||||
|
|
|
@ -46,7 +46,6 @@ private slots:
|
|||
|
||||
void showRestartWarning(bool fPersistent = false);
|
||||
void clearStatusLabel();
|
||||
void updateDisplayUnit();
|
||||
void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
|
||||
|
||||
signals:
|
||||
|
|
|
@ -90,12 +90,6 @@ void OptionsModel::Init()
|
|||
|
||||
// Wallet
|
||||
#ifdef ENABLE_WALLET
|
||||
if (!settings.contains("nTransactionFee"))
|
||||
settings.setValue("nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE);
|
||||
payTxFee = CFeeRate(settings.value("nTransactionFee").toLongLong()); // if -paytxfee is set, this will be overridden later in init.cpp
|
||||
if (mapArgs.count("-paytxfee"))
|
||||
addOverriddenOption("-paytxfee");
|
||||
|
||||
if (!settings.contains("bSpendZeroConfChange"))
|
||||
settings.setValue("bSpendZeroConfChange", true);
|
||||
if (!SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool()))
|
||||
|
@ -185,16 +179,6 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
|||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
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 (!(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
|
||||
|
@ -276,14 +260,6 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
|||
}
|
||||
break;
|
||||
#ifdef ENABLE_WALLET
|
||||
case Fee: { // core option - can be changed on-the-fly
|
||||
// Todo: Add is valid check and warn via message, if not
|
||||
CAmount nTransactionFee(value.toLongLong());
|
||||
payTxFee = CFeeRate(nTransactionFee, 1000);
|
||||
settings.setValue("nTransactionFee", qint64(nTransactionFee));
|
||||
emit transactionFeeChanged(nTransactionFee);
|
||||
break;
|
||||
}
|
||||
case SpendZeroConfChange:
|
||||
if (settings.value("bSpendZeroConfChange") != value) {
|
||||
settings.setValue("bSpendZeroConfChange", value);
|
||||
|
|
|
@ -34,7 +34,6 @@ public:
|
|||
ProxyUse, // bool
|
||||
ProxyIP, // QString
|
||||
ProxyPort, // int
|
||||
Fee, // qint64
|
||||
DisplayUnit, // BitcoinUnits::Unit
|
||||
ThirdPartyTxUrls, // QString
|
||||
Language, // QString
|
||||
|
@ -84,7 +83,6 @@ private:
|
|||
|
||||
signals:
|
||||
void displayUnitChanged(int unit);
|
||||
void transactionFeeChanged(const CAmount&);
|
||||
void coinControlFeaturesChanged(bool);
|
||||
};
|
||||
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
|
||||
#include "addresstablemodel.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include "clientmodel.h"
|
||||
#include "coincontroldialog.h"
|
||||
#include "guiutil.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "sendcoinsentry.h"
|
||||
#include "wallet.h"
|
||||
#include "walletmodel.h"
|
||||
|
||||
#include "base58.h"
|
||||
|
@ -19,6 +21,7 @@
|
|||
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include <QSettings>
|
||||
#include <QTextDocument>
|
||||
|
||||
SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
|
||||
|
@ -72,9 +75,46 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
|
|||
ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction);
|
||||
ui->labelCoinControlChange->addAction(clipboardChangeAction);
|
||||
|
||||
// init transaction fee section
|
||||
QSettings settings;
|
||||
if (!settings.contains("fFeeSectionMinimized"))
|
||||
settings.setValue("fFeeSectionMinimized", true);
|
||||
if (!settings.contains("nFeeRadio") && settings.contains("nTransactionFee") && settings.value("nTransactionFee").toLongLong() > 0) // compatibility
|
||||
settings.setValue("nFeeRadio", 1); // custom
|
||||
if (!settings.contains("nFeeRadio"))
|
||||
settings.setValue("nFeeRadio", 0); // recommended
|
||||
if (!settings.contains("nCustomFeeRadio") && settings.contains("nTransactionFee") && settings.value("nTransactionFee").toLongLong() > 0) // compatibility
|
||||
settings.setValue("nCustomFeeRadio", 1); // total at least
|
||||
if (!settings.contains("nCustomFeeRadio"))
|
||||
settings.setValue("nCustomFeeRadio", 0); // per kilobyte
|
||||
if (!settings.contains("nSmartFeeSliderPosition"))
|
||||
settings.setValue("nSmartFeeSliderPosition", 0);
|
||||
if (!settings.contains("nTransactionFee"))
|
||||
settings.setValue("nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE);
|
||||
if (!settings.contains("fPayOnlyMinFee"))
|
||||
settings.setValue("fPayOnlyMinFee", false);
|
||||
if (!settings.contains("fSendFreeTransactions"))
|
||||
settings.setValue("fSendFreeTransactions", false);
|
||||
ui->groupFee->setId(ui->radioSmartFee, 0);
|
||||
ui->groupFee->setId(ui->radioCustomFee, 1);
|
||||
ui->groupFee->button((int)std::max(0, std::min(1, settings.value("nFeeRadio").toInt())))->setChecked(true);
|
||||
ui->groupCustomFee->setId(ui->radioCustomPerKilobyte, 0);
|
||||
ui->groupCustomFee->setId(ui->radioCustomAtLeast, 1);
|
||||
ui->groupCustomFee->button((int)std::max(0, std::min(1, settings.value("nCustomFeeRadio").toInt())))->setChecked(true);
|
||||
ui->sliderSmartFee->setValue(settings.value("nSmartFeeSliderPosition").toInt());
|
||||
ui->customFee->setValue(settings.value("nTransactionFee").toLongLong());
|
||||
ui->checkBoxMinimumFee->setChecked(settings.value("fPayOnlyMinFee").toBool());
|
||||
ui->checkBoxFreeTx->setChecked(settings.value("fSendFreeTransactions").toBool());
|
||||
minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool());
|
||||
|
||||
fNewRecipientAllowed = true;
|
||||
}
|
||||
|
||||
void SendCoinsDialog::setClientModel(ClientModel *clientModel)
|
||||
{
|
||||
this->clientModel = clientModel;
|
||||
}
|
||||
|
||||
void SendCoinsDialog::setModel(WalletModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
|
@ -94,18 +134,51 @@ void SendCoinsDialog::setModel(WalletModel *model)
|
|||
model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
|
||||
connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
updateDisplayUnit();
|
||||
|
||||
// Coin Control
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
||||
connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool)));
|
||||
connect(model->getOptionsModel(), SIGNAL(transactionFeeChanged(CAmount)), this, SLOT(coinControlUpdateLabels()));
|
||||
ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures());
|
||||
coinControlUpdateLabels();
|
||||
|
||||
// fee section
|
||||
connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(updateSmartFeeLabel()));
|
||||
connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(updateSmartFeeLabel()));
|
||||
connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(updateGlobalFeeVariables()));
|
||||
connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
||||
connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateFeeSectionControls()));
|
||||
connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateGlobalFeeVariables()));
|
||||
connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(coinControlUpdateLabels()));
|
||||
connect(ui->groupCustomFee, SIGNAL(buttonClicked(int)), this, SLOT(updateGlobalFeeVariables()));
|
||||
connect(ui->groupCustomFee, SIGNAL(buttonClicked(int)), this, SLOT(coinControlUpdateLabels()));
|
||||
connect(ui->customFee, SIGNAL(valueChanged()), this, SLOT(updateGlobalFeeVariables()));
|
||||
connect(ui->customFee, SIGNAL(valueChanged()), this, SLOT(coinControlUpdateLabels()));
|
||||
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(setMinimumFee()));
|
||||
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateFeeSectionControls()));
|
||||
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables()));
|
||||
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
||||
connect(ui->checkBoxFreeTx, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables()));
|
||||
connect(ui->checkBoxFreeTx, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
||||
ui->customFee->setSingleStep(CWallet::minTxFee.GetFeePerK());
|
||||
updateFeeSectionControls();
|
||||
updateMinFeeLabel();
|
||||
updateSmartFeeLabel();
|
||||
updateGlobalFeeVariables();
|
||||
}
|
||||
}
|
||||
|
||||
SendCoinsDialog::~SendCoinsDialog()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("fFeeSectionMinimized", fFeeMinimized);
|
||||
settings.setValue("nFeeRadio", ui->groupFee->checkedId());
|
||||
settings.setValue("nCustomFeeRadio", ui->groupCustomFee->checkedId());
|
||||
settings.setValue("nSmartFeeSliderPosition", ui->sliderSmartFee->value());
|
||||
settings.setValue("nTransactionFee", (qint64)ui->customFee->value());
|
||||
settings.setValue("fPayOnlyMinFee", ui->checkBoxMinimumFee->isChecked());
|
||||
settings.setValue("fSendFreeTransactions", ui->checkBoxFreeTx->isChecked());
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
@ -214,6 +287,9 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||
questionString.append(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee));
|
||||
questionString.append("</span> ");
|
||||
questionString.append(tr("added as transaction fee"));
|
||||
|
||||
// append transaction size
|
||||
questionString.append(" (" + QString::number((double)currentTransaction.getTransactionSize() / 1000) + " kB)");
|
||||
}
|
||||
|
||||
// add total amount in all subdivision units
|
||||
|
@ -402,6 +478,9 @@ void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfir
|
|||
void SendCoinsDialog::updateDisplayUnit()
|
||||
{
|
||||
setBalance(model->getBalance(), 0, 0, 0, 0, 0);
|
||||
ui->customFee->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
|
||||
updateMinFeeLabel();
|
||||
updateSmartFeeLabel();
|
||||
}
|
||||
|
||||
void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg)
|
||||
|
@ -438,6 +517,9 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
|
|||
msgParams.first = tr("The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
|
||||
msgParams.second = CClientUIInterface::MSG_ERROR;
|
||||
break;
|
||||
case WalletModel::InsaneFee:
|
||||
msgParams.first = tr("A fee higher than %1 is considered an insanely high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
|
||||
break;
|
||||
// included to prevent a compiler warning.
|
||||
case WalletModel::OK:
|
||||
default:
|
||||
|
@ -447,6 +529,110 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
|
|||
emit message(tr("Send Coins"), msgParams.first, msgParams.second);
|
||||
}
|
||||
|
||||
void SendCoinsDialog::minimizeFeeSection(bool fMinimize)
|
||||
{
|
||||
ui->labelFeeMinimized->setVisible(fMinimize);
|
||||
ui->buttonChooseFee ->setVisible(fMinimize);
|
||||
ui->buttonMinimizeFee->setVisible(!fMinimize);
|
||||
ui->frameFeeSelection->setVisible(!fMinimize);
|
||||
ui->horizontalLayoutSmartFee->setContentsMargins(0, (fMinimize ? 0 : 6), 0, 0);
|
||||
fFeeMinimized = fMinimize;
|
||||
}
|
||||
|
||||
void SendCoinsDialog::on_buttonChooseFee_clicked()
|
||||
{
|
||||
minimizeFeeSection(false);
|
||||
}
|
||||
|
||||
void SendCoinsDialog::on_buttonMinimizeFee_clicked()
|
||||
{
|
||||
updateFeeMinimizedLabel();
|
||||
minimizeFeeSection(true);
|
||||
}
|
||||
|
||||
void SendCoinsDialog::setMinimumFee()
|
||||
{
|
||||
ui->radioCustomPerKilobyte->setChecked(true);
|
||||
ui->customFee->setValue(CWallet::minTxFee.GetFeePerK());
|
||||
}
|
||||
|
||||
void SendCoinsDialog::updateFeeSectionControls()
|
||||
{
|
||||
ui->sliderSmartFee ->setEnabled(ui->radioSmartFee->isChecked());
|
||||
ui->labelSmartFee ->setEnabled(ui->radioSmartFee->isChecked());
|
||||
ui->labelSmartFee2 ->setEnabled(ui->radioSmartFee->isChecked());
|
||||
ui->labelSmartFee3 ->setEnabled(ui->radioSmartFee->isChecked());
|
||||
ui->labelFeeEstimation ->setEnabled(ui->radioSmartFee->isChecked());
|
||||
ui->labelSmartFeeNormal ->setEnabled(ui->radioSmartFee->isChecked());
|
||||
ui->labelSmartFeeFast ->setEnabled(ui->radioSmartFee->isChecked());
|
||||
ui->checkBoxMinimumFee ->setEnabled(ui->radioCustomFee->isChecked());
|
||||
ui->labelMinFeeWarning ->setEnabled(ui->radioCustomFee->isChecked());
|
||||
ui->radioCustomPerKilobyte ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
|
||||
ui->radioCustomAtLeast ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
|
||||
ui->customFee ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
|
||||
}
|
||||
|
||||
void SendCoinsDialog::updateGlobalFeeVariables()
|
||||
{
|
||||
if (ui->radioSmartFee->isChecked())
|
||||
{
|
||||
nTxConfirmTarget = (int)25 - (int)std::max(0, std::min(24, ui->sliderSmartFee->value()));
|
||||
payTxFee = CFeeRate(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
nTxConfirmTarget = 25;
|
||||
payTxFee = CFeeRate(ui->customFee->value());
|
||||
fPayAtLeastCustomFee = ui->radioCustomAtLeast->isChecked();
|
||||
}
|
||||
|
||||
fSendFreeTransactions = ui->checkBoxFreeTx->isChecked();
|
||||
}
|
||||
|
||||
void SendCoinsDialog::updateFeeMinimizedLabel()
|
||||
{
|
||||
if(!model || !model->getOptionsModel())
|
||||
return;
|
||||
|
||||
if (ui->radioSmartFee->isChecked())
|
||||
ui->labelFeeMinimized->setText(ui->labelSmartFee->text());
|
||||
else {
|
||||
ui->labelFeeMinimized->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), ui->customFee->value()) +
|
||||
((ui->radioCustomPerKilobyte->isChecked()) ? "/kB" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
void SendCoinsDialog::updateMinFeeLabel()
|
||||
{
|
||||
if (model && model->getOptionsModel())
|
||||
ui->checkBoxMinimumFee->setText(tr("Pay only the minimum fee of %1").arg(
|
||||
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::minTxFee.GetFeePerK()) + "/kB")
|
||||
);
|
||||
}
|
||||
|
||||
void SendCoinsDialog::updateSmartFeeLabel()
|
||||
{
|
||||
if(!model || !model->getOptionsModel())
|
||||
return;
|
||||
|
||||
int nBlocksToConfirm = (int)25 - (int)std::max(0, std::min(24, ui->sliderSmartFee->value()));
|
||||
CFeeRate feeRate = mempool.estimateFee(nBlocksToConfirm);
|
||||
if (feeRate <= CFeeRate(0)) // not enough data => minfee
|
||||
{
|
||||
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::minTxFee.GetFeePerK()) + "/kB");
|
||||
ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...)
|
||||
ui->labelFeeEstimation->setText("");
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB");
|
||||
ui->labelSmartFee2->hide();
|
||||
ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %1 block(s).").arg(nBlocksToConfirm));
|
||||
}
|
||||
|
||||
updateFeeMinimizedLabel();
|
||||
}
|
||||
|
||||
// Coin Control: copy label "Quantity" to clipboard
|
||||
void SendCoinsDialog::coinControlClipboardQuantity()
|
||||
{
|
||||
|
@ -462,19 +648,19 @@ void SendCoinsDialog::coinControlClipboardAmount()
|
|||
// Coin Control: copy label "Fee" to clipboard
|
||||
void SendCoinsDialog::coinControlClipboardFee()
|
||||
{
|
||||
GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")));
|
||||
GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", ""));
|
||||
}
|
||||
|
||||
// Coin Control: copy label "After fee" to clipboard
|
||||
void SendCoinsDialog::coinControlClipboardAfterFee()
|
||||
{
|
||||
GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")));
|
||||
GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", ""));
|
||||
}
|
||||
|
||||
// Coin Control: copy label "Bytes" to clipboard
|
||||
void SendCoinsDialog::coinControlClipboardBytes()
|
||||
{
|
||||
GUIUtil::setClipboard(ui->labelCoinControlBytes->text());
|
||||
GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", ""));
|
||||
}
|
||||
|
||||
// Coin Control: copy label "Priority" to clipboard
|
||||
|
@ -492,7 +678,7 @@ void SendCoinsDialog::coinControlClipboardLowOutput()
|
|||
// Coin Control: copy label "Change" to clipboard
|
||||
void SendCoinsDialog::coinControlClipboardChange()
|
||||
{
|
||||
GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")));
|
||||
GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", ""));
|
||||
}
|
||||
|
||||
// Coin Control: settings menu - coin control enabled/disabled by user
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <QDialog>
|
||||
#include <QString>
|
||||
|
||||
class ClientModel;
|
||||
class OptionsModel;
|
||||
class SendCoinsEntry;
|
||||
class SendCoinsRecipient;
|
||||
|
@ -31,6 +32,7 @@ public:
|
|||
explicit SendCoinsDialog(QWidget *parent = 0);
|
||||
~SendCoinsDialog();
|
||||
|
||||
void setClientModel(ClientModel *clientModel);
|
||||
void setModel(WalletModel *model);
|
||||
|
||||
/** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907).
|
||||
|
@ -52,16 +54,22 @@ public slots:
|
|||
|
||||
private:
|
||||
Ui::SendCoinsDialog *ui;
|
||||
ClientModel *clientModel;
|
||||
WalletModel *model;
|
||||
bool fNewRecipientAllowed;
|
||||
bool fFeeMinimized;
|
||||
|
||||
// Process WalletModel::SendCoinsReturn and generate a pair consisting
|
||||
// of a message and message flags for use in emit message().
|
||||
// Additional parameter msgArg can be used via .arg(msgArg).
|
||||
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString());
|
||||
void minimizeFeeSection(bool fMinimize);
|
||||
void updateFeeMinimizedLabel();
|
||||
|
||||
private slots:
|
||||
void on_sendButton_clicked();
|
||||
void on_buttonChooseFee_clicked();
|
||||
void on_buttonMinimizeFee_clicked();
|
||||
void removeEntry(SendCoinsEntry* entry);
|
||||
void updateDisplayUnit();
|
||||
void coinControlFeatureChanged(bool);
|
||||
|
@ -77,6 +85,11 @@ private slots:
|
|||
void coinControlClipboardPriority();
|
||||
void coinControlClipboardLowOutput();
|
||||
void coinControlClipboardChange();
|
||||
void setMinimumFee();
|
||||
void updateFeeSectionControls();
|
||||
void updateMinFeeLabel();
|
||||
void updateSmartFeeLabel();
|
||||
void updateGlobalFeeVariables();
|
||||
|
||||
signals:
|
||||
// Fired when a message should be reported to the user
|
||||
|
|
|
@ -277,6 +277,10 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
CClientUIInterface::MSG_ERROR);
|
||||
return TransactionCreationFailed;
|
||||
}
|
||||
|
||||
// reject insane fee > 0.1 bitcoin
|
||||
if (nFeeRequired > 10000000)
|
||||
return InsaneFee;
|
||||
}
|
||||
|
||||
return SendCoinsReturn(OK);
|
||||
|
|
|
@ -110,7 +110,8 @@ public:
|
|||
AmountWithFeeExceedsBalance,
|
||||
DuplicateAddress,
|
||||
TransactionCreationFailed, // Error returned when wallet is still locked
|
||||
TransactionCommitFailed
|
||||
TransactionCommitFailed,
|
||||
InsaneFee
|
||||
};
|
||||
|
||||
enum EncryptionStatus
|
||||
|
|
|
@ -31,6 +31,11 @@ CWalletTx *WalletModelTransaction::getTransaction()
|
|||
return walletTransaction;
|
||||
}
|
||||
|
||||
unsigned int WalletModelTransaction::getTransactionSize()
|
||||
{
|
||||
return (!walletTransaction ? 0 : (::GetSerializeSize(*(CTransaction*)walletTransaction, SER_NETWORK, PROTOCOL_VERSION)));
|
||||
}
|
||||
|
||||
CAmount WalletModelTransaction::getTransactionFee()
|
||||
{
|
||||
return fee;
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
QList<SendCoinsRecipient> getRecipients();
|
||||
|
||||
CWalletTx *getTransaction();
|
||||
unsigned int getTransactionSize();
|
||||
|
||||
void setTransactionFee(const CAmount& newFee);
|
||||
CAmount getTransactionFee();
|
||||
|
|
|
@ -101,6 +101,7 @@ void WalletView::setClientModel(ClientModel *clientModel)
|
|||
this->clientModel = clientModel;
|
||||
|
||||
overviewPage->setClientModel(clientModel);
|
||||
sendCoinsPage->setClientModel(clientModel);
|
||||
}
|
||||
|
||||
void WalletView::setWalletModel(WalletModel *walletModel)
|
||||
|
|
|
@ -15,11 +15,16 @@
|
|||
|
||||
class CAutoFile;
|
||||
|
||||
inline double AllowFreeThreshold()
|
||||
{
|
||||
return COIN * 144 / 250;
|
||||
}
|
||||
|
||||
inline bool AllowFree(double dPriority)
|
||||
{
|
||||
// Large (in bytes) low-priority (new, small-coin) transactions
|
||||
// need a fee.
|
||||
return dPriority > COIN * 144 / 250;
|
||||
return dPriority > AllowFreeThreshold();
|
||||
}
|
||||
|
||||
/** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */
|
||||
|
|
|
@ -28,6 +28,8 @@ using namespace std;
|
|||
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
|
||||
unsigned int nTxConfirmTarget = 1;
|
||||
bool bSpendZeroConfChange = true;
|
||||
bool fSendFreeTransactions = false;
|
||||
bool fPayAtLeastCustomFee = true;
|
||||
|
||||
/**
|
||||
* Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
|
||||
|
@ -1382,7 +1384,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
|
|||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
{
|
||||
nFeeRet = payTxFee.GetFeePerK();
|
||||
nFeeRet = 0;
|
||||
while (true)
|
||||
{
|
||||
txNew.vin.clear();
|
||||
|
@ -1502,7 +1504,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
|
|||
break; // Done, enough fee included.
|
||||
|
||||
// Too big to send for free? Include more fee and try again:
|
||||
if (nBytes > MAX_FREE_TRANSACTION_CREATE_SIZE)
|
||||
if (!fSendFreeTransactions || nBytes > MAX_FREE_TRANSACTION_CREATE_SIZE)
|
||||
{
|
||||
nFeeRet = nFeeNeeded;
|
||||
continue;
|
||||
|
@ -1628,6 +1630,12 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge
|
|||
{
|
||||
// payTxFee is user-set "I want to pay this much"
|
||||
CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
|
||||
// prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
|
||||
if (nFeeNeeded > 0 && nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
|
||||
nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
|
||||
// user selected total at least (default=true)
|
||||
if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
|
||||
nFeeNeeded = payTxFee.GetFeePerK();
|
||||
// User didn't set: use -txconfirmtarget to estimate...
|
||||
if (nFeeNeeded == 0)
|
||||
nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
extern CFeeRate payTxFee;
|
||||
extern unsigned int nTxConfirmTarget;
|
||||
extern bool bSpendZeroConfChange;
|
||||
extern bool fSendFreeTransactions;
|
||||
extern bool fPayAtLeastCustomFee;
|
||||
|
||||
//! -paytxfee default
|
||||
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
|
||||
|
|
Loading…
Reference in New Issue