test: Use NodeClockContext in more tests

This commit is contained in:
MarcoFalke
2025-05-07 02:04:48 +02:00
parent fa8fe0941e
commit faad08e59c
11 changed files with 57 additions and 55 deletions

View File

@@ -3,7 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <bench/bench.h>
#include <test/util/time.h>
#include <util/time.h>
static void BenchTimeDeprecated(benchmark::Bench& bench)
@@ -15,11 +15,10 @@ static void BenchTimeDeprecated(benchmark::Bench& bench)
static void BenchTimeMock(benchmark::Bench& bench)
{
SetMockTime(111);
NodeClockContext clock_ctx{111s};
bench.run([&] {
(void)GetTime<std::chrono::seconds>();
});
SetMockTime(0);
}
static void BenchTimeMillis(benchmark::Bench& bench)

View File

@@ -10,6 +10,7 @@
#include <sync.h>
#include <test/util/mining.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <uint256.h>
#include <util/time.h>
#include <validation.h>
@@ -32,7 +33,7 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b
// Set clock to genesis block, so the descriptors/keys creation time don't interfere with the blocks scanning process.
// The reason is 'generatetoaddress', which creates a chain with deterministic timestamps in the past.
SetMockTime(test_setup->m_node.chainman->GetParams().GenesisBlock().nTime);
NodeClockContext clock_ctx{test_setup->m_node.chainman->GetParams().GenesisBlock().Time()};
CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockableWalletDatabase()};
{
LOCK(wallet.cs_wallet);

View File

@@ -20,6 +20,7 @@
#include <script/script.h>
#include <sync.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <uint256.h>
#include <util/result.h>
#include <util/time.h>
@@ -117,7 +118,7 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
// Set clock to genesis block, so the descriptors/keys creation time don't interfere with the blocks scanning process.
SetMockTime(test_setup->m_node.chainman->GetParams().GenesisBlock().nTime);
NodeClockContext clock_ctx{test_setup->m_node.chainman->GetParams().GenesisBlock().Time()};
CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockableWalletDatabase()};
{
LOCK(wallet.cs_wallet);
@@ -172,7 +173,7 @@ static void AvailableCoins(benchmark::Bench& bench, const std::vector<OutputType
{
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
// Set clock to genesis block, so the descriptors/keys creation time don't interfere with the blocks scanning process.
SetMockTime(test_setup->m_node.chainman->GetParams().GenesisBlock().nTime);
NodeClockContext clock_ctx{test_setup->m_node.chainman->GetParams().GenesisBlock().Time()};
CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockableWalletDatabase()};
{
LOCK(wallet.cs_wallet);

View File

@@ -12,6 +12,7 @@
#include <random.h>
#include <test/data/asmap.raw.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/asmap.h>
#include <util/string.h>
@@ -1030,7 +1031,8 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks)
BOOST_CHECK_EQUAL(addrman->SelectTriedCollision().first.ToStringAddrPort(), "250.1.1.36:0");
// Eviction is also successful if too much time has passed since last try
SetMockTime(GetTime() + 4 * 60 *60);
NodeClockContext clock_ctx{};
clock_ctx += 4h;
addrman->ResolveCollisions();
BOOST_CHECK(addrman->SelectTriedCollision().first.ToStringAddrPort() == "[::]:0");
//Now 19 is in tried again, and 36 back to new

View File

@@ -8,16 +8,16 @@
#include <streams.h>
#include <test/util/logging.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/readwritefile.h>
#include <boost/test/unit_test.hpp>
BOOST_FIXTURE_TEST_SUITE(banman_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(file)
{
SetMockTime(777s);
NodeClockContext clock_ctx{777s};
const fs::path banlist_path{m_args.GetDataDirBase() / "banlist_test"};
{
const std::string entries_write{

View File

@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <validation.h>
#include <validationinterface.h>
@@ -30,6 +31,7 @@ BOOST_FIXTURE_TEST_CASE(chainstate_write_interval, TestingSetup)
m_node.validation_signals->RegisterSharedValidationInterface(sub);
auto& chainstate{Assert(m_node.chainman)->ActiveChainstate()};
BlockValidationState state_dummy{};
NodeClockContext clock_ctx{};
// The first periodic flush sets m_next_write and does not flush
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
@@ -37,12 +39,12 @@ BOOST_FIXTURE_TEST_CASE(chainstate_write_interval, TestingSetup)
BOOST_CHECK(!sub->m_did_flush);
// The periodic flush interval is between 50 and 70 minutes (inclusive)
SetMockTime(GetTime<std::chrono::minutes>() + DATABASE_WRITE_INTERVAL_MIN - 1min);
clock_ctx += DATABASE_WRITE_INTERVAL_MIN - 1min;
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
m_node.validation_signals->SyncWithValidationInterfaceQueue();
BOOST_CHECK(!sub->m_did_flush);
SetMockTime(GetTime<std::chrono::minutes>() + DATABASE_WRITE_INTERVAL_MAX);
clock_ctx += DATABASE_WRITE_INTERVAL_MAX;
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
m_node.validation_signals->SyncWithValidationInterfaceQueue();
BOOST_CHECK(sub->m_did_flush);

View File

@@ -16,6 +16,7 @@
#include <test/util/net.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/string.h>
#include <util/time.h>
#include <validation.h>
@@ -90,17 +91,17 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
}
connman.FlushSendBuffer(dummyNode1);
int64_t nStartTime = GetTime();
// Wait 21 minutes
SetMockTime(nStartTime+21*60);
NodeClockContext clock_ctx{};
clock_ctx += 21min;
BOOST_CHECK(peerman.SendMessages(dummyNode1)); // should result in getheaders
{
LOCK(dummyNode1.cs_vSend);
const auto& [to_send, _more, _msg_type] = dummyNode1.m_transport->GetBytesToSend(false);
BOOST_CHECK(!to_send.empty());
}
// Wait 3 more minutes
SetMockTime(nStartTime+24*60);
clock_ctx += 3min;
BOOST_CHECK(peerman.SendMessages(dummyNode1)); // should result in disconnect
BOOST_CHECK(dummyNode1.fDisconnect == true);
@@ -151,9 +152,9 @@ BOOST_FIXTURE_TEST_CASE(stale_tip_peer_management, OutboundTest)
CConnman::Options options;
options.m_max_automatic_connections = DEFAULT_MAX_PEER_CONNECTIONS;
const auto time_init{GetTime<std::chrono::seconds>()};
SetMockTime(time_init);
const auto time_later{time_init + 3 * std::chrono::seconds{m_node.chainman->GetConsensus().nPowTargetSpacing} + 1s};
const auto time_init{Now<NodeSeconds>()};
NodeClockContext clock_ctx{time_init};
const auto delta{3 * std::chrono::seconds{m_node.chainman->GetConsensus().nPowTargetSpacing} + 1s};
connman->Init(options);
std::vector<CNode *> vNodes;
@@ -169,7 +170,7 @@ BOOST_FIXTURE_TEST_CASE(stale_tip_peer_management, OutboundTest)
BOOST_CHECK(node->fDisconnect == false);
}
SetMockTime(time_later);
clock_ctx += delta;
// Now tip should definitely be stale, and we should look for an extra
// outbound peer
@@ -184,9 +185,9 @@ BOOST_FIXTURE_TEST_CASE(stale_tip_peer_management, OutboundTest)
// If we add one more peer, something should get marked for eviction
// on the next check (since we're mocking the time to be in the future, the
// required time connected check should be satisfied).
SetMockTime(time_init);
clock_ctx.set(time_init);
AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY);
SetMockTime(time_later);
clock_ctx += delta;
peerLogic->CheckForStaleTipAndEvictPeers();
for (int i = 0; i < max_outbound_full_relay; ++i) {
@@ -212,9 +213,9 @@ BOOST_FIXTURE_TEST_CASE(stale_tip_peer_management, OutboundTest)
// Add an onion peer, that will be protected because it is the only one for
// its network, so another peer gets disconnected instead.
SetMockTime(time_init);
clock_ctx.set(time_init);
AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY, /*onion_peer=*/true);
SetMockTime(time_later);
clock_ctx += delta;
peerLogic->CheckForStaleTipAndEvictPeers();
for (int i = 0; i < max_outbound_full_relay - 2; ++i) {
@@ -225,9 +226,9 @@ BOOST_FIXTURE_TEST_CASE(stale_tip_peer_management, OutboundTest)
BOOST_CHECK(vNodes[max_outbound_full_relay]->fDisconnect == false);
// Add a second onion peer which won't be protected
SetMockTime(time_init);
clock_ctx.set(time_init);
AddRandomOutboundPeer(id, vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY, /*onion_peer=*/true);
SetMockTime(time_later);
clock_ctx += delta;
peerLogic->CheckForStaleTipAndEvictPeers();
BOOST_CHECK(vNodes.back()->fDisconnect == true);
@@ -246,7 +247,7 @@ BOOST_FIXTURE_TEST_CASE(block_relay_only_eviction, OutboundTest)
auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
constexpr int max_outbound_block_relay{MAX_BLOCK_RELAY_ONLY_CONNECTIONS};
constexpr int64_t MINIMUM_CONNECT_TIME{30};
constexpr auto MINIMUM_CONNECT_TIME{30s};
CConnman::Options options;
options.m_max_automatic_connections = DEFAULT_MAX_PEER_CONNECTIONS;
@@ -273,7 +274,8 @@ BOOST_FIXTURE_TEST_CASE(block_relay_only_eviction, OutboundTest)
}
BOOST_CHECK(vNodes.back()->fDisconnect == false);
SetMockTime(GetTime() + MINIMUM_CONNECT_TIME + 1);
NodeClockContext clock_ctx{};
clock_ctx += MINIMUM_CONNECT_TIME;
peerLogic->CheckForStaleTipAndEvictPeers();
for (int i = 0; i < max_outbound_block_relay; ++i) {
BOOST_CHECK(vNodes[i]->fDisconnect == false);
@@ -411,8 +413,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, *m_node.warnings, {});
banman->ClearBanned();
int64_t nStartTime = GetTime();
SetMockTime(nStartTime); // Overrides future calls to GetTime()
const NodeClockContext clock_ctx{}; // keep mocktime constant
CAddress addr(ip(0xa0b0c001), NODE_NONE);
NodeId id{0};

View File

@@ -4,6 +4,7 @@
#include <common/system.h>
#include <policy/policy.h>
#include <test/util/time.h>
#include <test/util/txmempool.h>
#include <txmempool.h>
#include <util/time.h>
@@ -251,28 +252,29 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
TryAddToMempool(pool, entry.Fee(900LL).FromTx(tx7));
std::vector<CTransactionRef> vtx;
SetMockTime(42);
SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE);
NodeClockContext clock_ctx{42s};
constexpr std::chrono::seconds HALFLIFE{CTxMemPool::ROLLING_FEE_HALFLIFE};
clock_ctx += HALFLIFE;
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE);
// ... we should keep the same min fee until we get a block
pool.removeForBlock(vtx, 1);
SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE);
clock_ctx += HALFLIFE;
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE)/2.0));
// ... then feerate should drop 1/2 each halflife
SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2);
clock_ctx += HALFLIFE / 2;
BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 5 / 2).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE)/4.0));
// ... with a 1/2 halflife when mempool is < 1/2 its target size
SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4);
clock_ctx += HALFLIFE / 4;
BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 9 / 2).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + DEFAULT_INCREMENTAL_RELAY_FEE)/8.0));
// ... with a 1/4 halflife when mempool is < 1/4 its target size
SetMockTime(42 + 7*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4);
clock_ctx += 5 * HALFLIFE;
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), DEFAULT_INCREMENTAL_RELAY_FEE);
// ... but feerate should never drop below DEFAULT_INCREMENTAL_RELAY_FEE
SetMockTime(42 + 8*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4);
clock_ctx += HALFLIFE;
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), 0);
// ... unless it has gone all the way to 0 (after getting past DEFAULT_INCREMENTAL_RELAY_FEE/2)
}

