Skip to content

Commit

Permalink
Released v3.87.14.
Browse files Browse the repository at this point in the history
Implemented smart transaction fee auto-calculation feature.
  • Loading branch information
FromHDDtoSSD committed Jul 29, 2024
1 parent 40a68cf commit e2b4658
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 10 deletions.
2 changes: 1 addition & 1 deletion SorachanCoinQ-qt.pro
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
TEMPLATE = app
VERSION = 3.86.14
VERSION = 3.87.14

INCLUDEPATH += src src/json src/qt
QT += core gui network
Expand Down
7 changes: 7 additions & 0 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,13 @@ int main(int argc, char *argv[])
if (splashref)
splash.finish(&window);

// Smartfee thread
QSettings settings;
bool fSmartFee = settings.value("smartFee", QVariant(false)).toBool();
//print_num("fSmartFee", fSmartFee ? 1: 0);
if(fSmartFee)
OptionsModel::beginSmartFee();

ClientModel clientModel(&optionsModel);
WalletModel walletModel(entry::pwalletMain, &optionsModel);
CheckpointsModel checkpointsModel(&optionsModel);
Expand Down
27 changes: 27 additions & 0 deletions src/qt/forms/optionsdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,33 @@ color: rgb(0, 170, 255);</string>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="smartfeeCheckBox">
<property name="text">
<string>Enable smart fee [Calculate the optimal fee from the last 10 blocks]</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="smartfeeHorizontalSlider">
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>8</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="smartfeeLabel">
<property name="text">
<string>Transaction priority: The further to the right, the higher the priority</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="bitcoinAtStartup">
<property name="toolTip">
Expand Down
13 changes: 13 additions & 0 deletions src/qt/optionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ void OptionsDialog::setModel(OptionsModel *model)
/* warn only when language selection changes by user action (placed here so init via mapper doesn't trigger this) */
connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning_Lang()));
connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning_URL()));
connect(ui->smartfeeCheckBox, SIGNAL(clicked()), this, SLOT(on_smartfeecheck_clicked()));

/* disable apply button after settings are loaded as there is nothing to save */
disableApplyButton();
Expand All @@ -181,6 +182,8 @@ void OptionsDialog::setMapper()
{
/* Main */
mapper->addMapping(ui->transactionFee, OptionsModel::Fee);
mapper->addMapping(ui->smartfeeCheckBox, OptionsModel::SmartFee);
mapper->addMapping(ui->smartfeeHorizontalSlider, OptionsModel::SmartFeePriority);
mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
mapper->addMapping(ui->detachDatabases, OptionsModel::DetachDatabases);

Expand Down Expand Up @@ -222,6 +225,16 @@ void OptionsDialog::disableApplyButton()
ui->applyButton->setEnabled(false);
}

void OptionsDialog::on_smartfeecheck_clicked() {
if(ui->smartfeeCheckBox->isChecked()) {
ui->smartfeeHorizontalSlider->setEnabled(false);
ui->transactionFee->setEnabled(false);
} else {
ui->smartfeeHorizontalSlider->setEnabled(true);
ui->transactionFee->setEnabled(true);
}
}

