Type-safe CFeeRate class

Use CFeeRate instead of an int64_t for quantities that are
fee-per-size.

Helps prevent unit-conversion mismatches between the wallet,
relaying, and mining code.
This commit is contained in:
Gavin Andresen
2014-04-10 14:14:18 -04:00
parent 345cb52e8b
commit c6cb21d17a
16 changed files with 123 additions and 115 deletions

View File

@@ -50,9 +50,9 @@ bool fTxIndex = false;
unsigned int nCoinCacheSize = 5000;
/** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */
int64_t CTransaction::nMinTxFee = 10000; // Override with -mintxfee
CFeeRate CTransaction::minTxFee = CFeeRate(10000); // Override with -mintxfee
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
int64_t CTransaction::nMinRelayTxFee = 1000;
CFeeRate CTransaction::minRelayTxFee = CFeeRate(1000);
struct COrphanBlock {
uint256 hashBlock;
@@ -543,7 +543,7 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
}
if (whichType == TX_NULL_DATA)
nDataOut++;
else if (txout.IsDust(CTransaction::nMinRelayTxFee)) {
else if (txout.IsDust(CTransaction::minRelayTxFee)) {
reason = "dust";
return false;
}
@@ -783,10 +783,10 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode)
{
// Base fee is either nMinTxFee or nMinRelayTxFee
int64_t nBaseFee = (mode == GMF_RELAY) ? tx.nMinRelayTxFee : tx.nMinTxFee;
// Base fee is either minTxFee or minRelayTxFee
CFeeRate baseFeeRate = (mode == GMF_RELAY) ? tx.minRelayTxFee : tx.minTxFee;
int64_t nMinFee = (1 + (int64_t)nBytes / 1000) * nBaseFee;
int64_t nMinFee = baseFeeRate.GetFee(nBytes);
if (fAllowFree)
{
@@ -800,16 +800,6 @@ int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree,
nMinFee = 0;
}
// This code can be removed after enough miners have upgraded to version 0.9.
// Until then, be safe when sending and require a fee if any output
// is less than CENT:
if (nMinFee < nBaseFee && mode == GMF_SEND)
{
BOOST_FOREACH(const CTxOut& txout, tx.vout)
if (txout.nValue < CENT)
nMinFee = nBaseFee;
}
if (!MoneyRange(nMinFee))
nMinFee = MAX_MONEY;
return nMinFee;
@@ -916,10 +906,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
hash.ToString(), nFees, txMinFee),
REJECT_INSUFFICIENTFEE, "insufficient fee");
// Continuously rate-limit free transactions
// Continuously rate-limit free (really, very-low-fee)transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm.
if (fLimitFree && nFees < CTransaction::nMinRelayTxFee)
if (fLimitFree && nFees < CTransaction::minRelayTxFee.GetFee(nSize))
{
static CCriticalSection csFreeLimiter;
static double dFreeCount;
@@ -940,10 +930,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
dFreeCount += nSize;
}
if (fRejectInsaneFee && nFees > CTransaction::nMinRelayTxFee * 10000)
if (fRejectInsaneFee && nFees > CTransaction::minRelayTxFee.GetFee(nSize) * 10000)
return error("AcceptToMemoryPool: : insane fees %s, %d > %d",
hash.ToString(),
nFees, CTransaction::nMinRelayTxFee * 10000);
nFees, CTransaction::minRelayTxFee.GetFee(nSize) * 10000);
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.