View File

@@ -13,6 +13,7 @@
#include <test/util/common.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <test/util/transaction_utils.h>
#include <array>
@@ -431,9 +432,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
FillableSigningProvider keystore;
BOOST_CHECK(keystore.AddKey(key));
// Freeze time for length of test
auto now{GetTime<std::chrono::seconds>()};
SetMockTime(now);
NodeClockContext clock_ctx{};
std::vector<CTransactionRef> orphans_added;

View File

@@ -5,11 +5,12 @@
#include <common/system.h>
#include <interfaces/mining.h>
#include <node/miner.h>
#include <test/util/common.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <util/time.h>
#include <validation.h>
#include <test/util/setup_common.h>
#include <boost/test/unit_test.hpp>
using interfaces::BlockTemplate;
@@ -39,14 +40,14 @@ BOOST_AUTO_TEST_CASE(MiningInterface)
std::unique_ptr<BlockTemplate> block_template;
// Set node time a few minutes past the testnet4 genesis block
const int64_t genesis_time{WITH_LOCK(cs_main, return m_node.chainman->ActiveChain().Tip()->GetBlockTime())};
SetMockTime(genesis_time + 3 * 60);
const auto template_time{3min + WITH_LOCK(cs_main, return m_node.chainman->ActiveChain().Tip()->Time())};
NodeClockContext clock_ctx{template_time};
block_template = mining->createNewBlock(options, /*cooldown=*/false);
BOOST_REQUIRE(block_template);
// The template should use the mocked system time
BOOST_REQUIRE_EQUAL(block_template->getBlockHeader().nTime, genesis_time + 3 * 60);
BOOST_REQUIRE_EQUAL(block_template->getBlockHeader().Time(), template_time);
const BlockWaitOptions wait_options{.timeout = MillisecondsDouble{0}, .fee_threshold = 1};
@@ -55,20 +56,14 @@ BOOST_AUTO_TEST_CASE(MiningInterface)
BOOST_REQUIRE(should_be_nullptr == nullptr);
// This remains the case when exactly 20 minutes have gone by
{
LOCK(cs_main);
SetMockTime(m_node.chainman->ActiveChain().Tip()->GetBlockTime() + 20 * 60);
}
clock_ctx += 17min;
should_be_nullptr = block_template->waitNext(wait_options);
BOOST_REQUIRE(should_be_nullptr == nullptr);
// One second later the difficulty drops and it returns a new template
// Note that we can't test the actual difficulty change, because the
// difficulty is already at 1.
{
LOCK(cs_main);
SetMockTime(m_node.chainman->ActiveChain().Tip()->GetBlockTime() + 20 * 60 + 1);
}
clock_ctx += 1s;
block_template = block_template->waitNext(wait_options);
BOOST_REQUIRE(block_template);
}

View File

@@ -12,6 +12,7 @@
#include <test/util/common.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <uint256.h>
#include <util/bitdeque.h>
#include <util/byte_units.h>
@@ -585,7 +586,7 @@ BOOST_AUTO_TEST_CASE(strprintf_numbers)
BOOST_AUTO_TEST_CASE(util_mocktime)
{
SetMockTime(111s);
NodeClockContext clock_ctx{111s};
// Check that mock time does not change after a sleep
for (const auto& num_sleep : {0ms, 1ms}) {
UninterruptibleSleep(num_sleep);
@@ -598,7 +599,6 @@ BOOST_AUTO_TEST_CASE(util_mocktime)
BOOST_CHECK_EQUAL(111000, TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()));
BOOST_CHECK_EQUAL(111000000, GetTime<std::chrono::microseconds>().count());
}
SetMockTime(0s);
}
BOOST_AUTO_TEST_CASE(util_ticksseconds)