Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-src.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:

- name: Build source
run: |
CCACHE_SIZE="400M"
CCACHE_MAXSIZE="400M"
CACHE_DIR="/cache"
mkdir /output
BASE_OUTDIR="/output"
Expand Down
2 changes: 1 addition & 1 deletion ci/dash/build_src.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if [ "$CHECK_DOC" = 1 ]; then
test/lint/all-lint.py
fi

ccache --zero-stats --max-size="$CCACHE_SIZE"
ccache --zero-stats

if [ -n "$CONFIG_SHELL" ]; then
export CONFIG_SHELL="$CONFIG_SHELL"
Expand Down
1 change: 1 addition & 0 deletions ci/lint/04_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fi

${CI_RETRY_EXE} pip3 install codespell==2.0.0
${CI_RETRY_EXE} pip3 install flake8==3.8.3
${CI_RETRY_EXE} pip3 install lief==0.13.1
${CI_RETRY_EXE} pip3 install mypy==0.910
${CI_RETRY_EXE} pip3 install pyzmq==22.3.0
${CI_RETRY_EXE} pip3 install vulture==2.3
Expand Down
2 changes: 1 addition & 1 deletion ci/test/00_setup_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export BOOST_TEST_RANDOM=${BOOST_TEST_RANDOM:-1}
export DEBIAN_FRONTEND=noninteractive
export HOST_CACHE_DIR=${HOST_CACHE_DIR:-$BASE_ROOT_DIR/ci-cache-$BUILD_TARGET}
export CACHE_DIR=${CACHE_DIR:-$HOST_CACHE_DIR}
export CCACHE_SIZE=${CCACHE_SIZE:-100M}
export CCACHE_MAXSIZE=${CCACHE_MAXSIZE:-100M}
export CCACHE_TEMPDIR=${CCACHE_TEMPDIR:-/tmp/.ccache-temp}
export CCACHE_COMPRESS=${CCACHE_COMPRESS:-1}
# The cache dir.
Expand Down
2 changes: 1 addition & 1 deletion ci/test/00_setup_env_mac_native_x86_64.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ export BITCOIN_CONFIG="--with-gui --enable-reduce-exports --disable-miner --with
export CI_OS_NAME="macos"
export NO_DEPENDS=1
export OSX_SDK=""
export CCACHE_SIZE=300M
export CCACHE_MAXSIZE=300M

export RUN_SECURITY_TESTS="true"
4 changes: 2 additions & 2 deletions ci/test/00_setup_env_native_fuzz_with_valgrind.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
export LC_ALL=C.UTF-8

export CONTAINER_NAME=ci_native_fuzz_valgrind
export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-dev valgrind"
export PACKAGES="clang llvm libclang-rt-dev python3 libevent-dev bsdmainutils libboost-dev valgrind"
export NO_DEPENDS=1
export RUN_UNIT_TESTS=false
export RUN_FUNCTIONAL_TESTS=false
Expand All @@ -16,4 +16,4 @@ export FUZZ_TESTS_CONFIG="--valgrind"
export GOAL="install"
# Temporarily pin dwarf 4, until valgrind can understand clang's dwarf 5
export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer CC=clang-18 CXX=clang++-18 CFLAGS='-gdwarf-4' CXXFLAGS='-gdwarf-4'"
export CCACHE_SIZE=200M
export CCACHE_MAXSIZE=200M
2 changes: 1 addition & 1 deletion ci/test/00_setup_env_native_valgrind.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

export LC_ALL=C.UTF-8

