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));
|
||||
}
|
||||
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->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->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(updateSmartFeeLabel()));
|
||||
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
|
||||
|
@ -194,7 +189,6 @@ void SendCoinsDialog::setModel(WalletModel *_model)
|
|||
updateFeeSectionControls();
|
||||
updateMinFeeLabel();
|
||||
updateSmartFeeLabel();
|
||||
updateGlobalFeeVariables();
|
||||
|
||||
// set default rbf checkbox state
|
||||
ui->optInRBF->setCheckState(model->getDefaultWalletRbf() ? Qt::Checked : Qt::Unchecked);
|
||||
|
@ -274,12 +268,8 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||
CCoinControl ctrl;
|
||||
if (model->getOptionsModel()->getCoinControlFeatures())
|
||||
ctrl = *CoinControlDialog::coinControl;
|
||||
if (ui->radioSmartFee->isChecked()) {
|
||||
ctrl.m_confirm_target = getConfTargetForIndex(ui->confTargetSelector->currentIndex());
|
||||
} else {
|
||||
ctrl.m_confirm_target = boost::none;
|
||||
}
|
||||
ctrl.signalRbf = ui->optInRBF->isChecked();
|
||||
|
||||
updateCoinControlState(ctrl);
|
||||
|
||||
prepareStatus = model->prepareTransaction(currentTransaction, ctrl);
|
||||
|
||||
|
@ -636,18 +626,6 @@ void SendCoinsDialog::updateFeeSectionControls()
|
|||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
if(!model || !model->getOptionsModel())
|
||||
return;
|
||||
|
||||
int nBlocksToConfirm = getConfTargetForIndex(ui->confTargetSelector->currentIndex());
|
||||
CCoinControl coin_control;
|
||||
updateCoinControlState(coin_control);
|
||||
coin_control.m_feerate = boost::none; // Explicitly use only fee estimation rate for smart fee labels
|
||||
FeeCalculation feeCalc;
|
||||
bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET, ui->optInRBF->isChecked());
|
||||
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocksToConfirm, &feeCalc, ::mempool, conservative_estimate);
|
||||
bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET, coin_control.signalRbf);
|
||||
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(*coin_control.m_confirm_target, &feeCalc, ::mempool, conservative_estimate);
|
||||
|
||||
if (feeRate <= CFeeRate(0)) // not enough data => minfee
|
||||
{
|
||||
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(),
|
||||
|
@ -752,8 +745,6 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked)
|
|||
if (!checked && model) // coin control features disabled
|
||||
CoinControlDialog::coinControl->SetNull();
|
||||
|
||||
// make sure we set back the confirmation target
|
||||
updateGlobalFeeVariables();
|
||||
coinControlUpdateLabels();
|
||||
}
|
||||
|
||||
|
@ -844,15 +835,11 @@ void SendCoinsDialog::coinControlUpdateLabels()
|
|||
if (!model || !model->getOptionsModel())
|
||||
return;
|
||||
|
||||
updateCoinControlState(*CoinControlDialog::coinControl);
|
||||
|
||||
// set pay amounts
|
||||
CoinControlDialog::payAmounts.clear();
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -68,6 +68,8 @@ private:
|
|||
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString());
|
||||
void minimizeFeeSection(bool fMinimize);
|
||||
void updateFeeMinimizedLabel();
|
||||
// Update the passed in CCoinControl with state from the GUI
|
||||
void updateCoinControlState(CCoinControl& ctrl);
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_sendButton_clicked();
|
||||
|
@ -91,7 +93,6 @@ private Q_SLOTS:
|
|||
void updateFeeSectionControls();
|
||||
void updateMinFeeLabel();
|
||||
void updateSmartFeeLabel();
|
||||
void updateGlobalFeeVariables();
|
||||
|
||||
Q_SIGNALS:
|
||||
// Fired when a message should be reported to the user
|
||||
|
|
Loading…
Reference in a new issue