test: Wrap validation functions with TestChainstateManager

This allows to access them in the fuzz test in the next commit
without making them public.

Co-authored-by: TheCharlatan <seb.kung@gmail.com>
This commit is contained in:
Martin Zumsande 2025-12-05 11:42:30 -05:00
parent 13891a8a68
commit c011e3aa54
4 changed files with 73 additions and 8 deletions

View File

@ -248,7 +248,6 @@ private:
ChainstateManager& chainman);
RecursiveMutex cs_LastBlockFile;
std::vector<CBlockFileInfo> m_blockfile_info;
//! Since assumedvalid chainstates may be syncing a range of the chain that is very
//! far away from the normal/background validation process, we should segment blockfiles
@ -283,12 +282,6 @@ private:
const Obfuscation m_obfuscation;
/** Dirty block index entries. */
std::set<CBlockIndex*> m_dirty_blockindex;
/** Dirty block file entries. */
std::set<int> m_dirty_fileinfo;
/**
* Map from external index name to oldest block that must not be pruned.
*
@ -304,6 +297,15 @@ private:
const FlatFileSeq m_block_file_seq;
const FlatFileSeq m_undo_file_seq;
protected:
std::vector<CBlockFileInfo> m_blockfile_info;
/** Dirty block index entries. */
std::set<CBlockIndex*> m_dirty_blockindex;
/** Dirty block file entries. */
std::set<int> m_dirty_fileinfo;
public:
using Options = kernel::BlockManagerOpts;
using ReadRawBlockResult = util::Expected<std::vector<std::byte>, ReadRawError>;

View File

@ -4,6 +4,7 @@
#include <test/util/validation.h>
#include <node/blockstorage.h>
#include <util/check.h>
#include <util/time.h>
#include <validation.h>
@ -11,6 +12,13 @@
using kernel::ChainstateRole;
void TestBlockManager::CleanupForFuzzing()
{
m_dirty_blockindex.clear();
m_dirty_fileinfo.clear();
m_blockfile_info.resize(1);
}
void TestChainstateManager::DisableNextWrite()
{
struct TestChainstate : public Chainstate {
@ -43,3 +51,43 @@ void ValidationInterfaceTest::BlockConnected(
{
obj.BlockConnected(role, block, pindex);
}
void TestChainstateManager::InvalidBlockFound(CBlockIndex* pindex, const BlockValidationState& state)
{
struct TestChainstate : public Chainstate {
void CallInvalidBlockFound(CBlockIndex* pindex, const BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
InvalidBlockFound(pindex, state);
}
};
static_cast<TestChainstate*>(&ActiveChainstate())->CallInvalidBlockFound(pindex, state);
}
void TestChainstateManager::InvalidChainFound(CBlockIndex* pindexNew)
{
struct TestChainstate : public Chainstate {
void CallInvalidChainFound(CBlockIndex* pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
InvalidChainFound(pindexNew);
}
};
static_cast<TestChainstate*>(&ActiveChainstate())->CallInvalidChainFound(pindexNew);
}
CBlockIndex* TestChainstateManager::FindMostWorkChain()
{
struct TestChainstate : public Chainstate {
CBlockIndex* CallFindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
return FindMostWorkChain();
}
};
return static_cast<TestChainstate*>(&ActiveChainstate())->CallFindMostWorkChain();
}
void TestChainstateManager::ResetBestInvalid()
{
m_best_invalid = nullptr;
}

View File

@ -7,8 +7,16 @@
#include <validation.h>
namespace node {
class BlockManager;
}
class CValidationInterface;
struct TestBlockManager : public node::BlockManager {
/** Test-only method to clear internal state for fuzzing */
void CleanupForFuzzing();
};
struct TestChainstateManager : public ChainstateManager {
/** Disable the next write of all chainstates */
void DisableNextWrite();
@ -16,6 +24,11 @@ struct TestChainstateManager : public ChainstateManager {
void ResetIbd();
/** Toggle IsInitialBlockDownload from true to false */
void JumpOutOfIbd();
/** Wrappers that avoid making chainstatemanager internals public for tests */
void InvalidBlockFound(CBlockIndex* pindex, const BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void InvalidChainFound(CBlockIndex* pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
CBlockIndex* FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void ResetBestInvalid() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
};
class ValidationInterfaceTest

View File

@ -929,7 +929,6 @@ enum class SnapshotCompletionResult {
class ChainstateManager
{
private:
CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr};
/** The last header for which a headerTip notification was issued. */
CBlockIndex* m_last_notified_header GUARDED_BY(GetMutex()){nullptr};
@ -983,6 +982,9 @@ private:
SteadyClock::duration GUARDED_BY(::cs_main) time_chainstate{};
SteadyClock::duration GUARDED_BY(::cs_main) time_post_connect{};
protected:
CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr};
public:
using Options = kernel::ChainstateManagerOpts;