Skip to content

Seat the v7 counter below the version nibble - #907

Merged
KodrAus merged 2 commits into
uuid-rs:mainfrom
lenamonj:v7-counter-placement
Sep 8, 2026
Merged

KodrAus merged 2 commits into
uuid-rs:mainfrom
lenamonj:v7-counter-placement

Conversation

@lenamonj

@lenamonj lenamonj commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Uuid::new_v7 shifts the counter so its most significant bit lands at bit 127 of the 128-bit value it hands to Builder::from_unix_timestamp_millis, but that builder spends the top four bits of the first payload byte on the version nibble. The top four bits of any counter are therefore discarded.

Measured at cdc96a8, from a scratch crate:

  • with a 42-bit counter, setting any of bits 38-41 gives the same rand_a/rand_b as a counter of zero; a counter of all ones gives rand_a = 0xff3, not 0xfff
  • a counter stepping from 0x3fffffffff to 0x4000000000 produces a UUID that sorts lower
  • with ContextV7::new().with_additional_precision() the discarded bits are the sub-millisecond ones, so two UUIDs drawn from one context at two instants inside the same millisecond can sort backwards

Change: seat the counter at bit 123 (the top of rand_a), open the two-bit variant gap only when the counter reaches past rand_a, and keep the 74 most significant bits of a wider counter. Two tests: every bit of a 42-bit counter reaches the UUID and a carry sorts upwards; additional precision sorts within a millisecond.

Verified on a fresh clone at cdc96a8: the two tests fail before the change and pass after; cargo test --all-features, --doc, cargo hack test --lib --each-feature, --all-features, the examples crate and the 1.85.0 smoke-test build are green. wasm not run here.

Found by an automated audit loop (Claude); patch and description reviewed by me.

@KodrAus KodrAus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @lenamonj! This needs some cleanup before it's ready. Particularly around the comments. Most of them should be removed.

Comment thread src/v7.rs Resolved
Comment thread src/v7.rs Resolved
Comment thread src/v7.rs Outdated
// the payload of a version 7 UUID starts at bit 123: `rand_a` runs from bit
// 123 down to bit 112, the variant occupies bits 111 and 110, and `rand_b`
// runs from bit 109 down to bit 48.
const PAYLOAD_TOP: u32 = 123;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This constant isn't pulling any weight. We can just inline it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 34ec102.

Comment thread src/v7.rs Resolved
Comment thread src/v7.rs Resolved
Comment thread src/v7.rs Resolved
new_v7 placed the counter's most significant bit at bit 127 of the
payload, where the version nibble overwrites it, so the top four counter
bits never reached the UUID. With with_additional_precision those are the
sub-millisecond bits, so two UUIDs from one context inside a millisecond
could sort backwards; a 42-bit counter carrying into bit 38 sorted lower
instead of higher.
@lenamonj
lenamonj force-pushed the v7-counter-placement branch from 1eab10c to 34ec102 Compare September 3, 2026 00:51
@lenamonj

lenamonj commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Pushed 34ec102: doc comment reduced to your wording, the explanatory comments replaced with a bit diagram, PAYLOAD_TOP inlined, the helper returns (u16, [u8; 4]) and moved into the test, tests renamed as suggested. cargo test --all-features and cargo hack --each-feature test --lib green.

@KodrAus KodrAus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @lenamonj!

@KodrAus
KodrAus merged commit c82e88c into uuid-rs:main Sep 8, 2026
23 checks passed
@lenamonj
lenamonj deleted the v7-counter-placement branch September 8, 2026 08:08
kodiakhq Bot pushed a commit to pdylanross/fatigue that referenced this pull request Sep 14, 2026
Bumps uuid from 1.26.0 to 1.26.1.

Release notes
Sourced from uuid's releases.

v1.26.1
What's Changed

Seat the v7 counter below the version nibble by @​lenamonj in uuid-rs/uuid#907
Don't panic in overflowing Timestamp to SystemTime conversion by @​KodrAus in uuid-rs/uuid#909
Prepare for 1.26.1 release by @​KodrAus in uuid-rs/uuid#910

New Contributors

@​lenamonj made their first contribution in uuid-rs/uuid#907

Full Changelog: uuid-rs/[email protected]



Commits

9f92712 Merge pull request #910 from uuid-rs/cargo/v1.26.1
d4df8f0 prepare for 1.26.1 release
5613f23 Merge pull request #909 from uuid-rs/fix/ts-conversion-overflow
fda00eb don't panic in overflowing Timestamp to SystemTime conversion
c82e88c Merge pull request #907 from lenamonj/v7-counter-placement
ac065a6 Align the counter diagram
34ec102 Seat the v7 counter below the version nibble
See full diff in compare view




Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

@dependabot rebase will rebase this PR
@dependabot recreate will recreate this PR, overwriting any edits that have been made to it
@dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
@dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
@dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
@dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
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