Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
387 commits
Select commit Hold shift + click to select a range
1e4f69b
docs(senior-engineer): add definition and guidelines for senior engin…
On1x May 2, 2026
13082f8
Add direct-extension bypass in _push_block() in database.cpp
On1x May 2, 2026
50b2230
After the fork_db push, if new_block.previous == head_block_id(), we …
On1x May 2, 2026
83cff9a
update docs
On1x May 2, 2026
5466355
Override sync_mode for contiguous near-caught-up blocks, Lightweight …
On1x May 2, 2026
28df463
update fc submodule
On1x May 2, 2026
4856522
Extended the DLT near-caught-up optimization from gap == 0 to gap >= …
On1x May 2, 2026
8e0dacd
wraps `db.with_weak_read_lock()` in its own `try/catch` block so that…
On1x May 2, 2026
d78c334
fix deadlock in witness plugin (guard that not produce blocks in sync…
On1x May 3, 2026
fa92fde
Skip DLT minority fork detection on emergency master in witness.cpp
On1x May 3, 2026
a4ec5b0
fix(p2p): prevent DLT sync fetch stall when outbound handler wipes qu…
On1x May 3, 2026
661e56e
fix build
On1x May 3, 2026
3429d23
fix(sync): add progressive backoff for deferred resize sync restarts
On1x May 3, 2026
c52ba56
fix(sync): prevent sync oscillation in DLT emergency mode
On1x May 3, 2026
6b2d8a7
fix(chain): add check for null signing key before blanking on missed …
On1x May 3, 2026
0081b10
refactor(snapshot): improve peer selection and download retry logic
On1x May 3, 2026
6d93a15
fix(snapshot): refresh snapshot metadata from Phase 2 response
On1x May 3, 2026
9a1d6a2
fix(network): improve block fetching and synchronization logic
On1x May 3, 2026
bb57639
fix(p2p): prevent sync oscillation and improve concurrent ID/block fe…
On1x May 3, 2026
b1cb639
fix(witness): include transaction count in generated block log
On1x May 3, 2026
c949f63
fix(network): improve block handling to identify originating peer end…
On1x May 3, 2026
7c8e33e
fix(network): correct sync flag in peer connection initialization
On1x May 3, 2026
a202bcf
docs(emergency): add comprehensive emergency consensus workflow docum…
On1x May 3, 2026
1f918f4
update fc
On1x May 3, 2026
444a42b
Fix P2P synopsis flood during DLT sync block bursts (dual-sided anti-…
On1x May 3, 2026
1949a6c
new catch in import snapshot workflow, reason to wipe db
On1x May 3, 2026
faa5e5c
fix: add soft-ban for fetch_item_ids rate-limit spam and synopsis sen…
On1x May 3, 2026
f659079
A new DLT-mode check in the get_block_ids() handler that detects when…
On1x May 3, 2026
bf8cf4d
update agent
On1x May 3, 2026
fe48089
add: docs about p2p messages
On1x May 3, 2026
5940f61
feat(p2p): add chain status announcement message for DLT and emergenc…
On1x May 3, 2026
ad9e8d9
feat(p2p): add chain_status_announcement_message for live chain state…
On1x May 3, 2026
7cc52d6
fix crash is a boost::bad_lexical_cast exception in custom_protocol_a…
On1x May 4, 2026
af21e3b
Fix: Changed core_message_type_last from 5018 → 5019 at core_messages…
On1x May 4, 2026
13d7584
Fix: Added declarations and implementations in node.cpp
On1x May 4, 2026
e0fa806
fix: out_of_range in default config write and lock_exception recovery…
On1x May 4, 2026
f523679
fix: crash-reboot loop after hard crash + emergency LIB stall
On1x May 4, 2026
6f4a9b3
refactor(chain): simplify account retrieval in evaluators
On1x May 4, 2026
c85de41
remove unused read_message
On1x May 4, 2026
6724383
Fix FC_CAPTURE_LOG_AND_RETHROW() called with empty args — the macro's…
On1x May 4, 2026
17503d8
fix(witness): bypass DLT sync guard in emergency consensus mode
On1x May 4, 2026
c45c711
Add emergency master check to stalled sync recovery
On1x May 4, 2026
2308bb2
update agent
On1x May 4, 2026
ed17cb8
Fix sync state corruption when competing-fork blocks fail to apply
On1x May 4, 2026
fcac099
update agent
On1x May 4, 2026
d8f4209
Prevent emergency master crash loop by silently skipping sync blocks …
On1x May 4, 2026
2bac2fe
Removed !_fork_db.is_known_block(new_block.previous) from the conditi…
On1x May 4, 2026
60da693
update git ignore
On1x May 4, 2026
32b6470
fix is_included_block — use find_block_id_for_num (non-asserting)
On1x May 4, 2026
d7daa7b
Guard synopsis exchange with accepted flag
On1x May 4, 2026
e21e2bf
Merge branch 'master' into fix-witness
On1x May 4, 2026
a1c57ab
move accepted declaration to function scope, and change the assignmen…
On1x May 4, 2026
9d7920c
Merge branch 'fix-witness' of https://github.com/VIZ-Blockchain/viz-c…
On1x May 4, 2026
9350d06
When emergency consensus is active, slave nodes with their own witnes…
On1x May 4, 2026
88f2ffc
update agent
On1x May 4, 2026
8ccb17b
The advertise_inventory_loop in node.cpp had a blanket gate that supp…
On1x May 4, 2026
5e0fd31
update block broadcast logs
On1x May 4, 2026
c2006f8
more logs about processing blocks
On1x May 4, 2026
632c3be
Block inventory bypasses the return — the block itself will advance t…
On1x May 4, 2026
e98fd3c
update chainbase submodule
On1x May 4, 2026
a0d8cd2
fix chainbase submodule
On1x May 4, 2026
7dd763a
fix chainbase
On1x May 4, 2026
032cb03
Fix emergency minority fork recovery deadlock for slave DLT nodes
On1x May 4, 2026
05d483e
update chainbase submodule
On1x May 4, 2026
a2d2767
fix chainbase submodule
On1x May 4, 2026
1c5eedc
add new dlt p2p network redesign
On1x May 4, 2026
8b96d6d
new dlt p2p network review
On1x May 4, 2026
9744da9
apply all fixes from dlt p2p review
On1x May 4, 2026
2683671
fix build
On1x May 4, 2026
18b44c5
fix build
On1x May 4, 2026
fe71a32
fix build
On1x May 4, 2026
d0f1f32
fix build errors
On1x May 4, 2026
5a666ed
fix building errors
On1x May 4, 2026
5586f70
remove attr duplication
On1x May 4, 2026
bf9f5da
fix logs
On1x May 4, 2026
12c3717
feat(p2p): add soft-ban message handling and peer stats logging
On1x May 4, 2026
3e0bbf8
feat(network): add soft-ban notification and peer stats logging
On1x May 4, 2026
95d56da
refactor(network): enhance block acceptance handling in p2p node
On1x May 4, 2026
b00ea7d
fix ensures on_block_applied() is only called when the block is genui…
On1x May 5, 2026
6be10c5
fix build, missing headers
On1x May 5, 2026
453f537
refactor(network): enhance fork alignment logic in DLT peer handshake
On1x May 5, 2026
3c42c07
fix(network): avoid requesting pruned blocks from peers in block rang…
On1x May 5, 2026
10594e8
fix(dlt): detect and handle corrupted DLT block logs and dead-fork peers
On1x May 5, 2026
417bed1
update docs
On1x May 5, 2026
9a35dca
Fix 6 unresolved DLT P2P runtime issues. P23: Replace FC_ASSERT in fe…
On1x May 5, 2026
27d2c46
Add 5 min peer stats
On1x May 5, 2026
8087caa
fix is too verbose for an expected condition
On1x May 5, 2026
fef0bdc
perf(dlt_p2p_node): enhance block logging and add periodic node statu…
On1x May 5, 2026
bd2b1fd
fix(network): improve error handling in peer connection logic
On1x May 5, 2026
51b491d
fix(network): make seed node connections asynchronous to avoid startu…
On1x May 5, 2026
01c1047
Fix slave DLT nodes producing stale blocks when emergency consensus i…
On1x May 5, 2026
a80ae7d
update docs
On1x May 5, 2026
db72508
fix(database): defer applied_block notifications to avoid write lock …
On1x May 5, 2026
3f43601
fix(witness): improve slot=0 stall detection and NTP resync logic
On1x May 5, 2026
41e243c
docs(dlt-forward-mode): add comprehensive documentation for forward m…
On1x May 5, 2026
04a6a48
fix(network): fix forward mode fork alignment and add forward→sync fa…
On1x May 5, 2026
483f887
docs(network): update dlt-forward-mode documentation for P27 fix and …
On1x May 5, 2026
a722c6e
fix
On1x May 5, 2026
d5a0307
fix(network): handle already known duplicate blocks in block acceptance
On1x May 5, 2026
192aed5
Fix DLT block gap after snapshot pause: add gap detection in resume_b…
On1x May 5, 2026
48f27cf
style(chain): apply dark-grey color to specific console log messages
On1x May 5, 2026
9648e4b
fix(network): add color to peer disconnection log message
On1x May 5, 2026
6104206
Fix block_too_old_exception during SYNC block range processing: when …
On1x May 5, 2026
6922aaa
fix(network): fix gap fill and forward mode stagnation detection (P37)
On1x May 5, 2026
2b52145
fix(p2p): fix cascade block application and gap fill peer requirements
On1x May 5, 2026
db5a7b9
refactor(chain): simplify tuple unpacking in branch info computation
On1x May 5, 2026
4d4b3b6
feat(p2p): extend fork status message and enhance peer stats logging
On1x May 5, 2026
57ba633
fix(p2p): optimize block acceptance during bulk sync
On1x May 5, 2026
202b4ed
fix(p2p): fix peer stats timing, enrich fork status updates, prevent …
On1x May 6, 2026
45582fc
fix: reset expected_next_block on new range requests to prevent false…
On1x May 6, 2026
322f84f
Fix per-IP connection deduplication to prevent duplicate block spam
On1x May 6, 2026
d8276a7
Fix silent crash caused by iterator invalidation in periodic_lifecycl…
On1x May 6, 2026
8ff9621
Emergency witness key emptification now runs only at schedule round b…
On1x May 6, 2026
4be7bce
Notify peers on SYNC→FORWARD transition to re-enable exchange
On1x May 6, 2026
1219a6b
Fix: reset stale peer state on reconnect
On1x May 6, 2026
6289d3c
Fix DLT P2P SYNC↔FORWARD oscillation when slave receives out-of-order…
On1x May 6, 2026
10151ad
Fix two bugs exposed by emergency consensus snapshot pauses. First, w…
On1x May 6, 2026
f3810a5
Move unused plugins to examples-plugins dir
On1x May 6, 2026
fd69c5d
Remove mongo plugin from build
On1x May 6, 2026
8113dba
fix build
On1x May 6, 2026
939d99c
move deprecated plugin to examples-plugins dir
On1x May 6, 2026
62e982d
fix: null signing key crash, non-consensus emergency blanking, gap fi…
On1x May 6, 2026
b6c93ee
Color-code diagnostic logs with ANSI escape sequences
On1x May 6, 2026
470cf5b
Fix 28s startup stall: block_info vector allocates 80M entries on sna…
On1x May 6, 2026
169ed41
Fix database_api build: update signal type to match applied_block_tim…
On1x May 6, 2026
c3aa1c6
Add Windows MSVC build support
On1x May 7, 2026
c32133c
update appbase submodule
On1x May 7, 2026
0f41ac0
update fc submodule
On1x May 7, 2026
4d632cf
update chainbase submodule
On1x May 7, 2026
aea258d
update fc submodule
On1x May 7, 2026
bf368a7
Resume P2P block processing immediately after snapshot DB read comple…
On1x May 7, 2026
695c558
Fix cli_wallet transactions not propagating to P2P peers
On1x May 7, 2026
7f19ca5
Fix 8 review issues from PR#96 full review. Address deferred notifica…
On1x May 7, 2026
44bf268
The fix adds _delegate->accept_transaction(msg.trx) after successful …
On1x May 7, 2026
a64b19e
fix build
On1x May 7, 2026
e88f527
fix webserver plugin options priority
On1x May 7, 2026
49753f4
Fix P40: skip spurious gap fill when broadcast block follows head dir…
On1x May 7, 2026
862a534
Fix P2P mempool TaPoS validation rejecting valid transactions
On1x May 7, 2026
ba37c6d
Fix TCP stream desync: disconnect on deserialization error in DLT P2P…
On1x May 7, 2026
484d91b
Fix deadlock where periodic snapshot blocks node for 110+ seconds. Th…
On1x May 7, 2026
c01a9bd
Include our head block in sync range requests to detect competing for…
On1x May 7, 2026
829387c
:Use LIB as sync start point when far behind peers to recover from mi…
On1x May 7, 2026
67e0865
Fix false ALREADY_KNOWN for competing-fork blocks deferred to fork_db…
On1x May 7, 2026
06c0f41
Fix peer_dlt_earliest corruption from range continuation and redirect…
On1x May 7, 2026
5c3c776
update agent
On1x May 7, 2026
195fb85
Problem: limit range reply size and add single-block fallback on dese…
On1x May 7, 2026
06d0366
fix(p2p): stop spamming peer exchange requests to rate-limited peers
On1x May 7, 2026
b4e48b0
Add block echo suppression to DLT P2P block relay
On1x May 7, 2026
f37d3b8
fix(p2p): advance expected_next_block on block application
On1x May 7, 2026
655dc2a
fix(p2p): demote stale out-of-order warnings to debug level
On1x May 7, 2026
ef41081
update docs
On1x May 7, 2026
fed0875
fix: defer block production during post-snapshot-pause catchup
On1x May 7, 2026
dc8bb73
fix: defer block production during post-snapshot-pause catchup
On1x May 7, 2026
bbdb556
fix: buffer blocks during snapshot pause instead of dropping them
On1x May 7, 2026
ec8ffbe
update debug logs
On1x May 7, 2026
42032a3
fix: buffer blocks during snapshot pause and defer witness production
On1x May 7, 2026
143d2f4
fix build
On1x May 7, 2026
c53f1b0
update debug log
On1x May 7, 2026
5f3c538
fix debug log for socket close race condition
On1x May 7, 2026
e700749
update tx debug log
On1x May 8, 2026
4c95c28
fix(p2p): prevent stream corruption from partial writes and fiber int…
On1x May 8, 2026
07da69f
fix(p2p): add per-peer send queue to serialize concurrent fiber writes
On1x May 8, 2026
8e64810
Fix P2P isolation oscillation: emergency peer reset when all peers di…
On1x May 8, 2026
322d871
update docs
On1x May 8, 2026
d1d0ffa
fix(snapshot): add backoff sleep in accept_loop error handlers
On1x May 8, 2026
7a6e53d
update docsfix(dlt-p2p): enable gap fill in SYNC mode and chunk large…
On1x May 8, 2026
7f97b2a
update docs
On1x May 8, 2026
b43d540
fix(dlt-p2p): include our head block in gap fill request to detect co…
On1x May 8, 2026
c758a67
Fix SYNC↔FORWARD oscillation when no peer is ahead
On1x May 8, 2026
8787f23
update docs
On1x May 8, 2026
989c334
Fix false DEAD_FORK when sync parent is on main chain but absent from…
On1x May 8, 2026
72b48d7
Remove witness signature skip during P2P bulk sync
On1x May 8, 2026
fed1d3f
Harden fork_db seeding and paused block queue resilience
On1x May 8, 2026
b9cd3b7
Document _pending_tx race and guard drain_send_queue stall
On1x May 8, 2026
5174764
Fix DLT sync stall from mutual soft-ban feedback loop
On1x May 8, 2026
00ec3e6
Document _pending_tx race and guard drain_send_queue stall
On1x May 8, 2026
a40b333
Merge branch 'fix-witness' of https://github.com/VIZ-Blockchain/viz-c…
On1x May 8, 2026
0941f62
refactor(dlt_p2p_node): simplify peer connection lifecycle and messag…
On1x May 8, 2026
36b4ed8
fix(dlt_p2p_node): guard transition_to_forward and improve sync catch…
On1x May 8, 2026
7d0cd98
fix(network): handle fork_db-only blocks correctly in packet result
On1x May 8, 2026
2f71b50
fix(dlt_sync): resolve false soft-ban and DLT snapshot fork-divergenc…
On1x May 8, 2026
6a37c14
fix build
On1x May 8, 2026
28f1ea9
debug(witness): add EMRG-DIAG logs to trace emergency master silent p…
On1x May 9, 2026
b3b257b
fix(network): disconnect peer when send queue is full instead of drop…
On1x May 9, 2026
da66672
Fix: Call node->pause_block_processing() directly — no async, no yiel…
On1x May 9, 2026
ebd2d43
debug(witness): add production watchdog and not_synced diagnostics
On1x May 9, 2026
e079344
add logs
On1x May 9, 2026
bf4048d
add watchdog log
On1x May 9, 2026
ddb9270
update fc submodule
On1x May 9, 2026
f1f8b6f
add uptime in stats
On1x May 9, 2026
2b4b8e6
add more logs
On1x May 9, 2026
bfcac4c
block IPs that send oversized messages for 1 hour
On1x May 9, 2026
7b91206
fix false positive ntp drift log
On1x May 9, 2026
294220c
update WITNESS-WATCHDOG log section
On1x May 9, 2026
4119d48
more logs in snapshot creation proccess
On1x May 10, 2026
bf1a064
fix(network): prevent reentrant handle_disconnect calls causing itera…
On1x May 10, 2026
4bac398
fix(network): handle syncing peer lifecycle and update expected next …
On1x May 10, 2026
1f402bd
add more logs to witness watchdog
On1x May 10, 2026
17aa514
fix(witness): refresh 'now' after op_guard to prevent silent slot drops
On1x May 10, 2026
d9aad28
fix(dlt_p2p): log peer ip:port in drain_send_queue send failure
On1x May 10, 2026
2cdf7fa
chore(thirdparty): update fc submodule commit reference
On1x May 10, 2026
adaa0d1
refactor(witness): rename block production condition to block validat…
On1x May 10, 2026
6c02390
refactor(protocol): rename "witness" to "validator" for clarity and c…
On1x May 10, 2026
c2604a1
fix(network): add constant for blocked IP duration in dlt_p2p_node
On1x May 10, 2026
3f48695
chore(build): remove MongoDB enable flag from build output
On1x May 10, 2026
4e47fda
fix(witness): prevent write-lock starvation during snapshot race cond…
On1x May 10, 2026
1bc1dcd
fix(network): correct log level for peer reconnection message
On1x May 10, 2026
df9d406
fix(network): change peer timeout log level to debug
On1x May 10, 2026
79e7505
fix(network): improve duplicate connection rejection log
On1x May 10, 2026
30da3e2
fix(network): prevent deadlock in accept_block calls from concurrent …
On1x May 10, 2026
1ed4138
fix(network): handle dead-fork blocks correctly during gap fill
On1x May 10, 2026
5d753dc
change EMRG-DIAG log to debug level
On1x May 10, 2026
be38117
fix(witness): improve witness schedule logging and detect op_guard stall
On1x May 10, 2026
6c5e5ae
fix(p2p): clear catchup flag unconditionally in transition_to_forward
On1x May 11, 2026
9c7cd0d
fix(network): refine per-IP connection deduplication logic
On1x May 11, 2026
c580e60
update fc submodule
On1x May 11, 2026
0ecd353
feat(p2p): add isolated peers mode to restrict connections and suppre…
On1x May 12, 2026
7692ca9
fix(webserver): handle empty request body with 400 response
On1x May 12, 2026
da45dcf
fix(p2p): prevent seed reconnect in isolated peers mode
On1x May 12, 2026
08e9f09
fix(witness): add diagnostic logging for slot=0 and not_my_turn strea…
On1x May 13, 2026
77a1dff
feat(witness): detect and log missed witness slots with diagnostic state
On1x May 13, 2026
823524a
fix(witness): enhance slot zero streak logging with witness context
On1x May 13, 2026
d0442e5
fix(witness): remove premature low_participation return that deadlock…
On1x May 13, 2026
0b14c3e
fix(witness): add watchdog production recovery and remove low_partici…
On1x May 13, 2026
240b052
fix(network): replace block processing flags with atomic variables
On1x May 13, 2026
079d48c
fix(network): clear both pause-related flags to unstick production
On1x May 13, 2026
7808c3f
fix(network): clear syncing flag on SYNC to FORWARD transition
On1x May 13, 2026
75ca74e
fix(sync): clear currently_syncing flag on SYNC to FORWARD transition
On1x May 13, 2026
dcbd65d
docs(witness): update partition guard logic in snapshot-pause workflow
On1x May 13, 2026
03b0c56
docs(dlt-p2p): add comprehensive DLT P2P statistics reference documen…
On1x May 14, 2026
1307f10
docs(dlt-p2p-stats): add peer exchange rate-limiting scenario and upd…
On1x May 14, 2026
c1aa5d0
docs(p2p): revise peer exchange rate-limiting policy description
On1x May 14, 2026
c3c521b
docs(dlt-p2p): update peer exchange rate limiting to sliding window m…
On1x May 14, 2026
e61ea36
feat(witness): add slot hijack detection in emergency mode
On1x May 14, 2026
093773c
add witness plugin docs
On1x May 14, 2026
c5bb1db
refactor(witness): remove cached flags and query live state for produ…
On1x May 14, 2026
31d8099
feat(witness): integrate snapshot plugin for block production control
On1x May 14, 2026
82f4039
refactor(witness): move snapshot plugin dependency handling out of he…
On1x May 14, 2026
e6310d2
fix(witness): correct slot hijack detection and logging logic
On1x May 14, 2026
d7898ef
fix(snapshot): pass snapshot path in load callback and reorder initia…
On1x May 14, 2026
8e889e3
fix typo
On1x May 14, 2026
3a08032
fix(snapshot): ensure proper flag reset and P2P resume on snapshot as…
On1x May 14, 2026
45261d8
fix(p2p): handle shared memory corruption in block acceptance
On1x May 15, 2026
b47fa02
fix(chain): pause and resume P2P block processing during auto-recovery
On1x May 15, 2026
a5ab8a9
fix(chain): add private include directory for p2p headers
On1x May 15, 2026
3f87f37
refactor(chain): update graphene p2p plugin reference
On1x May 15, 2026
3a1912c
refactor(p2p): improve block processing resume logic and thread handling
On1x May 15, 2026
7b589b7
fix(witness): prevent false slot hijack detection for own witnesses
On1x May 15, 2026
c3effcf
fix(network): correct atomic flag setting order in dlt_p2p_node
On1x May 15, 2026
5cc0a6e
fix(witness): correct slot index calculation in witness schedule call…
On1x May 15, 2026
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ documentation/doxygen/latex
*.egg-info/
build

.qoder/logs/*
# Local design specs and implementation plans (not part of repo)
docs/superpowers/

# Claude Code local session/config files
.claude/
.claude/
97 changes: 97 additions & 0 deletions .qoder/agents/senior-engineer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
name: senior-engineer
description: Senior engineer focused on implementation speed and correctness. Use for precise, surgical code changes where every modification must trace directly to the task. Ideal for feature implementation, bug fixes, and refactoring with minimal blast radius.
tools: Read, Write, Edit, Bash, Grep, Glob
---

# Role Definition

You are a senior engineer focused on implementation speed and correctness.

Your job: research bugs, build exactly what is asked, nothing more, nothing less.

## Language Rules

- **Chat responses**: respond to the user **only in Russian**
- **Plan, commit messages, code comments**: write in **English**
- **In-code comments**: must be self-contained — no references to external log files, ticket numbers, fix IDs, or task numbers (log files are temporary and will be deleted)

## Rules

- Read the full context before writing a single line
- Make surgical changes only, touch nothing adjacent to the task
- If you see a better approach, say so before building
- Validate your changes against existing logic before responding
- Every changed line must trace directly to the task
- For long-horizon tasks, state your plan and verify each step before moving to the next

## Agent Behavior

- Report progress every 30 steps
- Flag blockers immediately instead of working around them silently
- If a subtask fails, pause and surface it rather than continuing
- **Never suggest building the project** — this is a public project that auto-builds via GitHub Actions and publishes to Docker Hub. Always assume you are working with the latest build.

## Debugging Rules

- **Never guess workflow from logs.** Instead, verify step-by-step execution in the code — trace the actual code path that produced the log output.
- When analyzing a bug, read the relevant source files and follow the execution flow rather than hypothesizing based on log messages alone.

## Workflow

1. Read and fully understand the task requirements and surrounding code
2. Identify the minimal set of files and lines that need to change
3. If a better approach exists, state it clearly before proceeding
4. Plan the changes, listing each file and the specific modification
5. Implement changes one at a time, verifying each against existing logic
6. Confirm nothing adjacent was broken
7. After implementation, generate a **medium-length** git commit message in English and output it in chat inside a ``` block **without literal \n characters** so the user can copy-paste it in one click

## Output Format

**Plan**
- List of files to modify and what changes are needed
- Write the plan in **English**
- Ask to make changes, implement plan

**Changes Made**
- File and line references for each modification
- Brief justification tracing back to the task
- Code comments must be **self-contained** — no references to log files, fix numbers, task IDs, or any external artifact

**Verification**
- How the changes were validated
- Any risks or follow-up items

**Commit Message**
- After all changes are implemented, output a medium-length English commit message in a single ``` block
- Do NOT use literal `\n` in the message — write actual line breaks
- The message must be ready to copy-paste with one click

## Constraints

**MUST DO:**
- Trace every changed line directly to the task
- Verify changes against existing logic before finalizing
- Surface blockers immediately
- Ask to implement plan before making changes to files
- Respond to the user in Russian in chat
- Write plans and commit messages in English
- Make code comments self-contained without references to external artifacts
- Verify code execution paths step by step instead of guessing from logs
- Assume the latest build — never suggest building

**MUST NOT DO:**
- Touch code unrelated to the task
- Make speculative or "while I'm here" improvements
- Work around blockers silently
- Continue past a failed subtask without surfacing it
- Reference log file paths or names in code comments
- Include fix/task/ticket numbers in code comments
- Guess workflow from logs — verify in code
- Suggest building the project
- Use literal `\n` in commit message blocks

## Success Criteria

The change works, nothing else broke, every step is traceable.
128 changes: 127 additions & 1 deletion .qoder/docs/block-processing.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,56 @@ Source: [database.cpp:1125-1160](../../libraries/chain/database.cpp#L1125)

---

## Fork DB Head-Seeding

Source: [database.cpp `_push_block`](../../libraries/chain/database.cpp)

Before pushing a block to `fork_db`, `_push_block()` ensures the current database head block is present in `fork_db`. After snapshot import, stale sync recovery, or fork_db trimming, the head block may be absent from `fork_db`'s `_index`.

Without this seed, any block whose `previous == head_block_id()` would throw `unlinkable_block_exception` inside `fork_database::_push_block()` ("block does not link to known chain"), silently rejecting valid next-blocks and preventing head advancement.

```
if new_block.previous == head_block_id()
AND head_block_id() NOT in fork_db:
fetch head block from block log
fork_db.start_block(head_block) ← seeds fork_db with the head
```

This also fixes **witness nodes that generate their own blocks**: `generate_block()` sets `pending_block.previous = head_block_id()`, and without the seed the self-generated block would fail to push into `fork_db`.

---

## Direct-Extension Bypass

Source: [database.cpp `_push_block`](../../libraries/chain/database.cpp)

After pushing a block to `fork_db`, `_push_block()` checks whether the block directly extends the database head (`new_block.previous == head_block_id()`). If so, the fork switch logic is bypassed entirely and the block falls through to `apply_block()`.

This handles the case where `fork_db._head` points to a stale higher block accumulated from previous failed sync cycles (stale sync recovery does not reset `fork_db`). Without this bypass:

1. `fork_db.push_block()` returns the stale `_head` (e.g., block #79609893)
2. `new_head->data.previous != head_block_id()` evaluates to TRUE
3. The fork switch logic either rejects the block (head not in fork_db) or can't compare branches
4. The valid next-block is silently dropped, head never advances

```
if new_block.previous == head_block_id():
→ skip fork switch, fall through to apply_block
else if new_head->data.previous != head_block_id():
→ existing fork switch logic (unchanged)
```

Together with fork_db head-seeding, this ensures blocks that correctly link to the database head are always applied, regardless of `fork_db`'s internal `_head` state.

---

## Fork Switch Flow

When a node switches to a different fork:

1. `pop_block()` removes the current head block
- Transactions from the popped block are saved to `_popped_tx`
- Source: [database.cpp:1223-1238](../../libraries/chain/database.cpp#L1223)
- Source: [database.cpp](../../libraries/chain/database.cpp)

2. The new block is applied via `push_block()`

Expand All @@ -122,6 +165,88 @@ When a node switches to a different fork:
- Then original `_pending_transactions` are processed
- Duplicate transactions (already in the new chain) are silently skipped

### Linear Extension vs. Actual Fork

When `fork_db._push_next()` auto-links orphan blocks from the unlinked index, the fork_db head can jump multiple blocks ahead of the database head in a single `push_block()` call. This triggers the fork switch code path (`new_head->data.previous != head_block_id()`), but there is no actual fork — the new chain extends directly from the current head.

`fetch_branch_from(new_head, head_block_id)` always appends the common ancestor to **both** branches. For a linear extension, the common ancestor IS the current head:
- `branches.first` = `[new_tip, ..., HEAD]` (blocks to apply + common ancestor)
- `branches.second` = `[HEAD]` (just the common ancestor)

**Detection:** `is_linear_extension = branches.second.size() == 1 && branches.second.back()->id == head_block_id()`.

**Behavior when linear:**
- Skip the pop loop entirely (the common ancestor is already applied, no blocks to undo)
- Skip the common ancestor when applying `branches.first` (avoid re-applying HEAD)
- On error: pop any newly applied blocks back to the common ancestor, set fork_db head to it

**Why this matters in DLT mode:** In DLT mode, LIB = head, so undo sessions are committed (not just pushed). `pop_block()` → `undo()` has no effect — `head_block_id()` never changes. The pop loop becomes infinite, eventually emptying the fork_db and crashing with "popping head block would leave fork DB empty".

For **actual forks** (`branches.second.size() > 1` or common ancestor != head), the original behavior is preserved: pop old-fork blocks including the common ancestor, then re-apply the common ancestor and new-fork blocks from `branches.first`.

### Debug Logging

Diagnostic logs at every `pop_block()` call site:

| Log prefix | Location | Meaning |
|---|---|---|
| `Fork switch: new_head=#X, db_head=#Y, branches.first=N, branches.second=M` | Before fork switch | Shows branch sizes; `branches.second=0` = linear extension |
| `FORK-SWITCH-POP: popping head #H` | Main pop loop | Normal fork switch pop |
| `FORK-RECOVER-POP: popping head #H` | Error recovery pop loop | Reverting failed fork switch |
| `POP_BLOCK: db_head=#X, fork_db_head=#Y, fork_db_head_prev=Z` | Inside `database::pop_block()` | Fork_db state before every pop; `prev=0` = root block (will crash) |

---

## Orphan Block Handling (Unlinked Index)

Source: [database.cpp `_push_block`](../../libraries/chain/database.cpp), [fork_database.cpp](../../libraries/chain/fork_database.cpp)

When a block arrives whose parent is unknown (missed broadcast), the node can either reject it or defer it for later linking.

### Pre-check in `_push_block()`

```
if block.num > head_num
AND block.previous != head_block_id
AND block.previous not in fork_db:
if gap > 100 → reject (too far ahead, avoid memory bloat)
if gap <= 100 → allow through to fork_db
```

Blocks within 100 of head pass to `fork_db.push_block()`, which throws `unlinkable_block_exception` but stores the block in `_unlinked_index` first.

### Auto-linking via `_push_next()`

When the missing parent block finally arrives and is pushed to fork_db:
1. `_push_block(parent)` links the parent to the chain
2. `_push_next(parent)` searches `_unlinked_index` for children of `parent`
3. Found children are moved from `_unlinked_index` to `_index` and recursively linked
4. fork_db head may jump multiple blocks ahead in one call

This triggers the linear extension fork switch (see above).

### P2P Recovery

When `unlinkable_block_exception` propagates to the P2P layer (`process_block_during_normal_operation`):
- Block **at or below head** → strike counter incremented (soft-ban after 20 strikes)
- Block **ahead of head** → `start_synchronizing_with_peer()` restarts sync to fetch the missing block

---

## Peer Strike-Based Soft-Ban

Source: [node.cpp](../../libraries/network/node.cpp), [peer_connection.hpp](../../libraries/network/include/graphene/network/peer_connection.hpp)

Peers are not immediately soft-banned for sending unlinkable or rejected blocks. Instead, a strike counter accumulates:

| Path | Threshold | Counter field |
|---|---|---|
| Normal operation: unlinkable block at/below head | 20 strikes | `unlinkable_block_strikes` |
| Sync path: generic block rejection | 20 strikes | `unlinkable_block_strikes` |
| Dead fork / block too old | Immediate | N/A |

**Reset on valid block:** When a peer sends a block that is successfully accepted (normal or sync), their `unlinkable_block_strikes` counter resets to 0. This allows honest peers to recover from transient errors (snapshot reload, timing races, brief micro-forks).

---

## Bug Fix: False "Postponed" Log Messages
Expand Down Expand Up @@ -274,6 +399,7 @@ When block at T=6 is pushed, `update_global_dynamic_data()` counts `missed_block
| Participation | Network participation ≥ required (pre-HF12 only) | `low_participation` |
| Lag | `|scheduled_time - now| <= 500ms` | `lag` |
| Fork collision | No competing block at same height in fork_db | `fork_collision` |
| Minority fork | Last 21 blocks NOT all from our own witnesses (or `enable-stale-production` or emergency mode) | `minority_fork` |

---

Expand Down
Loading
Loading