Skip to content

Commit

Permalink
Merge PIVX-Project#1746: [Core] Only include undo.h from main.cpp
Browse files Browse the repository at this point in the history
9670a84 Move UndoWriteToDisk() and UndoReadFromDisk() to anon namespace (random-zebra)
4fe609f Decouple CBlockUndo from CDiskBlockPos (jtimon)
9703b0e Decouple miner.o and txmempool.o from CTxUndo (random-zebra)
cdc8cdc Decouple CCoins from CTxInUndo (jtimon)

Pull request description:

  Backport bitcoin#5111

  Original description:
  > Built on top of bitcoin#5100.
  > coins.o doesn't need to depend on undo.h (Decouple CCoins from CTxInUndo)
  > miner.o neither (Decouple miner.o from CTxUndo)
  > Finally, CBlockUndo can be moved from main.h to undo.h if it is first decoupled from CDiskBlockPos.

ACKs for top commit:
  furszy:
    utACK 9670a84
  Fuzzbawls:
    re-utACK 9670a84

Tree-SHA512: d77110525f50a3085013ca9cb87550ff786ee06c5b938a9002fe3a434c7a35a425238d1b623a01c26bebb5075c7e1bea9bc2ff4638c0c1190df15196b7097e55
  • Loading branch information
furszy committed Jul 16, 2020
2 parents 2e11030 + 9670a84 commit 128978d
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 96 deletions.
24 changes: 3 additions & 21 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,39 +34,21 @@ void CCoins::CalcMaskSize(unsigned int& nBytes, unsigned int& nNonzeroBytes) con
nBytes += nLastUsedByte;
}

bool CCoins::Spend(const COutPoint& out, CTxInUndo& undo)
bool CCoins::Spend(uint32_t nPos)
{
if (out.n >= vout.size())
if (nPos >= vout.size() || vout[nPos].IsNull())
return false;
if (vout[out.n].IsNull())
return false;
undo = CTxInUndo(vout[out.n]);
vout[out.n].SetNull();
vout[nPos].SetNull();
Cleanup();
if (vout.size() == 0) {
undo.nHeight = nHeight;
undo.fCoinBase = fCoinBase;
undo.fCoinStake = fCoinStake;
undo.nVersion = this->nVersion;
}
return true;
}

bool CCoins::Spend(int nPos)
{
CTxInUndo undo;
COutPoint out(UINT256_ZERO, nPos);
return Spend(out, undo);
}


bool CCoinsView::GetCoins(const uint256& txid, CCoins& coins) const { return false; }
bool CCoinsView::HaveCoins(const uint256& txid) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return UINT256_ZERO; }
bool CCoinsView::BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock) { return false; }
bool CCoinsView::GetStats(CCoinsStats& stats) const { return false; }


CCoinsViewBacked::CCoinsViewBacked(CCoinsView* viewIn) : base(viewIn) {}
bool CCoinsViewBacked::GetCoins(const uint256& txid, CCoins& coins) const { return base->GetCoins(txid, coins); }
bool CCoinsViewBacked::HaveCoins(const uint256& txid) const { return base->HaveCoins(txid); }
Expand Down
6 changes: 1 addition & 5 deletions src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "script/standard.h"
#include "serialize.h"
#include "uint256.h"
#include "undo.h"

#include <assert.h>
#include <stdint.h>
Expand Down Expand Up @@ -241,11 +240,8 @@ class CCoins
Cleanup();
}

//! mark an outpoint spent, and construct undo information
bool Spend(const COutPoint& out, CTxInUndo& undo);

//! mark a vout spent
bool Spend(int nPos);
bool Spend(uint32_t nPos);

//! check whether a particular output is still available
bool IsAvailable(unsigned int nPos) const
Expand Down
140 changes: 80 additions & 60 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1705,16 +1705,33 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo& txund
if (!tx.IsCoinBase() && !tx.HasZerocoinSpendInputs()) {
txundo.vprevout.reserve(tx.vin.size());
for (const CTxIn& txin : tx.vin) {
txundo.vprevout.push_back(CTxInUndo());
bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back());
assert(ret);
CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
unsigned nPos = txin.prevout.n;

if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
assert(false);
// mark an outpoint spent, and construct undo information
txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
coins->Spend(nPos);
if (coins->vout.size() == 0) {
CTxInUndo& undo = txundo.vprevout.back();
undo.nHeight = coins->nHeight;
undo.fCoinBase = coins->fCoinBase;
undo.nVersion = coins->nVersion;
}
}
}

// add outputs
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
}

void UpdateCoins(const CTransaction& tx, CCoinsViewCache &inputs, int nHeight)
{
CTxUndo txundo;
UpdateCoins(tx, inputs, txundo, nHeight);
}

