Transactions fee handling
authorCryptoManiac <balthazar@yandex.ru>
Sun, 1 Jun 2014 17:37:42 +0000 (21:37 +0400)
committerCryptoManiac <balthazar@yandex.ru>
Sun, 1 Jun 2014 17:37:42 +0000 (21:37 +0400)
* Enable free user transactions since 1 July 2014;
* Force CENT as nMinTxFee and nMinRelayTxFee until 1 July 2014.

novacoin-qt.pro
src/main.cpp
src/main.h
src/qt/coincontroldialog.cpp
src/timestamps.h [new file with mode: 0644]
src/wallet.cpp

index 5871e22..4e93471 100644 (file)
@@ -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 \
index afb2f99..7cd033a 100644 (file)
@@ -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;
index ac0140d..f76374d 100644 (file)
@@ -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)
     {
index 5bc8fd3..0fd690c 100644 (file)
@@ -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 (file)
index 0000000..18dac1c
--- /dev/null
@@ -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
index 2502f8f..331069b 100644 (file)
@@ -1474,7 +1474,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& 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<pair<CScript, int64> >& 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