Skip to content

feat(solana): dynamic pool bids (in-window request updates)#492

Merged
LandynDev merged 1 commit into
contract-v2from
solana-dynamic-pool-bids
Jun 22, 2026
Merged

feat(solana): dynamic pool bids (in-window request updates)#492
LandynDev merged 1 commit into
contract-v2from
solana-dynamic-pool-bids

Conversation

@anderdc

@anderdc anderdc commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #491#490. Until those merge, this PR's diff includes their changes too; once they land in contract-v2 it collapses to just this change. Review order: #490#491 → this.

What

A validator gets one shot per reservation pool today — a second open_or_request from the same validator while the pool is open is rejected with AlreadyRequested. This lets a validator update its bid in place while the window is still open (upsert), frozen once the pool resolves.

Why

The miner's rate is pinned at pool open, so the intended workflow is for a validator to run its user-selection after a pool opens (bidding against a now-stable rate) and refine as better users arrive. Part B of the reservation/initiation evolution.

  • No lottery gaming: draw odds are stake-weighted, not amount/time-weighted.
  • Miner protected: terms stay pinned regardless; an updated bid re-runs the amount-bounds + over-collateral checks (top of the handler).
  • busy_until unchanged: set only at OPEN, never extended by an update.

Changes (one handler)

open_or_request.rs:

  • JOIN branch upserts: a repeat call from the same validator replaces its Request in place; a new validator is appended (subject to MAX_VALIDATORS).
  • Fee is now charged only on a fresh entry (open or first join); a same-validator in-window update is free (refinement isn't taxed). Different validators each still pay.
  • ErrorCode::AlreadyRequested left defined (now unused) to avoid IDL churn.

Tests

  • test_validator_can_update_request (replaces the old dup-reject test), test_update_reflected_in_reservation, test_update_is_free, test_update_after_window_close_fails.
  • LiteSVM 68/68; e2e.sh 24/24 (build + deploy + on-chain).

@LandynDev LandynDev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dynamic pool bids (upsert): correct. Bounds + 1.1x over-collateral re-run on every update; draw is stake-weighted so updates can't game odds; OPEN clears requests (no stale-fee dodge); clean freeze at closes_at. Approving.

… in-window

A repeat open_or_request from the same validator while the pool is still open now
UPDATES that validator's bid in place instead of being rejected (AlreadyRequested).
Frozen once the window closes / the pool resolves. The miner's rate is pinned at
open, so refining a bid is against a stable rate; lottery odds are stake-weighted,
so updates can't game the draw.

- open_or_request JOIN branch: upsert (replace existing request by validator) vs push
- reservation fee charged only on a fresh entry; same-validator in-window updates free
- ErrorCode::AlreadyRequested left defined (now unused) to avoid IDL churn
- tests: validator-can-update, update-reflected-in-reservation, update-is-free,
  update-after-window-close-fails

LiteSVM 68/68, e2e.sh 24/24.
@LandynDev LandynDev force-pushed the solana-dynamic-pool-bids branch from 6cc9830 to 78c25bd Compare June 22, 2026 22:57
@LandynDev LandynDev merged commit fffb2e9 into contract-v2 Jun 22, 2026
@LandynDev LandynDev deleted the solana-dynamic-pool-bids branch June 22, 2026 22:58
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.

2 participants