Skip to content

Conversation

Peponks9
Copy link

Description

This PR addresses issue #761 by adding the documentation for implementing EnumerableSet with user-defined storage types in Stylus.

Changes Made

Added Examples to Existing EnumerableSet Documentation

  • Added concise usage example with EnumerableSet<Address> in contracts/src/utils/structs/enumerable_set/mod.rs
  • Included brief guidance on implementing custom storage types via Element and Accessor traits

Created Antora Documentation

  • Added new documentation file: docs/modules/ROOT/pages/enumerable-set-custom.adoc
  • Provided step-by-step implementation guide for custom storage types
  • Included examples with custom User struct

Updated Navigation and References

  • Added new documentation to docs/modules/ROOT/nav.adoc
  • Updated docs/modules/ROOT/pages/utilities.adoc with cross-reference

Addressed Limitations

  • Clearly documented that StorageBytes and StorageString cannot currently be implemented due to Stylus SDK limitations

Testing

  • Documentation builds successfully with npm run docs
  • Cargo test successfully run

Related Issue

Closes #761

@0xNeshi

…ustom storage types

- Enhanced existing EnumerableSet docs with usage examples
- Created comprehensive Antora documentation for custom storage types
- Added note about StorageBytes/StorageString limitations
- Updated navigation and cross-references

Closes OpenZeppelin#761
Copy link

netlify bot commented Aug 11, 2025

Deploy Preview for contracts-stylus ready!

Name Link
🔨 Latest commit 581d9ed
🔍 Latest deploy log https://app.netlify.com/projects/contracts-stylus/deploys/68a593c536f26d000846b87f
😎 Deploy Preview https://deploy-preview-786--contracts-stylus.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Collaborator

@0xNeshi 0xNeshi left a comment

Choose a reason for hiding this comment

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

Very good work 🚀

Let's polish it a bit and we can merge

Comment on lines 14 to 24
//! ```
//! extern crate alloc;
//!
//! use alloy_primitives::{Address, U256};
//! use stylus_sdk::prelude::*;
//! use openzeppelin_stylus::utils::structs::enumerable_set::EnumerableSet;
//!
//! #[storage]
//! struct MyContract {
//! whitelist: EnumerableSet<Address>,
//! }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
//! ```
//! extern crate alloc;
//!
//! use alloy_primitives::{Address, U256};
//! use stylus_sdk::prelude::*;
//! use openzeppelin_stylus::utils::structs::enumerable_set::EnumerableSet;
//!
//! #[storage]
//! struct MyContract {
//! whitelist: EnumerableSet<Address>,
//! }
//! ```rust
//! extern crate alloc;
//!
//! use alloy_primitives::{Address, U256};
//! use stylus_sdk::prelude::*;
//! use openzeppelin_stylus::utils::structs::enumerable_set::EnumerableSet;
//!
//! #[storage]
//! #[entrypoint]
//! struct MyContract {
//! whitelist: EnumerableSet<Address>,
//! }

Copy link
Collaborator

Choose a reason for hiding this comment

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

Unresolving, still missing #[entrypoint].

Copy link
Collaborator

@0xNeshi 0xNeshi Aug 19, 2025

Choose a reason for hiding this comment

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

Unresolving, still missing #[entrypoint].

@Peponks9 I need to remind you to please not resolve change requests which have not been addressed. This is very important, as it makes for better clarity during code reviews. Only resolve change requests once:

  1. The change request is addressed (implemented).
  2. Your local changes are pushed to remote and PR is updated.

[[limitations]]
== Current Limitations

**Note:** `StorageBytes` and `StorageString` cannot currently be implemented for `EnumerableSet` due to limitations in the Stylus SDK. This limitations may change in future versions of the Stylus SDK.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Update the sentence to state that Bytes and String cannot currently be implemented due to SDK limitation. Link to the actual types.

Copy link
Author

Choose a reason for hiding this comment

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

Made the changes but didn't find a link for String, just Bytes.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

Both links added

Copy link
Collaborator

Choose a reason for hiding this comment

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

The changes haven't been made or haven't been pushed, you can resolve this conversation together with https://github.com/OpenZeppelin/rust-contracts-stylus/pull/786/files#r2281442336

Comment on lines 172 to 173
[[testing]]
== Testing Your Implementation
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove this section, devs can't run OZ tests from within their projects

Copy link
Collaborator

Choose a reason for hiding this comment

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

Unresolving, the cargo test script is still present

Copy link
Collaborator

Choose a reason for hiding this comment

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

@Peponks9 another reminder not to resolve conversations that haven't been fully addressed and the changes pushed.

Peponks9 and others added 6 commits August 15, 2025 18:19
- Add comprehensive primitive type list with rustdoc links
- Move detailed docs from module level to struct level
- Update custom implementation guide with step-by-step breakdown
- Fix documentation structure and formatting issues
- Update limitations section with proper type links
- Add comprehensive primitive type list with rustdoc links
- Move detailed docs from module level to struct level
- Update custom implementation guide with step-by-step breakdown
- Fix documentation structure and formatting issues
- Update limitations section with proper type links
@Peponks9
Copy link
Author

Hey @0xNeshi, changes made :)

