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 Aug 16, 2019
1 parent 1bf2ff2 commit e26decf
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
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 @@ -65,7 +65,7 @@ class BaseIndex : public CValidationInterface
bool Commit();

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
1 change: 1 addition & 0 deletions src/interfaces/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class NotificationsHandlerImpl : public Handler, CValidationInterface
}
void BlockConnected(const std::shared_ptr<const CBlock>& block,
const CBlockIndex* index,
const std::shared_ptr<const CBlockUndo> &block_undo,
const std::vector<CTransactionRef>& tx_conflicted) override
{
m_notifications->BlockConnected(*block, tx_conflicted);
Expand Down
2 changes: 1 addition & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,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 @@ -33,7 +33,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 @@ -36,7 +36,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
30 changes: 18 additions & 12 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1712,7 +1712,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 @@ -1887,15 +1887,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 @@ -1971,9 +1971,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 @@ -1993,7 +1993,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 @@ -2279,6 +2279,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 @@ -2308,12 +2309,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 @@ -2362,9 +2366,11 @@ 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(&CoinsTip());
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 @@ -2394,7 +2400,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 @@ -2658,7 +2664,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 (!m_chain.Tip() || (starting_tip && CBlockIndexWorkComparator()(m_chain.Tip(), starting_tip)));
if (!blocks_connected) return true;
Expand Down Expand Up @@ -3560,7 +3566,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 (!::ChainstateActive().ConnectBlock(block, state, &indexDummy, viewNew, chainparams, true))
if (!::ChainstateActive().ConnectBlock(block, state, &indexDummy, viewNew, chainparams, nullptr, true))
return false;
assert(state.IsValid());

Expand Down Expand Up @@ -4020,7 +4026,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 (!::ChainstateActive().ConnectBlock(block, state, pindex, coins, chainparams))
if (!::ChainstateActive().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
2 changes: 1 addition & 1 deletion src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,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);

// Apply the effects of a block disconnection on the UTXO set.
bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);
Expand Down
16 changes: 11 additions & 5 deletions src/validationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include <primitives/block.h>
#include <scheduler.h>
#include <txmempool.h>
#include <util/system.h>
#include <undo.h>
#include <validation.h>

#include <list>
#include <atomic>
Expand All @@ -30,7 +33,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 @@ -93,7 +99,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 @@ -152,9 +158,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 CConnman;
class CValidationInterface;
Expand Down Expand Up @@ -108,7 +109,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 @@ -177,7 +181,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 BlockChecked(const CBlock&, const CValidationState&);
Expand Down
5 changes: 4 additions & 1 deletion src/zmq/zmqnotificationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,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 e26decf

Please sign in to comment.