arkchannel: Add durable channel lifecycle - #1190
Conversation
Model funding, activation, payments, cooperative settlement, materialization, and recovery as one restart-safe protofsm lifecycle.
Adapt prepared OOR transfers and the VTXO unroller to the channel FSM without moving either subsystem into the channel domain.
Store channel state, recovery handoff, receive reservations, and pre-commit expiry with role-relative balances and idempotent transitions.
Expose the client-hub negotiation and process-control messages needed to operate one durable channel lifecycle.
Allow the wallet and Ark channel peers to share one mailbox transport without colliding service registrations or delivery cursors.
There was a problem hiding this comment.
Pull request overview
This PR introduces the core “Ark channel” lifecycle plumbing across transport, persistence, and protocol surfaces. It extends the mailbox connector to support per-connector reply mailboxes and runtime namespaces, and adds a new arkchannel domain package with durable coordination logic, DB storage/migrations, and RPC protos.
Changes:
- Add
RuntimeID+ReplyMailboxIDsupport toserverconnso multiple independent connectors can share an authenticated identity while isolating ingress and durable state. - Introduce Ark-channel coordination domain (
arkchannel) including actions/events, cooperative close + backing validation logic, and bridges to OOR + unroll subsystems. - Add SQL migrations + sqlc queries/models and protobuf definitions for Ark-channel control and peer protocols.
Reviewed changes
Copilot reviewed 49 out of 51 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| serverconn/unary_facade.go | Set RPC ReplyTo using the configured reply mailbox. |
| serverconn/unary_facade_test.go | Assert default and isolated reply-mailbox behavior. |
| serverconn/types.go | Add RuntimeID/ReplyMailboxID and helper replyMailboxID(). |
| serverconn/runtime.go | Namespace durable actor IDs via runtimeID(). |
| serverconn/runtime_test.go | Verify distinct runtime IDs don’t collide across runtimes. |
| serverconn/ingress.go | Pull/Ack/log using reply mailbox; namespace checkpoints by runtime ID. |
| serverconn/ingress_error_test.go | Verify ingress uses ReplyMailboxID for Pull/Ack. |
| serverconn/heartbeat.go | Use reply mailbox for heartbeat RPC ReplyTo. |
| serverconn/actor.go | Add runtimeID() helper; use reply mailbox for client event/unary sends. |
| scripts/gen_protos.sh | Generate protos for the new rpc/arkchannelrpc package. |
| rpc/arkchannelrpc/ark_channel.proto | Define Ark-channel local control RPCs + authenticated peer services/messages. |
| db/store.go | Add NewArkChannelStore constructor on db.Store. |
| db/sqlc/schemas/generated_schema.sql | Include ark_channels table and indexes in generated schema output. |
| db/sqlc/queries/ark_channels.sql | Add sqlc queries for Ark channel CRUD/CAS/list operations. |
| db/sqlc/querier.go | Extend sqlc Querier with Ark channel query methods. |
| db/sqlc/models.go | Add sqlc model struct for ArkChannel. |
| db/sqlc/migrations/000019_ark_channels.up.sql | Create initial ark_channels table + indexes. |
| db/sqlc/migrations/000019_ark_channels.down.sql | Drop ark_channels table. |
| db/sqlc/migrations/000020_ark_channel_recovery.up.sql | Add recovery-related columns to ark_channels. |
| db/sqlc/migrations/000020_ark_channel_recovery.down.sql | Remove recovery-related columns. |
| db/sqlc/migrations/000021_ark_channel_pre_ponr_expiry.up.sql | Add pre_ponr_started_at and backfill for existing rows. |
| db/sqlc/migrations/000021_ark_channel_pre_ponr_expiry.down.sql | Drop pre_ponr_started_at. |
| db/migrations.go | Bump LatestMigrationVersion to 21. |
| db/ark_channel_store_test.go | End-to-end coverage for Ark channel store persistence + CAS behavior. |
| arkchannel/unrollbridge/controller.go | Bridge Ark channel materialization to the unroll registry + policy resolver. |
| arkchannel/unrollbridge/controller_test.go | Unit tests for unroll bridge admission + resolver behavior. |
| arkchannel/types.go | Define core Ark-channel terms, phases, bindings, backing validation, and cloning. |
| arkchannel/service.go | Service layer coordinating durable state transitions + executing actions. |
| arkchannel/service_test.go | Service workflow tests including replay/resume/error aggregation. |
| arkchannel/recovery.go | Define/export recovery package structures + validation/cloning. |
| arkchannel/recovery_test.go | Validate deep clone behavior for recovery packages. |
| arkchannel/payment_bridge_test.go | Add tests covering payment-bridge invariants and transitions (test-only changes shown). |
| arkchannel/oorbridge/preparer.go | Implement durable OOR preparation/lookup flow for channel-policy VTXO creation. |
| arkchannel/oorbridge/controller.go | Implement commit/abort control + terminal result mapping for prepared OOR sessions. |
| arkchannel/native_executor.go | Route Ark-channel durable actions into native subsystems (OOR/unroll/lnd adapters). |
| arkchannel/native_executor_test.go | Verify executor dispatch + funder-only fencing of OOR control paths. |
| arkchannel/events.go | Define sealed event + action types for the Ark-channel FSM boundary. |
| arkchannel/coordinator.go | Durable coordinator for CAS-based event application and resumable actions. |
| arkchannel/cooperative_close.go | Deterministic cooperative close proposal/template + signature verification. |
| arkchannel/cooperative_close_test.go | Cooperative close invariants + canonical proposal/signature tests. |
| arkchannel/backing.go | Validate/construct backing tx template and final signed backing record. |
| arkchannel/backing_test.go | Backing template validation and negative-case tests. |
Files not reviewed (1)
- db/sqlc/ark_channels.sql.go: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ebd9381555
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if len(tx.TxIn[0].Witness) == 0 { | ||
| return fmt.Errorf("backing transaction is not fully signed") |
There was a problem hiding this comment.
Verify the backing witness before accepting it
When a backing artifact is received from the peer or restored from storage, any arbitrary non-empty witness passes this check; unlike BackingTemplate.Complete, this method never executes the channel spend path against source.PkScript. Because applyBacking and the unroll resolver rely on Backing.Validate, an invalid signature can be persisted, allow the OOR transfer to commit, and later leave materialization with a transaction that consensus rejects.
Useful? React with 👍 / 👎.
| if !changed { | ||
| switch event.(type) { | ||
| case *SourceSpent, *RecoveryPackageInstalled, *OORFinalized, | ||
| *OORAborted: |
There was a problem hiding this comment.
Re-emit pending actions when completion facts are retried
If executing an action fails after its transition commits, retrying most triggering events silently returns no action because only these four event types consult PendingAction. For example, a transient CommitPreparedOOR failure after the second FundingFinalized leaves the record in PhaseBackingReady; retrying that same callback succeeds without retrying CommitOOR, stranding the channel until an explicit resume or process restart. The same gap affects failed negotiation and cooperative-close actions, so duplicate facts should replay the action already implied by the durable phase.
Useful? React with 👍 / 👎.
Summary
This is layer 2 of 5 in the Ark channels stack. It depends on #1189; the next layer is #1191.
Testing
go test ./arkchannel/... ./db ./serverconn ./rpc/arkchannelrpcmake buildmake lint-changed-local