Undo file creation
authoralexhz <balthazar@yandex.ru>
Wed, 15 Jan 2014 19:18:38 +0000 (19:18 +0000)
committeralexhz <balthazar@yandex.ru>
Wed, 15 Jan 2014 19:18:38 +0000 (19:18 +0000)
Create files with block undo information for the transactions in it.

src/main.cpp
src/main.h

index 55a09d7..ca9eb8e 100644 (file)
@@ -1618,6 +1618,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
     else
         nTxPos = ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - (2 * GetSizeOfCompactSize(0)) + GetSizeOfCompactSize(vtx.size());
 
+    CBlockUndo blockundo;
+
     map<uint256, CTxIndex> mapQueuedChanges;
     int64 nFees = 0;
     int64 nValueIn = 0;
@@ -1649,6 +1651,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
             nValueOut += tx.GetValueOut();
         else
         {
+            CTxUndo undo;
+
             bool fInvalid;
             if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid))
                 return false;
@@ -1670,8 +1674,15 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
             if (!tx.IsCoinStake())
                 nFees += nTxValueIn - nTxValueOut;
 
+
+            BOOST_FOREACH(const CTxIn &in, tx.vin) {
+                undo.vprevout.push_back(CTxInUndo(mapInputs[in.prevout.hash].second.vout[in.prevout.n], pindex->nHeight));
+            }
+
             if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fStrictPayToScriptHash))
                 return false;
+
+            blockundo.vtxundo.push_back(undo);
         }
 
         mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size());
@@ -1708,6 +1719,13 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
             return error("ConnectBlock() : WriteBlockIndex failed");
     }
 
+    // Write undo information to disk
+    if (pindex->nHeight > Checkpoints::GetTotalBlocksEstimate())
+    {
+        CAutoFile fileUndo(fopen(pindex->GetBlockPos().GetUndoFile(GetDataDir()).string().c_str(), "wb"), SER_DISK, CLIENT_VERSION);
+        fileUndo << blockundo;
+    }
+
     // Watch for transactions paying to me
     BOOST_FOREACH(CTransaction& tx, vtx)
         SyncWithWallets(tx, this, true);
index beeba3d..98fd427 100644 (file)
@@ -168,6 +168,10 @@ public:
         return GetDirectory(base) / strprintf("%08u%s.blk", nHeight, GetAlternative().c_str());
     }
 
+    boost::filesystem::path GetUndoFile(const boost::filesystem::path &base) const {
+        return GetDirectory(base) / strprintf("%08u%s.und", nHeight, GetAlternative().c_str());
+    }
+
     // TODO: make thread-safe (lockfile, atomic file creation, ...?)
     void MakeUnique(const boost::filesystem::path &base) {
         while (boost::filesystem::exists(GetFileName(base)))
@@ -868,6 +872,16 @@ public:
     )
 };
 
+/** Undo information for a CBlock */
+class CBlockUndo
+{
+public:
+    std::vector<CTxUndo> vtxundo;
+
+    IMPLEMENT_SERIALIZE(
+        READWRITE(vtxundo);
+    )
+};
 
 /** pruned version of CTransaction: only retains metadata and unspent transaction outputs
  *