Use MoneyRange(txout.nValue) to get rid of excessive checking.
[novacoin.git] / src / main.cpp
index f2cc876..7cce81e 100644 (file)
@@ -116,13 +116,6 @@ bool static IsFromMe(CTransaction& tx)
     return false;
 }
 
-// erases transaction with the given hash from all wallets
-void static EraseFromWallets(uint256 hash)
-{
-    for(CWallet* pwallet :  setpwalletRegistered)
-        pwallet->EraseFromWallet(hash);
-}
-
 // make sure all wallets know about the given transaction, in the given block
 void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fConnect)
 {
@@ -366,7 +359,7 @@ bool CTransaction::AreInputsStandard(const MapPrevTx& mapInputs) const
     if (IsCoinBase())
         return true; // Coinbases don't use vin normally
 
-    for (unsigned int i = 0; i < vin.size(); i++)
+    for (uint32_t i = 0; i < vin.size(); i++)
     {
         const CTxOut& prev = GetOutputFor(vin[i], mapInputs);
 
@@ -505,11 +498,8 @@ bool CTransaction::CheckTransaction() const
         const CTxOut& txout = vout[i];
         if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake())
             return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction"));
-
-        if (txout.nValue < 0)
-            return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue is negative"));
-        if (txout.nValue > MAX_MONEY)
-            return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high"));
+        if (!MoneyRange(txout.nValue))
+            return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue is out of range"));
         nValueOut += txout.nValue;
         if (!MoneyRange(nValueOut))
             return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range"));
@@ -638,7 +628,6 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
             return false;
 
     // Check for conflicts with in-memory transactions
-    CTransaction* ptxOld = NULL;
     for (unsigned int i = 0; i < tx.vin.size(); i++)
     {
         auto outpoint = tx.vin[i].prevout;
@@ -717,19 +706,9 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
     // Store transaction in memory
     {
         LOCK(cs);
-        if (ptxOld)
-        {
-            printf("CTxMemPool::accept() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
-            remove(*ptxOld);
-        }
         addUnchecked(hash, tx);
     }
 
-    ///// are we sure this is ok when loading transactions or restoring block txes
-    // If updated, erase old tx from wallet
-    if (ptxOld)
-        EraseFromWallets(ptxOld->GetHash());
-
     printf("CTxMemPool::accept() : accepted %s (poolsz %" PRIszu ")\n",
            hash.ToString().substr(0,10).c_str(),
            mapTx.size());
@@ -3087,23 +3066,26 @@ string GetWarnings(string strFor)
 
 bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
 {
-    switch (inv.type)
+    int nType = inv.GetType();
+    auto nHash = inv.GetHash();
+
+    switch (nType)
     {
     case MSG_TX:
         {
         bool txInMap = false;
             {
             LOCK(mempool.cs);
-            txInMap = (mempool.exists(inv.hash));
+            txInMap = (mempool.exists(nHash));
             }
         return txInMap ||
-               mapOrphanTransactions.count(inv.hash) ||
-               txdb.ContainsTx(inv.hash);
+               mapOrphanTransactions.count(nHash) ||
+               txdb.ContainsTx(nHash);
         }
 
     case MSG_BLOCK:
-        return mapBlockIndex.count(inv.hash) ||
-               mapOrphanBlocks.count(inv.hash);
+        return mapBlockIndex.count(nHash) ||
+               mapOrphanBlocks.count(nHash);
     }
     // Don't know what it is, just say we already got one
     return true;
@@ -3344,10 +3326,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
         }
 
         // find last block in inv vector
-        size_t nLastBlock = std::numeric_limits<size_t>::max();
+        int nLastBlock = -1;
         for (size_t nInv = 0; nInv < vInv.size(); nInv++) {
-            if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) {
-                nLastBlock = vInv.size() - 1 - nInv;
+            if (vInv[vInv.size() - 1 - nInv].GetType() == MSG_BLOCK) {
+                nLastBlock = (int) (vInv.size() - 1 - nInv);
                 break;
             }
         }
@@ -3355,6 +3337,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
         for (size_t nInv = 0; nInv < vInv.size(); nInv++)
         {
             const CInv &inv = vInv[nInv];
+            int nType = inv.GetType();
+            auto nHash = inv.GetHash();
 
             if (fShutdown)
                 return true;
@@ -3366,19 +3350,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
 
             if (!fAlreadyHave)
                 pfrom->AskFor(inv);
-            else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
-                pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
-            } else if (nInv == nLastBlock) {
+            else if (nType == MSG_BLOCK && mapOrphanBlocks.count(nHash)) {
+                pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[nHash]));
+            } else if (nType == nLastBlock) {
                 // In case we are on a very long side-chain, it is possible that we already have
                 // the last block in an inv bundle sent in response to getblocks. Try to detect
                 // this situation and push another getblocks to continue.
-                pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0));
+                pfrom->PushGetBlocks(mapBlockIndex[nHash], uint256(0));
                 if (fDebug)
                     printf("force request: %s\n", inv.ToString().c_str());
             }
 
             // Track requests for our stuff
