changeset 3646:4314bbfbfee5 draft

Preliminary undo file creation Create files (one per block) with undo information for the transactions in it.
author Pieter Wuille <pieter.wuille@gmail.com>
date Sat, 23 Jun 2012 14:17:13 +0200
parents 1f8d48b2b3c5
children fdd92a9e5196
files src/main.cpp src/main.h
diffstat 2 files changed, 32 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1432,6 +1432,8 @@
     else
         nTxPos = ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size());
 
+    CBlockUndo blockundo;
+
     map<uint256, CTxIndex> mapQueuedChanges;
     int64 nFees = 0;
     unsigned int nSigOps = 0;
@@ -1461,6 +1463,8 @@
         MapPrevTx mapInputs;
         if (!tx.IsCoinBase())
         {
+            CTxUndo undo;
+
             bool fInvalid;
             if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid))
                 return false;
@@ -1477,8 +1481,14 @@
 
             nFees += tx.GetValueIn(mapInputs)-tx.GetValueOut();
 
+            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(mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fStrictPayToScriptHash))
                 return false;
+
+            blockundo.vtxundo.push_back(undo);
         }
 
         mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size());
@@ -1507,6 +1517,13 @@
             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);
--- a/src/main.h
+++ b/src/main.h
@@ -155,6 +155,10 @@
         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)))
@@ -810,6 +814,17 @@
     )
 };
 
+/** 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
  *
  * Serialized format: