Skip to content

Commit

Permalink
Add CBlockUndo data to BlockConnected callbacks
Browse files Browse the repository at this point in the history
Changes cherry-picked from bitcoin#14035.

Co-authored-by: Maciej Grychowski <maciej.grychowski@onet.eu>
  • Loading branch information
marcinja and mgrychow committed Mar 20, 2019
1 parent b3f8228 commit 1d5e31f
Show file tree
Hide file tree
Showing 12 changed files with 48 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ bool BaseIndex::WriteBestBlock(const CBlockIndex* block_index)
return true;
}

void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex, const std::shared_ptr<const CBlockUndo> &block_undo,
const std::vector<CTransactionRef>& txn_conflicted)
{
if (!m_synced) {
Expand Down
2 changes: 1 addition & 1 deletion src/index/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class BaseIndex : public CValidationInterface
bool WriteBestBlock(const CBlockIndex* block_index);

protected:
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex, const std::shared_ptr<const CBlockUndo> &block_undo,
const std::vector<CTransactionRef>& txn_conflicted) override;

void ChainStateFlushed(const CBlockLocator& locator) override;
Expand Down
2 changes: 1 addition & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@ PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CS
* Evict orphan txn pool entries (EraseOrphanTx) based on a newly connected
* block. Also save the time of the last tip update.
*/
void PeerLogicValidation::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted) {
void PeerLogicValidation::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::shared_ptr<const CBlockUndo> &block_undo, const std::vector<CTransactionRef>& vtxConflicted) {
LOCK(g_cs_orphans);

std::vector<uint256> vOrphanErase;
Expand Down
2 changes: 1 addition & 1 deletion src/net_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PeerLogicValidation final : public CValidationInterface, public NetEventsI
/**
* Overridden from CValidationInterface.
*/
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected, const std::shared_ptr<const CBlockUndo> &block_undo, const std::vector<CTransactionRef>& vtxConflicted) override;
/**
* Overridden from CValidationInterface.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/test/validation_block_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct TestSubscriber : public CValidationInterface {
BOOST_CHECK_EQUAL(m_expected_tip, pindexNew->GetBlockHash());
}

void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex, const std::vector<CTransactionRef>& txnConflicted) override
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex, const std::shared_ptr<const CBlockUndo>& block_undo, const std::vector<CTransactionRef>& txnConflicted) override
{
BOOST_CHECK_EQUAL(m_expected_tip, block->hashPrevBlock);
BOOST_CHECK_EQUAL(m_expected_tip, pindex->pprev->GetBlockHash());
Expand Down
31 changes: 18 additions & 13 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class CChainState {
// Block (dis)connection on a given view:
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view);
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex,
CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
CCoinsViewCache& view, const CChainParams& chainparams, std::shared_ptr<CBlockUndo> block_undo, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);

// Block disconnection on our pcoinsTip:
bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
Expand Down Expand Up @@ -1779,7 +1779,7 @@ static int64_t nBlocksTotal = 0;
* Validity checks that depend on the UTXO set are also done; ConnectBlock()
* can fail if those validity checks fail (among other reasons). */
bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex,
CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck)
CCoinsViewCache& view, const CChainParams& chainparams, std::shared_ptr<CBlockUndo> block_undo, bool fJustCheck)
{
AssertLockHeld(cs_main);
assert(pindex);
Expand Down Expand Up @@ -1954,15 +1954,15 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);

CBlockUndo blockundo;
if(block_undo == nullptr) block_undo = std::make_shared<CBlockUndo>();

CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : nullptr);

std::vector<int> prevheights;
CAmount nFees = 0;
int nInputs = 0;
int64_t nSigOpsCost = 0;
blockundo.vtxundo.reserve(block.vtx.size() - 1);
block_undo->vtxundo.reserve(block.vtx.size() - 1);
std::vector<PrecomputedTransactionData> txdata;
txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
for (unsigned int i = 0; i < block.vtx.size(); i++)
Expand Down Expand Up @@ -2019,9 +2019,9 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl

CTxUndo undoDummy;
if (i > 0) {
blockundo.vtxundo.push_back(CTxUndo());
block_undo->vtxundo.push_back(CTxUndo());
}
UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
UpdateCoins(tx, view, i == 0 ? undoDummy : block_undo->vtxundo.back(), pindex->nHeight);
}
int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal);
Expand All @@ -2041,7 +2041,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
if (fJustCheck)
return true;

if (!WriteUndoDataForBlock(blockundo, state, pindex, chainparams))
if (!WriteUndoDataForBlock(*block_undo, state, pindex, chainparams))
return false;

