feat: harden LLM resolver settlement, recovery, and key management - #31
feat: harden LLM resolver settlement, recovery, and key management#31iamnycx wants to merge 4 commits into
Conversation
|
@iamnycx is attempting to deploy a commit to the nitish-bot-8298's projects Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughThe PR validates Arweave Resolution Spec references, restricts accepted outcomes, adds resolver rotation and timeout recovery, and implements explicit no-fault settlement for ChangesResolution lifecycle
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Resolver
participant SubmitLlmResolution
participant ProtocolConfig
participant LlmResolutionRound
Resolver->>SubmitLlmResolution: submit True, False, or Unresolvable
SubmitLlmResolution->>ProtocolConfig: verify resolver key
SubmitLlmResolution->>LlmResolutionRound: store validated outcome
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@programs/opal/src/instructions/recover_pending_llm.rs`:
- Around line 67-71: Update submit_llm_resolution to calculate the round’s
recovery deadline from requested_at and config.llm_resolution_timeout_seconds,
then reject submissions when now is at or beyond that deadline using the
appropriate OpalError. Reuse the same checked deadline logic and boundary
semantics as recover_pending_llm, while preserving submission behavior for
rounds still within the timeout.
🪄 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 Plus
Run ID: a422a664-7ff5-44e9-b73e-e6241f4603a8
📒 Files selected for processing (19)
README.mddocs/architecture.mddocs/glossary.mddocs/resolution.mddocs/tokenomics.mdprograms/opal/src/constants.rsprograms/opal/src/errors.rsprograms/opal/src/instructions/create_assertion.rsprograms/opal/src/instructions/finalize_llm_resolution.rsprograms/opal/src/instructions/finalize_vote_resolution_placeholder.rsprograms/opal/src/instructions/initialize_protocol_config.rsprograms/opal/src/instructions/mod.rsprograms/opal/src/instructions/recover_pending_llm.rsprograms/opal/src/instructions/submit_llm_resolution.rsprograms/opal/src/instructions/update_resolver.rsprograms/opal/src/lib.rsprograms/opal/src/state/protocol_config.rsprograms/opal/src/utils.rstests/opal.test.ts
| let recovery_deadline = checked_add_i64( | ||
| llm_round.requested_at, | ||
| config.llm_resolution_timeout_seconds, | ||
| )?; | ||
| require!(now >= recovery_deadline, OpalError::DeadlineNotReached); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Enforce the timeout in resolver submission too.
recover_pending_llm only makes recovery available after this deadline. The supplied submit_llm_resolution handler still accepts any PENDING_LLM round without checking requested_at, so a resolver can submit a decisive result after expiry before a recovery transaction lands. Reject late submissions using this same deadline.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@programs/opal/src/instructions/recover_pending_llm.rs` around lines 67 - 71,
Update submit_llm_resolution to calculate the round’s recovery deadline from
requested_at and config.llm_resolution_timeout_seconds, then reject submissions
when now is at or beyond that deadline using the appropriate OpalError. Reuse
the same checked deadline logic and boundary semantics as recover_pending_llm,
while preserving submission behavior for rounds still within the timeout.
Overview
This PR completes the on-chain safety and operational lifecycle required by the trusted Opal LLM resolver. It builds on #29, which introduced the dedicated resolver signer and
submit_llm_resolution, and adds the settlement, recovery, rotation, specification, and fund-safety guarantees needed to operate that resolver beyond a one-off demo.The resolver remains deliberately separate from governance: it may post a challengeable verdict, while only the protocol authority may rotate the resolver key or change governance-controlled state.
Protocol behavior
No-fault Unresolvable settlement
Unresolvablenow has explicit economics across the LLM and vote paths:UnresolvableTooEarlyis rejected by the shared outcome validation path. Statements whose truth does not yet exist resolve asUnresolvable, following ADR-0005.Verifiable Resolution Specs
Every new assertion must provide a canonical Resolution Spec reference in this bounded form:
ar://<43-character-transaction-id>#sha256=<64-character-lowercase-hex-digest>create_assertionvalidates the reference before accepting the assertion. This gives the off-chain resolver both a retrievable immutable document and the digest required to verify its exact bytes before resolution.Pending-round recovery
ProtocolConfignow includesllm_resolution_timeout_seconds.After
requested_at + llm_resolution_timeout_seconds, anyone may callrecover_pending_llmto move a still-pending round to a challengeableUnresolvableverdict. Recovery opens the normal LLM challenge window instead of immediately settling funds.Resolver submission and timeout recovery share the same
PendingLLMand unset-outcome guards, so only one path can win.Resolver rotation
The new
update_resolverinstruction allows the governance authority to rotate a compromised, depleted, or retired hot resolver key without redeploying the program.Rotation rejects:
After rotation, the old resolver is rejected immediately by
submit_llm_resolution.Initialization and fund safety
Protocol initialization is authenticated against the programs upgrade authority and matching ProgramData account. Configuration invariants reject unsafe economics, an empty resolver, and reuse of the governance authority as the hot resolver.
Settlement instructions validate the expected treasury and participant token accounts before transfers. Substituted payout accounts are rejected without moving funds, and the tests assert token conservation across decisive and no-fault outcomes.
Account-layout compatibility
This adds
llm_resolution_timeout_secondstoProtocolConfig, producing the 201-byte config layout expected by the companion resolver service.Existing deployments using the older layout require a fresh initialization or an explicit migration. This must land before initializing the next devnet or production deployment.
Validation
bun run test:local:Coverage includes:
The companion resolver cross-repository suite also passes against this program artifact for direct verdict settlement, timeout recovery, permissionless finalization, and resolver rotation.
Related
The on-chain program should be merged and deployed before the companion resolver is deployed, because the resolver intentionally fails preflight against the older account layout.
Summary by CodeRabbit
New Features
Unresolvableoutcomes.Bug Fixes
Unresolvableoutcomes now return all bonds, charge no fee, and slash no party.Documentation