Skip to content
Open
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
137 changes: 135 additions & 2 deletions foundations/config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -430,12 +430,18 @@ This parameter provides the configuration for the `Catchain` protocol in the TON

## Param 29: consensus config

This parameter provides the configuration for the consensus protocol above `Catchain` ([Param 28](#param-28)) in the TON Blockchain. The consensus protocol is a crucial component of a blockchain network, and it ensures that all nodes agree on the state of the distributed ledger.
This parameter provides the configuration for the consensus protocol above `Catchain` ([Param 28](#param-28-catchain-config)) in the TON Blockchain. The consensus protocol is a crucial component of a blockchain network, and it ensures that all nodes agree on the state of the distributed ledger.

<Aside>
`ConfigParam 29` has evolved through several constructors. The latest, `consensus_config_v4#d9`, is defined in [`block.tlb`](https://github.com/ton-blockchain/ton/blob/af252bcdaea357fee21739e984654c2c84e7d61d/crypto/block/block.tlb#L782). It extends `consensus_config_v3#d8` with a new `use_quic:Bool` (taking one bit from `flags`, which shrinks from 7 to 6 bits) and an additional `catchain_max_blocks_coeff:uint32` field at the end.
</Aside>
Comment thread
novusnota marked this conversation as resolved.

### Configuration parameters

- `flags`: A general field that can be used to set various binary parameters.

- `use_quic`: A Boolean value indicating whether the legacy Catchain consensus path uses QUIC transport instead of RLDP2. Introduced in `consensus_config_v4#d9`; has the same meaning as the `use_quic` field in [Param 30](#param-30-consensus-extension).

- `new_catchain_ids`: A Boolean value indicating whether to generate new `Catchain` identifiers.

- `round_candidates`: The number of candidates to be considered in each round of the consensus protocol.
Expand All @@ -458,10 +464,137 @@ This parameter provides the configuration for the consensus protocol above `Catc

- `catchain_max_blocks_coeff`: The coefficient limiting the rate of block generation in `Catchain`, [description](https://github.com/ton-blockchain/ton/blob/master/doc/catchain-dos.md).

For up-to-date values, see [https://tonviewer.com/config](https://tonviewer.com/config).
For up-to-date values, see [Parameter #29 on mainnet](https://tonviewer.com/config#29).

#### On-chain schema

`ConfigParam 29` is a tagged union: validators must accept any of the legacy constructors so old serialized configs keep parsing, but new on-chain values are written using the latest tag. The current set defined in [`block.tlb`](https://github.com/ton-blockchain/ton/blob/af252bcdaea357fee21739e984654c2c84e7d61d/crypto/block/block.tlb#L782) is:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this block.tlb reference pins a commit hash (af252bcdae...), but the param 30 section a few hundred lines down pins a tag (v2026.04). both are stable, mixing them in adjacent sections looks accidental. could we settle on one form - probably the tag since it matches the release-note Aside in param 30?

Suggested change
`ConfigParam 29` is a tagged union: validators must accept any of the legacy constructors so old serialized configs keep parsing, but new on-chain values are written using the latest tag. The current set defined in [`block.tlb`](https://github.com/ton-blockchain/ton/blob/af252bcdaea357fee21739e984654c2c84e7d61d/crypto/block/block.tlb#L782) is:
`ConfigParam 29` is a tagged union: validators must accept any of the legacy constructors so old serialized configs keep parsing, but new on-chain values are written using the latest tag. The current set defined in [`block.tlb`](https://github.com/ton-blockchain/ton/blob/v2026.04/crypto/block/block.tlb#L782) is:

and the same line 436 in the Aside above


```tlb
consensus_config#d6 round_candidates:# { round_candidates >= 1 }
next_candidate_delay_ms:uint32 consensus_timeout_ms:uint32
fast_attempts:uint32 attempt_duration:uint32 catchain_max_deps:uint32
max_block_bytes:uint32 max_collated_bytes:uint32 = ConsensusConfig;

consensus_config_new#d7 flags:(## 7) { flags = 0 } new_catchain_ids:Bool
round_candidates:(## 8) { round_candidates >= 1 }
next_candidate_delay_ms:uint32 consensus_timeout_ms:uint32
fast_attempts:uint32 attempt_duration:uint32 catchain_max_deps:uint32
max_block_bytes:uint32 max_collated_bytes:uint32 = ConsensusConfig;

consensus_config_v3#d8 flags:(## 7) { flags = 0 } new_catchain_ids:Bool
round_candidates:(## 8) { round_candidates >= 1 }
next_candidate_delay_ms:uint32 consensus_timeout_ms:uint32
fast_attempts:uint32 attempt_duration:uint32 catchain_max_deps:uint32
max_block_bytes:uint32 max_collated_bytes:uint32
proto_version:uint16 = ConsensusConfig;

consensus_config_v4#d9 flags:(## 6) { flags = 0 } use_quic:Bool new_catchain_ids:Bool
round_candidates:(## 8) { round_candidates >= 1 }
next_candidate_delay_ms:uint32 consensus_timeout_ms:uint32
fast_attempts:uint32 attempt_duration:uint32 catchain_max_deps:uint32
max_block_bytes:uint32 max_collated_bytes:uint32
proto_version:uint16 catchain_max_blocks_coeff:uint32 = ConsensusConfig;

_ ConsensusConfig = ConfigParam 29;
Comment thread
novusnota marked this conversation as resolved.
```

<Aside>
`consensus_config_v4#d9` was introduced together with the [Catchain 2.0 / Simplex](https://github.com/ton-blockchain/simplex-docs/blob/main/Simplex.md) migration tracked by [Param 30](#param-30-consensus-extension). The `use_quic` toggle in Param 29 controls the transport for the legacy Catchain path; the `use_quic` toggle in Param 30 controls the transport for the new Simplex path. They are configured independently.
</Aside>

[Parameter #29 on mainnet](https://tonviewer.com/config#29)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

small dup: the same Parameter #29 on mainnet link already shows up at line 467 (For up-to-date values, see [Parameter #29 on mainnet](...)), so this trailing standalone link is redundant after the rewrite. probably it makes sense to drop one of them?

Suggested change
[Parameter #29 on mainnet](https://tonviewer.com/config#29)


## Param 30: consensus extension

<Aside type="note">
- [TON v2026.03](https://github.com/ton-blockchain/ton/releases/tag/v2026.03): `ConfigParam 30` introduced on testnet.
- [TON v2026.04](https://github.com/ton-blockchain/ton/releases/tag/v2026.04): `ConfigParam 30` enabled on mainnet.
</Aside>

This parameter configures [Catchain 2.0](https://github.com/ton-blockchain/simplex-docs/blob/main/Simplex.md) — the Simplex-based consensus protocol that succeeds the original Catchain. The settings are optional and can be supplied independently for each chain. Block-size limits are not duplicated here: the node continues to read `max_block_bytes` and `max_collated_bytes` from [`ConfigParam 29`](/foundations/config#param-29-consensus-config).

The `crypto/block/block.tlb` [defines](https://github.com/ton-blockchain/ton/blob/v2026.04/crypto/block/block.tlb#L782) the following schema:

```tlb
simplex_config#21 flags:(## 7)
use_quic:Bool
target_rate_ms:uint32
slots_per_leader_window:uint32
first_block_timeout_ms:uint32
max_leader_window_desync:uint32
= NewConsensusConfig;

simplex_config_v2#22 flags:(## 7)
use_quic:Bool
slots_per_leader_window:uint32
noncritical_params:(HashmapE 8 uint32)
= NewConsensusConfig;
Comment on lines +528 to +532
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

small but worth double-checking against the upstream block.tlb at v2026.04 line 782: consensus_config_v4#d9 (line 492 here) has flags:(## 6) { flags = 0 }, while both simplex_config#21 and simplex_config_v2#22 have flags:(## 7) with no { flags = 0 } constraint. is that intentional, or did the flags = 0 predicate just get dropped in the copy? if the upstream schema does require flags = 0 for the simplex configs too, we should keep it here for reviewers who use this page as the spec reference


new_consensus_config_all#10
mc:(Maybe ^NewConsensusConfig)
shard:(Maybe ^NewConsensusConfig)
= NewConsensusConfigAll;

_ NewConsensusConfigAll = ConfigParam 30;
```

The `simplex_config_v2#22` constructor moves noncritical configuration parameters into a sparse dictionary.
There are two optional refs in `new_consensus_config_all#10`. If a ref is absent, then the pre-2.0 Catchain config is active for the corresponding class of chains:

| Field | Type | Meaning |
| ------- | --------------------------- | ------------------------------------------------------- |
| `mc` | `Maybe ^NewConsensusConfig` | Config for the masterchain (`workchain = -1`) |
| `shard` | `Maybe ^NewConsensusConfig` | Config for shardchains (all non-masterchain workchains) |

The `NewConsensusConfig` has two constructors:

- `simplex_config#21` is the legacy fixed-layout format; scheduled for removal.
- `simplex_config_v2#22` is the current extensible format, which supports arbitrary `noncritical_params` without changes to the `block.tlb` layout.

### Configuration parameters of `simplex_config_v2`

- `flags`: A general field that can be used to set various binary parameters.
- `use_quic`: Whether the QUIC transport is used instead of RLDP2. Set to **True** in mainnet.
- `slots_per_leader_window`: Number of consecutive slots assigned to one leader. Set to **4** in mainnet.
Comment thread
novusnota marked this conversation as resolved.
Comment on lines +558 to +559
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

bolding values like **True** and **4** falls under the no-bold-on-tokens rule of the style guide (see emphasis), code font keeps the literal grep-friendly and matches how Bool values are written elsewhere in the repo (lowercase)

Suggested change
- `use_quic`: Whether the QUIC transport is used instead of RLDP2. Set to **True** in mainnet.
- `slots_per_leader_window`: Number of consecutive slots assigned to one leader. Set to **4** in mainnet.
- `use_quic`: Whether the QUIC transport is used instead of RLDP2. Set to `true` on mainnet.
- `slots_per_leader_window`: Number of consecutive slots assigned to one leader. Set to `4` on mainnet.

- `noncritical_params`: A `HashmapE 8 uint32` map from parameter IDs to raw 32-bit values.

Inherited from [Param 29](https://tonviewer.com/config#29):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this link points at tonviewer's #29 anchor, but in the param 30 intro (line 515) the same reference uses the internal anchor [ConfigParam 29](/foundations/config#param-29-consensus-config)

should we keep them consistent? @reveloper the internal anchor is also what the style guide prefers for cross-page references (see links)

Suggested change
Inherited from [Param 29](https://tonviewer.com/config#29):
Inherited from [Param 29](/foundations/config#param-29-consensus-config):


- `max_block_bytes` — maximum block size.
- `max_collated_bytes` — maximum size of serialized block correctness proofs.

The `noncritical_params` dictionary contains tunable timing and DoS-protection parameters that might differ between validators:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tiny but the phrasing might differ between validators reads as if every validator runs its own noncritical config, which isn't the case - the dictionary lives in ConfigParam 30 on-chain, so all validators apply the same values. could we soften to something like tunable across config updates without changing the block.tlb layout?

Suggested change
The `noncritical_params` dictionary contains tunable timing and DoS-protection parameters that might differ between validators:
The `noncritical_params` dictionary contains tunable timing and DoS-protection parameters that can be changed via a config update without altering the `block.tlb` layout:


- The key is an 8-bit parameter ID.
- The value is always a raw 32-bit word.
- Unknown IDs are ignored by the current implementation.
- Missing IDs use default values.
- Duration-like parameters store milliseconds directly.
- Floating-point parameters store `float32` bits according to the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) standard in a `uint32` value. The loader then reinterprets these bits as a floating-point numeric value.

IDs from `0` through `14` are recognized and supported. On the mainnet, only IDs `0`, `1`, and `13` are explicitly set. All other IDs are normally absent and use defaults.

| ID | Name | Stored as | Default | Meaning |
| ---- | -------------------------------------- | -------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `0` | `target_rate` | `uint32` milliseconds | `2400 ms` | Target slot or block interval; used for leader pacing, block production timing, and skip scheduling. |
| `1` | `first_block_timeout` | `uint32` milliseconds | `1000 ms` | Base timeout before skip voting starts for the first missing block in a leader window. |
| `2` | `first_block_timeout_multiplier` | `float32` bits in `uint32` | `1.2` | Multiplier applied to `first_block_timeout` after a window that had skips. |
| `3` | `first_block_timeout_cap` | `uint32` milliseconds | `100,000 ms` | Cap for the adaptive `first_block_timeout` growth. |
| `4` | `candidate_resolve_timeout` | `uint32` milliseconds | `1000 ms` | Initial timeout for candidate or notarization resolution requests. |
| `5` | `candidate_resolve_timeout_multiplier` | `float32` bits in `uint32` | `1.2` | Backoff multiplier for candidate resolution retries. |
| `6` | `candidate_resolve_timeout_cap` | `uint32` milliseconds | `10,000 ms` | Cap for candidate resolution timeout growth. |
| `7` | `candidate_resolve_cooldown` | `uint32` milliseconds | `10 ms` | Cooldown between candidate resolution attempts. |
| `8` | `standstill_timeout` | `uint32` milliseconds | `10,000 ms` | No-progress timeout before standstill recovery or rebroadcast logic triggers. |
| `9` | `standstill_max_egress_bytes_per_s` | `uint32` number | `6,553,600` (`50 << 17`) | Egress rate cap used during standstill rebroadcast. |
| `10` | `max_leader_window_desync` | `uint32` number | `250` | Maximum tolerated future leader-window distance for inbound Simplex traffic. |
Comment on lines +589 to +590
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tiny inconsistency in the Stored as column: rows for IDs 9, 10, 12 use uint32 number while the rest are uint32 milliseconds / float32 bits in uint32. number adds no info that uint32 doesn't already carry

wdyt to drop the suffix on the dimensionless rows so the column reads uint32 / uint32 milliseconds / float32 bits in uint32?

Suggested change
| `9` | `standstill_max_egress_bytes_per_s` | `uint32` number | `6,553,600` (`50 << 17`) | Egress rate cap used during standstill rebroadcast. |
| `10` | `max_leader_window_desync` | `uint32` number | `250` | Maximum tolerated future leader-window distance for inbound Simplex traffic. |
| `9` | `standstill_max_egress_bytes_per_s` | `uint32` | `6,553,600` (`50 << 17`) | Egress rate cap used during standstill rebroadcast. |
| `10` | `max_leader_window_desync` | `uint32` | `250` | Maximum tolerated future leader-window distance for inbound Simplex traffic. |

| `11` | `bad_signature_ban_duration` | `uint32` milliseconds | `5000 ms` | Temporary ban duration after receiving bad signatures from a peer. |
| `12` | `candidate_resolve_rate_limit` | `uint32` number | `10` | Per-peer rate limit for candidate resolution requests. |
| `13` | `min_block_interval` | `uint32` milliseconds | `0 ms` | Minimum interval between parent block time and the next locally generated block. |
| `14` | `no_empty_blocks_on_error_timeout` | `uint32` milliseconds | `15,000 ms` | How long empty-block fallback is allowed after the last finalized block when collation fails or times out. |

[Parameter #30 on mainnet](https://tonviewer.com/config#30)

## Param 31: fee-exempt contracts

This parameter represents the configuration of smart contract addresses from which no fees are charged for either gas or storage, and where **tick-tock** transactions can be created. The list usually includes governance contracts. The parameter is presented as a binary tree structure — a tree (HashMap 256), where the keys are a 256-bit representation of the address. Only addresses in the masterchain can be present in this list.
Expand Down
Loading