Add current PoW reward and stake interest into getmininginfo result
[novacoin.git] / src / main.cpp
index b7b20bc..fbc785a 100644 (file)
@@ -37,6 +37,7 @@ CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); // "standard" scrypt target limit
 CBigNum bnProofOfStakeLegacyLimit(~uint256(0) >> 24); // proof of stake target limit from block #15000 and until 20 June 2013, results with 0,00390625 proof of stake difficulty
 CBigNum bnProofOfStakeLimit(~uint256(0) >> 27); // proof of stake target limit since 20 June 2013, equal to 0.03125  proof of stake difficulty
 CBigNum bnProofOfStakeHardLimit(~uint256(0) >> 30); // disabled temporarily, will be used in the future to fix minimal proof of stake difficulty at 0.25
+CBigNum bnPoWBase = CBigNum(uint256("0x00000000ffff0000000000000000000000000000000000000000000000000000")); // difficulty-1 target
 
 CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16);
 
@@ -476,8 +477,10 @@ bool CTransaction::CheckTransaction() const
         if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake())
             return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction"));
 
-        // ppcoin: enforce minimum output amount
-        if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT)
+        // NovaCoin: enforce minimum output amount for user transactions
+        // (and for all transactions until 20 Sep 2013)
+        if ((!IsCoinBase() || nTime < CHAINCHECKS_SWITCH_TIME)
+                && (!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT)
             return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum"));
 
         if (txout.nValue > MAX_MONEY)
@@ -499,7 +502,7 @@ bool CTransaction::CheckTransaction() const
     if (IsCoinBase())
     {
         if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
-            return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size"));
+            return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size is invalid"));
     }
     else
     {
@@ -982,6 +985,7 @@ int64 GetProofOfWorkReward(unsigned int nBits)
     }
 
     int64 nSubsidy = bnUpperBound.getuint64();
+
     nSubsidy = (nSubsidy / CENT) * CENT;
     if (fDebug && GetBoolArg("-printcreation"))
         printf("GetProofOfWorkReward() : create=%s nBits=0x%08x nSubsidy=%"PRI64d"\n", FormatMoney(nSubsidy).c_str(), nBits, nSubsidy);
@@ -990,7 +994,7 @@ int64 GetProofOfWorkReward(unsigned int nBits)
 }
 
 // miner's coin stake reward based on nBits and coin age spent (coin-days)
-int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime)
+int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, bool bCoinYearOnly)
 {
     int64 nRewardCoinYear;
 
@@ -1034,7 +1038,11 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi
         nRewardCoinYear = 5 * CENT;
     }
 
+    if(bCoinYearOnly)
+        return nRewardCoinYear;
+
     int64 nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear;
+
     if (fDebug && GetBoolArg("-printcreation"))
         printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits);
     return nSubsidy;
@@ -2111,11 +2119,14 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const
     }
     else
     {
+        // Coinbase fee paid until 20 Sep 2013
+        int64 nFee = GetBlockTime() < CHAINCHECKS_SWITCH_TIME ? vtx[0].GetMinFee() - MIN_TX_FEE : 0;
+
         // Check coinbase reward
-        if (vtx[0].GetValueOut() > (GetProofOfWorkReward(nBits) - vtx[0].GetMinFee() + MIN_TX_FEE))
+        if (vtx[0].GetValueOut() > (GetProofOfWorkReward(nBits) - nFee))
             return DoS(50, error("CheckBlock() : coinbase reward exceeded %s > %s", 
                    FormatMoney(vtx[0].GetValueOut()).c_str(),
-                   FormatMoney(IsProofOfWork()? GetProofOfWorkReward(nBits) : 0).c_str()));
+                   FormatMoney(GetProofOfWorkReward(nBits) - nFee).c_str()));
     }
 
     // Check transactions
@@ -2243,30 +2254,32 @@ bool CBlock::AcceptBlock()
 CBigNum CBlockIndex::GetBlockTrust() const
 {
     CBigNum bnTarget;
+    bnTarget.SetCompact(nBits);
 
-    // Old protocol
-    if (!fTestNet && GetBlockTime() < CHAINCHECKS_SWITCH_TIME)
-    {
-        CBigNum bnTarget;
-        bnTarget.SetCompact(nBits);
+    if (bnTarget <= 0)
+        return 0;
 
-        if (bnTarget <= 0)
-            return 0;
+    /* Old protocol, will be removed later */
+    if (!fTestNet && GetBlockTime() < CHAINCHECKS_SWITCH_TIME)
         return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1);
-    }
 
