Skip to content

cluster-tool: drive the folded liqsol_core OPP outpost + real yield flush#25

Open
valthon wants to merge 2 commits into
masterfrom
feat/opp-liqsol-integrated-support
Open

cluster-tool: drive the folded liqsol_core OPP outpost + real yield flush#25
valthon wants to merge 2 commits into
masterfrom
feat/opp-liqsol-integrated-support

Conversation

@valthon

@valthon valthon commented Jul 10, 2026

Copy link
Copy Markdown

Summary

Teaches the OPP harness to drive the folded liqsol_core integrated outpost — deployed upgradeable, every admin op gated by a global_config PDA — and reworks flow-yield-distribution to exercise the program's real staking-yield path. The integrated outpost is the harness's only Solana OPP mode; the epoch warp the yield flow needs is a per-cluster config option a flow opts into, not a shared env var, so the e2e gate's "no per-flow env" contract holds with zero workflow plumbing.

Changes (2 commits)

1. cluster-tool: drive folded liqsol_core outpost — the harness capability:

  • Upgradeable deploy. SolanaValidatorProcess gains an optional upgradeAuthority; when set, the program loads via --upgradeable-program (so a ProgramData account exists). SolanaValidatorProcessSteps deploys liqsol_core with the per-cluster SOL deployer as that authority — which is also the global_config.admin.
  • global_config gating. SolanaOutpostBootstrapper runs initialize_global_config once, then passes admin + global_config (and adminAta on SPL reserve creation) on every OPP admin instruction. OppSolProgram holds the supporting constants (global_config seed, BPF upgradeable-loader id, per-cluster deployer keypair, epoch-warp validator args).
  • ClusterConfig.solanaEpochWarp — a new per-cluster option (resolved through ClusterBuildOptionsClusterConfigProvider, exposed as a CLI flag, default off). When set, the validator launches warped past Solana epoch 3. Off by default: the warp advances the Solana clock past the depot's sysio.authex 10-minute nonce window, so only a flow with no cross-chain SOL deposit may enable it.

2. flow-yield-distribution: real flush emission — the flow drives the program's genuine yield pipeline: SolanaYieldEmitterTool seeds a staker via the dev-only dev_seed_staker_yield, then cranks flush_staking_yield so liqsol_core itself packs the StakingReward into the outbound buffer (retiring the prior bespoke add_attestation hand-injection). The scenario opts its own cluster into the epoch warp via its ClusterBuildOptions defaults (solanaEpochWarp: true). Because the program derives its own reward ref, the verify matches the depot's unmapped row by the staker's native SOL address (not a fixed ref) and asserts the credited WIRE amount equals the emitted reward.

⚠️ Build requirement

flow-yield-distribution calls the dev-only dev_seed_staker_yield, so the deployed program must be the development build (anchor build -- --features development). This is wired into the e2e gate by wire-solana next-integ (BUILD.bazel); every other flow runs on either build.

Verification

Green end-to-end against next-integ + companion branches, on this branch's exact commit:

  • e2e gate 13/13 — run 29875326396: every flow-* scenario passed, including yield-distribution, on the --features development build.
  • Local (SOL_OPP_* unset)swap-variance-revert + yield-distribution both pass, proving the code-driven path stands alone (the validator launches with --slots-per-epoch 4096 --warp-slot 12300 purely from the scenario defaults).
  • Clean build; cluster-tool unit suites green, with new coverage for the solanaEpochWarp flag + config resolution.

Companion PRs

  • wire-sysio (#502) — IDL-derived envelope offsets + retirement of nodeop's dead add_attestation binding (so the folded IDL is consumed verbatim).
  • wire-solana (next-integ, #385) — the folded outpost, the custody_mint/custody_decimals Reserve fields, the dev_seed_staker_yield helper, and the --features development E2E build.

🤖 Generated with Claude Code

https://claude.ai/code/session_015CbgvM8EhrPL1VjX8RhNze

@valthon
valthon force-pushed the feat/opp-liqsol-integrated-support branch from e84708b to 8701bc7 Compare July 10, 2026 03:08
@valthon
valthon force-pushed the feat/opp-liqsol-integrated-support branch 3 times, most recently from 4f83d04 to 0038098 Compare July 21, 2026 20:08
valthon and others added 2 commits July 21, 2026 18:17
The OPP Solana outpost was folded into the full liqsol_core program,
which gates every admin op (initialize_outpost, set_token_*, the reserve
creators) behind a global_config PDA whose admin is the program's on-chain
upgrade authority. Standing that up needs an upgradeable deploy (so a
ProgramData account exists) and a one-time initialize_global_config before
the outpost — neither of which the standalone bootstrap did.

Teach the harness to drive it:
  - OppSolProgram: the integrated-outpost constants (global_config seed,
    BPF upgradeable-loader id, per-cluster deployer keypair, epoch-warp
    validator args).
  - SolanaValidatorProcess[Steps]: deploy the program upgradeable with the
    per-cluster deployer as its upgrade authority (== global_config.admin).
  - SolanaOutpostBootstrapper: initialize global_config, then pass
    admin + global_config (and adminAta on SPL reserve creation) on every
    OPP admin instruction.

Also add a per-cluster ClusterConfig.solanaEpochWarp option (resolved
through ClusterBuildOptions -> ClusterConfigProvider, exposed as a CLI
flag): when set, the validator launches warped past Solana epoch 3 for a
flow that cranks flush_staking_yield (Clock.epoch >= 3). Off by default —
the warp advances the Solana clock past the depot's sysio.authex 10-minute
nonce window, so only a flow with no cross-chain SOL deposit may opt in.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015CbgvM8EhrPL1VjX8RhNze
The flow hand-injected a STAKING_REWARD attestation through a bespoke
Borsh-encoded add_attestation call. Drive the program's genuine yield
pipeline instead: SolanaYieldEmitterTool seeds a staker's on-chain yield
state via the dev-only dev_seed_staker_yield (built under
--features development), then cranks flush_staking_yield so liqsol_core
itself packs the StakingReward into the outbound buffer — the exact path
a production yield-aware Solana contract exercises.

flush_staking_yield requires Clock.epoch >= 3, so the scenario opts its
own cluster into the epoch warp via its ClusterBuildOptions defaults
(solanaEpochWarp: true) — no other flow warps, keeping the shared-env e2e
contract intact. The chainCode/tokenCode/externalEpochRef inputs the old
hand-injection needed are gone: the program forces the token code and
derives the epoch ref.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015CbgvM8EhrPL1VjX8RhNze
@valthon
valthon force-pushed the feat/opp-liqsol-integrated-support branch from 0038098 to 328dee2 Compare July 21, 2026 22:35
@valthon
valthon marked this pull request as ready for review July 22, 2026 00:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant