Skip to content

feat: deterministic Random utility for Collections#266

Open
0xNeshi wants to merge 10 commits intomainfrom
feat/random
Open

feat: deterministic Random utility for Collections#266
0xNeshi wants to merge 10 commits intomainfrom
feat/random

Conversation

@0xNeshi
Copy link
Copy Markdown
Collaborator

@0xNeshi 0xNeshi commented Mar 27, 2026

Resolves #260

PR Checklist

  • Tests
  • Documentation
  • Changelog - DIDN'T ADD, as this utility is meant only for internal use.

Summary by CodeRabbit

  • New Features

    • Introduced OpenZeppelin Collections package with a deterministic pseudo-random number generator utility for reproducible randomization.
  • Tests

    • Added comprehensive unit tests validating generator determinism, non-degeneracy, and consistent behavior across multiple seed values.

@0xNeshi 0xNeshi self-assigned this Mar 27, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9f0684ce-8434-4448-a141-7fd850aa1253

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

A new Move package openzeppelin_collections is introduced, containing a deterministic pseudo-random number generator. The package includes a Random struct with a linear-congruential-style algorithm, a constructor, and a mutation-based generator function. Package manifest, documentation, implementation, and comprehensive unit tests are provided.

Changes

Cohort / File(s) Summary
Package Manifest & Documentation
collections/Move.toml, collections/README.md
New Move package manifest for openzeppelin_collections targeting edition 2024 with address mapping; documentation header added.
Random Generator Implementation
collections/sources/random.move
New Random struct with deterministic pseudo-random generation using linear-congruential-style algorithm; includes new() constructor and rand() mutation function for state-based number generation.
Random Generator Tests
collections/tests/random_tests.move
Comprehensive unit tests validating deterministic behavior, seed consistency, non-degeneracy, and reproducibility of the random number generator across multiple test scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • bidzyyys
  • ericnordelo
  • immrsd

Poem

🐰 A random seed we plant with care,
Numbers dance in states so fair,
Linear congruence, oh what a sight,
Deterministic chaos, perfectly tight!
A generator hopping through Move's domain. 🌱

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: introducing a deterministic Random utility for the Collections module.
Linked Issues check ✅ Passed The PR implements a deterministic Random utility with a struct, constructor, and generator function, directly addressing the feature request in issue #260.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the Random utility: Move.toml setup, README documentation, the random module, and comprehensive tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description addresses all required template sections: references issue #260, provides context about the deterministic Random utility, and includes a complete PR checklist with explicit status for each item.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/random

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 88.69%. Comparing base (63a864e) to head (022ded2).

Files with missing lines Patch % Lines
collections/sources/random.move 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #266      +/-   ##
==========================================
- Coverage   89.88%   88.69%   -1.19%     
==========================================
  Files          19       20       +1     
  Lines        1790     1814      +24     
  Branches      484      502      +18     
==========================================
  Hits         1609     1609              
- Misses        168      192      +24     
  Partials       13       13              
Flag Coverage Δ
contracts/access 42.39% <0.00%> (-2.49%) ⬇️
math/core 84.55% <0.00%> (-1.57%) ⬇️
math/fixed_point 56.23% <0.00%> (-2.48%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
collections/sources/random.move (1)

40-46: Potential short period due to bit shifting in the LCG.

The >> 1 shift discards the LSB on each iteration, which deviates from a standard Linear Congruential Generator and may significantly reduce the generator's period (potentially to ~2^63 or less depending on the multiplier's properties). For a utility intended for "reproducible internal flows," this might be acceptable, but if longer periods are needed, consider removing the shift or using a different approach.

Also, the mask 0x0000000000000000ffffffffffffffff has redundant leading zeros—0xffffffffffffffff is equivalent and cleaner.