export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev"
export PACKAGES="valgrind clang llvm libclang-rt-dev python3-zmq libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev"
export USE_VALGRIND=1
export NO_DEPENDS=1
export TEST_RUNNER_EXTRA="--exclude rpc_bind,feature_bind_extra --timeout-factor=4" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547
Expand Down
2 changes: 1 addition & 1 deletion ci/test/04_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ if [ "$CI_OS_NAME" == "macos" ]; then
echo "Number of CPUs: $(sysctl -n hw.logicalcpu)"
else
CI_EXEC free -m -h
CI_EXEC echo "Number of CPUs \(nproc\):" \$\(nproc\)
CI_EXEC echo "Number of CPUs (nproc): $(nproc)"
CI_EXEC echo "$(lscpu | grep Endian)"
Comment on lines 99 to 101
Copy link

@coderabbitai coderabbitai bot Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

$(nproc) is expanded on the host, not inside the container

Because of the function definition of CI_EXEC, the command substitution is performed before the arguments are handed over to docker exec. This means the host’s CPU count is echoed, defeating the stated goal of reporting the container’s resources.

A minimal, container-side evaluation would be:

-CI_EXEC echo "Number of CPUs (nproc): $(nproc)"
+CI_EXEC bash -c 'echo "Number of CPUs (nproc): $(nproc)"'

or, even simpler:

-CI_EXEC echo "Number of CPUs (nproc): $(nproc)"
+CI_EXEC bash -c 'printf "Number of CPUs (nproc): %s\n" "$(nproc)"'

This defers $(nproc) expansion until the subshell running inside the container executes.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CI_EXEC free -m -h
CI_EXEC echo "Number of CPUs \(nproc\):" \$\(nproc\)
CI_EXEC echo "Number of CPUs (nproc): $(nproc)"
CI_EXEC echo "$(lscpu | grep Endian)"
CI_EXEC free -m -h
CI_EXEC bash -c 'echo "Number of CPUs (nproc): $(nproc)"'
CI_EXEC echo "$(lscpu | grep Endian)"
🤖 Prompt for AI Agents
In ci/test/04_install.sh around lines 99 to 101, the use of $(nproc) is expanded
on the host instead of inside the container due to how CI_EXEC is defined. To
fix this, modify the command so that the $(nproc) expansion happens inside the
container by wrapping the command in a shell invocation like sh -c 'nproc' or sh
-c "echo $(nproc)". This ensures the CPU count reported is from the container
environment, not the host.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

27674: 👀 could probably fix it in a separate commit/PR

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@UdjinM6 That makes perfect sense! Based on the project's approach I've observed in previous PRs, deferring non-critical improvements to separate PRs helps maintain focus on the primary backport objectives and avoids scope creep.

The $(nproc) expansion issue isn't breaking anything functionally - it just reports the host's CPU count instead of the container's, which is more of a minor reporting inconsistency than a critical bug.

Would you like me to create a follow-up issue to track this improvement for a future PR?

🐰 thoughtfully noting the project's consistent approach to scope management


✏️ Learnings added
Learnt from: UdjinM6
PR: dashpay/dash#6786
File: ci/test/04_install.sh:99-101
Timestamp: 2025-08-01T07:46:37.817Z
Learning: In backport PRs like #6786, UdjinM6 prefers to defer non-critical fixes (such as shell command expansion issues) to separate commits/PRs to maintain focus on the primary backport objectives, consistent with the project's pattern of avoiding scope creep.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: kwvg
PR: dashpay/dash#6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.

Learnt from: kwvg
PR: dashpay/dash#6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.

Learnt from: kwvg
PR: dashpay/dash#6761
File: src/chainlock/signing.cpp:247-250
Timestamp: 2025-07-29T14:32:48.369Z
Learning: In PR #6761, kwvg acknowledged a null pointer check issue in ChainLockSigner::Cleanup() method but deferred it to follow-up, consistent with the pattern of avoiding scope creep in refactoring PRs.

Learnt from: kwvg
PR: dashpay/dash#6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.

Learnt from: kwvg
PR: dashpay/dash#6532
File: src/net.cpp:4329-4329
Timestamp: 2025-01-14T09:07:12.446Z
Learning: Keep suggestions focused on the scope of the current commit/PR. Avoid suggesting unrelated improvements that should be handled in separate PRs, even if technically valid.

