PPCoin: Version number and rename checkpoint related constants
[novacoin.git] / src / main.cpp
index 3598c4a..aaf3f36 100644 (file)
@@ -30,7 +30,7 @@ map<COutPoint, CInPoint> mapNextTx;
 
 map<uint256, CBlockIndex*> mapBlockIndex;
 set<pair<COutPoint, unsigned int> > setStakeSeen;
-uint256 hashGenesisBlock("0x000000007c82d1f0aa2896b01bf533a8cc26a1f44790be4ceb4ecde7bee24add");
+uint256 hashGenesisBlock = hashGenesisBlockOfficial;
 static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
 const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download"
 CBlockIndex* pindexGenesisBlock = NULL;
@@ -1338,8 +1338,8 @@ bool CTransaction::CheckProofOfStake(unsigned int nBits) const
     CBlock block;
     if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
         return false; // unable to read block of previous transaction
-    if (block.GetBlockTime() + AUTO_CHECKPOINT_TRUST_SPAN > nTime)
-        return false; // only count coins from at least one week ago
+    if (block.GetBlockTime() + STAKE_MIN_AGE > nTime)
+        return false; // only count coins meeting min age requirement
 
     int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
     CBigNum bnCoinDay = CBigNum(nValueIn) * (nTime-txPrev.nTime) / COIN / (24 * 60 * 60);
@@ -1353,10 +1353,10 @@ bool CTransaction::CheckProofOfStake(unsigned int nBits) const
 }
 
 // ppcoin: total coin age spent in transaction, in the unit of coin-days.
-// Only those coins last spent at least a week ago count. As those
+// Only those coins meeting minimum age requirement counts. As those
 // transactions not in main chain are not currently indexed so we
 // might not find out about their coin age. Older transactions are 
-// guaranteed to be in main chain by auto checkpoint. This rule is
+// guaranteed to be in main chain by sync-checkpoint. This rule is
 // introduced to help nodes establish a consistent view of the coin
 // age (trust score) of competing branches.
 bool CTransaction::GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const
@@ -1381,8 +1381,8 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const
         CBlock block;
         if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
             return false; // unable to read block of previous transaction
-        if (block.GetBlockTime() + AUTO_CHECKPOINT_TRUST_SPAN > nTime)
-            continue; // only count coins from at least one week ago
+        if (block.GetBlockTime() + STAKE_MIN_AGE > nTime)
+            continue; // only count coins meeting min age requirement
 
         int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
         bnCentSecond += CBigNum(nValueIn) * (nTime-txPrev.nTime) / CENT;
@@ -1642,6 +1642,9 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
         }
     }
 
+    // ppcoin: ask for pending sync-checkpoint if any
+    if (!IsInitialBlockDownload())
+        Checkpoints::AskForPendingSyncCheckpoint(pfrom);
 
     // If don't already have its previous block, shunt it off to holding area until we get it
     if (!mapBlockIndex.count(pblock->hashPrevBlock))
@@ -1770,7 +1773,7 @@ bool LoadBlockIndex(bool fAllowNew)
 {
     if (fTestNet)
     {
-        hashGenesisBlock = uint256("0x00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008");
+        hashGenesisBlock = hashGenesisBlockTestNet;
         bnProofOfWorkLimit = CBigNum(~uint256(0) >> 28);
         pchMessageStart[0] = 0xfa;
         pchMessageStart[1] = 0xbf;
@@ -1843,11 +1846,26 @@ bool LoadBlockIndex(bool fAllowNew)
             return error("LoadBlockIndex() : genesis block not accepted");
 
         // ppcoin: initialize synchronized checkpoint
-        CTxDB txdbc;
-        if (!txdbc.WriteSyncCheckpoint(hashGenesisBlock))
+        if (!Checkpoints::WriteSyncCheckpoint(hashGenesisBlock))
             return error("LoadBlockIndex() : failed to init sync checkpoint");
-        txdbc.Close();
-        Checkpoints::hashSyncCheckpoint = hashGenesisBlock;
+    }
+
+    // ppcoin: if checkpoint master key changed must reset sync-checkpoint
+    {
+        CTxDB txdb;
+        string strPubKey = "";
+        if (!txdb.ReadCheckpointPubKey(strPubKey) || strPubKey != CSyncCheckpoint::strMasterPubKey)
+        {
+            // write checkpoint master key to db
+            txdb.TxnBegin();
+            if (!txdb.WriteCheckpointPubKey(CSyncCheckpoint::strMasterPubKey))
+                return error("LoadBlockIndex() : failed to write new checkpoint master key to db");
+            if (!txdb.TxnCommit())
+                return error("LoadBlockIndex() : failed to commit new checkpoint master key to db");
+            if (!Checkpoints::ResetSyncCheckpoint())
+                return error("LoadBlockIndex() : failed to reset sync-checkpoint");
+        }
+        txdb.Close();
     }
 
     return true;
@@ -2189,6 +2207,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
         printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
 
         cPeerBlockCounts.input(pfrom->nStartingHeight);
+
+        // ppcoin: ask for pending sync-checkpoint if any
+        if (!IsInitialBlockDownload())
+            Checkpoints::AskForPendingSyncCheckpoint(pfrom);
     }
 
 
