feat(foundations): migrate ADNL documentation#2052
feat(foundations): migrate ADNL documentation#2052coalus wants to merge 3 commits intoton-org:mainfrom
Conversation
|
Skipping AI review because this PR is from a fork. A maintainer can start the review by commenting /review in this PR. |
📝 WalkthroughWalkthroughAdds a new "Network protocols" navigation group and redirects in Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
foundations/network/adnl-udp.mdx (1)
9-11: Prefer docs-owned routes for the DHT/RLDP links.Lines 9-11 and 181-188 hardcode
old-docs.ton.orgfor related protocol links.docs.jsonalready owns redirects for those topics, so these should point to the site-local routes instead; that keeps users ondocs.ton.organd avoids another content edit when DHT/RLDP are migrated.🔗 Suggested link cleanup
- ADNL over UDP is the protocol used by TON nodes to communicate with each other. It serves as the foundation for higher-level protocols such as [DHT](https://old-docs.ton.org/v3/documentation/network/protocols/dht/overview) and [RLDP](https://old-docs.ton.org/v3/documentation/network/protocols/rldp). + ADNL over UDP is the protocol used by TON nodes to communicate with each other. It serves as the foundation for higher-level protocols such as [DHT](/v3/documentation/network/protocols/dht/overview) and [RLDP](/v3/documentation/network/protocols/rldp).Apply the same replacement in the See also list.
Also applies to: 181-188
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@foundations/network/adnl-udp.mdx` around lines 9 - 11, Replace hardcoded external links to "https://old-docs.ton.org/..." with the site-local routes defined in docs.json for the DHT and RLDP pages in the ADNL over UDP doc: update the two inline links that currently point to the DHT and RLDP old-docs URLs (the ones used in the paragraph contrasting ADNL over UDP and ADNL over TCP) and the same two entries in the "See also" list to use the local route paths (e.g., the canonical /foundations/... or /network/... routes managed by docs.json) so the links remain on docs.ton.org and follow existing redirects.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs.json`:
- Around line 1400-1401: The redirect entry mapping "source":
"/v3/documentation/network/protocols/adnl/low-level" currently points to the
generic overview; update its "destination" to the migrated deep-dive path
"/foundations/network/adnl-udp" so legacy deep links resolve to the
low-level/channel material, and ensure the chained redirect for
"/learn/networking/low-level-adnl" (if present elsewhere) also targets
"/foundations/network/adnl-udp" to keep both redirects consistent.
In `@foundations/network/adnl-tcp.mdx`:
- Around line 55-57: Update the hyperlink target so the sentence "Data is
serialized using [TL]" points to the TL overview, not the TL‑B overview: change
the link in the ADNL TCP handshake paragraph (the
"[TL](/languages/tl-b/overview)" occurrence in foundations/network/adnl-tcp.mdx)
to the TL overview URL (for example "/languages/tl/overview") so implementers
are directed to the correct serialization format.
In `@foundations/network/adnl.mdx`:
- Around line 9-124: The ADNL overview omits definitions for "public/private
overlays" and "ADNL forks" referenced by issue `#1035`; add a short dedicated
subsection (e.g., "## Overlays and ADNL forks") that: defines public vs private
overlays, explains how ADNL forks occur and their effect on peer
discovery/neighbour tables, and links to any migrated detailed pages or the
original issue for full specs; place this subsection near "Neighbor tables" or
before "P2P protocol (ADNL over UDP)" and reference existing pages like "ADNL
TCP" / "ADNL UDP" for examples so readers can follow up.
- Around line 67-73: The byte-range notation for deriving AES key/nonce from
secret and hash is ambiguous; update the descriptions around
SHA-256(aes_params), key and nonce so they use explicit half-open ranges or byte
counts (e.g., secret[0..16) meaning bytes 0–15, hash[16..32) meaning bytes
16–31) and state resulting lengths (key = 32 bytes, nonce = 12 bytes), and make
the identical change in the TCP page copy; reference the symbols `secret`, `hash
= SHA-256(aes_params)`, `key` and `nonce` so the two occurrences are updated
consistently.
---
Nitpick comments:
In `@foundations/network/adnl-udp.mdx`:
- Around line 9-11: Replace hardcoded external links to
"https://old-docs.ton.org/..." with the site-local routes defined in docs.json
for the DHT and RLDP pages in the ADNL over UDP doc: update the two inline links
that currently point to the DHT and RLDP old-docs URLs (the ones used in the
paragraph contrasting ADNL over UDP and ADNL over TCP) and the same two entries
in the "See also" list to use the local route paths (e.g., the canonical
/foundations/... or /network/... routes managed by docs.json) so the links
remain on docs.ton.org and follow existing redirects.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f54e7dd6-96e0-46f0-986e-be6ab7bbfb1f
📒 Files selected for processing (4)
docs.jsonfoundations/network/adnl-tcp.mdxfoundations/network/adnl-udp.mdxfoundations/network/adnl.mdx
| "source": "/v3/documentation/network/protocols/adnl/low-level", | ||
| "destination": "https://old-docs.ton.org/v3/documentation/network/protocols/adnl/low-level", | ||
| "destination": "/foundations/network/adnl", |
There was a problem hiding this comment.
Route the legacy low-level ADNL URL to the UDP page.
/v3/documentation/network/protocols/adnl/low-level was the old deep-dive entry, but Line 1401 now sends it to the generic overview. The migrated low-level/channel material lives in /foundations/network/adnl-udp, so existing deep links lose the implementation details they used to surface. /learn/networking/low-level-adnl inherits the same mismatch through the chained redirect.
🔀 Suggested redirect fix
{
"source": "/v3/documentation/network/protocols/adnl/low-level",
- "destination": "/foundations/network/adnl",
+ "destination": "/foundations/network/adnl-udp",
"permanent": true
},📝 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.
| "source": "/v3/documentation/network/protocols/adnl/low-level", | |
| "destination": "https://old-docs.ton.org/v3/documentation/network/protocols/adnl/low-level", | |
| "destination": "/foundations/network/adnl", | |
| "source": "/v3/documentation/network/protocols/adnl/low-level", | |
| "destination": "/foundations/network/adnl-udp", |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs.json` around lines 1400 - 1401, The redirect entry mapping "source":
"/v3/documentation/network/protocols/adnl/low-level" currently points to the
generic overview; update its "destination" to the migrated deep-dive path
"/foundations/network/adnl-udp" so legacy deep links resolve to the
low-level/channel material, and ensure the chained redirect for
"/learn/networking/low-level-adnl" (if present elsewhere) also targets
"/foundations/network/adnl-udp" to keep both redirects consistent.
| The Abstract Datagram Network Layer (ADNL) is the core networking protocol of the TON network. It is a peer-to-peer, unreliable datagram protocol that operates over both UDP and TCP. | ||
|
|
||
| Higher-level protocols such as [RLDP](https://old-docs.ton.org/v3/documentation/network/protocols/rldp) and [DHT](https://old-docs.ton.org/v3/documentation/network/protocols/dht/overview) are built on top of ADNL. | ||
|
|
||
| ## ADNL address | ||
|
|
||
| Each participant in the network has a 256-bit ADNL address. ADNL allows sending and receiving datagrams using only these addresses, hiding the underlying IP addresses and ports. | ||
|
|
||
| An ADNL address is derived as: | ||
|
|
||
| ```text | ||
| address = SHA-256(type_id || public_key) | ||
| ``` | ||
|
|
||
| where `type_id` is a little-endian uint32 indicating the key type (the TL-serialized key object ID). The corresponding private key must be known to receive and decrypt messages sent to a given address. | ||
|
|
||
| ## Public-key cryptosystems | ||
|
|
||
| | `type_id` | Cryptosystem | | ||
| | ------------ | ------------ | | ||
| | `0x4813b4c6` | ed25519 | | ||
|
|
||
| <Aside type="note"> | ||
| To perform x25519, the keypair must be generated in x25519 format. The public key is transmitted over the network in ed25519 format, so conversion from x25519 to ed25519 is required. See [this example](https://github.com/andreypfau/curve25519-kotlin/blob/f008dbc2c0ebc3ed6ca5d3251ffb7cf48edc91e2/src/commonMain/kotlin/curve25519/MontgomeryPoint.kt#L39) for Kotlin. | ||
| </Aside> | ||
|
|
||
| ## Peer identity | ||
|
|
||
| Each peer must have at least one identity, consisting of a keypair for the Diffie-Hellman exchange. An abstract network address is derived from the public key as described above. | ||
|
|
||
| ## Encryption and security | ||
|
|
||
| ADNL packets can be signed and encrypted. When signatures are present, recipients verify integrity and authenticity. | ||
|
|
||
| ## Neighbor tables | ||
|
|
||
| A TON ADNL node maintains a _neighbor table_ containing information about known nodes: their abstract addresses, public keys, IP addresses, and UDP ports. The table is updated over time as new entries are discovered from query responses and outdated records are removed. | ||
|
|
||
| ## Client-server protocol (ADNL over TCP) | ||
|
|
||
| The client connects to the server using TCP and sends a handshake packet containing a server abstract address, a client public key, and encrypted AES-CTR session parameters. | ||
|
|
||
| ### Handshake | ||
|
|
||
| 1. The client performs a key agreement protocol (x25519) using its private key and the server's public key to derive a `secret`. | ||
|
|
||
| 1. The client generates AES-CTR session parameters (16-byte nonce and 32-byte key for both transmit and receive directions) and serializes them into a 160-byte buffer: | ||
|
|
||
| | Parameter | Size | | ||
| | ---------- | -------- | | ||
| | `rx_key` | 32 bytes | | ||
| | `tx_key` | 32 bytes | | ||
| | `rx_nonce` | 16 bytes | | ||
| | `tx_nonce` | 16 bytes | | ||
| | `padding` | 64 bytes | | ||
|
|
||
| Fill the entire 160-byte buffer with random bytes. Otherwise, an attacker may perform an active man-in-the-middle attack using compromised AES-CTR session parameters. | ||
|
|
||
| 1. The client encrypts the session parameters using AES-256-CTR with a key and nonce derived from the `secret` and the SHA-256 hash of the parameters: | ||
|
|
||
| ```cpp | ||
| hash = SHA-256(aes_params) | ||
| key = secret[0..16] || hash[16..32] | ||
| nonce = hash[0..4] || secret[20..32] | ||
| ``` | ||
|
|
||
| 1. The client sends the 256-byte handshake packet: | ||
|
|
||
| | Parameter | Size | Description | | ||
| | --------------------- | --------- | ------------------------------------- | | ||
| | `receiver_address` | 32 bytes | Server peer identity | | ||
| | `sender_public` | 32 bytes | Client public key | | ||
| | `SHA-256(aes_params)` | 32 bytes | Integrity proof of session parameters | | ||
| | `E(aes_params)` | 160 bytes | Encrypted session parameters | | ||
|
|
||
| 1. The server decrypts the session parameters and verifies: | ||
|
|
||
| - It possesses the private key for `receiver_address`. | ||
| - `SHA-256(aes_params) == SHA-256(D(E(aes_params)))`. | ||
|
|
||
| If any check fails, the server drops the connection. If all checks pass, the server sends an empty datagram to prove private key ownership. | ||
|
|
||
| ### Datagram | ||
|
|
||
| Both sides initialize two AES-CTR instances (transmit and receive) using the session parameters from the handshake. | ||
|
|
||
| Each datagram has the following structure: | ||
|
|
||
| | Parameter | Size | Description | | ||
| | --------- | ----------------------- | ------------------------------------------- | | ||
| | `length` | 4 bytes (little-endian) | Total datagram length, excluding this field | | ||
| | `nonce` | 32 bytes | Random value | | ||
| | `buffer` | `length - 64` bytes | Payload | | ||
| | `hash` | 32 bytes | `SHA-256(nonce \|\| buffer)` for integrity | | ||
|
|
||
| The entire structure is encrypted using the corresponding AES-CTR instance. The receiver decrypts the first 4 bytes to get the length, reads exactly that many bytes, and verifies the hash. On failure, the connection must be dropped. | ||
|
|
||
| The first datagram always goes from the server to the client after a successful handshake, with an empty buffer. | ||
|
|
||
| For practical examples of ADNL over TCP, including liteserver communication, ping/pong, and smart contract method calls, see [ADNL TCP](/foundations/network/adnl-tcp). | ||
|
|
||
| ### Security considerations | ||
|
|
||
| **Handshake padding**: The 64-byte padding field in the handshake is unused by current implementations. It may have been intended to support future migration to alternative encryption primitives. | ||
|
|
||
| **Session key derivation**: The encryption key is derived from both the static `secret` and `SHA-256(aes_params)`. Since `aes_params` is random per session, this ensures a unique encryption key for each connection. However, the concatenation-based key derivation algorithm (mixing subarrays of secret and hash) is considered suboptimal by modern standards. | ||
|
|
||
| **Datagram nonce**: In CTR mode, AES functions as a stream cipher, making bit-flipping attacks possible if an attacker knows the plaintext. The nonce field prevents this: even if an attacker can reconstruct the key stream and compute a valid `SHA-256(buffer)`, they cannot forge the hash without knowing the random nonce. | ||
|
|
||
| ## P2P protocol (ADNL over UDP) | ||
|
|
||
| In the UDP variant, the connection is established simultaneously with sending initial data. If the initiator sends a _create channel_ message, a channel key is calculated and creation is confirmed by the peer. | ||
|
|
||
| Unlike TCP, the UDP implementation uses channels for ongoing communication. Encryption keys are derived from the client's private key and the peer's public key (known from configuration or discovered from other nodes). | ||
|
|
||
| For the full protocol walkthrough with packet examples, see [ADNL UDP](/foundations/network/adnl-udp). |
There was a problem hiding this comment.
The migration still omits overlays and ADNL fork behavior.
Issue #1035 explicitly calls out public/private overlays and ADNL forks, but this overview never defines those concepts or links to a migrated replacement. As merged, the new foundations section still leaves part of the promised ADNL coverage behind.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@foundations/network/adnl.mdx` around lines 9 - 124, The ADNL overview omits
definitions for "public/private overlays" and "ADNL forks" referenced by issue
`#1035`; add a short dedicated subsection (e.g., "## Overlays and ADNL forks")
that: defines public vs private overlays, explains how ADNL forks occur and
their effect on peer discovery/neighbour tables, and links to any migrated
detailed pages or the original issue for full specs; place this subsection near
"Neighbor tables" or before "P2P protocol (ADNL over UDP)" and reference
existing pages like "ADNL TCP" / "ADNL UDP" for examples so readers can follow
up.
| 1. The client encrypts the session parameters using AES-256-CTR with a key and nonce derived from the `secret` and the SHA-256 hash of the parameters: | ||
|
|
||
| ```cpp | ||
| hash = SHA-256(aes_params) | ||
| key = secret[0..16] || hash[16..32] | ||
| nonce = hash[0..4] || secret[20..32] | ||
| ``` |
There was a problem hiding this comment.
Make the handshake byte ranges unambiguous.
Lines 71-72 use 0..16 / 16..32 notation without saying whether the end index is inclusive. If a reader treats those literally, the derived AES key/nonce lengths are wrong. Please spell these as half-open ranges or explicit byte counts. The TCP page repeats the same formula later, so both copies should use the same notation.
🧮 Suggested notation fix
- hash = SHA-256(aes_params)
- key = secret[0..16] || hash[16..32]
- nonce = hash[0..4] || secret[20..32]
+ hash = SHA-256(aes_params)
+ key = secret[0..16) || hash[16..32)
+ nonce = hash[0..4) || secret[20..32)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@foundations/network/adnl.mdx` around lines 67 - 73, The byte-range notation
for deriving AES key/nonce from secret and hash is ambiguous; update the
descriptions around SHA-256(aes_params), key and nonce so they use explicit
half-open ranges or byte counts (e.g., secret[0..16) meaning bytes 0–15,
hash[16..32) meaning bytes 16–31) and state resulting lengths (key = 32 bytes,
nonce = 12 bytes), and make the identical change in the TCP page copy; reference
the symbols `secret`, `hash = SHA-256(aes_params)`, `key` and `nonce` so the two
occurrences are updated consistently.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
foundations/network/adnl-tcp.mdx (1)
57-57: Prefer internal TL docs link for consistency and longevity.Line 57 points to
core.telegram.org. Consider linking to your internal TL docs page so navigation stays in-repo and less sensitive to external URL drift.Suggested fix
-After this exchange the connection is established. Data is serialized using [TL (Type Language)](https://core.telegram.org/mtproto/TL). +After this exchange the connection is established. Data is serialized using [TL (Type Language)](/languages/tl/overview).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@foundations/network/adnl-tcp.mdx` at line 57, Replace the external core.telegram.org link used in the sentence "Data is serialized using [TL (Type Language)](https://core.telegram.org/mtproto/TL)" with the project's internal TL documentation page to ensure link stability; update the Markdown link target while keeping the link text "TL (Type Language)" unchanged so references to TL remain consistent across the repo (edit the adnl-tcp.mdx line containing that link).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@foundations/network/adnl-tcp.mdx`:
- Around line 136-138: The schema block is labeled as "tlb" but is a TL schema;
update the code fence label from tlb to tl for the snippet containing
liteServer.runSmcMethod (the line starting with "liteServer.runSmcMethod mode:#
... = liteServer.RunMethodResult") so syntax highlighting and reader
expectations match the TL grammar.
---
Nitpick comments:
In `@foundations/network/adnl-tcp.mdx`:
- Line 57: Replace the external core.telegram.org link used in the sentence
"Data is serialized using [TL (Type
Language)](https://core.telegram.org/mtproto/TL)" with the project's internal TL
documentation page to ensure link stability; update the Markdown link target
while keeping the link text "TL (Type Language)" unchanged so references to TL
remain consistent across the repo (edit the adnl-tcp.mdx line containing that
link).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 51423583-f7f6-4a66-8d58-5d093dd14f14
📒 Files selected for processing (2)
foundations/network/adnl-tcp.mdxfoundations/network/adnl.mdx
✅ Files skipped from review due to trivial changes (1)
- foundations/network/adnl.mdx
| ```tlb | ||
| liteServer.runSmcMethod mode:# id:tonNode.blockIdExt account:liteServer.accountId method_id:long params:bytes = liteServer.RunMethodResult | ||
| ``` |
There was a problem hiding this comment.
Use tl instead of tlb for this schema block.
Line 136 labels the snippet as tlb, but liteServer.runSmcMethod ... is a TL schema, not TL-B. This can mislead readers and syntax highlighting.
Suggested fix
-```tlb
+```tl
liteServer.runSmcMethod mode:# id:tonNode.blockIdExt account:liteServer.accountId method_id:long params:bytes = liteServer.RunMethodResult</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **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.
```suggestion
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@foundations/network/adnl-tcp.mdx` around lines 136 - 138, The schema block is
labeled as "tlb" but is a TL schema; update the code fence label from tlb to tl
for the snippet containing liteServer.runSmcMethod (the line starting with
"liteServer.runSmcMethod mode:# ... = liteServer.RunMethodResult") so syntax
highlighting and reader expectations match the TL grammar.
resolves #1035
Summary by CodeRabbit