Skip to content

PLT-465: wire key/size/op distributions into StorageRW#54

Open
bdchatham wants to merge 3 commits into
mainfrom
brandon2/plt-465-m33-wire-key-distslot-and-size-distcalldata-into-storagerw
Open

PLT-465: wire key/size/op distributions into StorageRW#54
bdchatham wants to merge 3 commits into
mainfrom
brandon2/plt-465-m33-wire-key-distslot-and-size-distcalldata-into-storagerw

Conversation

@bdchatham

@bdchatham bdchatham commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Implements PLT-465 (M3.3) — turns StorageRW into the two customer-named axes (key-contention + tx-size).

What (generator/scenarios/StorageRW.go)

  • slot index = keyDist.SampleIndex(recordcount); op (read/write/rmw) by configured proportions; calldata pad length = sizeDist bucket draw.
  • Independent seeded sub-streams per axis: dist:%d:key, dist:%d:size (existing), dist:%d:op (new, append-only to the FROZEN set) — changing one axis never perturbs another's sequence (guarded by a determinism test).
  • Nil-guarded like the gas-picker: no distribution config → fixed slot 0 / rmw / empty pad, byte-identical to the PLT-461 scaffold (consumes zero randomness; account cadence untouched).
  • Pad gas added as intrinsic EIP-2028 cost (4/byte) on top of the 50k base — empty pad = exactly today's 50k; large pad can't underprovision.

One-way door (flagged)

The new dist:%d:op sub-stream id is an append-only addition to the FROZEN seed→stream contract (doesn't reseed existing streams; expands the saved-replay surface).

Verify

make lint 0 issues · go build · go test -race ./... green. Tests: contention sweep, size-bucket histogram, key/size + key/op independence, op-mix, byte-identical default, additive config.

🤖 Generated with Claude Code


📐 Design: decision brief — PLT-465 · parent design

Turn StorageRW into the contention + size axes: slot = keyDist.SampleIndex(
recordcount), op (read/write/rmw) by configured proportions, calldata pad =
sizeDist bucket draw — each on an INDEPENDENT seeded sub-stream so changing
one axis never perturbs another. Nil-guarded like the gas-picker: no
distribution config => fixed slot 0 / rmw / empty pad, byte-identical to the
PLT-461 scaffold (consumes zero randomness, account cadence untouched).

Adds one append-only sub-stream id (dist:%d:op) to the FROZEN set per the
append-only derivation rule; pad gas added as intrinsic EIP-2028 cost so it
can't underprovision.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cursor

cursor Bot commented Jun 15, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes load-generator hot paths and the frozen RNG stream-id set (replay surface expands); default-path compatibility is explicitly tested but misconfigured large pads are now possible until validation catches them.

Overview
StorageRW moves from a fixed single-slot rmw scaffold to configurable key contention, tx size, and read/write/rmw mix. Each tx draws a slot via KeyDistribution + recordCount, pad length via SizeDistribution + sizeBuckets, and an operation via weighted operations; key, size, and op use separate RNG sub-streams (dist:%d:key|size|op) so tuning one axis does not shift the others.

Scenario JSON gains optional recordCount, sizeBuckets, and operations; OperationMix.Select handles weighted op choice with nil/zero-weight fallback to rmw. ValidateScenarios rejects bad sizeBuckets (negative or over 1 MiB) at load time. Gas stays at a 50k base plus 4 gas per zero pad byte (EIP-2028). With no distribution config, behavior stays byte-identical to the prior fixed slot 0 / empty pad / rmw path.

The new dist:%d:op stream id is an append-only addition to the frozen seed contract; generator wiring binds it alongside existing distribution streams.

Reviewed by Cursor Bugbot for commit a541fba. Bugbot is set up for automated code reviews on this repo. Configure here.

bdchatham and others added 2 commits June 15, 2026 15:50
…view)

- Scenario.Validate rejects SizeBuckets[i] < 0 (make([]byte,-1) panic on the
  pickPad hot path) and > maxCalldataPadBytes (1 MiB OOM guard); wired via
  LoadConfig.ValidateScenarios in loadConfig, mirroring ValidateFunding.
- Inline OperationMix.stream (drop the one-field opStreamHolder wrapper) to
  match GasPicker/Distribution; move the mis-subjected doc comment to the field.

No change to draw behavior — byte-identical-default + independence tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
De-changelog the doc.go StorageRW narrative (drop 'PLT-465 turns it into',
'PLT-461 scaffold byte-for-byte') to a timeless present-tense description, and
replace the now-dangling era term 'scaffold' with 'default' in inline
default-path notes. Keep load-bearing comments (FROZEN append-only stream-id
ledger, EIP-2028 gas-per-byte why, nil-guard/default invariants, the
no-underprovision note). Comment-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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