From 05f0aaf76e6da88f32b3b7c80d22c830396aa8bb Mon Sep 17 00:00:00 2001 From: alexhz Date: Wed, 15 Jan 2014 19:18:38 +0000 Subject: [PATCH] Undo file creation Create files with block undo information for the transactions in it. --- src/main.cpp | 18 ++++++++++++++++++ src/main.h | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 0 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 55a09d7..ca9eb8e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 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); diff --git a/src/main.h b/src/main.h index beeba3d..98fd427 100644 --- a/src/main.h +++ b/src/main.h @@ -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 vtxundo; + + IMPLEMENT_SERIALIZE( + READWRITE(vtxundo); + ) +}; /** pruned version of CTransaction: only retains metadata and unspent transaction outputs * -- 1.7.1