void OptionsDialog::enableSaveButtons()
{
/* prevent enabling of the save buttons when data modified, if there is an invalid proxy address present */
Expand Down
1 change: 1 addition & 0 deletions src/qt/optionsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ private slots:
void on_okButton_clicked();
void on_cancelButton_clicked();
void on_applyButton_clicked();
void on_smartfeecheck_clicked();

void showRestartWarning_Proxy();
void showRestartWarning_Tor();
Expand Down
142 changes: 134 additions & 8 deletions src/qt/optionsmodel.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin Developers
// Copyright (c) 2018-2024 The SorachanCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand All @@ -10,6 +11,106 @@
#include <wallet.h>
#include <walletdb.h>
#include <qt/guiutil.h>
#include <thread/threadqai.h>
#include <init.h>
#include <block/block_process.h>

namespace {

bool CheckFee(int64_t value) {
int64_t checkfeeL = block_params::MIN_TX_FEE;
int64_t checkfeeH = util::roundint64(0.099 * util::COIN);
if (value < checkfeeL || checkfeeH < value) {
return false;
}

return true;
}

constexpr int32_t nPriorityL = 2;
constexpr int32_t nPriorityH = 8;
std::atomic<bool> fEnableComputeSmartFeeThread(false);
void ComputeSmartFee(std::shared_ptr<CDataStream> stream) {
int32_t nPriority;
int nInterval;
try {
(*stream) >> nPriority >> nInterval;
} catch (const std::exception &) {
return;
}

block_info::nTransactionFee = block_params::MIN_TX_FEE;
for(;;) {
{
LOCK2(block_process::cs_main, entry::pwalletMain->cs_wallet);
const int block_begin = block_info::nBestHeight - nInterval;
int32_t nSerSize = 0;
for (int nHeight = block_begin; nHeight <= block_info::nBestHeight; ++nHeight) {
CBlockIndex *pblockindex = block_info::mapBlockIndex[block_info::hashBestChain];
while (pblockindex->get_nHeight() > nHeight)
pblockindex = pblockindex->set_pprev();

pblockindex = block_info::mapBlockIndex[*pblockindex->get_phashBlock()];
CBlock block;
if(!block.ReadFromDisk(pblockindex, true))
return;

for(const CTransaction &tx: block.get_vtx()) {
nSerSize += tx.GetSerializeSize();
}
}

// Check fee
//print_num("fee compute: transaction size", nSerSize);
double dAve = (double)nSerSize / nInterval;
bool fRaiseFee = false;
if(dAve > 30 * 1024) { // If over 30KB, raise fee
fRaiseFee = true;
}

// Raise fee
if(fRaiseFee) {
block_info::nTransactionFee = nPriority * block_params::MIN_TX_FEE;
if(!CheckFee(block_info::nTransactionFee))
block_info::nTransactionFee = block_params::MIN_TX_FEE;
}
print_num("new fee", block_info::nTransactionFee);
}

// Wait: mainnet 60s, testnet 3s
const int nCheck = args_bool::fTestNet ? 3: 60;
for(int i=0; i < nCheck; ++i) {
util::Sleep(1000);
if(args_bool::fShutdown || fEnableComputeSmartFeeThread.load() == false)
return;
}
}
}

} // namespace

void OptionsModel::beginSmartFee() {
if(fEnableComputeSmartFeeThread.load())
return;
fEnableComputeSmartFeeThread.store(true);

QSettings settings;
int32_t nPriority = settings.value("SmartFeePriority", QVariant(nPriorityL)).toInt();
int nInterval = 10;

CThread thread;
CDataStream stream;
stream << nPriority << nInterval;
CThread::THREAD_INFO info(&stream, ComputeSmartFee);
thread.BeginThread(info);
thread.Detach();
}

void OptionsModel::stopSmartFee() {
fEnableComputeSmartFeeThread.store(false);
QSettings settings;
block_info::nTransactionFee = settings.value("nTransactionFee", QVariant(block_params::MIN_TX_FEE)).toLongLong();
}

OptionsModel::OptionsModel(QObject *parent) :
QAbstractListModel(parent)
Expand Down Expand Up @@ -198,9 +299,16 @@ QVariant OptionsModel::data(const QModelIndex &index, int role) const
return QVariant(bDisplayAddresses);
case ThirdPartyTxUrls:
return QVariant(strThirdPartyTxUrls);
case SmartFee:
return settings.value("smartFee", QVariant(false));
case SmartFeePriority:
return settings.value("smartFeePriority", QVariant(0));
#ifdef USE_BERKELEYDB
case DetachDatabases:
return QVariant(CDBEnv::get_instance().GetDetach());
#else
case DetachDatabases:
return settings.value("detachDB", QVariant(false));
#endif
case Language:
return settings.value("language", "");
Expand Down Expand Up @@ -303,18 +411,33 @@ bool OptionsModel::setData(const QModelIndex &index, const QVariant &value, int
case ExternalSeeder:
settings.setValue("externalSeeder", value.toString());
break;
case Fee:
case SmartFee:
{
int64_t checkfeeL = block_params::MIN_TX_FEE;
int64_t checkfeeH = util::roundint64(0.099 * util::COIN);
if(value.toLongLong() < checkfeeL || checkfeeH < value.toLongLong()) {
QMB(QMB::M_ERROR).setText(tr("The fee is outside the acceptable range.").toStdString(), tr("").toStdString()).exec();
successful = false;
break;
bool fSmartFee = value.toBool();
if(fSmartFee) {
beginSmartFee();
} else {
stopSmartFee();
}
settings.setValue("smartFee", fSmartFee);
}
break;
case SmartFeePriority:
{
int32_t nPriority = value.toInt();
settings.setValue("smartFeePriority", nPriority);
}
break;
case Fee:
if(!CheckFee(value.toLongLong())) {
QMB(QMB::M_ERROR).setText(tr("The fee is outside the acceptable range.").toStdString(), tr("").toStdString()).exec();
settings.setValue("nTransactionFee", static_cast<qlonglong>(block_info::nTransactionFee));
emit transactionFeeChanged(block_info::nTransactionFee);
successful = false;
break;
}
block_info::nTransactionFee = value.toLongLong();
settings.setValue("block_info::nTransactionFee", static_cast<qlonglong>(block_info::nTransactionFee));
settings.setValue("nTransactionFee", static_cast<qlonglong>(block_info::nTransactionFee));
emit transactionFeeChanged(block_info::nTransactionFee);
break;
case DisplayUnit:
Expand All @@ -331,6 +454,9 @@ bool OptionsModel::setData(const QModelIndex &index, const QVariant &value, int
bool fDetachDB = value.toBool();
CDBEnv::get_instance().SetDetach(fDetachDB);
settings.setValue("detachDB", fDetachDB);
#else
bool fDetachDB = value.toBool();
settings.setValue("detachDB", fDetachDB);
#endif
}
break;
Expand Down
6 changes: 6 additions & 0 deletions src/qt/optionsmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class OptionsModel : public QAbstractListModel
TorOnly, // bool
TorName, // QString
Fee, // qint64
SmartFee, // bool
SmartFeePriority, // int32_t
DisplayUnit, // BitcoinUnits::Unit
DisplayAddresses, // bool
ThirdPartyTxUrls, // QString
Expand Down Expand Up @@ -69,6 +71,10 @@ class OptionsModel : public QAbstractListModel
QString getThirdPartyTxUrls() { return strThirdPartyTxUrls; }
QString getLanguage() { return language; }

//! SmartFee starting thread
static void beginSmartFee();
static void stopSmartFee();

private:
BitcoinUnits::Unit nDisplayUnit;
bool bDisplayAddresses;
Expand Down
2 changes: 1 addition & 1 deletion src/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class format_version : private no_instance

// display version
#define DISPLAY_VERSION_MAJOR 3
#define DISPLAY_VERSION_MINOR 86
#define DISPLAY_VERSION_MINOR 87
#define DISPLAY_VERSION_REVISION 14

#endif

0 comments on commit e2b4658

Please sign in to comment.