x/state_channel Real (skeleton)
Nitro / ForceMove turn-taking over a Cosmos backend. Open with one tx, transact off-chain, close with one tx. 24-hour challenge window. Highest co-signed turn_num wins settlement.
Channel state machine
OpenChannel(escrow) CooperativeClose
(none) ----------------------------> OPEN -------------------> CLOSED
|
ChallengeChannel|
v
CHALLENGED
(24h window)
RespondChallenge|
(higher turn)
v
CHALLENGED -- EndBlocker --> SETTLED
(window
elapses)
The off-chain ChannelState carries a monotonic turn_num; whichever side presents the highest co-signed turn_num during the challenge window wins. MsgChallengeChannel opens the window; MsgRespondChallenge overwrites the on-chain best_state if state.turn_num > best_state.turn_num.
Genesis params
| Param | Default | Notes |
|---|---|---|
channel_challenge_blocks | 86,487 | ~24h at 999ms blocks |
channel_max_duration | 86,487 * 30 | ~30 days deadline ceiling |
channel_max_participants | 9 | per design language |
Messages
MsgOpenChannel { user, host, model_id, max_calls, deadline,
escrow_amount }
MsgCloseChannel { signer, channel_id, final_state } // cooperative
MsgChallengeChannel { signer, channel_id, last_signed_state }
MsgRespondChallenge { signer, channel_id, higher_turn_state }
MsgUpdateParams { authority, params } // gov-only
Queries
Channel(id)ChannelsByUser(user_addr, pagination)ChannelsByHost(host_addr, pagination)
State layout
KeyPrefixChannel channel_id -> Channel KeyPrefixUserIndex (user_addr, channel_id) -> () KeyPrefixHostIndex (host_addr, channel_id) -> () KeyPrefixExpiryIndex (expiry_height, channel_id) -> () KeyPrefixCounter next_channel_id
Settlement payout math
On settle (cooperative or post-challenge):
spent_amount = best_state.spent_amount to_host = spent_amount refund_to_user = channel.escrow_amount - spent_amount take_rate = (settled separately by x/compute_market take rate if applicable)
What's wired today
Real KV layout, channel ID counter, all iterators, ValidateBasic for all 5 msgs and ChannelState.ValidateForChannel, the OPEN -> CHALLENGED -> SETTLED / CLOSED transitions, strict turn_num monotonicity check, settlement payout math, genesis init/export.
Phase 1 Bank movements, canonical ChannelState encoding + secp256k1 signature verification in VerifyChannelStateSig, pagination, typed events.
See also
- SPUR-IC spec for the off-chain receipt format that gets co-signed into
ChannelState - Tenant guide for the channel-open + dispute flow
- Source: x/state_channel/