[Qt] Add Smartfee to GUI
This commit is contained in:
@@ -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));
|
||||
// Fee
|
||||
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
||||
|
||||
// Min Fee
|
||||
if (nPayFee == 0)
|
||||
{
|
||||
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
||||
// Allow free?
|
||||
double dPriorityNeeded = mempoolEstimatePriority;
|
||||
if (dPriorityNeeded <= 0)
|
||||
dPriorityNeeded = AllowFreeThreshold(); // not enough data, back to hard-coded
|
||||
fAllowFree = (dPriority >= dPriorityNeeded);
|
||||
|
||||
double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
|
||||
if (dPriorityNeeded <= 0 && !AllowFree(dPriority)) // not enough mempool history: never send free
|
||||
dPriorityNeeded = std::numeric_limits<double>::max();
|
||||
|
||||
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, " "));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user