Preliminary undo file creation

Create files (one per block) with undo information for the transactions
in it.
This commit is contained in:
Pieter Wuille 2012-06-23 14:17:13 +02:00
parent 630fd8dcb6
commit 8adf48dc9b
2 changed files with 32 additions and 0 deletions

View file

@ -1432,6 +1432,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
else else
nTxPos = ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size()); nTxPos = ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size());
CBlockUndo blockundo;
map<uint256, CTxIndex> mapQueuedChanges; map<uint256, CTxIndex> mapQueuedChanges;
int64 nFees = 0; int64 nFees = 0;
unsigned int nSigOps = 0; unsigned int nSigOps = 0;
@ -1461,6 +1463,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
MapPrevTx mapInputs; MapPrevTx mapInputs;
if (!tx.IsCoinBase()) if (!tx.IsCoinBase())
{ {
CTxUndo undo;
bool fInvalid; bool fInvalid;
if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid)) if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid))
return false; return false;
@ -1477,8 +1481,14 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
nFees += tx.GetValueIn(mapInputs)-tx.GetValueOut(); 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)) if (!tx.ConnectInputs(mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fStrictPayToScriptHash))
return false; return false;
blockundo.vtxundo.push_back(undo);
} }
mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size()); 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"); 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 // Watch for transactions paying to me
BOOST_FOREACH(CTransaction& tx, vtx) BOOST_FOREACH(CTransaction& tx, vtx)
SyncWithWallets(tx, this, true); SyncWithWallets(tx, this, true);

View file

@ -155,6 +155,10 @@ public:
return GetDirectory(base) / strprintf("%08u%s.blk", nHeight, GetAlternative().c_str()); 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, ...?) // TODO: make thread-safe (lockfile, atomic file creation, ...?)
void MakeUnique(const boost::filesystem::path &base) { void MakeUnique(const boost::filesystem::path &base) {
while (boost::filesystem::exists(GetFileName(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 /** pruned version of CTransaction: only retains metadata and unspent transaction outputs
* *
* Serialized format: * Serialized format: