From ed6120eef953d94b975f0e81a92c063901259a50 Mon Sep 17 00:00:00 2001 From: DanS Date: Mon, 22 Jun 2026 13:41:36 -0500 Subject: [PATCH] feat(fullnode): parse the new multi-threaded daemon's witness-rebuild progress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The updated dragonxd (parallel witness rebuild) replaced the per-block "Building Witnesses for block complete, remaining" log line with a clean serial read counter "Reading blocks for witness rebuild: / ". Parse the new line and map it onto the existing phase-2 path (remaining = total - done), so the witness progress bar shows done/total against this daemon. The old "Building Witnesses" matcher is kept for backward compatibility with older daemons; "Setting Initial Sapling Witness for tx … i of N" (phase 1) is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/app.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/app.cpp b/src/app.cpp index 884208e..3bd24d3 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -844,6 +844,35 @@ void App::update() lastStatus = line; } + // Newer multi-threaded daemon: "Reading blocks for witness rebuild: / ". + // This replaced the per-block "Building Witnesses" line. It's a clean done/total + // count, so map it onto the same phase-2 "remaining" signal (remaining = total - + // done) and the existing cache-walk logic yields progress = done/total. + auto rdIdx = line.find("Reading blocks for witness rebuild:"); + if (rdIdx != std::string::npos) { + foundWitness = true; + auto slash = line.find('/', rdIdx); + if (slash != std::string::npos) { + size_t dEnd = slash; + while (dEnd > rdIdx && !std::isdigit((unsigned char)line[dEnd - 1])) dEnd--; + size_t dStart = dEnd; + while (dStart > rdIdx && std::isdigit((unsigned char)line[dStart - 1])) dStart--; + size_t tStart = slash + 1; + while (tStart < line.size() && !std::isdigit((unsigned char)line[tStart])) tStart++; + size_t tEnd = tStart; + while (tEnd < line.size() && std::isdigit((unsigned char)line[tEnd])) tEnd++; + if (dStart < dEnd && tStart < tEnd) { + try { + long done = std::stol(line.substr(dStart, dEnd - dStart)); + long total = std::stol(line.substr(tStart, tEnd - tStart)); + if (total > 0 && done >= 0 && done <= total) + witnessRemaining = static_cast(total - done); + } catch (...) {} + } + } + lastStatus = line; + } + // Primary signal: "Setting Initial Sapling Witness for tx , of ". // is the tx's slot in an unordered map (bounces — useless as progress), so // we key on (one per tx) and count distinct txs against . Extract the