Skip to content

fix(#856): the shared UUID-shaped identifier, and the messaging/storage family - #1275

Merged
scttfrdmn merged 1 commit into
mainfrom
fix/856-tier2-shared-uuid-mint
Sep 26, 2026
Merged

scttfrdmn merged 1 commit into
mainfrom
fix/856-tier2-shared-uuid-mint

Conversation

@scttfrdmn

Copy link
Copy Markdown
Owner

Tier 2 of #856. Tier 1 (#1265) built IDMint and moved EC2, IAM and STS onto it.

Substrate had two shared draw sites, not one

randomHex was the known one, documented as the chokepoint that makes the per-family
tiering possible. The other was a UUID-shaped generator declared in the Lambda plugin that
six other services publish an identifier from:

Service What it publishes from the shared generator
ECS task ID (runTask)
Step Functions execution name, when the caller names none
SQS message ID (SendMessage, SendMessageBatch)
EventBridge event ID (PutEvents)
CloudWatch Logs upload sequence token
Service Quotas quota-increase request ID

Tiering strictly per service family would have left this generator on crypto/rand until
the last of the six moved, and every one of those identifiers diverging on replay in the
meantime. So it moves here, with Lambda's own revision IDs.

Its rendering is unchanged: sixteen derived bytes in UUID shape — 8-4-4-4-12
lowercase hex, without the RFC 4122 version and variant bits. IDMint.UUID sets those bits,
and using it here would have changed which bytes a caller sees. #856 is about reproducing an
identifier across a replay, not about changing it, so the doc comment says why UUID is
deliberately not called.

The messaging/storage family, moving with it

SQS receipt handles; SNS subscription IDs and notification-envelope message IDs; EFS
file-system, access-point and mount-target IDs; FSx file-system IDs and Lustre mount names;
Transfer Family server IDs.

One behavioural note worth recording: a send mints a message's initial receipt handle and
each receive replaces it.
That matches real SQS, where a handle belongs to a receive and
only the most recent one deletes — so the handle derives from the mint's ordinal rather than
from the message. Deriving from the message would make every receive of one message agree,
which would be a different bug wearing determinism's clothes.

Three helpers minted without a request context in scope and now take the mint as a
parameter: buildSNSEnvelope, requestServiceQuotaIncrease (whose own ids name was
already taken by a local []string, so the parameter is mint) and FSx's Lustre
mount-name branch.

29 draw sites remain on crypto/rand, down from 32. The TODO(#856) on both randomHex
and IDMint carries the new count.

Tests

  • The ordinal, through the shared generator — one SendMessageBatch whose three entries
    carry identical bodies mints three distinct message IDs.
  • The wire-level claim — a recorded stream that sends and receives an SQS message,
    deletes it by the handle the receive returned, creates an SNS topic and subscribes to it,
    then creates an EFS file system with an access point naming it, replays with zero
    differences and StateValid true, with WithRecordedBodies(),
    WithRecordedStateHashes() and ReplayConfig{ValidateState: true}.
  • Non-vacuity, demonstrated — reverting generateSQSReceiptHandle alone to
    crypto/rand fails that test at
    seq=2 op=ReceiveMessage response_body/…/ReceiptHandle: 74d7… -> 3dbf… (major) plus a
    state_hash_after mismatch on every event from seq=1 onward. Restoring it returns the
    test to green.
  • Two branches the change touched that nothing covered gained tests of their own: an
    unnamed StartExecution (asserting both that two starts under one mint differ and that a
    second mint over the same seed reproduces the first name), and a Lustre deployment type
    other than SCRATCH_2. Patch coverage of the changed non-test lines is 87/87.

Verification

make lint (0 issues), make test (race, -count=1),
make docs-reference-check docs-versions version-check discarded-unmarshal-check wire-bookkeeping-check.

Refs #856 — the issue stays open until its checklist empties; this PR ships two of the six
remaining family groups plus the shared generator.

…ge family

Substrate had two shared draw sites, not one. randomHex was the known one; the other
was a UUID-shaped generator declared in the Lambda plugin that six other services
publish an identifier from — an ECS task id, a Step Functions execution name, an SQS
message id, an EventBridge event id, a CloudWatch Logs upload sequence token and a
Service Quotas request id. Tiering per service family would have left it on
crypto/rand until the last of the six moved, so it moves here with Lambda's own
revision ids.

Its rendering is unchanged: sixteen derived bytes in UUID *shape*, 8-4-4-4-12
lowercase hex without the RFC 4122 version and variant bits. IDMint.UUID sets those
bits, and using it here would have changed which bytes a caller sees, which is not
what #856 is about.

Moving with it: SQS receipt handles, SNS subscription ids and notification-envelope
message ids, EFS file-system/access-point/mount-target ids, FSx file-system ids and
Lustre mount names, and Transfer Family server ids. A send mints a message's initial
receipt handle and each receive replaces it, matching real SQS, so the handle derives
from the mint's ordinal rather than from the message — deriving from the message would
make every receive of one message agree.

Three helpers minted without a request context in scope and now take the mint as a
parameter: buildSNSEnvelope, requestServiceQuotaIncrease and FSx's Lustre mount-name
branch.

29 draw sites remain on crypto/rand, down from 32; the TODO on randomHex and on
IDMint carries the new count.

Tests: a SendMessageBatch whose three entries carry identical bodies mints three
distinct message ids, which is the ordinal's test through the shared generator; and a
recorded stream that sends and receives an SQS message, subscribes to an SNS topic and
creates an EFS file system with an access point — each later request naming what an
earlier one minted — replays with zero differences and StateValid true. Reverting
generateSQSReceiptHandle alone to crypto/rand fails that test on the ReceiptHandle
difference and on every state hash after it, so it is not vacuous. Two branches the
change touched and nothing covered gained tests of their own: an unnamed
StartExecution, and a Lustre deployment type other than SCRATCH_2.

Refs #856.
@codecov

codecov Bot commented Sep 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@scttfrdmn
scttfrdmn merged commit 252351a into main Sep 26, 2026
18 checks passed
@scttfrdmn
scttfrdmn deleted the fix/856-tier2-shared-uuid-mint branch September 26, 2026 07:16
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