serviceability: EdgeSeat feed-seat data model and SetAccessPassFeeds#3954
serviceability: EdgeSeat feed-seat data model and SetAccessPassFeeds#3954nikw9944 wants to merge 1 commit into
Conversation
Rework the AccessPass EdgeSeat variant from a bare marker into EdgeSeat(Vec<FeedSeat>) (feed_key + per-feed cap) and add the SetAccessPassFeeds instruction so the oracle provisions feed_keys onto a pass via its ACCESS_PASS_ADMIN permission. Connect-time enforcement of the per-feed metro gate lands in the next PR.
martinsander00
left a comment
There was a problem hiding this comment.
A few inline notes (F1/F2/F4 from the review). F1 breaks make generate-fixtures and should land in this PR; F2 is a real double-count bug; F4 is a latent note for Part 3. Otherwise this looks well-scoped and the design comments are great.
| /// Layout note (#1700): this variant previously carried no payload (#3865). EdgeSeat is new and | ||
| /// has no production passes, so changing the payload (same discriminant index 4) does not | ||
| /// orphan any deployed account; no migration is required. | ||
| EdgeSeat(Vec<FeedSeat>), |
There was a problem hiding this comment.
Build break — fix in this PR. Turning EdgeSeat into a tuple variant breaks the fixture generator, which still constructs the bare unit variant at sdk/serviceability/testdata/fixtures/generate-fixtures/src/main.rs:1199 (accesspass_type: AccessPassType::EdgeSeat). That crate is in the workspace exclude list, so make rust-build / rust-test skip it and CI stays green — but make generate-fixtures compiles it and hard-fails. One-line fix there: AccessPassType::EdgeSeat(vec![]). (Regenerating the fixture data itself stays deferred to Part 4 — only the compile fix belongs here.)
(Commenting here since main.rs isn't part of this diff; this variant change is the root cause.)
| .map(|s| s.current_users) | ||
| .unwrap_or(0); | ||
|
|
||
| if !prior_seats.iter().any(|s| s.feed_key == seat.feed_key) { |
There was a problem hiding this comment.
Duplicate feed_key double-counts. prior_seats is snapshotted once before the loop (line 105) and never updated, so if value.feeds lists the same feed_key twice (and it wasn't already on the pass) this guard passes on both iterations: reference_count is bumped twice — the second Feed::try_from re-reads the just-written +1 — and new_seats ends up with two identical FeedSeat entries. Nothing dedups value.feeds. Since reference_count is never decremented, the over-count isn't reclaimable either. Recommend rejecting or de-duplicating repeated feed_keys (track seen keys in-loop, or revert on a dup) so a feed is bumped at most once and seats aren't duplicated.
| try_acc_write(&feed, feed_account, payer_account, accounts)?; | ||
| } | ||
|
|
||
| new_seats.push(FeedSeat { |
There was a problem hiding this comment.
max_users can be set below the preserved current_users. current_users is preserved from the prior seat while max_users comes from the caller, with no max_users >= current_users check — so a re-provision can leave a seat over its cap. Latent today (nothing ticks current_users until Part 3), but Part 3's connect-time enforcement will inherit this unchecked invariant. Worth a clamp/guard when that lands — flagging here so it isn't lost.
Stack — review/merge bottom-up. Replaces #3952.
SetAccessPassFeeds---## Summary
AccessPassEdgeSeatvariant from a bare marker intoEdgeSeat(Vec<FeedSeat>)(feed_key+ per-feed cap), changing theAccessPassborsh layout for EdgeSeat passes (EdgeSeat is new and unused, so no migration).SetAccessPassFeedsinstruction so the oracle provisions feed_keys onto a pass via itsACCESS_PASS_ADMINpermission, plus its Rust SDK builder.Testing Verification
SetAccessPassFeedsSDK builder test; existing access-pass cap and CLI tests updated for the new variant.