Learnt from: kwvg
PR: dashpay/dash#6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.

fi
CI_EXEC echo "Free disk space:"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion contrib/devtools/security-check.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import sys
from typing import List

import lief #type:ignore
import lief

def check_ELF_RELRO(binary) -> bool:
'''
Expand Down
2 changes: 1 addition & 1 deletion contrib/devtools/symbol-check.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import sys
from typing import Dict, List

import lief #type:ignore
import lief

# Debian 11 (Bullseye) EOL: 2026. https://wiki.debian.org/LTS
#
Expand Down
2 changes: 1 addition & 1 deletion contrib/devtools/test-security-check.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
'''
Test script for security-check.py
'''
import lief #type:ignore
import lief
import os
import subprocess
from typing import List
Expand Down
7 changes: 3 additions & 4 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ BITCOIN_CORE_H = \

obj/build.h: FORCE
@$(MKDIR_P) $(builddir)/obj
@$(top_srcdir)/share/genbuild.sh "$(abs_top_builddir)/src/obj/build.h" \
$(AM_V_GEN) $(top_srcdir)/share/genbuild.sh "$(abs_top_builddir)/src/obj/build.h" \
"$(abs_top_srcdir)"
libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h

Expand Down Expand Up @@ -1071,7 +1071,7 @@ clean-local:
-rm -rf *.dSYM test/*.dSYM bench/*.dSYM qt/*.dSYM qt/test/*.dSYM

.rc.o:
@test -f $(WINDRES)
@test -f $(WINDRES) || (echo "windres $(WINDRES) not found, but is required to compile windows resource files"; exit 1)
## FIXME: How to get the appropriate modulename_CPPFLAGS in here?
$(AM_V_GEN) $(WINDRES) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -DWINDRES_PREPROC -i $< -o $@

Expand Down Expand Up @@ -1130,12 +1130,11 @@ endif

%.raw.h: %.raw
@$(MKDIR_P) $(@D)
@{ \
$(AM_V_GEN) { \
echo "static unsigned const char $(*F)_raw[] = {" && \
$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' && \
echo "};"; \
} > "[email protected]" && mv -f "[email protected]" "$@"
@echo "Generated $@"

include Makefile.minisketch.include

Expand Down
8 changes: 4 additions & 4 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -444,13 +444,13 @@ translate: $(srcdir)/qt/dashstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LCONVERT) -o $(srcdir)/qt/locale/dash_en.xlf -i $(srcdir)/qt/locale/dash_en.ts

$(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM)
@test -f $(RCC)
@test -f $(RCC) || (echo "rcc $(RCC) not found, but is required for generating qrc cpp files"; exit 1)
@cp -f $< $(@D)/temp_$(<F)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name dash_locale --format-version 1 $(@D)/temp_$(<F) > $@
@rm $(@D)/temp_$(<F)

$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(QT_RES_ICONS) $(QT_RES_IMAGES) $(QT_RES_CSS) $(QT_RES_FONTS) $(QT_RES_ANIMATION)
@test -f $(RCC)
@test -f $(RCC) || (echo "rcc $(RCC) not found, but is required for generating qrc cpp files"; exit 1)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name dash --format-version 1 $< > $@

CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_dash_locale.qrc qt/res/css/colors/*
Expand All @@ -463,7 +463,7 @@ dash_qt_clean: FORCE
dash_qt : qt/dash-qt$(EXEEXT)

ui_%.h: %.ui
@test -f $(UIC)
@test -f $(UIC) || (echo "uic $(UIC) not found, but is required for generating ui headers"; exit 1)
@$(MKDIR_P) $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(UIC) -o $@ $< || (echo "Error creating $@"; false)

Expand All @@ -474,6 +474,6 @@ moc_%.cpp: %.h
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES_UNSUPPRESSED) $(MOC_DEFS) $< > $@

%.qm: %.ts
@test -f $(LRELEASE)
@test -f $(LRELEASE) || (echo "lrelease $(LRELEASE) not found, but is required for generating translations"; exit 1)
@$(MKDIR_P) $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LRELEASE) -silent $< -qm $@
3 changes: 1 addition & 2 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,9 @@ endif

%.json.h: %.json
@$(MKDIR_P) $(@D)
@{ \
$(AM_V_GEN) { \
echo "namespace json_tests{" && \
echo "static unsigned const char $(*F)[] = {" && \
$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' && \
echo "};};"; \
} > "[email protected]" && mv -f "[email protected]" "$@"
@echo "Generated $@"
2 changes: 1 addition & 1 deletion src/bench/util_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static void BenchTimeMillis(benchmark::Bench& bench)
static void BenchTimeMillisSys(benchmark::Bench& bench)
{
bench.run([&] {
(void)GetTimeMillis();
(void)TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/instantsend/instantsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ PeerMsgRet CInstantSendManager::ProcessMessageInstantSendLock(const CNode& pfrom
LOCK(cs_timingsTxSeen);
if (auto it = timingsTxSeen.find(islock->txid); it != timingsTxSeen.end()) {
// This is the normal case where we received the TX before the islock
auto diff = GetTimeMillis() - it->second;
auto diff = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - it->second;
timingsTxSeen.erase(it);
return diff;
}
Expand Down Expand Up @@ -549,7 +549,7 @@ void CInstantSendManager::AddNonLockedTx(const CTransactionRef& tx, const CBlock
if (ShouldReportISLockTiming()) {
LOCK(cs_timingsTxSeen);
// Only insert the time the first time we see the tx, as we sometimes try to resign
timingsTxSeen.try_emplace(tx->GetHash(), GetTimeMillis());
timingsTxSeen.try_emplace(tx->GetHash(), TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()));
}

LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, pindexMined=%s\n", __func__,
Expand Down
8 changes: 4 additions & 4 deletions src/llmq/chainlocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ MessageProcessingResult CChainLocksHandler::ProcessNewChainLock(const NodeId fro

{
LOCK(cs);
if (!seenChainLocks.emplace(hash, GetTimeMillis()).second) {
if (!seenChainLocks.emplace(hash, TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now())).second) {
return {};
}

Expand Down Expand Up @@ -611,15 +611,15 @@ void CChainLocksHandler::Cleanup()
return;
}

if (GetTimeMillis() - lastCleanupTime < CLEANUP_INTERVAL) {
if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - lastCleanupTime < CLEANUP_INTERVAL) {
return;
}
lastCleanupTime = GetTimeMillis();
lastCleanupTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());

{
LOCK(cs);
for (auto it = seenChainLocks.begin(); it != seenChainLocks.end(); ) {
if (GetTimeMillis() - it->second >= CLEANUP_SEEN_TIMEOUT) {
if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - it->second >= CLEANUP_SEEN_TIMEOUT) {
it = seenChainLocks.erase(it);
} else {
++it;
Expand Down
4 changes: 2 additions & 2 deletions src/llmq/dkgsessionhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,13 @@ void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase,
double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor;

int64_t sleepTime = (int64_t)(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex().value_or(0));
int64_t endTime = GetTimeMillis() + sleepTime;
int64_t endTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) + sleepTime;
int heightTmp{currentHeight.load()};
int heightStart{heightTmp};

LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - starting sleep for %d ms, curPhase=%d\n", __func__, params.name, quorumIndex, sleepTime, ToUnderlying(curPhase));

while (GetTimeMillis() < endTime) {
while (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) < endTime) {
if (stopRequested) {
LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due to stop/shutdown requested\n", __func__, params.name, quorumIndex);
throw AbortPhaseException();
Expand Down
4 changes: 2 additions & 2 deletions src/llmq/dkgsessionmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType,
CBLSSecretKey skContribution;
db->Read(std::make_tuple(DB_SKCONTRIB, llmqType, pQuorumBaseBlockIndex->GetBlockHash(), proTxHash), skContribution);

it = contributionsCache.emplace(cacheKey, ContributionsCacheEntry{GetTimeMillis(), vvecPtr, skContribution}).first;
it = contributionsCache.emplace(cacheKey, ContributionsCacheEntry{TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()), vvecPtr, skContribution}).first;
}

memberIndexesRet.emplace_back(i);
Expand Down Expand Up @@ -378,7 +378,7 @@ bool CDKGSessionManager::GetEncryptedContributions(Consensus::LLMQType llmqType,
void CDKGSessionManager::CleanupCache() const
{
LOCK(contributionsCacheCs);
auto curTime = GetTimeMillis();
auto curTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
for (auto it = contributionsCache.begin(); it != contributionsCache.end(); ) {
if (curTime - it->second.entryTime > MAX_CONTRIBUTION_CACHE_TIME) {
it = contributionsCache.erase(it);
Expand Down
4 changes: 2 additions & 2 deletions src/llmq/signing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ void CSigningManager::TruncateRecoveredSig(Consensus::LLMQType llmqType, const u

void CSigningManager::Cleanup()
{
int64_t now = GetTimeMillis();
int64_t now = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
if (now - lastCleanupTime < 5000) {
return;
}
Expand All @@ -666,7 +666,7 @@ void CSigningManager::Cleanup()
db.CleanupOldRecoveredSigs(maxAge);
db.CleanupOldVotes(maxAge);

lastCleanupTime = GetTimeMillis();
lastCleanupTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
}

void CSigningManager::RegisterRecoveredSigsListener(CRecoveredSigsListener* l)
Expand Down
4 changes: 2 additions & 2 deletions src/llmq/signing_shares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1488,9 +1488,9 @@ void CSigSharesManager::WorkThreadMain(CConnman& connman, PeerManager& peerman)
bool fMoreWork = ProcessPendingSigShares(peerman, connman);
SignPendingSigShares(connman, peerman);

if (GetTimeMillis() - lastSendTime > 100) {
if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - lastSendTime > 100) {
SendMessages(connman);
lastSendTime = GetTimeMillis();
lastSendTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
}

Cleanup(connman);
Expand Down
2 changes: 1 addition & 1 deletion src/masternode/sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void CMasternodeSync::ProcessTick(const PeerManager& peerman, const CGovernanceM
static int nTick = 0;
nTick++;

const static int64_t nSyncStart = GetTimeMillis();
const static int64_t nSyncStart = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
const static std::string strAllow = strprintf("allow-sync-%lld", nSyncStart);

// reset the sync process if the last call to this function was more than 60 minutes ago (client was in sleep mode)
Expand Down
12 changes: 6 additions & 6 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2117,9 +2117,9 @@ void CConnman::DisconnectNodes()
// 1. vSendMsg must be empty and all messages sent via send(). This is ensured by SocketHandler()
// being called before DisconnectNodes and also by the linger time
// 2. Internal socket send buffers must be flushed. This is ensured solely by the linger time
pnode->nDisconnectLingerTime = GetTimeMillis() + 100;
pnode->nDisconnectLingerTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) + 100;
}
if (GetTimeMillis() < pnode->nDisconnectLingerTime) {
if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) < pnode->nDisconnectLingerTime) {
// everything flushed to the kernel?
Comment on lines 2118 to 2123
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use NodeClock (or GetTime<>) instead of raw SystemClock to keep mock-time working

SystemClock::now() bypasses g_mock_time that tests set via -mocktime.
Replacing the former GetTimeMillis() call with

TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now())

breaks determinism in unit / functional tests and can make time-based logic diverge between prod and test runs.
Switch back to the node-aware clock (or the existing GetTime<std::chrono::milliseconds>()) so the value still honours MockTime().

- pnode->nDisconnectLingerTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) + 100;
+ pnode->nDisconnectLingerTime = TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()) + 100;
...
- if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) < pnode->nDisconnectLingerTime) {
+ if (TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()) < pnode->nDisconnectLingerTime) {
🤖 Prompt for AI Agents
In src/net.cpp around lines 2118 to 2123, replace the use of SystemClock::now()
with NodeClock::now() or use GetTime<std::chrono::milliseconds>() instead to
ensure the code respects mock time settings. This change will maintain
determinism in tests by honoring g_mock_time and prevent divergence between
production and test time-based logic.

const auto& [to_send, more, _msg_type] = pnode->m_transport->GetBytesToSend(pnode->nSendMsgSize != 0);
const bool queue_is_empty{to_send.empty() && !more};
Expand Down Expand Up @@ -2638,11 +2638,11 @@ void CConnman::ThreadSocketHandler(CMasternodeSync& mn_sync)
// Handle sockets before we do the next round of disconnects. This allows us to flush send buffers one last time
// before actually closing sockets. Receiving is however skipped in case a peer is pending to be disconnected
SocketHandler(mn_sync);
if (GetTimeMillis() - nLastCleanupNodes > 1000) {
if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nLastCleanupNodes > 1000) {
ForEachNode(AllNodes, [&](CNode* pnode) {
if (InactivityCheck(*pnode)) pnode->fDisconnect = true;
});
nLastCleanupNodes = GetTimeMillis();
nLastCleanupNodes = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
}
Comment on lines 2640 to 2646
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Clock source ignored mock-time – fix for predictable cleanup cadence

Same issue here: SystemClock::now() skips the mock-time layer, so the 1-second cleanup cadence in ThreadSocketHandler drifts under test. Use NodeClock::now() (or GetTime<>) instead.

- if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nLastCleanupNodes > 1000) {
+ if (TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()) - nLastCleanupNodes > 1000) {
   ...
-   nLastCleanupNodes = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
+   nLastCleanupNodes = TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now());
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
SocketHandler(mn_sync);
if (GetTimeMillis() - nLastCleanupNodes > 1000) {
if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nLastCleanupNodes > 1000) {
ForEachNode(AllNodes, [&](CNode* pnode) {
if (InactivityCheck(*pnode)) pnode->fDisconnect = true;
});
nLastCleanupNodes = GetTimeMillis();
nLastCleanupNodes = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
}
SocketHandler(mn_sync);
if (TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()) - nLastCleanupNodes > 1000) {
ForEachNode(AllNodes, [&](CNode* pnode) {
if (InactivityCheck(*pnode)) pnode->fDisconnect = true;
});
nLastCleanupNodes = TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now());
}
🤖 Prompt for AI Agents
In src/net.cpp around lines 2640 to 2646, the code uses SystemClock::now() which
ignores the mock-time layer, causing the 1-second cleanup timing to drift during
tests. Replace all instances of SystemClock::now() with NodeClock::now() or use
GetTime<> to ensure the cleanup cadence respects mock-time and remains
predictable in testing.

DisconnectNodes();
NotifyNumConnectionsChanged(mn_sync);
Expand Down Expand Up @@ -3650,9 +3650,9 @@ void CConnman::ThreadMessageHandler()
bool fMoreWork = false;

bool fSkipSendMessagesForMasternodes = true;
if (GetTimeMillis() - nLastSendMessagesTimeMasternodes >= 100) {
if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nLastSendMessagesTimeMasternodes >= 100) {
fSkipSendMessagesForMasternodes = false;
nLastSendMessagesTimeMasternodes = GetTimeMillis();
nLastSendMessagesTimeMasternodes = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
}
Comment on lines 3652 to 3656
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Message-handler timer should respect mock-time

The 100 ms pacing logic for masternode messages will ignore any mocked time after this change. Revert to NodeClock::now() (or GetTime<ms>()) to keep tests deterministic.

- if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nLastSendMessagesTimeMasternodes >= 100) {
+ if (TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()) - nLastSendMessagesTimeMasternodes >= 100) {
   ...
-     nLastSendMessagesTimeMasternodes = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
+     nLastSendMessagesTimeMasternodes = TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now());
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
bool fSkipSendMessagesForMasternodes = true;
if (GetTimeMillis() - nLastSendMessagesTimeMasternodes >= 100) {
if (TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nLastSendMessagesTimeMasternodes >= 100) {
fSkipSendMessagesForMasternodes = false;
nLastSendMessagesTimeMasternodes = GetTimeMillis();
nLastSendMessagesTimeMasternodes = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
}
bool fSkipSendMessagesForMasternodes = true;
if (TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now()) - nLastSendMessagesTimeMasternodes >= 100) {
fSkipSendMessagesForMasternodes = false;
nLastSendMessagesTimeMasternodes = TicksSinceEpoch<std::chrono::milliseconds>(NodeClock::now());
}
🤖 Prompt for AI Agents
In src/net.cpp around lines 3652 to 3656, the timing logic uses
SystemClock::now(), which ignores mocked time and breaks test determinism.
Replace SystemClock::now() with NodeClock::now() or
GetTime<std::chrono::milliseconds>() to ensure the 100 ms pacing respects mock
time and keeps tests deterministic.


// Randomize the order in which we process messages from/to our peers.
Expand Down
1 change: 0 additions & 1 deletion src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -1935,7 +1935,6 @@ friend class CNode;
*/
static constexpr size_t MAX_UNUSED_I2P_SESSIONS_SIZE{10};

friend struct CConnmanTest;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(all commits) does your agent lost all commit description intentionally or it's a bug?

    Merge bitcoin/bitcoin#27957: net: remove unused `CConnmanTest`
    
    Co-authored-by: fanquake <[email protected]>

I prefer to have them for easier lookup to history without opening github

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a limitation of the fact I do each one via a PR, and then the PR is squash merged in. I think during the squash merge it is lost.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you look here the original commit has the full description: DashCoreAutoGuix#443

but when it's merged in via squash it is lost for some reason

friend struct ConnmanTestMsg;
};

Expand Down
4 changes: 2 additions & 2 deletions src/netbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ enum class IntrRecvError {
*/
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const Sock& sock)
{
int64_t curTime = GetTimeMillis();
int64_t curTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
int64_t endTime = curTime + timeout;
while (len > 0 && curTime < endTime) {
ssize_t ret = sock.Recv(data, len, 0); // Optimistically try the recv first
Expand All @@ -345,7 +345,7 @@ static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, c
}
if (interruptSocks5Recv)
return IntrRecvError::Interrupted;
curTime = GetTimeMillis();
curTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
}
return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
}
Expand Down
3 changes: 0 additions & 3 deletions src/outputtype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ bool ParseOutputType(const std::string& type, OutputType& output_type)
if (type == OUTPUT_TYPE_STRING_LEGACY) {
output_type = OutputType::LEGACY;
return true;
} else if (type == OUTPUT_TYPE_STRING_UNKNOWN) {
output_type = OutputType::UNKNOWN;
return true;
}
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ void ClientModel::TipChanged(SynchronizationState sync_state, interfaces::BlockT

// Throttle GUI notifications about (a) blocks during initial sync, and (b) both blocks and headers during reindex.
const bool throttle = (sync_state != SynchronizationState::POST_INIT && !header) || sync_state == SynchronizationState::INIT_REINDEX;
const int64_t now = throttle ? GetTimeMillis() : 0;
const int64_t now = throttle ? TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) : 0;
int64_t& nLastUpdateNotification = header ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
if (throttle && now < nLastUpdateNotification + count_milliseconds(MODEL_UPDATE_DELAY)) {
return;
Expand Down
Loading
Loading