-    // New protocol
-    if (pprev == NULL || pprev->nHeight < 10)
-        return 1;
+    /* New protocol */
+
+    // Calculate work amount for block
+    CBigNum bnPoWTrust = bnPoWBase / (bnTarget+1);
+
+    // Set bnPowTrust to 1 if we are checking PoS block or PoW difficulty is too low
+    bnPoWTrust = (IsProofOfStake() || bnPoWTrust < 1) ? 1 : bnPoWTrust;
+
+    // Return bnPoWTrust for the first 12 blocks
+    if (pprev == NULL || pprev->nHeight < 12)
+        return bnPoWTrust;
 
     const CBlockIndex* currentIndex = pprev;
 
     if(IsProofOfStake())
     {
-        bnTarget.SetCompact(nBits);
-        if (bnTarget <= 0)
-            return 0;
-
+        // Return 1/3 of score if parent block is not the PoW block
         if (!pprev->IsProofOfWork())
             return (CBigNum(1)<<256) / (3 * (bnTarget+1));
 
@@ -2288,8 +2301,9 @@ CBigNum CBlockIndex::GetBlockTrust() const
     }
     else
     {
+        // Return bnPoWTrust + 2/3 of previous block score if two parent blocks are not PoS blocks
         if (!(pprev->IsProofOfStake() && pprev->pprev->IsProofOfStake()))
-            return 1 + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
+            return bnPoWTrust + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
 
         int nPoSCount = 0;
 
@@ -2301,11 +2315,17 @@ CBigNum CBlockIndex::GetBlockTrust() const
             currentIndex = currentIndex->pprev;
         }
 
-        // Return 2/3 of previous block score if less than 7 PoS blocks found
+        // Return bnPoWTrust + 2/3 of previous block score if less than 7 PoS blocks found
         if (nPoSCount < 7)
-            return 1 + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
+            return bnPoWTrust + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3);
 
-        return (pprev->bnChainTrust - pprev->pprev->bnChainTrust);
+        bnTarget.SetCompact(pprev->nBits);
+
+        if (bnTarget <= 0)
+            return 0;
+
+        // Return bnPoWTrust + full trust score for previous block nBits
+        return bnPoWTrust + (CBigNum(1)<<256) / (bnTarget+1);
     }
 }
 
@@ -3426,6 +3446,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
         CInv inv(MSG_TX, tx.GetHash());
         pfrom->AddInventoryKnown(inv);
 
+        // Truncate messages to the size of the tx in them
+        unsigned int nSize = ::GetSerializeSize(tx,SER_NETWORK, PROTOCOL_VERSION);
+        if (nSize < vMsg.size()){
+            vMsg.resize(nSize);
+        }
+
         bool fMissingInputs = false;
         if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs))
         {
@@ -4417,12 +4443,6 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
     return true;
 }
 
-void static ThreadBitcoinMiner(void* parg);
-
-static bool fGenerateBitcoins = false;
-static bool fLimitProcessors = false;
-static int nLimitProcessors = -1;
-
 void BitcoinMiner(CWallet *pwallet, bool fProofOfStake)
 {
     SetThreadPriority(THREAD_PRIORITY_LOWEST);
@@ -4486,52 +4506,3 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake)
     }
 }
 
-void static ThreadBitcoinMiner(void* parg)
-{
-    CWallet* pwallet = (CWallet*)parg;
-    try
-    {
-        vnThreadsRunning[THREAD_MINER]++;
-        BitcoinMiner(pwallet, false);
-        vnThreadsRunning[THREAD_MINER]--;
-    }
-    catch (std::exception& e) {
-        vnThreadsRunning[THREAD_MINER]--;
-        PrintException(&e, "ThreadBitcoinMiner()");
-    } catch (...) {
-        vnThreadsRunning[THREAD_MINER]--;
-        PrintException(NULL, "ThreadBitcoinMiner()");
-    }
-    nHPSTimerStart = 0;
-    if (vnThreadsRunning[THREAD_MINER] == 0)
-        dHashesPerSec = 0;
-    printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINER]);
-}
-
-
-void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
-{
-    fGenerateBitcoins = fGenerate;
-    nLimitProcessors = GetArg("-genproclimit", -1);
-    if (nLimitProcessors == 0)
-        fGenerateBitcoins = false;
-    fLimitProcessors = (nLimitProcessors != -1);
-
-    if (fGenerate)
-    {
-        int nProcessors = boost::thread::hardware_concurrency();
-        printf("%d processors\n", nProcessors);
-        if (nProcessors < 1)
-            nProcessors = 1;
-        if (fLimitProcessors && nProcessors > nLimitProcessors)
-            nProcessors = nLimitProcessors;
-        int nAddThreads = nProcessors - vnThreadsRunning[THREAD_MINER];
-        printf("Starting %d BitcoinMiner threads\n", nAddThreads);
-        for (int i = 0; i < nAddThreads; i++)
-        {
-            if (!NewThread(ThreadBitcoinMiner, pwallet))
-                printf("Error: NewThread(ThreadBitcoinMiner) failed\n");
-            Sleep(10);
-        }
-    }
-}