Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f14f880
refactor: rename witness→validator across protocol, chain, API, and w…
On1x May 17, 2026
76b8d47
renamed missed witness fields
On1x May 17, 2026
d3aa9ef
add missed rename vars
On1x May 17, 2026
ad4401d
fix rename
On1x May 17, 2026
df04493
fix renames
On1x May 17, 2026
06ddbfc
fix renames
On1x May 17, 2026
cc3d06f
fix(snapshot): use find() instead of contains() on mutable_variant_ob…
On1x May 17, 2026
30a7a89
fix naming
On1x May 17, 2026
2ee5bc9
more renames
On1x May 17, 2026
987a78a
update docs
On1x May 17, 2026
fa74a85
rename(file): witness → validator physical renames
On1x May 17, 2026
78379c0
fix constructor name
On1x May 17, 2026
fc76f3c
rename(api): account fields, config constants, get_config keys
On1x May 17, 2026
9240418
fix missing testnet conts in config
On1x May 17, 2026
aebfab4
fix missed define
On1x May 17, 2026
a6dd6c1
Merge branch 'master' into witness-rename
On1x May 17, 2026
1b81c60
fix naming
On1x May 17, 2026
aa1416b
fix naming
On1x May 17, 2026
2938336
fix witness naming in logs
On1x May 17, 2026
0a41045
update logs text
On1x May 17, 2026
3c8dd0a
fix(chain): prevent exception propagation on invalid fork branch
On1x May 18, 2026
05601b3
fix(p2p): soft-ban peers that send only fork-db blocks with no progre…
On1x May 18, 2026
e22dcaa
fix(network): clarify block validation log messages
On1x May 18, 2026
eca9e39
docs(validator): rename witness to validator throughout documentation
On1x May 18, 2026
5ca460e
docs(cli-wallet): rename witness terms to validator in documentation
On1x May 18, 2026
adf23fa
chain: treat wrong-scheduled-validator as soft fork-resolution condition
On1x May 18, 2026
ad90040
fix(dlt-p2p): add grace period to prevent instant SYNC↔FORWARD oscill…
On1x May 19, 2026
9fb3af2
add new docs
On1x May 19, 2026
d32a5cf
docs(api): add Swift client library to official client libraries section
On1x May 19, 2026
e488f5a
chore(thirdparty): update fc submodule commit reference
On1x May 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
48 changes: 48 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Deploy Docs

on:
push:
branches: [master]
paths:
- 'docs/**'
- '@l10n/**'
- 'redocly.yaml'
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- run: npm ci

- run: npm run build

- uses: actions/upload-pages-artifact@v3
with:
path: dist

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@v4
id: deployment
34 changes: 17 additions & 17 deletions .qoder/docs/block-processing.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# VIZ Blockchain — Block Processing & Pending Transactions
# VIZ Blockchain — Block Processing & Pending Transactions

Internal mechanics of block application, transaction queuing, and the pending transaction lifecycle.

Expand Down Expand Up @@ -122,7 +122,7 @@ if new_block.previous == head_block_id()
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`.
This also fixes **validator 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`.

---

Expand Down Expand Up @@ -294,9 +294,9 @@ Now the log only fires once, after both loops complete, with an accurate count o

---

## Bug Fix: Witness Plugin Option Parsing
## Bug Fix: Validator Plugin Option Parsing

Source: [witness.cpp](../../plugins/witness/witness.cpp)
Source: [validator.cpp](../../plugins/validator/validator.cpp)

### Bug 1: `enable-stale-production` with `implicit_value(false)`

Expand Down Expand Up @@ -346,18 +346,18 @@ _required_witness_participation = options["required-participation"].as<uint32_t>

---

## Witness Block Production Timing
## validator Block Production Timing

Source: [witness.cpp](../../plugins/witness/witness.cpp)
Source: [validator.cpp](../../plugins/validator/validator.cpp)

### Production Loop Mechanism

The witness plugin uses a timer-based production loop with a look-ahead to detect when it's time to produce a block:
The Validator Plugin uses a timer-based production loop with a look-ahead to detect when it's time to produce a block:

1. **Timer** fires every **250ms** (aligned to 250ms boundaries, minimum sleep 50ms)
2. On each tick, `maybe_produce_block()` computes `now = NTP_time + 250ms` (look-ahead)
3. `get_slot_at_time(now)` finds which slot corresponds to `now`
4. If the slot belongs to one of our witnesses and `|scheduled_time - now| <= 500ms`, the block is produced with `scheduled_time` as the timestamp
4. If the slot belongs to one of our validators and `|scheduled_time - now| <= 500ms`, the block is produced with `scheduled_time` as the timestamp

The block timestamp is always the **deterministic slot time** (computed from `head_block_time` rounded to `CHAIN_BLOCK_INTERVAL` boundary + `slot_num × 3s`), never the current clock time.

Expand All @@ -374,15 +374,15 @@ This gives a **500ms safety margin** against the LAG threshold, compared to 0ms

### Missed Block Behavior

When a witness misses their slot, the production loop does NOT wait or retry. The next tick simply finds a later slot:
When a validator misses their slot, the production loop does NOT wait or retry. The next tick simply finds a later slot:

```
Slot T=3 missed (witness A absent):
Tick at T=3.000 → now=3.250 → slot=1 → witness A → not our witness → not_my_turn
Slot T=3 missed (validator A absent):
Tick at T=3.000 → now=3.250 → slot=1 → validator A → not our validator → not_my_turn
(A's slot passes unclaimed)

Slot T=6 (witness B - our witness):
Tick at T=5.750 → now=6.000 → slot=2 → witness B → PRODUCE with timestamp T=6.000
Slot T=6 (validator B - our validator):
Tick at T=5.750 → now=6.000 → slot=2 → validator B → PRODUCE with timestamp T=6.000
```

When block at T=6 is pushed, `update_global_dynamic_data()` counts `missed_blocks = get_slot_at_time(6.000) - 1 = 1` and increments `current_aslot` accordingly.
Expand All @@ -393,13 +393,13 @@ When block at T=6 is pushed, `update_global_dynamic_data()` counts `missed_block
|---|---|---|
| Sync status | Chain is not stale (or `enable-stale-production`) | `not_synced` |
| Slot time | `get_slot_at_time(now) > 0` | `not_time_yet` |
| Witness ownership | Scheduled witness is in our `_witnesses` set | `not_my_turn` |
| Signing key | Witness has non-zero `signing_key` on chain | `not_my_turn` |
| validator ownership | Scheduled validator is in our `_witnesses` set | `not_my_turn` |
| Signing key | validator has non-zero `signing_key` on chain | `not_my_turn` |
| Private key | We have the private key for the signing key | `no_private_key` |
| 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` |
| Minority fork | Last 21 blocks NOT all from our own validators (or `enable-stale-production` or emergency mode) | `minority_fork` |

---

Expand All @@ -410,4 +410,4 @@ When block at T=6 is pushed, `update_global_dynamic_data()` counts `missed_block
| `CHAIN_PENDING_TRANSACTION_EXECUTION_LIMIT` | 200ms | Max time to spend re-applying pending txs after block push |
| `CHAIN_BLOCK_GENERATION_POSTPONED_TX_LIMIT` | 5 | Max consecutive oversized txs to skip during block generation |
| `CHAIN_BLOCK_SIZE` | 65536 bytes | Hard limit on block size |
| `maximum_block_size` | Dynamic (witness median) | Soft limit on block size |
| `maximum_block_size` | Dynamic (validator median) | Soft limit on block size |
Loading
Loading