@@ -3037,7 +3059,7 @@ public:
 };
 
 
-CBlock* CreateNewBlock(CWallet* pwallet)
+CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfWorkOnly)
 {
     CReserveKey reservekey(pwallet);
 
@@ -3059,24 +3081,28 @@ CBlock* CreateNewBlock(CWallet* pwallet)
     // ppcoin: if coinstake available add coinstake tx
     static unsigned int nLastCoinStakeCheckTime = GetAdjustedTime() - nMaxClockDrift + 60;  // only initialized at startup
     CBlockIndex* pindexPrev = pindexBest;
-    while (nLastCoinStakeCheckTime < GetAdjustedTime())
+
+    if (!fProofOfWorkOnly)
     {
-        pindexPrev = pindexBest;  // get best block again to avoid getting stale
-        pblock->nBits = GetNextTargetRequired(pindexPrev, true);
-        static CCriticalSection cs;
-        CTransaction txCoinStake;
-        CRITICAL_BLOCK(cs)
-        {
-            // mining may have been suspended for a while so 
-            // need to take max to satisfy the timestamp protocol
-            nLastCoinStakeCheckTime = max(++nLastCoinStakeCheckTime, (unsigned int) (GetAdjustedTime() - nMaxClockDrift + 60));
-            txCoinStake.nTime = nLastCoinStakeCheckTime;
-        }
-        if (pwallet->CreateCoinStake(pblock->nBits, txCoinStake))
+        while (nLastCoinStakeCheckTime < GetAdjustedTime())
         {
-            pblock->vtx.push_back(txCoinStake);
-            pblock->vtx[0].vout[0].SetEmpty();
-            break;
+            pindexPrev = pindexBest;  // get best block again to avoid getting stale
+            pblock->nBits = GetNextTargetRequired(pindexPrev, true);
+            static CCriticalSection cs;
+            CTransaction txCoinStake;
+            CRITICAL_BLOCK(cs)
+            {
+                // mining may have been suspended for a while so 
+                // need to take max to satisfy the timestamp protocol
+                nLastCoinStakeCheckTime = max(++nLastCoinStakeCheckTime, (unsigned int) (GetAdjustedTime() - nMaxClockDrift + 60));
+                txCoinStake.nTime = nLastCoinStakeCheckTime;
+            }
+            if (pwallet->CreateCoinStake(pblock->nBits, txCoinStake))
+            {
+                pblock->vtx.push_back(txCoinStake);
+                pblock->vtx[0].vout[0].SetEmpty();
+                break;
+            }
         }
     }
 
@@ -3355,8 +3381,11 @@ void static BitcoinMiner(CWallet *pwallet)
         // ppcoin: if proof-of-stake block found then process block
         if (pblock->IsProofOfStake())
         {
-            // should be able to sign block - assert here for now
-            assert(pblock->SignBlock(*pwalletMain));
+            if (!pblock->SignBlock(*pwalletMain))
+            {
+                error("BitcoinMiner: Unable to sign new proof-of-stake block");
+                return;
+            }
             printf("BitcoinMiner : proof-of-stake block found %s\n", pblock->GetHash().ToString().c_str()); 
             SetThreadPriority(THREAD_PRIORITY_NORMAL);
             CheckWork(pblock.get(), *pwalletMain, reservekey);
@@ -3407,8 +3436,11 @@ void static BitcoinMiner(CWallet *pwallet)
                     // Found a solution
                     pblock->nNonce = ByteReverse(nNonceFound);
                     assert(hash == pblock->GetHash());
-                    // should be able to sign block - assert here for now
-                    assert(pblock->SignBlock(*pwalletMain));
+                    if (!pblock->SignBlock(*pwalletMain))
+                    {
+                        error("BitcoinMiner: Unable to sign new proof-of-work block");
+                        return;
+                    }
 
                     SetThreadPriority(THREAD_PRIORITY_NORMAL);
                     CheckWork(pblock.get(), *pwalletMain, reservekey);