-            Inventory(inv.hash);
+            Inventory(nHash);
         }
     }
 
@@ -3403,10 +3387,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
             if (fDebugNet || (vInv.size() == 1))
                 printf("received getdata for: %s\n", inv.ToString().c_str());
 
-            if (inv.type == MSG_BLOCK)
+            int nType = inv.GetType();
+            auto nHash = inv.GetHash();
+
+            if (nType == MSG_BLOCK)
             {
                 // Send block from disk
-                auto mi = mapBlockIndex.find(inv.hash);
+                auto mi = mapBlockIndex.find(nHash);
                 if (mi != mapBlockIndex.end())
                 {
                     CBlock block;
@@ -3414,7 +3401,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
                     pfrom->PushMessage("block", block);
 
                     // Trigger them to send a getblocks request for the next batch of inventory
-                    if (inv.hash == pfrom->hashContinue)
+                    if (nHash == pfrom->hashContinue)
                     {
                         // ppcoin: send latest proof-of-work block to allow the
                         // download node to accept as orphan (proof-of-stake 
@@ -3438,10 +3425,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
                         pushed = true;
                     }
                 }
-                if (!pushed && inv.type == MSG_TX) {
+                if (!pushed && nType == MSG_TX) {
                     LOCK(mempool.cs);
-                    if (mempool.exists(inv.hash)) {
-                        CTransaction tx = mempool.lookup(inv.hash);
+                    if (mempool.exists(nHash)) {
+                        CTransaction tx = mempool.lookup(nHash);
                         CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                         ss.reserve(1000);
                         ss << tx;
@@ -3451,7 +3438,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
             }
 
             // Track requests for our stuff
-            Inventory(inv.hash);
+            Inventory(nHash);
         }
     }
 
@@ -3558,11 +3545,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
         bool fMissingInputs = false;
         if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs))
         {
+            auto nHash = inv.GetHash();
+
             SyncWithWallets(tx, NULL, true);
-            RelayTransaction(tx, inv.hash);
+            RelayTransaction(tx, nHash);
             mapAlreadyAskedFor.erase(inv);
-            vWorkQueue.push_back(inv.hash);
-            vEraseQueue.push_back(inv.hash);
+            vWorkQueue.push_back(nHash);
+            vEraseQueue.push_back(nHash);
 
             // Recursively process any orphan transactions that depended on this one
             for (unsigned int i = 0; i < vWorkQueue.size(); i++)
@@ -3973,13 +3962,13 @@ bool SendMessages(CNode* pto)
                     continue;
 
                 // trickle out tx inv to protect privacy
-                if (inv.type == MSG_TX && !fSendTrickle)
+                if (inv.GetType() == MSG_TX && !fSendTrickle)
                 {
                     // 1/4 of tx invs blast to all immediately
                     static uint256 hashSalt;
                     if (hashSalt == 0)
                         hashSalt = GetRandHash();
-                    uint256 hashRand = inv.hash ^ hashSalt;
+                    uint256 hashRand = inv.GetHash() ^ hashSalt;
                     hashRand = Hash(hashRand.begin(), hashRand.end());
                     bool fTrickleWait = ((hashRand & 3) != 0);