From: CryptoManiac Date: Sun, 1 Jun 2014 17:37:42 +0000 (+0400) Subject: Transactions fee handling X-Git-Tag: v0.4.4.7-nvc-bugfix5~1^2~16 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=d3de168c1c3c8ef0edf8c479bbbe520250687f70 Transactions fee handling * Enable free user transactions since 1 July 2014; * Force CENT as nMinTxFee and nMinRelayTxFee until 1 July 2014. --- diff --git a/novacoin-qt.pro b/novacoin-qt.pro index 5871e22..4e93471 100644 --- a/novacoin-qt.pro +++ b/novacoin-qt.pro @@ -162,6 +162,7 @@ HEADERS += src/qt/bitcoingui.h \ src/sync.h \ src/util.h \ src/hash.h \ + src/timestamps.h \ src/uint256.h \ src/kernel.h \ src/scrypt.h \ diff --git a/src/main.cpp b/src/main.cpp index afb2f99..7cd033a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -633,15 +633,23 @@ bool CTransaction::CheckTransaction() const } int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, - enum GetMinFee_mode mode, unsigned int nBytes) const + enum GetMinFee_mode mode, unsigned int nBytes, int64 nMinTxFee, int64 nMinRelayTxFee) const { - // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE - int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; + // Minimum fee in main network is 0.01 until 1 July 2014 + if(!fTestNet && nTime < FEE_SWITCH_TIME) + { + nMinTxFee = nMinRelayTxFee = CENT; + } + + // Base fee is either nMinTxFee or nMinRelayTxFee + int64 nBaseFee = (mode == GMF_RELAY) ? nMinRelayTxFee : nMinTxFee; unsigned int nNewBlockSize = nBlockSize + nBytes; int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; - if (fAllowFree && nTime > FEE_SWITCH_TIME) + // Free transactions on main network are + // not allowed until 1 July 2014 + if (fAllowFree && (nTime > FEE_SWITCH_TIME || fTestNet)) { if (nBlockSize == 1) { @@ -1550,11 +1558,13 @@ bool CTransaction::CheckInputs(CCoinsViewCache &inputs, enum CheckSig_mode csmod if (!GetCoinAge(nCoinAge)) return error("CheckInputs() : %s unable to get coin age for coinstake", GetHash().ToString().substr(0,10).c_str()); - int64 nStakeReward = GetValueOut() - nValueIn; - int64 nCalculatedStakeReward = GetProofOfStakeReward(nCoinAge, pblock->nBits, nTime) - GetMinFee() + MIN_TX_FEE; + unsigned int nTxSize = (nTime > STAKEFEE_SWITCH_TIME) ? GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) : 0; + + int64 nReward = GetValueOut() - nValueIn; + int64 nCalculatedReward = GetProofOfStakeReward(nCoinAge, pblock->nBits, nTime) - GetMinFee(1, false, GMF_BLOCK, nTxSize, CENT) + CENT; - if (nStakeReward > nCalculatedStakeReward) - return DoS(100, error("CheckInputs() : coinstake pays too much(actual=%"PRI64d" vs calculated=%"PRI64d")", nStakeReward, nCalculatedStakeReward)); + if (nReward > nCalculatedReward) + return DoS(100, error("CheckInputs() : coinstake pays too much(actual=%"PRI64d" vs calculated=%"PRI64d")", nReward, nCalculatedReward)); } else { @@ -1577,7 +1587,7 @@ bool CTransaction::CheckInputs(CCoinsViewCache &inputs, enum CheckSig_mode csmod // Skip ECDSA signature verification when connecting blocks // before the last blockchain checkpoint. This is safe because block merkle hashes are // still computed and checked, and any change will be caught at the next checkpoint. - if (csmode == CS_ALWAYS || + if (csmode == CS_ALWAYS || (csmode == CS_AFTER_CHECKPOINT && inputs.GetBestBlock()->nHeight >= Checkpoints::GetTotalBlocksEstimate())) { for (unsigned int i = 0; i < vin.size(); i++) { const COutPoint &prevout = vin[i].prevout; diff --git a/src/main.h b/src/main.h index ac0140d..f76374d 100644 --- a/src/main.h +++ b/src/main.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_MAIN_H #define BITCOIN_MAIN_H +#include "timestamps.h" #include "bignum.h" #include "sync.h" #include "net.h" @@ -38,20 +39,13 @@ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF; -static const int64 MIN_TX_FEE = CENT; -static const int64 MIN_RELAY_TX_FEE = CENT; +static const int64 MIN_TX_FEE = CENT / 20; +static const int64 MIN_RELAY_TX_FEE = CENT / 50; + static const int64 MAX_MONEY = 2000000000 * COIN; static const int64 MAX_MINT_PROOF_OF_WORK = 100 * COIN; static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * COIN; -static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; - -static const unsigned int ENTROPY_SWITCH_TIME = 1362791041; // Sat, 09 Mar 2013 01:04:01 GMT -static const unsigned int STAKE_SWITCH_TIME = 1371686400; // Thu, 20 Jun 2013 00:00:00 GMT -static const unsigned int TARGETS_SWITCH_TIME = 1374278400; // Sat, 20 Jul 2013 00:00:00 GMT -static const unsigned int CHAINCHECKS_SWITCH_TIME = 1379635200; // Fri, 20 Sep 2013 00:00:00 GMT -static const unsigned int STAKECURVE_SWITCH_TIME = 1382227200; // Sun, 20 Oct 2013 00:00:00 GMT -static const unsigned int FEE_SWITCH_TIME = 1404172800; // Thu, 01 Jun 2014 00:00:00 GMT - +static const int64 MIN_TXOUT_AMOUNT = CENT / 100; inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. @@ -585,7 +579,7 @@ public: return dPriority > COIN * 144 / 250; } - int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, enum GetMinFee_mode mode=GMF_BLOCK, unsigned int nBytes = 0) const; + int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, enum GetMinFee_mode mode=GMF_BLOCK, unsigned int nBytes = 0, int64 nMinTxFee = MIN_TX_FEE, int64 nMinRelayTxFee = MIN_RELAY_TX_FEE) const; friend bool operator==(const CTransaction& a, const CTransaction& b) { diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 5bc8fd3..0fd690c 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -489,6 +489,13 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Min Fee bool fAllowFree = CTransaction::AllowFree(dPriority); + + // Disable free transactions until 1 July 2014 + if (!fTestNet && txDummy.nTime < FEE_SWITCH_TIME) + { + fAllowFree = false; + } + int64 nMinFee = txDummy.GetMinFee(1, fAllowFree, GMF_SEND, nBytes); nPayFee = max(nFee, nMinFee); diff --git a/src/timestamps.h b/src/timestamps.h new file mode 100644 index 0000000..18dac1c --- /dev/null +++ b/src/timestamps.h @@ -0,0 +1,12 @@ +#ifndef BITCOIN_TIMESTAMPS_H +#define BITCOIN_TIMESTAMPS_H + +static const unsigned int ENTROPY_SWITCH_TIME = 1362791041; // Sat, 09 Mar 2013 01:04:01 GMT +static const unsigned int STAKE_SWITCH_TIME = 1371686400; // Thu, 20 Jun 2013 00:00:00 GMT +static const unsigned int TARGETS_SWITCH_TIME = 1374278400; // Sat, 20 Jul 2013 00:00:00 GMT +static const unsigned int CHAINCHECKS_SWITCH_TIME = 1379635200; // Fri, 20 Sep 2013 00:00:00 GMT +static const unsigned int STAKECURVE_SWITCH_TIME = 1382227200; // Sun, 20 Oct 2013 00:00:00 GMT +static const unsigned int FEE_SWITCH_TIME = 1404172800; // Tue, 01 Jul 2014 00:00:00 GMT +static const unsigned int STAKEFEE_SWITCH_TIME = 1406851200; // Fri, 01 Aug 2014 00:00:00 GMT + +#endif diff --git a/src/wallet.cpp b/src/wallet.cpp index 2502f8f..331069b 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1474,7 +1474,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW } // sub-cent change is moved to fee - if (nChange > 0 && nChange < MIN_TXOUT_AMOUNT) + if (nChange > 0 && nChange < CENT) { nFeeRet += nChange; nChange = 0; @@ -1535,6 +1535,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000); bool fAllowFree = CTransaction::AllowFree(dPriority); + // Disable free transactions until 1 July 2014 if (!fTestNet && wtxNew.nTime < FEE_SWITCH_TIME) { fAllowFree = false; @@ -1851,9 +1852,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int return error("CreateCoinStake : exceeded coinstake size limit"); // Check enough fee is paid - if (nMinFee < txNew.GetMinFee() - MIN_TX_FEE) + if (nMinFee < txNew.GetMinFee(1, false, GMF_BLOCK, nBytes, CENT) - CENT) { - nMinFee = txNew.GetMinFee() - MIN_TX_FEE; + nMinFee = txNew.GetMinFee(1, false, GMF_BLOCK, nBytes, CENT) - CENT; continue; // try signing again } else