♻️ Minor cleanup: remove redundant zeros
 public(package) fun rand(r: &mut Random): u64 {
     r.seed = (
         (
-            ((9223372036854775783u128 * ((r.seed as u128)) + 999983) >> 1) & 0x0000000000000000ffffffffffffffff,
+            ((9223372036854775783u128 * ((r.seed as u128)) + 999983) >> 1) & 0xffffffffffffffff,
         ) as u64,
     );
     r.seed
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@collections/sources/random.move` around lines 40 - 46, In rand(&mut Random)
the right-shift ">> 1" truncates the LSB each iteration (reducing LCG period)
and the mask has redundant leading zeros; to fix, remove the ">> 1" shift so the
LCG update uses the full 128-bit product+increment before truncating to 64 bits,
and replace the mask literal 0x0000000000000000ffffffffffffffff with the
canonical 0xffffffffffffffff; update the assignment to r.seed in function rand
to compute (multiplier * (r.seed as u128) + increment) then mask/cast to u64
without shifting.
collections/tests/random_tests.move (1)

37-42: Consider strengthening the property test to check more values.

The property test only asserts that the first rand() output matches for identical seeds. Checking a few more values would provide stronger confidence in sequence determinism.

♻️ Suggested enhancement
 #[random_test]
 fun test_same_seed_produces_same_sequence(seed: u64) {
     let mut random1 = new(seed);
     let mut random2 = new(seed);
     assert_eq!(random1.rand(), random2.rand());
+    assert_eq!(random1.rand(), random2.rand());
+    assert_eq!(random1.rand(), random2.rand());
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@collections/tests/random_tests.move` around lines 37 - 42, The test
test_same_seed_produces_same_sequence currently only checks the first rand()
value; extend it to verify multiple outputs to ensure deterministic sequences
for identical seeds by calling new(seed) to create random1 and random2 and then
comparing several subsequent rand() calls (e.g., in a for loop for N iterations
or by collecting N values into vectors and asserting equality). Use the existing
symbols new and rand and keep the seed parameter; ensure you assert equality for
each iteration (or for the collected sequences) so the test fails if any later
value diverges.
collections/README.md (1)

1-1: Consider expanding README documentation.

The README currently contains only a title. Consider adding:

  • Brief package description
  • Available modules (e.g., random)
  • Basic usage examples
  • Any important caveats (e.g., "not cryptographically secure")

The PR checklist indicates documentation is pending, so this may already be planned.

Would you like me to draft expanded README content for this package?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@collections/README.md` at line 1, The README currently only has the title "#
openzeppelin_collections"; expand it to include a brief package description, a
short list of available modules (e.g., random) with one-line summaries, basic
usage examples for core API calls, and any important caveats (for example "not
cryptographically secure"); update the top-level README content (replace/augment
the existing title) and ensure you add a "Usage" and "Caveats" section so the
documentation satisfies the PR checklist.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@collections/README.md`:
- Line 1: The README currently only has the title "# openzeppelin_collections";
expand it to include a brief package description, a short list of available
modules (e.g., random) with one-line summaries, basic usage examples for core
API calls, and any important caveats (for example "not cryptographically
secure"); update the top-level README content (replace/augment the existing
title) and ensure you add a "Usage" and "Caveats" section so the documentation
satisfies the PR checklist.

In `@collections/sources/random.move`:
- Around line 40-46: In rand(&mut Random) the right-shift ">> 1" truncates the
LSB each iteration (reducing LCG period) and the mask has redundant leading
zeros; to fix, remove the ">> 1" shift so the LCG update uses the full 128-bit
product+increment before truncating to 64 bits, and replace the mask literal
0x0000000000000000ffffffffffffffff with the canonical 0xffffffffffffffff; update
the assignment to r.seed in function rand to compute (multiplier * (r.seed as
u128) + increment) then mask/cast to u64 without shifting.

In `@collections/tests/random_tests.move`:
- Around line 37-42: The test test_same_seed_produces_same_sequence currently
only checks the first rand() value; extend it to verify multiple outputs to
ensure deterministic sequences for identical seeds by calling new(seed) to
create random1 and random2 and then comparing several subsequent rand() calls
(e.g., in a for loop for N iterations or by collecting N values into vectors and
asserting equality). Use the existing symbols new and rand and keep the seed
parameter; ensure you assert equality for each iteration (or for the collected
sequences) so the test fails if any later value diverges.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 85e15975-7eb2-48d4-b53f-00da88694ba4

📥 Commits

Reviewing files that changed from the base of the PR and between 63a864e and 4ca4b95.

⛔ Files ignored due to path filters (1)
  • collections/Move.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • collections/Move.toml
  • collections/README.md
  • collections/sources/random.move
  • collections/tests/random_tests.move

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.

[Feature]: Random

2 participants