Use CoinControl to pass custom fee setting from QT.
This fixes buggy behavior where we were temporarily setting and unsetting the global payTxFee when trying to send a transaction with a custom fee from the GUI. The previous behavior was inconsistent depending on the order of using the RPC call settxfee and clicking various radio buttons in the sendcoinsdialog. The new behavior is that transactions sent with the GUI will always use either the smartfee slider value or the custom fee set on the GUI and they will not affect the global defaults which are only for RPC and initial GUI values.
This commit is contained in:
parent
03ee701161
commit
1983ca6cb3
2 changed files with 25 additions and 37 deletions
|
@ -175,18 +175,13 @@ void SendCoinsDialog::setModel(WalletModel *_model)
|
||||||
ui->confTargetSelector->addItem(tr("%1 (%2 blocks)").arg(GUIUtil::formatNiceTimeOffset(n*Params().GetConsensus().nPowTargetSpacing)).arg(n));
|
ui->confTargetSelector->addItem(tr("%1 (%2 blocks)").arg(GUIUtil::formatNiceTimeOffset(n*Params().GetConsensus().nPowTargetSpacing)).arg(n));
|
||||||
}
|
}
|
||||||
connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSmartFeeLabel()));
|
connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSmartFeeLabel()));
|
||||||
connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateGlobalFeeVariables()));
|
|
||||||
connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
||||||
connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateFeeSectionControls()));
|
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->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->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->customFee, SIGNAL(valueChanged()), this, SLOT(coinControlUpdateLabels()));
|
||||||
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(setMinimumFee()));
|
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(updateFeeSectionControls()));
|
||||||
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables()));
|
|
||||||
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
||||||
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(updateSmartFeeLabel()));
|
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(updateSmartFeeLabel()));
|
||||||
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
||||||
|
@ -194,7 +189,6 @@ void SendCoinsDialog::setModel(WalletModel *_model)
|
||||||
updateFeeSectionControls();
|
updateFeeSectionControls();
|
||||||
updateMinFeeLabel();
|
updateMinFeeLabel();
|
||||||
updateSmartFeeLabel();
|
updateSmartFeeLabel();
|
||||||
updateGlobalFeeVariables();
|
|
||||||
|
|
||||||
// set default rbf checkbox state
|
// set default rbf checkbox state
|
||||||
ui->optInRBF->setCheckState(model->getDefaultWalletRbf() ? Qt::Checked : Qt::Unchecked);
|
ui->optInRBF->setCheckState(model->getDefaultWalletRbf() ? Qt::Checked : Qt::Unchecked);
|
||||||
|
@ -274,12 +268,8 @@ void SendCoinsDialog::on_sendButton_clicked()
|
||||||
CCoinControl ctrl;
|
CCoinControl ctrl;
|
||||||
if (model->getOptionsModel()->getCoinControlFeatures())
|
if (model->getOptionsModel()->getCoinControlFeatures())
|
||||||
ctrl = *CoinControlDialog::coinControl;
|
ctrl = *CoinControlDialog::coinControl;
|
||||||
if (ui->radioSmartFee->isChecked()) {
|
|
||||||
ctrl.m_confirm_target = getConfTargetForIndex(ui->confTargetSelector->currentIndex());
|
updateCoinControlState(ctrl);
|
||||||
} else {
|
|
||||||
ctrl.m_confirm_target = boost::none;
|
|
||||||
}
|
|
||||||
ctrl.signalRbf = ui->optInRBF->isChecked();
|
|
||||||
|
|
||||||
prepareStatus = model->prepareTransaction(currentTransaction, ctrl);
|
prepareStatus = model->prepareTransaction(currentTransaction, ctrl);
|
||||||
|
|
||||||
|
@ -636,18 +626,6 @@ void SendCoinsDialog::updateFeeSectionControls()
|
||||||
ui->customFee ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
|
ui->customFee ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendCoinsDialog::updateGlobalFeeVariables()
|
|
||||||
{
|
|
||||||
if (ui->radioSmartFee->isChecked())
|
|
||||||
{
|
|
||||||
payTxFee = CFeeRate(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
payTxFee = CFeeRate(ui->customFee->value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SendCoinsDialog::updateFeeMinimizedLabel()
|
void SendCoinsDialog::updateFeeMinimizedLabel()
|
||||||
{
|
{
|
||||||
if(!model || !model->getOptionsModel())
|
if(!model || !model->getOptionsModel())
|
||||||
|
@ -669,15 +647,30 @@ void SendCoinsDialog::updateMinFeeLabel()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SendCoinsDialog::updateCoinControlState(CCoinControl& ctrl)
|
||||||
|
{
|
||||||
|
if (ui->radioCustomFee->isChecked()) {
|
||||||
|
ctrl.m_feerate = CFeeRate(ui->customFee->value());
|
||||||
|
} else {
|
||||||
|
ctrl.m_feerate = boost::none;
|
||||||
|
}
|
||||||
|
// Avoid using global defaults when sending money from the GUI
|
||||||
|
// Either custom fee will be used or if not selected, the confirmation target from dropdown box
|
||||||
|
ctrl.m_confirm_target = getConfTargetForIndex(ui->confTargetSelector->currentIndex());
|
||||||
|
ctrl.signalRbf = ui->optInRBF->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
void SendCoinsDialog::updateSmartFeeLabel()
|
void SendCoinsDialog::updateSmartFeeLabel()
|
||||||
{
|
{
|
||||||
if(!model || !model->getOptionsModel())
|
if(!model || !model->getOptionsModel())
|
||||||
return;
|
return;
|
||||||
|
CCoinControl coin_control;
|
||||||
int nBlocksToConfirm = getConfTargetForIndex(ui->confTargetSelector->currentIndex());
|
updateCoinControlState(coin_control);
|
||||||
|
coin_control.m_feerate = boost::none; // Explicitly use only fee estimation rate for smart fee labels
|
||||||
FeeCalculation feeCalc;
|
FeeCalculation feeCalc;
|
||||||
bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET, ui->optInRBF->isChecked());
|
bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET, coin_control.signalRbf);
|
||||||
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocksToConfirm, &feeCalc, ::mempool, conservative_estimate);
|
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(*coin_control.m_confirm_target, &feeCalc, ::mempool, conservative_estimate);
|
||||||
|
|
||||||
if (feeRate <= CFeeRate(0)) // not enough data => minfee
|
if (feeRate <= CFeeRate(0)) // not enough data => minfee
|
||||||
{
|
{
|
||||||
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(),
|
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(),
|
||||||
|
@ -752,8 +745,6 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked)
|
||||||
if (!checked && model) // coin control features disabled
|
if (!checked && model) // coin control features disabled
|
||||||
CoinControlDialog::coinControl->SetNull();
|
CoinControlDialog::coinControl->SetNull();
|
||||||
|
|
||||||
// make sure we set back the confirmation target
|
|
||||||
updateGlobalFeeVariables();
|
|
||||||
coinControlUpdateLabels();
|
coinControlUpdateLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,15 +835,11 @@ void SendCoinsDialog::coinControlUpdateLabels()
|
||||||
if (!model || !model->getOptionsModel())
|
if (!model || !model->getOptionsModel())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
updateCoinControlState(*CoinControlDialog::coinControl);
|
||||||
|
|
||||||
// set pay amounts
|
// set pay amounts
|
||||||
CoinControlDialog::payAmounts.clear();
|
CoinControlDialog::payAmounts.clear();
|
||||||
CoinControlDialog::fSubtractFeeFromAmount = false;
|
CoinControlDialog::fSubtractFeeFromAmount = false;
|
||||||
if (ui->radioSmartFee->isChecked()) {
|
|
||||||
CoinControlDialog::coinControl->m_confirm_target = getConfTargetForIndex(ui->confTargetSelector->currentIndex());
|
|
||||||
} else {
|
|
||||||
CoinControlDialog::coinControl->m_confirm_target = boost::none;
|
|
||||||
}
|
|
||||||
CoinControlDialog::coinControl->signalRbf = ui->optInRBF->isChecked();
|
|
||||||
|
|
||||||
for(int i = 0; i < ui->entries->count(); ++i)
|
for(int i = 0; i < ui->entries->count(); ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,6 +68,8 @@ private:
|
||||||
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString());
|
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString());
|
||||||
void minimizeFeeSection(bool fMinimize);
|
void minimizeFeeSection(bool fMinimize);
|
||||||
void updateFeeMinimizedLabel();
|
void updateFeeMinimizedLabel();
|
||||||
|
// Update the passed in CCoinControl with state from the GUI
|
||||||
|
void updateCoinControlState(CCoinControl& ctrl);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void on_sendButton_clicked();
|
void on_sendButton_clicked();
|
||||||
|
@ -91,7 +93,6 @@ private Q_SLOTS:
|
||||||
void updateFeeSectionControls();
|
void updateFeeSectionControls();
|
||||||
void updateMinFeeLabel();
|
void updateMinFeeLabel();
|
||||||
void updateSmartFeeLabel();
|
void updateSmartFeeLabel();
|
||||||
void updateGlobalFeeVariables();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
// Fired when a message should be reported to the user
|
// Fired when a message should be reported to the user
|
||||||
|
|
Loading…
Reference in a new issue