YNU-864: Learn and protocol reconciliation#158
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
|
|
||
| Transitions that map to `OPERATE` do not require on-chain checkpointing under normal operation. | ||
|
|
||
| Escrow and migration transition names are included for protocol accuracy. Their public app-builder workflow is not documented yet. |
There was a problem hiding this comment.
I think it is worth mentioning not only that migration and escrow are not documented, but that they are not implemented by the Nitronode, although protocol already describes them.
| ## Node Liquidity and Cross-Chain Trust | ||
|
|
||
| Each User channel is opened with a Node. To maintain cross-chain functionality, the Node MUST hold sufficient liquidity on each supported blockchain to satisfy off-chain state allocations. | ||
| Each User channel is opened with a Node. Cross-chain functionality depends on the Node operator maintaining enough liquidity on each supported blockchain to satisfy off-chain state allocations. | ||
|
|
||
| When a User with home chain A transfers assets to a User with home chain B, the Node receives the amount on chain A and allocates from its own balance to the recipient on chain B. If the recipient later enforces state on chain B and the Node lacks sufficient liquidity there, on-chain enforcement will fail. |
There was a problem hiding this comment.
As a matter of fact, liquidity also matters for single-chain operations, because during transfer sender's funds are not returned to the node immediately, but after some lag when sender's state is enforced on-chain.
I think we should mention it here as well.
| | Cooperative close | A participant submits a state with the `CLOSE` intent, signed by all participants. | | ||
| | Unilateral close | After challenge expiry, any party MAY call close without additional signatures. Funds are released according to the last enforced state's allocations. | | ||
|
|
||
| It is not possible to close an already `CLOSED` or `MIGRATED_OUT` channel. In both close paths, locked funds are set to zero and the channel lifecycle ends. |
There was a problem hiding this comment.
Generally, I think we should leave cross-chain functionality docs, because the protocol is already defined - it is the Nitronode, which does not implement the cross-chain funtionality.
Therefore, my comment applies not only to this place, but to all other cross-chain concepts that were removed from protocol section.
@philanton , @ihsraham , WDYT?
| An escrow is not a separate protocol entity with its own state. It is an on-chain record derived from a channel state transition. | ||
|
|
||
| ## Cross-Chain Deposit | ||
| :::caution Builder workflow not documented yet |
There was a problem hiding this comment.
This caution and all other similar mentions in the documentation should say that escrow and migration are supported by the protocol, but not implemented by the Nitronode.
|
|
||
| | Path | Use when | | ||
| | --- | --- | | ||
| | **Compat first** | You need the smallest migration and want familiar helper shapes while moving to the v1 package family. | |
There was a problem hiding this comment.
It should be explicitly mentioned here that staying with compat is NOT a long-term decision. Compat is just a step for an application to adapt to v1 quickly, but the full migration is still needed for better DX.
|
|
||
| 1. Pick compat-first or native v1. | ||
| 2. Replace package imports. | ||
| 3. Review amount units for every transfer, deposit, withdrawal, and app-session call. |
There was a problem hiding this comment.
Is reviewing amounts a requirement if migrating with compat? I thought it performs the necessary formatting under the hood.
| If there's an ongoing transition, the Clearnode will return a relevant error and the submission is rejected. | ||
| If there's an ongoing transition, the Nitronode will return a relevant error and the submission is rejected. | ||
|
|
||
| **Atomic Operations**: `escrow_deposit`, `escrow_withdrawal`, and `home-chain migration` operations are considered as one atomic operation. This means that if, for example, an escrow deposit was started with `initiate_escrow_deposit` transition, then no other states will be issued apart from `finalize_escrow_deposit`. Only after finalization can a `transfer` (or other non-`finalize_escrow_deposit` transition) be accepted by the Node. |
There was a problem hiding this comment.
I think it is better to keep the previous version (red). The new version only vaguely describes the atomicity.
|
|
||
| | Term | Meaning | | ||
| | --- | --- | | ||
| | **App session** | An off-chain application-specific state funded from a channel through `commit` transitions and settled back through `release` transitions. | |
There was a problem hiding this comment.
So, "App session [is a] ... state ..."? This should be reformulated to include application specific logic, other users, collecting signatures etc.
| | **Channel** | A user-node relationship for one asset, with signed state updates and an on-chain enforcement path. | | ||
| | **Channel state** | The signed record of channel version, transition, ledgers, and participant signatures. | | ||
| | **ChannelHub** | The v1 on-chain entrypoint for channel creation, deposits, withdrawals, checkpoints, challenges, and close operations. | | ||
| | **Checkpoint** | An on-chain submission that records a valid signed state without necessarily closing the channel. | |
There was a problem hiding this comment.
We use these terms interchangiably.
| | **Checkpoint** | An on-chain submission that records a valid signed state without necessarily closing the channel. | | |
| | **Checkpoint / enforcement** | An on-chain submission that records a valid signed state without necessarily closing the channel. | |
| | **Non-home ledger** | The secondary ledger used when a cross-chain operation is in progress. It is empty during ordinary same-chain operation. | | ||
| | **Pending state** | A Node-issued state with only the Node signature. It becomes enforceable only after the user acknowledges it. | | ||
| | **Quorum** | The signature threshold required by an app session before an app-state update is accepted. | | ||
| | **Session key** | A scoped signing key an application can use for app-session updates without asking the wallet to sign every step. | |
There was a problem hiding this comment.
There is a concept of a state channel session key as well, not only for an app session.
| | `void` | No channel exists yet. | | ||
| | `open` | The channel exists and can accept normal state updates. | | ||
| | `challenged` | A challenge is active and the response window is running. | | ||
| | `closing` | The channel is in the close path after a final state or expired challenge. | |
There was a problem hiding this comment.
The channel does NOT have closing status after a challenge was expired. The status does not change after expiration - it only does after a channel was closed.
closing is only for when the Node has issued the finalization state.
| # Challenge-Response & Disputes | ||
|
|
||
| In this guide, you will learn how Yellow Network resolves disputes and ensures your funds are always recoverable. | ||
| Challenge-response is the on-chain fallback that lets a participant enforce the latest valid channel state if the counterparty stops cooperating. |
There was a problem hiding this comment.
Why is this called "challenge-response", and not just "challenge" concept?
| ## Why Challenge-Response Matters | ||
|
|
||
| In any off-chain system, a critical question arises: **What if someone tries to cheat?** | ||
| In any off-chain system, a critical question arises: what if someone tries to settle an old state? | ||
|
|
||
| <Tooltip content={tooltipDefinitions.channel}>State channels</Tooltip> solve this with a challenge-response mechanism: | ||
| <Tooltip content={tooltipDefinitions.channel}>State channels</Tooltip> answer this with versioned, signed states: | ||
|
|
||
| 1. Anyone can submit a <Tooltip content={tooltipDefinitions.channelState}>state</Tooltip> to the blockchain | ||
| 2. Counterparties have time to respond with a newer state | ||
| 3. The newest valid state always wins | ||
| 4. Funds are distributed according to that state | ||
|
|
||
| --- | ||
| 1. A participant submits a signed <Tooltip content={tooltipDefinitions.channelState}>state</Tooltip> on-chain. | ||
| 2. The counterparty has a challenge window to respond with a newer valid state. | ||
| 3. The newest valid state wins. | ||
| 4. Funds are released according to the final accepted state. |
There was a problem hiding this comment.
Actually, "settle an old state" and "challenge" are unrelated.
Settling an old state is guarded by versioning system, which declines the state with a version less than or equal to an already enforced one.
Challenge, on the other hand, is useful when the other party (either user or Node) is unresponsive for a specific action, or trust was broken. In such case the channel can be closed unilaterally after the challenge period has passed and if it was not resolved by a counterparty with a newer valid state.
| | Guarantee | How it is achieved | | ||
| | --- | --- | | ||
| | **Fund custody** | ChannelHub holds channel funds on-chain, not Nitronode. | | ||
| | **State validity** | Only valid signed states can advance the channel. | |
There was a problem hiding this comment.
| | **State validity** | Only valid signed states can advance the channel. | | |
| | **State validity** | Only valid (singed by both states with a greater version and a correct intent) states can advance the channel. | |
| 3. **Response window**: a counterparty can submit a newer valid state. | ||
| 4. **Resolution**: after timeout, the latest accepted state can be closed. |
There was a problem hiding this comment.
This sounds like if a newer state was accepted during challenge, the channel will still close, but with that latter state.
Instead, there should be a fork: "Resolved: a channel is resolved with a newer valid state, and channel lifecycle continues", or "Timed-out: if no valid state is submitted to counter-act the challenge during the specific period, the channel can be closed with the state it was challenged with".
| ### States are signed | ||
|
|
||
| With the default SimpleConsensus adjudicator, both parties must sign every state. If someone signed a state, they can't later claim they didn't agree. | ||
| The default v1 channel path requires both user and node signatures for enforceable states. A party that signed a state cannot later deny that signature. |
There was a problem hiding this comment.
As a matter of fact, for a state to be valid, it must be signed by both a user and the Node. Therefore, this sentence should be reformulated.
| | `checkpoint()` | Record a valid state without forcing closure. | Stays `open`. | | ||
| | `challenge()` | Start the on-chain dispute path. | Changes to `challenged`. | | ||
|
|
||
| Use checkpoint for safety snapshots. Use challenge when you need to force settlement. | ||
|
|
||
| --- | ||
| Use checkpoint for safety snapshots. Use challenge when you need to force settlement because a counterparty is not cooperating. |
There was a problem hiding this comment.
checkpoint(...) ChannelHub method can only be used with intent: OPERATE states. I would actually replace "checkpoint" term with "enforce" in all docs codebase, as "checkpoint" term collides with the same name ChannelHub function.
Also, there is no single function that updates the latest state on the ChannelHub - all functions are used.
| | **Nitronode goes offline** | Challenge with the latest signed state, then close after timeout. | | ||
| | **You lose state history** | An older state can be defeated by a newer valid state if the counterparty has it. | | ||
| | **Counterparty submits a stale state** | Submit a newer valid state during the challenge window. | | ||
| | **Block reorg occurs** | Replay confirmed chain state from the last trusted block. | |
There was a problem hiding this comment.
During the reorg, the dropped transaction is guaranteed to be included in the new chain fork soon. No need for a user to do anything.
| | --- | --- | | ||
| | **Nitronode goes offline** | Challenge with the latest signed state, then close after timeout. | | ||
| | **You lose state history** | An older state can be defeated by a newer valid state if the counterparty has it. | | ||
| | **Counterparty submits a stale state** | Submit a newer valid state during the challenge window. | |
There was a problem hiding this comment.
I think we should add 2 separate cases:
| | **Counterparty submits a stale state** | Submit a newer valid state during the challenge window. | | |
| | **Counterparty submits a stale state** | Update the channel on-chain by submitting a the latest valid state. | | |
| | **Counterparty challenges with a stale state** | Resolve the challenge by submitting the latest valid state during the challenge window. | |
| | --- | --- | | ||
| | **Challenge** | Starts on-chain dispute resolution. | | ||
| | **Response** | A newer valid state defeats an older challenged state. | | ||
| | **Timeout** | After expiry, the accepted state can be closed. | |
There was a problem hiding this comment.
| | **Timeout** | After expiry, the accepted state can be closed. | | |
| | **Challenge duration** | A time during which it is possible to resolve the challenge. After it expires, the channel can be closed with the state it was challenged with. | |
| 5. **No ongoing operation** exists for this channel (the Nitronode will deny the request otherwise). | ||
|
|
||
| :::note | ||
| The "no ongoing operation" requirement applies to ALL operations except `finalize_escrow_deposit`, `finalize_escrow_withdrawal`, and `finalize_migration`. |
There was a problem hiding this comment.
The note names finalize_escrow_deposit, finalize_escrow_withdrawal, and finalize_migration — these are RPC method names, a different layer from the transition literals (escrow_deposit, escrow_withdraw, migrate) introduced in the glossary and intent mapping. A reader coming from those new pages won't know these are the same operations at a different abstraction level. Suggest labelling them: (RPC operation names — see transition literals in the Glossary). Same issue at home-channel-withdrawal.mdx:54.
|
|
||
| **[App Session Deposit](./protocol-flows/app-session-deposit.mdx)**: Depositing funds into app sessions. | ||
|
|
||
| ## Migration |
There was a problem hiding this comment.
The body structure here implies the reading order: Core Concepts → Protocol Flows → Migration. But the Quick Reference table at lines 72–74 places Glossary and migration pages before Protocol Flows entries. A reader using the table as a reading guide follows a different order than the section structure suggests. Given the PR's intent that the What Changed page is pre-code orientation for returning builders, the table order (migration before protocol flows) is more useful — the body section placement is the one to reconcile upward, moving Migration before Protocol Flows.
Summary
Reconciles the Learn and Protocol docs with the current Nitrolite v1 behavior and terminology.
Changes
@erc7824/nitrolite@0.5.3.Rationale
The Learn pages should teach the current builder path without implying unfinished escrow/migration operations are ready for public app workflows. The escrow routes stay in place to avoid broken links, but now describe current documentation status and preserve only the transition-name context readers need when they encounter protocol/API references. The Protocol updates keep the conceptual model accurate while avoiding operational instructions for paths that are not productized for docs.yellow.org yet.
The new 0.5.3 mental model page is intentionally pre-code: it explains that Clearnode is now Nitronode, Custody is now ChannelHub, old auth handshakes are legacy/compat concepts, and app code should think in home channels, app sessions, signed state, and checkpointing. It does not replace the existing code migration docs; it links readers onward when they are ready to migrate code.
Validation
rg -n "Clearnode|clearnode|DISPUTE|DISPUTED|ChannelUpdate|BalanceUpdate" docs/nitrolite/learn docs/nitrolite/protocolreturns only intentional 0.5.3 migration/mental-model context.rg -n "Submitted by|how to work with escrow|step-by-step" docs/nitrolite/learn/protocol-flows/escrow-*returns no hits.rg -n "auth_request|auth_challenge|auth_verify" docs/nitrolite/learn/whats-new-from-0.5.3.mdxframes these only as legacy/compat concepts.rg -n "server-push|push notification|ChannelUpdate|BalanceUpdate" docs/nitrolite/learn/whats-new-from-0.5.3.mdxdoes not present server-push as active v1 behavior.git diff --checknpm run buildsucceeds. Existing broken-link and broken-anchor warnings remain; the follow-up Build/SDK + IA cleanup PR owns those.Review Status
Independently re-reviewed against
docs/reorg-for-v1; scope and validation match the changes above. Ready for review.