Add Dogecoin current fee calculation logic
Introduces 1 COIN/kb fees, rounded up to the next 1 COIN. Disable free transactions Dust outputs incur a 1 COIN additional fee Add unit tests for fee calculation Update existing unit tests with higher transaction values so that transactions are still standard
This commit is contained in:
parent
3ba610bc41
commit
c81d7632e9
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "arith_uint256.h"
|
||||
#include "dogecoin.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
|
||||
int static generateMTRandom(unsigned int s, int range)
|
||||
|
@ -150,3 +151,15 @@ CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusP
|
|||
return 10000 * COIN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int64_t GetDogecoinDustFee(const std::vector<CTxOut> &vout, CFeeRate &baseFeeRate) {
|
||||
int64_t nFee = 0;
|
||||
|
||||
// To limit dust spam, add base fee for each output less than DUST_SOFT_LIMIT
|
||||
BOOST_FOREACH(const CTxOut& txout, vout)
|
||||
if (txout.IsDust(::minRelayTxFee))
|
||||
nFee += baseFeeRate.GetFeePerK();
|
||||
|
||||
return nFee;
|
||||
}
|
||||
|
|
|
@ -17,3 +17,5 @@ unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, in
|
|||
* @return True iff the PoW is correct.
|
||||
*/
|
||||
bool CheckAuxPowProofOfWork(const CBlockHeader& block, const Consensus::Params& params);
|
||||
|
||||
int64_t GetDogecoinDustFee(const std::vector<CTxOut> &vout, CFeeRate &baseFeeRate);
|
||||
|
|
|
@ -66,7 +66,7 @@ uint64_t nPruneTarget = 0;
|
|||
bool fAlerts = DEFAULT_ALERTS;
|
||||
|
||||
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
|
||||
CFeeRate minRelayTxFee = CFeeRate(1000);
|
||||
CFeeRate minRelayTxFee = CFeeRate(COIN);
|
||||
|
||||
CTxMemPool mempool(::minRelayTxFee);
|
||||
|
||||
|
@ -867,8 +867,10 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
|
|||
}
|
||||
|
||||
CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
|
||||
nMinFee += GetDogecoinDustFee(tx.vout, ::minRelayTxFee);
|
||||
|
||||
if (fAllowFree)
|
||||
// Dogecoin: Disable free transactions
|
||||
/* if (fAllowFree)
|
||||
{
|
||||
// There is a free transaction area in blocks created by most miners,
|
||||
// * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
|
||||
|
@ -876,7 +878,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
|
|||
// multiple transactions instead of one big transaction to avoid fees.
|
||||
if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
|
||||
nMinFee = 0;
|
||||
}
|
||||
} */
|
||||
|
||||
if (!MoneyRange(nMinFee))
|
||||
nMinFee = MAX_MONEY;
|
||||
|
|
|
@ -548,7 +548,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
nBytes -= 34;
|
||||
|
||||
// Fee
|
||||
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
||||
nPayFee = CWallet::GetMinimumFee(txDummy, nBytes, nTxConfirmTarget, mempool);
|
||||
|
||||
// Allow free?
|
||||
double dPriorityNeeded = mempoolEstimatePriority;
|
||||
|
|
|
@ -528,7 +528,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
|
|||
msgParams.second = CClientUIInterface::MSG_ERROR;
|
||||
break;
|
||||
case WalletModel::AbsurdFee:
|
||||
msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
|
||||
msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 100 * COIN));
|
||||
break;
|
||||
case WalletModel::PaymentRequestExpired:
|
||||
msgParams.first = tr("Payment request expired.");
|
||||
|
|
|
@ -290,8 +290,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
return TransactionCreationFailed;
|
||||
}
|
||||
|
||||
// reject absurdly high fee > 0.1 bitcoin
|
||||
if (nFeeRequired > 10000000)
|
||||
// reject absurdly high fee > 100 DOGE
|
||||
if (nFeeRequired > (100 * COIN))
|
||||
return AbsurdFee;
|
||||
}
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ BOOST_AUTO_TEST_CASE(set)
|
|||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
txFrom.vout[i].scriptPubKey = outer[i];
|
||||
txFrom.vout[i].nValue = CENT;
|
||||
txFrom.vout[i].nValue = COIN;
|
||||
}
|
||||
BOOST_CHECK(IsStandardTx(txFrom, reason));
|
||||
|
||||
|
@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(set)
|
|||
txTo[i].vout.resize(1);
|
||||
txTo[i].vin[0].prevout.n = i;
|
||||
txTo[i].vin[0].prevout.hash = txFrom.GetHash();
|
||||
txTo[i].vout[0].nValue = 1*CENT;
|
||||
txTo[i].vout[0].nValue = 1*COIN;
|
||||
txTo[i].vout[0].scriptPubKey = inner[i];
|
||||
#ifdef ENABLE_WALLET
|
||||
BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
|
||||
|
|
|
@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|||
t.vout[0].nValue = 501; // dust
|
||||
BOOST_CHECK(!IsStandardTx(t, reason));
|
||||
|
||||
t.vout[0].nValue = 601; // not dust
|
||||
t.vout[0].nValue = COIN; // not dust
|
||||
BOOST_CHECK(IsStandardTx(t, reason));
|
||||
|
||||
t.vout[0].scriptPubKey = CScript() << OP_1;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "txmempool.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <set>
|
||||
|
@ -307,4 +308,39 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests)
|
|||
empty_wallet();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetMinimumFee_test)
|
||||
{
|
||||
uint64_t value = 1000 * COIN; // 1,000 DOGE
|
||||
|
||||
CMutableTransaction tx;
|
||||
CTxMemPool pool(payTxFee);
|
||||
CTxOut txout1(value, (CScript)vector<unsigned char>(24, 0));
|
||||
tx.vout.push_back(txout1);
|
||||
|
||||
int64_t nMinTxFee = COIN;
|
||||
|
||||
BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 250, 0, pool), nMinTxFee);
|
||||
BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 1000, 0, pool), 2 * nMinTxFee);
|
||||
BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 1999, 0, pool), 2 * nMinTxFee);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetMinimumFee_dust_test)
|
||||
{
|
||||
// Derived from main net TX 3d6ec3ae2aca3ae0a6c65074fd8ee888cd7ed262f2cbaa25d33861989324a14e
|
||||
CMutableTransaction tx;
|
||||
CTxMemPool pool(payTxFee);
|
||||
CTxOut txout1(139496846, (CScript)vector<unsigned char>(24, 0)); // Regular output
|
||||
CTxOut txout2(15499649, (CScript)vector<unsigned char>(24, 0)); // Dust output
|
||||
tx.vout.push_back(txout1);
|
||||
tx.vout.push_back(txout2);
|
||||
|
||||
int64_t nMinTxFee = COIN;
|
||||
|
||||
// Confirm dust penalty fees are added on
|
||||
|
||||
BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 963, 0, pool), 2 * nMinTxFee);
|
||||
BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 1000, 0, pool), 3 * nMinTxFee);
|
||||
BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 1999, 0, pool), 3 * nMinTxFee);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "coincontrol.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "dogecoin.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "script/script.h"
|
||||
|
@ -40,7 +41,7 @@ bool fPayAtLeastCustomFee = true;
|
|||
* Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
|
||||
* Override with -mintxfee
|
||||
*/
|
||||
CFeeRate CWallet::minTxFee = CFeeRate(1000);
|
||||
CFeeRate CWallet::minTxFee = CFeeRate(COIN);
|
||||
|
||||
/** @defgroup mapWallet
|
||||
*
|
||||
|
@ -1935,7 +1936,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend,
|
|||
break;
|
||||
}
|
||||
|
||||
CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
||||
CAmount nFeeNeeded = GetMinimumFee(txNew, nBytes, nTxConfirmTarget, mempool);
|
||||
|
||||
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
|
||||
// because we must be at the maximum allowed fee.
|
||||
|
@ -2010,8 +2011,12 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
|
|||
return true;
|
||||
}
|
||||
|
||||
CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
|
||||
CAmount CWallet::GetMinimumFee(const CMutableTransaction& tx, unsigned int nTxBytes,
|
||||
unsigned int nConfirmTarget, const CTxMemPool& pool)
|
||||
{
|
||||
// Dogecoin: Round TX bytes up to the next 1,000 bytes
|
||||
nTxBytes += 1000 - (nTxBytes % 1000);
|
||||
|
||||
// payTxFee is user-set "I want to pay this much"
|
||||
CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
|
||||
// user selected total at least (default=true)
|
||||
|
@ -2022,8 +2027,11 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge
|
|||
nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
|
||||
// ... unless we don't have enough mempool data, in which case fall
|
||||
// back to a hard-coded fee
|
||||
if (nFeeNeeded == 0)
|
||||
if (nFeeNeeded == 0) {
|
||||
nFeeNeeded = minTxFee.GetFee(nTxBytes);
|
||||
// Dogecoin: Add an increased fee for each dust output
|
||||
nFeeNeeded += GetDogecoinDustFee(tx.vout, minTxFee);
|
||||
}
|
||||
// prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
|
||||
if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
|
||||
nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
|
||||
|
@ -2034,8 +2042,6 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
||||
{
|
||||
if (!fFileBacked)
|
||||
|
|
|
@ -42,9 +42,9 @@ extern bool fPayAtLeastCustomFee;
|
|||
//! -paytxfee default
|
||||
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
|
||||
//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB
|
||||
static const CAmount nHighTransactionFeeWarning = 0.01 * COIN;
|
||||
static const CAmount nHighTransactionFeeWarning = 10 * COIN;
|
||||
//! -maxtxfee default
|
||||
static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN;
|
||||
static const CAmount DEFAULT_TRANSACTION_MAXFEE = 100 * COIN;
|
||||
//! -txconfirmtarget default
|
||||
static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2;
|
||||
//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)
|
||||
|
@ -573,7 +573,7 @@ public:
|
|||
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
|
||||
|
||||
static CFeeRate minTxFee;
|
||||
static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool);
|
||||
static CAmount GetMinimumFee(const CMutableTransaction& tx, unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool);
|
||||
|
||||
bool NewKeyPool();
|
||||
bool TopUpKeyPool(unsigned int kpSize = 0);
|
||||
|
|
Loading…
Reference in a new issue