Un-hardcode TX_FEE constants

Allow setting of MIN_TX_FEE / MIN_RELAY_TX_FEE with
-mintxfee / -mintxrelayfee

Default values are the same (0.0001 BTC).
This commit is contained in:
Gavin Andresen 2013-04-25 20:11:27 -04:00
parent 1f00f4e9c9
commit 000dc55181
5 changed files with 53 additions and 40 deletions

View File

@ -583,6 +583,28 @@ bool AppInit2(boost::thread_group& threadGroup)
const char* pszP2SH = "/P2SH/"; const char* pszP2SH = "/P2SH/";
COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH)); COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
// Fee-per-kilobyte amount considered the same as "free"
// If you are mining, be careful setting this:
// if you set it to zero then
// a transaction spammer can cheaply fill blocks using
// 1-satoshi-fee transactions. It should be set above the real
// cost to you of processing a transaction.
if (mapArgs.count("-mintxfee"))
{
int64 n = 0;
if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
CTransaction::nMinTxFee = n;
else
return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"].c_str()));
}
if (mapArgs.count("-minrelaytxfee"))
{
int64 n = 0;
if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0)
CTransaction::nMinRelayTxFee = n;
else
return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"].c_str()));
}
if (mapArgs.count("-paytxfee")) if (mapArgs.count("-paytxfee"))
{ {

View File

@ -48,6 +48,11 @@ bool fBenchmark = false;
bool fTxIndex = false; bool fTxIndex = false;
unsigned int nCoinCacheSize = 5000; unsigned int nCoinCacheSize = 5000;
/** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */
int64 CTransaction::nMinTxFee = 10000; // Override with -mintxfee
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying) */
int64 CTransaction::nMinRelayTxFee = 10000;
CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes claim to have CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes claim to have
map<uint256, CBlock*> mapOrphanBlocks; map<uint256, CBlock*> mapOrphanBlocks;
@ -352,9 +357,22 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// CTransaction // CTransaction / CTxOut
// //
bool CTxOut::IsDust() const
{
// "Dust" is defined in terms of CTransaction::nMinRelayTxFee,
// which has units satoshis-per-kilobyte.
// If you'd pay more than 1/3 in fees
// to spend something, then we consider it dust.
// A typical txout is 33 bytes big, and will
// need a CTxIn of at least 148 bytes to spend,
// so dust is a txout less than 54 uBTC
// (5430 satoshis) with default nMinRelayTxFee
return ((nValue*1000)/(3*((int)GetSerializeSize(SER_DISK,0)+148)) < CTransaction::nMinRelayTxFee);
}
bool CTransaction::IsStandard() const bool CTransaction::IsStandard() const
{ {
if (nVersion > CTransaction::CURRENT_VERSION) if (nVersion > CTransaction::CURRENT_VERSION)
@ -574,8 +592,8 @@ bool CTransaction::CheckTransaction(CValidationState &state) const
int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree,
enum GetMinFee_mode mode) const enum GetMinFee_mode mode) const
{ {
// Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE // Base fee is either nMinTxFee or nMinRelayTxFee
int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; int64 nBaseFee = (mode == GMF_RELAY) ? nMinRelayTxFee : nMinTxFee;
unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
unsigned int nNewBlockSize = nBlockSize + nBytes; unsigned int nNewBlockSize = nBlockSize + nBytes;
@ -598,7 +616,7 @@ int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree,
} }
} }
// To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01 // To limit dust spam, require base fee if any output is less than 0.01
if (nMinFee < nBaseFee) if (nMinFee < nBaseFee)
{ {
BOOST_FOREACH(const CTxOut& txout, vout) BOOST_FOREACH(const CTxOut& txout, vout)
@ -746,7 +764,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
// Continuously rate-limit free transactions // Continuously rate-limit free transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm. // be annoying or make others' transactions take longer to confirm.
if (fLimitFree && nFees < MIN_RELAY_TX_FEE) if (fLimitFree && nFees < CTransaction::nMinRelayTxFee)
{ {
static double dFreeCount; static double dFreeCount;
static int64 nLastTime; static int64 nLastTime;
@ -4184,15 +4202,6 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
unsigned int nBlockMinSize = GetArg("-blockminsize", 0); unsigned int nBlockMinSize = GetArg("-blockminsize", 0);
nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
// Fee-per-kilobyte amount considered the same as "free"
// Be careful setting this: if you set it to zero then
// a transaction spammer can cheaply fill blocks using
// 1-satoshi-fee transactions. It should be set above the real
// cost to you of processing a transaction.
int64 nMinTxFee = MIN_TX_FEE;
if (mapArgs.count("-mintxfee"))
ParseMoney(mapArgs["-mintxfee"], nMinTxFee);
// Collect memory pool transactions into the block // Collect memory pool transactions into the block
int64 nFees = 0; int64 nFees = 0;
{ {
@ -4310,7 +4319,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
continue; continue;
// Skip free transactions if we're past the minimum block size: // Skip free transactions if we're past the minimum block size:
if (fSortedByFee && (dFeePerKb < nMinTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) if (fSortedByFee && (dFeePerKb < CTransaction::nMinTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
continue; continue;
// Prioritize by fee once past the priority size or we run out of high-priority // Prioritize by fee once past the priority size or we run out of high-priority

View File

@ -44,10 +44,6 @@ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
/** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */ /** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */
static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF; static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF;
/** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */
static const int64 MIN_TX_FEE = 10000;
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying) */
static const int64 MIN_RELAY_TX_FEE = 10000;
/** No amount larger than this (in satoshi) is valid */ /** No amount larger than this (in satoshi) is valid */
static const int64 MAX_MONEY = 21000000 * COIN; static const int64 MAX_MONEY = 21000000 * COIN;
inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
@ -439,23 +435,7 @@ public:
return !(a == b); return !(a == b);
} }
size_t size() const bool IsDust() const;
{
return sizeof(nValue)+scriptPubKey.size();
}
bool IsDust() const
{
// "Dust" is defined in terms of MIN_RELAY_TX_FEE, which
// has units satoshis-per-kilobyte.
// If you'd pay more than 1/3 in fees
// to spend something, then we consider it dust.
// A typical txout is 32 bytes big, and will
// need a CTxIn of at least 148 bytes to spend,
// so dust is a txout less than 54 uBTC
// (5400 satoshis)
return ((nValue*1000)/(3*(size()+148)) < MIN_RELAY_TX_FEE);
}
std::string ToString() const std::string ToString() const
{ {
@ -485,6 +465,8 @@ enum GetMinFee_mode
class CTransaction class CTransaction
{ {
public: public:
static int64 nMinTxFee;
static int64 nMinRelayTxFee;
static const int CURRENT_VERSION=1; static const int CURRENT_VERSION=1;
int nVersion; int nVersion;
std::vector<CTxIn> vin; std::vector<CTxIn> vin;

View File

@ -69,7 +69,7 @@ static bool ThreadSafeAskFee(int64 nFeeRequired)
{ {
if(!guiref) if(!guiref)
return false; return false;
if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon) if(nFeeRequired < CTransaction::nMinTxFee || nFeeRequired <= nTransactionFee || fDaemon)
return true; return true;
bool payFee = false; bool payFee = false;

View File

@ -1197,12 +1197,12 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend,
} }
int64 nChange = nValueIn - nValue - nFeeRet; int64 nChange = nValueIn - nValue - nFeeRet;
// if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE // if sub-cent change is required, the fee must be raised to at least nMinTxFee
// or until nChange becomes zero // or until nChange becomes zero
// NOTE: this depends on the exact behaviour of GetMinFee // NOTE: this depends on the exact behaviour of GetMinFee
if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT) if (nFeeRet < CTransaction::nMinTxFee && nChange > 0 && nChange < CENT)
{ {
int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet); int64 nMoveToFee = min(nChange, CTransaction::nMinTxFee - nFeeRet);
nChange -= nMoveToFee; nChange -= nMoveToFee;
nFeeRet += nMoveToFee; nFeeRet += nMoveToFee;
} }