if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
Expand Down Expand Up @@ -2327,6 +2327,7 @@ struct PerBlockConnectTrace {
CBlockIndex* pindex = nullptr;
std::shared_ptr<const CBlock> pblock;
std::shared_ptr<std::vector<CTransactionRef>> conflictedTxs;
std::shared_ptr<const CBlockUndo> block_undo;
PerBlockConnectTrace() : conflictedTxs(std::make_shared<std::vector<CTransactionRef>>()) {}
};
/**
Expand Down Expand Up @@ -2356,12 +2357,15 @@ class ConnectTrace {
m_connNotifyEntryRemoved = pool.NotifyEntryRemoved.connect(std::bind(&ConnectTrace::NotifyEntryRemoved, this, std::placeholders::_1, std::placeholders::_2));
}

void BlockConnected(CBlockIndex* pindex, std::shared_ptr<const CBlock> pblock) {
void BlockConnected(CBlockIndex* pindex,
std::shared_ptr<const CBlock> pblock,
std::shared_ptr<CBlockUndo> block_undo) {
assert(!blocksConnected.back().pindex);
assert(pindex);
assert(pblock);
blocksConnected.back().pindex = pindex;
blocksConnected.back().pblock = std::move(pblock);
blocksConnected.back().block_undo = std::move(block_undo);
blocksConnected.emplace_back();
}

Expand Down Expand Up @@ -2410,9 +2414,10 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp
int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
int64_t nTime3;
LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO);
std::shared_ptr<CBlockUndo> block_undo = std::make_shared<CBlockUndo>();
{
CCoinsViewCache view(pcoinsTip.get());
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams, block_undo);
GetMainSignals().BlockChecked(blockConnecting, state);
if (!rv) {
if (state.IsInvalid())
Expand Down Expand Up @@ -2442,7 +2447,7 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp
LogPrint(BCLog::BENCH, " - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO, nTimePostConnect * MILLI / nBlocksTotal);
LogPrint(BCLog::BENCH, "- Connect block: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime1) * MILLI, nTimeTotal * MICRO, nTimeTotal * MILLI / nBlocksTotal);

connectTrace.BlockConnected(pindexNew, std::move(pthisBlock));
connectTrace.BlockConnected(pindexNew, std::move(pthisBlock), std::move(block_undo));
return true;
}

Expand Down Expand Up @@ -2700,7 +2705,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&

for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
assert(trace.pblock && trace.pindex);
GetMainSignals().BlockConnected(trace.pblock, trace.pindex, trace.conflictedTxs);
GetMainSignals().BlockConnected(trace.pblock, trace.pindex, trace.block_undo, trace.conflictedTxs);
}
} while (!chainActive.Tip() || (starting_tip && CBlockIndexWorkComparator()(chainActive.Tip(), starting_tip)));
if (!blocks_connected) return true;
Expand Down Expand Up @@ -3586,7 +3591,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state));
if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev))
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state));
if (!g_chainstate.ConnectBlock(block, state, &indexDummy, viewNew, chainparams, true))
if (!g_chainstate.ConnectBlock(block, state, &indexDummy, viewNew, chainparams, nullptr, true))
return false;
assert(state.IsValid());

Expand Down Expand Up @@ -4036,7 +4041,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
CBlock block;
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
if (!g_chainstate.ConnectBlock(block, state, pindex, coins, chainparams))
if (!g_chainstate.ConnectBlock(block, state, pindex, coins, chainparams, nullptr))
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state));
}
}
Expand Down
14 changes: 9 additions & 5 deletions src/validationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <scheduler.h>
#include <txmempool.h>
#include <util/system.h>
#include <undo.h>
#include <validation.h>

#include <list>
Expand All @@ -33,7 +34,10 @@ struct ValidationInterfaceConnections {
struct MainSignalsInstance {
boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip;
boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool;
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef>&)> BlockConnected;
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &,
const CBlockIndex *pindex,
const std::shared_ptr<const CBlockUndo> &block_undo,
const std::vector<CTransactionRef>&)> BlockConnected;
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &)> BlockDisconnected;
boost::signals2::signal<void (const CTransactionRef &)> TransactionRemovedFromMempool;
boost::signals2::signal<void (const CBlockLocator &)> ChainStateFlushed;
Expand Down Expand Up @@ -97,7 +101,7 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
ValidationInterfaceConnections& conns = g_signals.m_internals->m_connMainSignals[pwalletIn];
conns.UpdatedBlockTip = g_signals.m_internals->UpdatedBlockTip.connect(std::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
conns.TransactionAddedToMempool = g_signals.m_internals->TransactionAddedToMempool.connect(std::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, std::placeholders::_1));
conns.BlockConnected = g_signals.m_internals->BlockConnected.connect(std::bind(&CValidationInterface::BlockConnected, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
conns.BlockConnected = g_signals.m_internals->BlockConnected.connect(std::bind(&CValidationInterface::BlockConnected, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
conns.BlockDisconnected = g_signals.m_internals->BlockDisconnected.connect(std::bind(&CValidationInterface::BlockDisconnected, pwalletIn, std::placeholders::_1));
conns.TransactionRemovedFromMempool = g_signals.m_internals->TransactionRemovedFromMempool.connect(std::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, std::placeholders::_1));
conns.ChainStateFlushed = g_signals.m_internals->ChainStateFlushed.connect(std::bind(&CValidationInterface::ChainStateFlushed, pwalletIn, std::placeholders::_1));
Expand Down Expand Up @@ -157,9 +161,9 @@ void CMainSignals::TransactionAddedToMempool(const CTransactionRef &ptx) {
});
}

void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>>& pvtxConflicted) {
m_internals->m_schedulerClient.AddToProcessQueue([pblock, pindex, pvtxConflicted, this] {
m_internals->BlockConnected(pblock, pindex, *pvtxConflicted);
void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex, const std::shared_ptr<const CBlockUndo> &block_undo, const std::shared_ptr<const std::vector<CTransactionRef>>& pvtxConflicted) {
m_internals->m_schedulerClient.AddToProcessQueue([pblock, pindex, block_undo, pvtxConflicted, this] {
m_internals->BlockConnected(pblock, pindex, block_undo, *pvtxConflicted);
});
}

Expand Down
11 changes: 9 additions & 2 deletions src/validationinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
extern CCriticalSection cs_main;
class CBlock;
class CBlockIndex;
class CBlockUndo;
struct CBlockLocator;
class CBlockIndex;
class CConnman;
Expand Down Expand Up @@ -110,7 +111,10 @@ class CValidationInterface {
*
* Called on a background thread.
*/
virtual void BlockConnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex, const std::vector<CTransactionRef> &txnConflicted) {}
virtual void BlockConnected(const std::shared_ptr<const CBlock> &block,
const CBlockIndex *pindex,
const std::shared_ptr<const CBlockUndo> &block_undo,
const std::vector<CTransactionRef> &txnConflicted) {}
/**
* Notifies listeners of a block being disconnected
*
Expand Down Expand Up @@ -181,7 +185,10 @@ class CMainSignals {

void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
void TransactionAddedToMempool(const CTransactionRef &);
void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>> &);
void BlockConnected(const std::shared_ptr<const CBlock> &,
const CBlockIndex *pindex,
const std::shared_ptr<const CBlockUndo> &,
const std::shared_ptr<const std::vector<CTransactionRef>> &);
void BlockDisconnected(const std::shared_ptr<const CBlock> &);
void ChainStateFlushed(const CBlockLocator &);
void Broadcast(int64_t nBestBlockTime, CConnman* connman);
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ void CWallet::TransactionRemovedFromMempool(const CTransactionRef &ptx) {
}
}

void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) {
void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::shared_ptr<const CBlockUndo>& block_undo, const std::vector<CTransactionRef>& vtxConflicted) {
auto locked_chain = chain().lock();
LOCK(cs_wallet);
// TODO: Temporarily ensure that mempool removals are notified before
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
bool AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose=true);
void LoadToWallet(const CWalletTx& wtxIn) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void TransactionAddedToMempool(const CTransactionRef& tx) override;
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::shared_ptr<const CBlockUndo>& block_undo, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) override;
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update);

Expand Down
5 changes: 4 additions & 1 deletion src/zmq/zmqnotificationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ void CZMQNotificationInterface::TransactionAddedToMempool(const CTransactionRef&
}
}

void CZMQNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected, const std::vector<CTransactionRef>& vtxConflicted)
void CZMQNotificationInterface::BlockConnected( const std::shared_ptr<const CBlock>& pblock,
const CBlockIndex* pindexConnected,
const std::shared_ptr<const CBlockUndo> &block_undo,
const std::vector<CTransactionRef>& vtxConflicted)
{
for (const CTransactionRef& ptx : pblock->vtx) {
// Do a normal notify for each transaction added in the block
Expand Down
2 changes: 1 addition & 1 deletion src/zmq/zmqnotificationinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class CZMQNotificationInterface final : public CValidationInterface

// CValidationInterface
void TransactionAddedToMempool(const CTransactionRef& tx) override;
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected, const std::shared_ptr<const CBlockUndo> &block_undo, const std::vector<CTransactionRef>& vtxConflicted) override;
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) override;
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;

Expand Down

0 comments on commit 1d5e31f

Please sign in to comment.