bool CScriptCheck::operator()()
{
const CScript& scriptSig = ptxTo->vin[nIn].scriptSig;
Expand Down Expand Up @@ -1916,6 +1933,63 @@ static bool AbortNode(CValidationState& state, const std::string& strMessage, co
return state.Error(strMessage);
}

namespace {

bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock)
{
// Open history file to append
CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
return error("%s : OpenUndoFile failed", __func__);

// Write index header
unsigned int nSize = GetSerializeSize(fileout, blockundo);
fileout << FLATDATA(Params().MessageStart()) << nSize;

// Write undo data
long fileOutPos = ftell(fileout.Get());
if (fileOutPos < 0)
return error("%s : ftell failed", __func__);
pos.nPos = (unsigned int)fileOutPos;
fileout << blockundo;

// calculate & write checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock;
hasher << blockundo;
fileout << hasher.GetHash();

return true;
}

bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
{
// Open history file to read
CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
return error("%s : OpenBlockFile failed", __func__);

// Read block
uint256 hashChecksum;
try {
filein >> blockundo;
filein >> hashChecksum;
} catch (const std::exception& e) {
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
}

// Verify checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock;
hasher << blockundo;
if (hashChecksum != hasher.GetHash())
return error("%s : Checksum mismatch", __func__);

return true;
}

} // anon namespace

bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
{
AssertLockHeld(cs_main);
Expand All @@ -1935,7 +2009,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
CDiskBlockPos pos = pindex->GetUndoPos();
if (pos.IsNull())
return error("DisconnectBlock() : no undo data available");
if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
return error("DisconnectBlock() : failure reading undo data");

if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
Expand Down Expand Up @@ -2303,7 +2377,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CDiskBlockPos diskPosBlock;
if (!FindUndoPos(state, pindex->nFile, diskPosBlock, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock() : FindUndoPos failed");
if (!blockundo.WriteToDisk(diskPosBlock, pindex->pprev->GetBlockHash()))
if (!UndoWriteToDisk(blockundo, diskPosBlock, pindex->pprev->GetBlockHash()))
return AbortNode(state, "Failed to write undo data");

// update nUndoPos in block index
Expand Down Expand Up @@ -4334,7 +4408,7 @@ bool CVerifyDB::VerifyDB(CCoinsView* coinsview, int nCheckLevel, int nCheckDepth
CBlockUndo undo;
CDiskBlockPos pos = pindex->GetUndoPos();
if (!pos.IsNull()) {
if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
return error("%s: *** found bad undo data at %d, hash=%s\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString());
}
}
Expand Down Expand Up @@ -6200,60 +6274,6 @@ bool SendMessages(CNode* pto)
return true;
}


bool CBlockUndo::WriteToDisk(CDiskBlockPos& pos, const uint256& hashBlock)
{
// Open history file to append
CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");

// Write index header
unsigned int nSize = GetSerializeSize(fileout, *this);
fileout << FLATDATA(Params().MessageStart()) << nSize;

// Write undo data
long fileOutPos = ftell(fileout.Get());
if (fileOutPos < 0)
return error("CBlockUndo::WriteToDisk : ftell failed");
pos.nPos = (unsigned int)fileOutPos;
fileout << *this;

// calculate & write checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock;
hasher << *this;
fileout << hasher.GetHash();

return true;
}

bool CBlockUndo::ReadFromDisk(const CDiskBlockPos& pos, const uint256& hashBlock)
{
// Open history file to read
CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");

// Read block
uint256 hashChecksum;
try {
filein >> *this;
filein >> hashChecksum;
} catch (const std::exception& e) {
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
}

// Verify checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock;
hasher << *this;
if (hashChecksum != hasher.GetHash())
return error("CBlockUndo::ReadFromDisk : Checksum mismatch");

return true;
}

std::string CBlockFileInfo::ToString() const
{
return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast));
Expand Down
2 changes: 1 addition & 1 deletion src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, const CTxMemPool& pool, unsigned
bool CheckInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& view, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck>* pvChecks = NULL);

/** Apply the effects of this transaction on the UTXO set represented by view */
void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo& txundo, int nHeight);
void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight);

bool IsTransactionInChain(const uint256& txId, int& nHeightTx, CTransaction& tx);
bool IsTransactionInChain(const uint256& txId, int& nHeightTx);
Expand Down
3 changes: 1 addition & 2 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
continue;

CTxUndo txundo;
UpdateCoins(tx, view, txundo, nHeight);
UpdateCoins(tx, view, nHeight);

// Added
pblock->vtx.push_back(tx);
Expand Down
6 changes: 2 additions & 4 deletions src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,9 +662,8 @@ void CTxMemPool::check(const CCoinsViewCache* pcoins) const
waitingOnDependants.push_back(&(*it));
else {
CValidationState state;
CTxUndo undo;
assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL));
UpdateCoins(tx, mempoolDuplicate, undo, 1000000);
UpdateCoins(tx, mempoolDuplicate, 1000000);
}
}

Expand All @@ -679,8 +678,7 @@ void CTxMemPool::check(const CCoinsViewCache* pcoins) const
assert(stepsSinceLastRemove < waitingOnDependants.size());
} else {
assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL));
CTxUndo undo;
UpdateCoins(entry->GetTx(), mempoolDuplicate, undo, 1000000);
UpdateCoins(entry->GetTx(), mempoolDuplicate, 1000000);
stepsSinceLastRemove = 0;
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/undo.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ class CBlockUndo
{
READWRITE(vtxundo);
}

bool WriteToDisk(CDiskBlockPos& pos, const uint256& hashBlock);
bool ReadFromDisk(const CDiskBlockPos& pos, const uint256& hashBlock);
};

#endif // BITCOIN_UNDO_H

0 comments on commit 128978d

Please sign in to comment.