Comment on lines +14 to +21
/// Sets have the following properties:
///
/// * Elements are added, removed, and checked for existence in constant time
/// (O(1)).
/// * Elements are enumerated in O(n). No guarantees are made on the ordering.
/// * Set can be cleared (all elements removed) in O(n).
///
/// ## Usage
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/// Sets have the following properties:
///
/// * Elements are added, removed, and checked for existence in constant time
/// (O(1)).
/// * Elements are enumerated in O(n). No guarantees are made on the ordering.
/// * Set can be cleared (all elements removed) in O(n).
///
/// ## Usage
/// Storage type for managing [sets] of primitive types.
///
/// Sets have the following properties:
///
/// * Elements are added, removed, and checked for existence in constant time
/// (O(1)).
/// * Elements are enumerated in O(n). No guarantees are made on the ordering.
/// * Set can be cleared (all elements removed) in O(n).
///
/// [sets]: https://en.wikipedia.org/wiki/Set_(abstract_data_type)
///
/// ## Usage

@@ -188,6 +237,7 @@ mod tests {
use stylus_sdk::prelude::TopLevelStorage;
use alloy_primitives::private::proptest::{prop_assert, prop_assert_eq, proptest};


Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change

Copy link
Author

Choose a reason for hiding this comment

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

I don't seem to find this one, on lines provided it is not after use alloy_primitives::private::proptest::{prop_assert, prop_assert_eq, proptest}; anymore.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe you didn't push local changes?

@@ -2,13 +2,6 @@

Copy link
Collaborator

Choose a reason for hiding this comment

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

Change the mod-level doc to:

//! Storage type for managing [sets] of primitive types.
//!
//! [sets]: https://en.wikipedia.org/wiki/Set_(abstract_data_type)

Comment on lines 14 to 24
//! ```
//! extern crate alloc;
//!
//! use alloy_primitives::{Address, U256};
//! use stylus_sdk::prelude::*;
//! use openzeppelin_stylus::utils::structs::enumerable_set::EnumerableSet;
//!
//! #[storage]
//! struct MyContract {
//! whitelist: EnumerableSet<Address>,
//! }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unresolving, still missing #[entrypoint].

Comment on lines 48 to 50
//! You can implement `EnumerableSet` for your own storage types by implementing
//! the `Element` and `Accessor` traits. See `element.rs` for trait definitions
//! and the documentation for comprehensive examples.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unresolving, as types for not converted into links.

[[limitations]]
== Current Limitations

**Note:** https://docs.rs/alloy-primitives/latest/alloy_primitives/struct.Bytes.html[`Bytes`] and `String` cannot currently be implemented for `EnumerableSet` due to limitations in the Stylus SDK. These limitations may change in future versions of the Stylus SDK.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
**Note:** https://docs.rs/alloy-primitives/latest/alloy_primitives/struct.Bytes.html[`Bytes`] and `String` cannot currently be implemented for `EnumerableSet` due to limitations in the Stylus SDK. These limitations may change in future versions of the Stylus SDK.
https://docs.rs/alloy-primitives/latest/alloy_primitives/struct.Bytes.html[`Bytes`] and `String` cannot currently be implemented for `EnumerableSet` due to limitations in the Stylus SDK. These limitations may change in future versions of the Stylus SDK.

nit: redundant, already in a separate section.

[[limitations]]
== Current Limitations

**Note:** https://docs.rs/alloy-primitives/latest/alloy_primitives/struct.Bytes.html[`Bytes`] and `String` cannot currently be implemented for `EnumerableSet` due to limitations in the Stylus SDK. These limitations may change in future versions of the Stylus SDK.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
**Note:** https://docs.rs/alloy-primitives/latest/alloy_primitives/struct.Bytes.html[`Bytes`] and `String` cannot currently be implemented for `EnumerableSet` due to limitations in the Stylus SDK. These limitations may change in future versions of the Stylus SDK.
**Note:** https://docs.rs/alloy-primitives/latest/alloy_primitives/struct.Bytes.html[`Bytes`] and https://doc.rust-lang.org/stable/alloc/string/struct.String.html[`String`] cannot currently be implemented for `EnumerableSet` due to limitations in the Stylus SDK. These limitations may change in future versions of the Stylus SDK.

Comment on lines 172 to 173
[[testing]]
== Testing Your Implementation
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unresolving, the cargo test script is still present

Comment on lines +268 to +285
#[storage]
struct AccessControl {
role_members: StorageMap<B256, EnumerableSet<Address>>,
}

impl AccessControl {
fn grant_role(&mut self, role: B256, account: Address) {
self.role_members.get(role).add(account);
}

fn revoke_role(&mut self, role: B256, account: Address) {
self.role_members.get(role).remove(account);
}

fn get_role_members(&self, role: B256) -> Vec<Address> {
self.role_members.get(role).values()
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Provide a full working contract example, including imports. Devs should be able to copy/paste this example and have it deployable out of the box.

[source,rust]
----
#[storage]
struct Whitelist {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same for this, make it fully working example

@0xNeshi
Copy link
Collaborator

0xNeshi commented Aug 18, 2025

Also, fix the failing doc CI.

The other CI jobs seem to be failing due to some issue with cargo-stylus, we'll take a look into that.

@0xNeshi 0xNeshi marked this pull request as ready for review August 19, 2025 04:45
@Peponks9
Copy link
Author

@0xNeshi yes, still haven’t pushed changes and some errors still to be addressed. But didn’t some progress today ñ.

Copy link
Collaborator

@0xNeshi 0xNeshi left a comment

Choose a reason for hiding this comment

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

All the active conversations need to be addressed. For future reference, feel free to just make the necessary change requests or discuss them in the conversation threads, but leave it to the maintainers to actually resolve the conversations.

@0xNeshi
Copy link
Collaborator

0xNeshi commented Aug 25, 2025

Hey @Peponks9 , just checking in to see if you need any help addressing the issues

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.

[Docs]: Add Clear Examples and Docs for How to Implement Custom EnumerableSet
3 participants