aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-06-23 14:17:13 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2012-10-20 23:08:57 +0200
commit8adf48dc9b45816793c7b98e2f4fa625c2e09f2c (patch)
tree017ab9d78c3269430c82ca35f0e107f34ca98373 /src
parent630fd8dcb6662ed167e967625f2715f97ddd2db5 (diff)
Preliminary undo file creation
Create files (one per block) with undo information for the transactions in it.
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp17
-rw-r--r--src/main.h15
2 files changed, 32 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
index fa818bd053..8b1532e48c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1432,6 +1432,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
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 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
MapPrevTx mapInputs;
if (!tx.IsCoinBase())
{
+ CTxUndo undo;
+
bool fInvalid;
if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid))
return false;
@@ -1477,8 +1481,14 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
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 @@ 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 a1d6334746..9257b53f30 100644
--- a/src/main.h
+++ b/src/main.h
@@ -155,6 +155,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)))
@@ -810,6 +814,17 @@ 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
*
* Serialized format: