mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-21 14:34:49 +01:00
interfaces, refactor: Add more block information to block connected notifications
Add new interfaces::BlockInfo struct to be able to pass extra block information (file and undo information) to indexes which they are updated to use high level interfaces::Chain notifications. This commit does not change behavior in any way.
This commit is contained in:
parent
8d4a058ac4
commit
a0b5b4ae5a
8 changed files with 94 additions and 21 deletions
|
@ -171,6 +171,7 @@ BITCOIN_CORE_H = \
|
|||
interfaces/ipc.h \
|
||||
interfaces/node.h \
|
||||
interfaces/wallet.h \
|
||||
kernel/chain.h \
|
||||
kernel/chainstatemanager_opts.h \
|
||||
kernel/checks.h \
|
||||
kernel/coinstats.h \
|
||||
|
@ -365,6 +366,7 @@ libbitcoin_node_a_SOURCES = \
|
|||
index/coinstatsindex.cpp \
|
||||
index/txindex.cpp \
|
||||
init.cpp \
|
||||
kernel/chain.cpp \
|
||||
kernel/checks.cpp \
|
||||
kernel/coinstats.cpp \
|
||||
kernel/context.cpp \
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
class ArgsManager;
|
||||
class CBlock;
|
||||
class CBlockUndo;
|
||||
class CFeeRate;
|
||||
class CRPCCommand;
|
||||
class CScheduler;
|
||||
|
@ -67,6 +68,19 @@ public:
|
|||
mutable bool found = false;
|
||||
};
|
||||
|
||||
//! Block data sent with blockConnected, blockDisconnected notifications.
|
||||
struct BlockInfo {
|
||||
const uint256& hash;
|
||||
const uint256* prev_hash = nullptr;
|
||||
int height = -1;
|
||||
int file_number = -1;
|
||||
unsigned data_pos = 0;
|
||||
const CBlock* data = nullptr;
|
||||
const CBlockUndo* undo_data = nullptr;
|
||||
|
||||
BlockInfo(const uint256& hash LIFETIMEBOUND) : hash(hash) {}
|
||||
};
|
||||
|
||||
//! Interface giving clients (wallet processes, maybe other analysis tools in
|
||||
//! the future) ability to access to the chain state, receive notifications,
|
||||
//! estimate fees, and submit transactions.
|
||||
|
@ -239,8 +253,8 @@ public:
|
|||
virtual ~Notifications() {}
|
||||
virtual void transactionAddedToMempool(const CTransactionRef& tx, uint64_t mempool_sequence) {}
|
||||
virtual void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) {}
|
||||
virtual void blockConnected(const CBlock& block, int height) {}
|
||||
virtual void blockDisconnected(const CBlock& block, int height) {}
|
||||
virtual void blockConnected(const BlockInfo& block) {}
|
||||
virtual void blockDisconnected(const BlockInfo& block) {}
|
||||
virtual void updatedBlockTip() {}
|
||||
virtual void chainStateFlushed(const CBlockLocator& locator) {}
|
||||
};
|
||||
|
|
26
src/kernel/chain.cpp
Normal file
26
src/kernel/chain.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2022 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chain.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <sync.h>
|
||||
#include <uint256.h>
|
||||
|
||||
class CBlock;
|
||||
|
||||
namespace kernel {
|
||||
interfaces::BlockInfo MakeBlockInfo(const CBlockIndex* index, const CBlock* data)
|
||||
{
|
||||
interfaces::BlockInfo info{index ? *index->phashBlock : uint256::ZERO};
|
||||
if (index) {
|
||||
info.prev_hash = index->pprev ? index->pprev->phashBlock : nullptr;
|
||||
info.height = index->nHeight;
|
||||
LOCK(::cs_main);
|
||||
info.file_number = index->nFile;
|
||||
info.data_pos = index->nDataPos;
|
||||
}
|
||||
info.data = data;
|
||||
return info;
|
||||
}
|
||||
} // namespace kernel
|
19
src/kernel/chain.h
Normal file
19
src/kernel/chain.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) 2022 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_KERNEL_CHAIN_H
|
||||
#define BITCOIN_KERNEL_CHAIN_H
|
||||
|
||||
class CBlock;
|
||||
class CBlockIndex;
|
||||
namespace interfaces {
|
||||
struct BlockInfo;
|
||||
} // namespace interfaces
|
||||
|
||||
namespace kernel {
|
||||
//! Return data from block index.
|
||||
interfaces::BlockInfo MakeBlockInfo(const CBlockIndex* block_index, const CBlock* data = nullptr);
|
||||
} // namespace kernel
|
||||
|
||||
#endif // BITCOIN_KERNEL_CHAIN_H
|
|
@ -19,6 +19,7 @@
|
|||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <kernel/chain.h>
|
||||
#include <node/coin.h>
|
||||
#include <node/context.h>
|
||||
#include <node/transaction.h>
|
||||
|
@ -426,11 +427,11 @@ public:
|
|||
}
|
||||
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
|
||||
{
|
||||
m_notifications->blockConnected(*block, index->nHeight);
|
||||
m_notifications->blockConnected(kernel::MakeBlockInfo(index, block.get()));
|
||||
}
|
||||
void BlockDisconnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
|
||||
{
|
||||
m_notifications->blockDisconnected(*block, index->nHeight);
|
||||
m_notifications->blockDisconnected(kernel::MakeBlockInfo(index, block.get()));
|
||||
}
|
||||
void UpdatedBlockTip(const CBlockIndex* index, const CBlockIndex* fork_index, bool is_ibd) override
|
||||
{
|
||||
|
|
|
@ -137,8 +137,13 @@ FUZZ_TARGET_INIT(wallet_notifications, initialize_setup)
|
|||
block.vtx.emplace_back(MakeTransactionRef(tx));
|
||||
}
|
||||
// Mine block
|
||||
a.wallet->blockConnected(block, chain.size());
|
||||
b.wallet->blockConnected(block, chain.size());
|
||||
const uint256& hash = block.GetHash();
|
||||
interfaces::BlockInfo info{hash};
|
||||
info.prev_hash = &block.hashPrevBlock;
|
||||
info.height = chain.size();
|
||||
info.data = █
|
||||
a.wallet->blockConnected(info);
|
||||
b.wallet->blockConnected(info);
|
||||
// Store the coins for the next block
|
||||
Coins coins_new;
|
||||
for (const auto& tx : block.vtx) {
|
||||
|
@ -154,8 +159,13 @@ FUZZ_TARGET_INIT(wallet_notifications, initialize_setup)
|
|||
auto& [coins, block]{chain.back()};
|
||||
if (block.vtx.empty()) return; // Can only disconnect if the block was submitted first
|
||||
// Disconnect block
|
||||
a.wallet->blockDisconnected(block, chain.size() - 1);
|
||||
b.wallet->blockDisconnected(block, chain.size() - 1);
|
||||
const uint256& hash = block.GetHash();
|
||||
interfaces::BlockInfo info{hash};
|
||||
info.prev_hash = &block.hashPrevBlock;
|
||||
info.height = chain.size() - 1;
|
||||
info.data = █
|
||||
a.wallet->blockDisconnected(info);
|
||||
b.wallet->blockDisconnected(info);
|
||||
chain.pop_back();
|
||||
});
|
||||
auto& [coins, first_block]{chain.front()};
|
||||
|
|
|
@ -1314,30 +1314,31 @@ void CWallet::transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRe
|
|||
}
|
||||
}
|
||||
|
||||
void CWallet::blockConnected(const CBlock& block, int height)
|
||||
void CWallet::blockConnected(const interfaces::BlockInfo& block)
|
||||
{
|
||||
const uint256& block_hash = block.GetHash();
|
||||
assert(block.data);
|
||||
LOCK(cs_wallet);
|
||||
|
||||
m_last_block_processed_height = height;
|
||||
m_last_block_processed = block_hash;
|
||||
for (size_t index = 0; index < block.vtx.size(); index++) {
|
||||
SyncTransaction(block.vtx[index], TxStateConfirmed{block_hash, height, static_cast<int>(index)});
|
||||
transactionRemovedFromMempool(block.vtx[index], MemPoolRemovalReason::BLOCK, 0 /* mempool_sequence */);
|
||||
m_last_block_processed_height = block.height;
|
||||
m_last_block_processed = block.hash;
|
||||
for (size_t index = 0; index < block.data->vtx.size(); index++) {
|
||||
SyncTransaction(block.data->vtx[index], TxStateConfirmed{block.hash, block.height, static_cast<int>(index)});
|
||||
transactionRemovedFromMempool(block.data->vtx[index], MemPoolRemovalReason::BLOCK, 0 /* mempool_sequence */);
|
||||
}
|
||||
}
|
||||
|
||||
void CWallet::blockDisconnected(const CBlock& block, int height)
|
||||
void CWallet::blockDisconnected(const interfaces::BlockInfo& block)
|
||||
{
|
||||
assert(block.data);
|
||||
LOCK(cs_wallet);
|
||||
|
||||
// At block disconnection, this will change an abandoned transaction to
|
||||
// be unconfirmed, whether or not the transaction is added back to the mempool.
|
||||
// User may have to call abandontransaction again. It may be addressed in the
|
||||
// future with a stickier abandoned state or even removing abandontransaction call.
|
||||
m_last_block_processed_height = height - 1;
|
||||
m_last_block_processed = block.hashPrevBlock;
|
||||
for (const CTransactionRef& ptx : block.vtx) {
|
||||
m_last_block_processed_height = block.height - 1;
|
||||
m_last_block_processed = *Assert(block.prev_hash);
|
||||
for (const CTransactionRef& ptx : Assert(block.data)->vtx) {
|
||||
SyncTransaction(ptx, TxStateInactive{});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -508,8 +508,8 @@ public:
|
|||
CWalletTx* AddToWallet(CTransactionRef tx, const TxState& state, const UpdateWalletTxFn& update_wtx=nullptr, bool fFlushOnClose=true, bool rescanning_old_block = false);
|
||||
bool LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void transactionAddedToMempool(const CTransactionRef& tx, uint64_t mempool_sequence) override;
|
||||
void blockConnected(const CBlock& block, int height) override;
|
||||
void blockDisconnected(const CBlock& block, int height) override;
|
||||
void blockConnected(const interfaces::BlockInfo& block) override;
|
||||
void blockDisconnected(const interfaces::BlockInfo& block) override;
|
||||
void updatedBlockTip() override;
|
||||
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue