Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(platform): token distribution part two #2450

Open
wants to merge 7 commits into
base: v2.0-tokens-dev
Choose a base branch
from

Conversation

QuantumExplorer
Copy link
Member

@QuantumExplorer QuantumExplorer commented Feb 3, 2025

Issue being fixed or feature implemented

What was done?

How Has This Been Tested?

Breaking Changes

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features
    • Introduced support for token pre-programmed distributions, enabling detailed retrieval of distribution data including proofs, across various client platforms.
  • Refactor
    • Enhanced internal modules for managing token distribution paths, cost estimations, and verification, streamlining backend processing.
  • Tests
    • Added and reorganized test cases ensuring robust functionality for token distribution queries and data integrity.

These improvements expand the API’s capability to manage and verify token distributions while offering a more reliable and efficient integration experience.

@QuantumExplorer QuantumExplorer added this to the v2.0.0 milestone Feb 3, 2025
Copy link
Contributor

coderabbitai bot commented Feb 3, 2025

Walkthrough

The pull request adds comprehensive support for token pre‐programmed distributions across multiple language clients and the underlying platform. New RPC methods and message types have been integrated into Java, NodeJS, Objective‑C, Python, and Web clients. Additionally, extensive modifications have been made to the Rust modules (rs-dpp, Drive, and versioning components) to support new distribution keys, encoding/decoding, cost estimation, querying, and verification. Several helper functions, enums, and structures have been introduced or updated to ensure proper handling of token distribution operations throughout the service, state transitions, and storage layers.

Changes

File(s) Change Summary
packages/dapi-grpc/clients/platform/v0/java/.../PlatformGrpc.java Added a new RPC method descriptor and handlers for token pre-programmed distributions.
packages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.js Introduced new message types and methods for handling token pre-programmed distributions.
packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.{h,m}, Platform.pbrpc.{h,m} Added new classes and methods to support token pre-programmed distribution requests and responses.
packages/dapi-grpc/clients/platform/v0/python/platform_pb2_grpc.py Added new method getTokenPreProgrammedDistributions to both the stub and servicer.
packages/dapi-grpc/clients/platform/v0/web/{platform_pb.d.ts,platform_pb_service.{d.ts,js},platform_pb.js} Expanded protocol definitions and service calls to include token pre-programmed distributions.
packages/dapi-grpc/protos/platform/v0/platform.proto Added new messages: GetTokenPreProgrammedDistributionsRequest and Response.
packages/rs-dpp/src/data_contract/associated_token/... Introduced new module for token distribution keys and updated distribution function encoding/decoding with new enum variants.
packages/rs-drive/src/drive/tokens/... Added modules and methods for inserting, fetching, proving, and verifying token pre-programmed (and perpetual) distributions; updated path constants accordingly.
packages/rs-platform-version/src/version/... Updated versioning structures by adding new fields and bounds for token pre-programmed distributions.
Other (batch transition files) Removed obsolete constants related to token freeze/unfreeze transitions.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant gRPC Server
    participant ServiceLogic
    Client->>gRPC Server: getTokenPreProgrammedDistributions(request)
    gRPC Server->>ServiceLogic: Process pre-programmed distribution request
    ServiceLogic-->>gRPC Server: Distribution response (or proof)
    gRPC Server->>Client: Return response
Loading

Possibly related PRs

Suggested reviewers

  • shumkov

Poem

Oh, hop and skip, I’m on the run,
Adding tokens beneath the sun!
Pre-programmed tricks in code so neat,
Distributions now share a bouncy beat.
With changes crisp, and paths so clear,
This rabbit cheers with a joyful cheer! 🐰✨

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@QuantumExplorer
Copy link
Member Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Feb 3, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@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.

Actionable comments posted: 7

🧹 Nitpick comments (40)
packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/mod.rs (1)

10-12: Consider adding module-level documentation.

The new modules provide a clear separation of concerns for token distribution functionality. Consider adding module-level documentation (//! comments) to describe the purpose and contents of each module.

packages/rs-drive/src/drive/tokens/estimated_costs/for_token_pre_programmed_distribution/mod.rs (2)

51-63: Validate handling of empty or large times iterators.
If times is empty, the method currently performs no operations, which may or may not be intended. For large iterators, ensure this approach is performant enough, as each timestamp might add an estimated layer entry.


65-70: Confirm that all future versions will follow a similar pattern.
The version handling logic is straightforward but ensure that any new version uses the same naming convention (v1, v2, etc.) to keep code consistent and easy to follow.

packages/rs-drive/src/drive/tokens/distribution/add_pre_programmed_distribution/mod.rs (1)

14-21: Add clarity on subtree creation.
The docstring states that necessary subtrees are created, but the actual creation logic is delegated to add_pre_programmed_distributions_v0. Consider documenting or referencing that logic explicitly for maintainability.

packages/rs-drive/src/drive/tokens/distribution/prove/mod.rs (2)

31-31: Fix doc mismatch about the returned type

The doc comment says "A Result containing a nested BTreeMap on success or an Error on failure," but the function actually returns a Result<Vec<u8>, Error>. Please align the documentation with the code:

-/// A `Result` containing a nested `BTreeMap` on success or an `Error` on failure.
+/// A `Result` containing proof bytes (`Vec<u8>`) on success or an `Error` on failure.

69-69: Fix doc mismatch about the returned type

Similarly, the doc comment refers to a nested BTreeMap, while the method still returns Result<Vec<u8>, Error>. Please update the doc block here as well:

-/// A `Result` containing a nested `BTreeMap` on success or an `Error` on failure.
+/// A `Result` containing proof bytes (`Vec<u8>`) on success or an `Error` on failure.
packages/rs-drive/src/drive/tokens/distribution/add_perpetual_distribution/v0/mod.rs (1)

40-45: Remove or clarify commented-out code

The commented-out code within this if statement may cause confusion. Consider removing it if it's no longer needed or uncommenting it if it’s intended to be used:

         if estimated_costs_only_with_layer_info.is_some() {
-            // Drive::add_estimation_costs_for_perpetual_distribution(
-            //     estimated_costs_only_with_layer_info,
-            //     &platform_version.drive,
-            // )?;
         }
packages/rs-drive-abci/src/query/token_queries/token_pre_programmed_distributions/v0/mod.rs (3)

37-50: Clarify default vs max query limit.
The code checks if limit_value as u16 exceeds config.default_query_limit, yet it reports an error message referencing config.max_query_limit. This may cause confusion if default_query_limit and max_query_limit differ. Consider ensuring that the error accurately reflects the specific limit being exceeded or aligning both values if they are intended to match.

- .ok_or(drive::error::Error::Query(QuerySyntaxError::InvalidLimit(
-     format!("limit greater than max limit {}", config.max_query_limit),
- )))?;
+ .ok_or(drive::error::Error::Query(QuerySyntaxError::InvalidLimit(
+     format!("limit greater than allowed limit {}", config.default_query_limit),
+ )))?;

81-100: Extract proof handling into a dedicated helper method.
The “prove” logic is nicely separated by an if-else, but we can further improve readability by extracting the proof sequence into a dedicated helper. This would keep the main function concise and more maintainable.


101-136: Check for large distribution lists.
When fetching token distributions, if the returned list is unexpectedly large, performance might degrade. Consider adding guard checks for the total distributions count or evaluating a streaming approach to prevent potential memory overhead.

packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/encode.rs (2)

6-12: Validate infinities.
NotNan<f64> currently protects only against NaN. If your logic disallows infinity or negative infinity, consider adding checks (e.g., returning an error if the decoded float is infinite) to prevent unexpected extremes.


144-208: Reduce repetition in decode/borrow_decode implementations.
The Decode and BorrowDecode implementations largely duplicate logic. Consider unifying them via a shared helper or macro to simplify maintenance and reduce risk of inconsistencies.

packages/rs-drive/src/drive/tokens/distribution/add_pre_programmed_distribution/v0/mod.rs (3)

103-104: Avoid overshadowing variable names.
In for (time, distribution) in distribution.distributions(), the loop variable distribution shadows the parameter named distribution. Renaming the inner variable to something like entries or dist_entry clarifies the logic.

-for (time, distribution) in distribution.distributions() {
+for (time, dist_entry) in distribution.distributions() {
     ...
 }

82-100: Validate existence checks earlier.
The code returns an error if the pre-programmed distribution already exists. If feasible, validate existence in a preceding step (e.g., during a prior check or guard) to fail fast before performing partial insert operations.


134-183: Assess potential integer overflow.
You correctly guard against amounts exceeding i64::MAX. Also consider logging or monitoring high values that are not rejected but remain dangerously close to this limit to avoid silent near-overflow issues.

packages/rs-drive/src/drive/tokens/paths.rs (1)

30-31: Correct the doc comment mismatch for TOKEN_TIMED_DISTRIBUTIONS_KEY.

The doc comment says "Key for the perpetual distributions," but the constant clearly represents timed distributions. Please fix to reflect the intended meaning and avoid confusion.

packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs (1)

405-470: Ensure consistency in subtree creation and coverage in tests.

All nested distribution subtrees are initialized as empty trees. Confirm that each sub-distribution scenario (timed, perpetual, pre-programmed) either needs sum tracking or can remain a plain tree. Also consider adding or expanding test scenarios to validate each subtree's creation and usage paths.

packages/rs-drive/src/drive/tokens/distribution/mod.rs (1)

1-11: Add or expand documentation for newly introduced modules.

The new modules add_perpetual_distribution, add_pre_programmed_distribution, fetch, and prove are referenced conditionally via feature flags. For clarity, consider adding short doc comments explaining their responsibilities and expected usage patterns.

packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/methods/v0/mod.rs (1)

6-24: Consider enhancing method documentation.

The trait implementation is well-structured and uses appropriate data structures. However, the method documentation could be more detailed.

Consider adding more detailed documentation for each method:

 /// Trait for managing pre-programmed token distributions.
 pub trait TokenPreProgrammedDistributionV0Methods {
-    /// Gets the scheduled token distributions.
+    /// Gets the scheduled token distributions.
+    /// Returns a BTreeMap where:
+    /// - Keys are timestamps in milliseconds
+    /// - Values are maps of recipient identifiers to token amounts
     fn distributions(&self) -> &BTreeMap<TimestampMillis, BTreeMap<Identifier, TokenAmount>>;

-    /// Sets the scheduled token distributions.
+    /// Sets the scheduled token distributions.
+    /// Replaces the entire distribution schedule with the provided map.
     fn set_distributions(
         &mut self,
         distributions: BTreeMap<TimestampMillis, BTreeMap<Identifier, TokenAmount>>,
     );

-    /// Adds a new token distribution for a recipient at a specific time.
+    /// Adds a new token distribution for a recipient at a specific time.
+    /// If a distribution already exists for the given time and recipient,
+    /// it will be overwritten with the new amount.
     fn add_distribution(
         &mut self,
         time: TimestampMillis,
         recipient: Identifier,
         amount: TokenAmount,
     );
 }
packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_recipient.rs (1)

12-14: Enhance documentation for EvonodesByParticipation.

The documentation for EvonodesByParticipation could be more detailed about the participation criteria and epoch-based distribution mechanism.

Consider expanding the documentation:

-    /// Distribute tokens by participation
-    /// This distribution can only happen when choosing epoch based distribution
+    /// Distribute tokens to Evonodes based on their participation metrics
+    /// This distribution can only happen when choosing epoch based distribution.
+    /// The distribution amount for each Evonode is calculated proportionally
+    /// to their participation score within the epoch.
     EvonodesByParticipation,
packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/methods/v0/mod.rs (1)

5-7: Enhance trait documentation.

Consider adding more detailed documentation explaining:

  • The purpose and lifecycle of token perpetual distributions
  • The relationship between distribution type and recipient
  • Example usage scenarios
packages/rs-drive/src/drive/tokens/mod.rs (1)

47-48: Enhance distribution module documentation.

The current documentation "Distribution module" is too brief. Consider adding details about:

  • The purpose of token distributions
  • Types of distributions supported (perpetual, pre-programmed)
  • Key functionalities provided by the module
packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/methods.rs (1)

15-17: Add similar overflow protection for time and epoch calculations.

The time and epoch calculations could also benefit from overflow protection using checked arithmetic operations.

Also applies to: 20-22

packages/rs-drive/src/drive/tokens/estimated_costs/for_root_token_ms_interval_distribution/mod.rs (1)

12-19: Add documentation for the method parameters and return value.

The method implementation looks good, but could benefit from detailed documentation explaining:

  • Purpose of the times iterator
  • Structure and usage of the estimated_costs_only_with_layer_info map
  • Expected error conditions

Add rustdoc comments:

+/// Adds cost estimation entries for root token MS interval distribution
+/// 
+/// # Arguments
+/// * `times` - Iterator of timestamp milliseconds for intervals
+/// * `estimated_costs_only_with_layer_info` - Map to store estimated layer information
+/// * `drive_version` - Version information for compatibility check
+/// 
+/// # Returns
+/// `Ok(())` on success, or `Error` if version is not supported
packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/methods/mod.rs (1)

10-36: LGTM! Well-structured accessor implementation.

The implementation:

  • Properly handles version-specific access
  • Provides both getters and setters
  • Uses appropriate pattern matching

Consider adding documentation for the trait methods to improve API clarity.

packages/rs-drive/src/drive/tokens/distribution/add_perpetual_distribution/mod.rs (1)

15-28: Enhance method documentation with parameter details.

While the basic documentation is present, it would be helpful to add:

  • Parameter descriptions
  • Expected error conditions
  • Example usage

Add detailed rustdoc:

 /// Adds a TokenPerpetualDistribution to the state tree.
+/// 
+/// # Arguments
+/// * `token_id` - Unique identifier of the token
+/// * `owner_id` - Identity of the token owner
+/// * `distribution` - Distribution configuration to be added
+/// * `block_info` - Current block information
+/// * `estimated_costs_only_with_layer_info` - Optional cost estimation map
+/// * `batch_operations` - Vector to collect state modifications
+/// * `transaction` - Transaction context
+/// * `platform_version` - Platform version information
+/// 
+/// # Returns
+/// `Ok(())` on success, or `Error` if version is not supported
packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/reward_distribution_type/mod.rs (1)

8-16: LGTM! Well-structured enum design.

The enum effectively models different distribution types with appropriate parameters. Good use of type safety with specific interval types.

Consider adding examples in the doc comments for each variant to illustrate typical usage:

 #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, PartialOrd)]
 pub enum RewardDistributionType {
     /// An amount of tokens is emitted every n blocks
+    /// 
+    /// # Example
+    /// ```
+    /// use crate::RewardDistributionType;
+    /// let distribution = RewardDistributionType::BlockBasedDistribution(
+    ///     100,                    // every 100 blocks
+    ///     1000.into(),           // 1000 tokens
+    ///     DistributionFunction::FixedAmount,
+    /// );
+    /// ```
     BlockBasedDistribution(BlockHeightInterval, TokenAmount, DistributionFunction),
packages/rs-drive/src/drive/tokens/distribution/prove/pre_programmed_distributions/mod.rs (1)

32-40: Consider adding input validation.

The method could benefit from validating the limit parameter to ensure it's within reasonable bounds.

 pub(super) fn prove_token_pre_programmed_distributions_operations_v0(
     &self,
     token_id: [u8; 32],
     start_at: Option<QueryPreProgrammedDistributionStartAt>,
     limit: Option<u16>,
     drive_operations: &mut Vec<LowLevelDriveOperation>,
     transaction: TransactionArg,
     platform_version: &PlatformVersion,
 ) -> Result<Vec<u8>, Error> {
+    if let Some(limit) = limit {
+        if limit == 0 {
+            return Err(Error::InvalidArgument("limit cannot be zero".into()));
+        }
+    }
     let path_query = pre_programmed_distributions_query(token_id, start_at, limit);
packages/rs-drive/src/drive/tokens/estimated_costs/for_root_token_ms_interval_distribution/v0/mod.rs (1)

39-39: Document the magic numbers used in estimations.

The code uses magic numbers for layer counts and sizes:

  • Line 39: EstimatedLevel(10, false) - Why 10 layers?
  • Line 58: DEFAULT_HASH_SIZE_U32 * 2 + 2 - What's the reasoning behind this calculation?

Consider adding comments explaining these values or extracting them as named constants.

Also applies to: 58-58

packages/rs-drive/src/drive/tokens/estimated_costs/for_token_pre_programmed_distribution/v0/mod.rs (2)

49-49: Consider making the estimation level configurable.

The hardcoded value of 10 for estimated_layer_count might not be optimal for all scenarios. Consider making this configurable or calculating it based on actual usage patterns.


75-75: Consider making the estimation level configurable.

The hardcoded value of 3 for estimated_layer_count might not be optimal for all scenarios. Consider making this configurable or calculating it based on actual usage patterns.

packages/rs-drive/src/drive/tokens/distribution/fetch/mod.rs (1)

38-38: Consider documenting the start_at parameter.

The start_at parameter's purpose and usage are not documented in the function's documentation. Consider adding details about how this parameter affects the query behavior.

packages/rs-drive/src/drive/initialization/v1/mod.rs (1)

91-131: Consider adding a tree structure diagram in comments.

The initialization creates a complex tree structure for token distributions. Consider adding an ASCII diagram in the comments to visualize the tree hierarchy and relationships between different distribution types.

Example structure:

tokens/
├── distributions/
│   ├── timed/
│   │   ├── ms/
│   │   ├── block/
│   │   └── epoch/
│   ├── perpetual/
│   └── pre_programmed/
packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs (1)

218-247: LGTM! Consider extracting distribution handling into a separate method.

The implementation correctly processes both perpetual and pre-programmed distributions. However, to improve readability and maintainability, consider extracting the distribution handling logic into a separate method.

 fn insert_contract_operations_v1(
     &self,
     contract_element: Element,
     contract: &DataContract,
     block_info: &BlockInfo,
     estimated_costs_only_with_layer_info: &mut Option<
         HashMap<KeyInfoPath, EstimatedLayerInformation>,
     >,
     transaction: TransactionArg,
     platform_version: &PlatformVersion,
 ) -> Result<Vec<LowLevelDriveOperation>, Error> {
     // ... existing code ...

     for (token_pos, token_config) in contract.tokens() {
         // ... existing token setup code ...

-        if let Some(perpetual_distribution) =
-            token_config.distribution_rules().perpetual_distribution()
-        {
-            self.add_perpetual_distribution(
-                token_id.to_buffer(),
-                contract.owner_id().to_buffer(),
-                perpetual_distribution,
-                block_info,
-                estimated_costs_only_with_layer_info,
-                &mut batch_operations,
-                transaction,
-                platform_version,
-            )?;
-        }
-
-        if let Some(pre_programmed_distribution) = token_config
-            .distribution_rules()
-            .pre_programmed_distribution()
-        {
-            self.add_pre_programmed_distributions(
-                token_id.to_buffer(),
-                contract.owner_id().to_buffer(),
-                pre_programmed_distribution,
-                block_info,
-                estimated_costs_only_with_layer_info,
-                &mut batch_operations,
-                transaction,
-                platform_version,
-            )?;
-        }
+        self.handle_token_distributions(
+            token_config,
+            token_id,
+            contract.owner_id(),
+            block_info,
+            estimated_costs_only_with_layer_info,
+            &mut batch_operations,
+            transaction,
+            platform_version,
+        )?;

         // ... remaining code ...
     }
 }

+impl Drive {
+    fn handle_token_distributions(
+        &self,
+        token_config: &TokenConfiguration,
+        token_id: &TokenId,
+        owner_id: &IdentityId,
+        block_info: &BlockInfo,
+        estimated_costs_only_with_layer_info: &mut Option<HashMap<KeyInfoPath, EstimatedLayerInformation>>,
+        batch_operations: &mut Vec<LowLevelDriveOperation>,
+        transaction: TransactionArg,
+        platform_version: &PlatformVersion,
+    ) -> Result<(), Error> {
+        if let Some(perpetual_distribution) = token_config.distribution_rules().perpetual_distribution() {
+            self.add_perpetual_distribution(
+                token_id.to_buffer(),
+                owner_id.to_buffer(),
+                perpetual_distribution,
+                block_info,
+                estimated_costs_only_with_layer_info,
+                batch_operations,
+                transaction,
+                platform_version,
+            )?;
+        }
+
+        if let Some(pre_programmed_distribution) = token_config.distribution_rules().pre_programmed_distribution() {
+            self.add_pre_programmed_distributions(
+                token_id.to_buffer(),
+                owner_id.to_buffer(),
+                pre_programmed_distribution,
+                block_info,
+                estimated_costs_only_with_layer_info,
+                batch_operations,
+                transaction,
+                platform_version,
+            )?;
+        }
+
+        Ok(())
+    }
+}
packages/dapi-grpc/clients/platform/v0/python/platform_pb2_grpc.py (1)

464-469: Add docstring to describe the method's purpose.

The method is missing a descriptive docstring that explains its purpose and behavior.

Apply this diff to add documentation:

    def getTokenPreProgrammedDistributions(self, request, context):
-        """Missing associated documentation comment in .proto file."""
+        """Retrieves pre-programmed token distributions for a given token.
+
+        Args:
+            request: GetTokenPreProgrammedDistributionsRequest containing the token ID
+            context: gRPC service context
+
+        Returns:
+            GetTokenPreProgrammedDistributionsResponse containing the distributions
+
+        Raises:
+            NotImplementedError: Method needs to be implemented by service
+        """
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs (3)

694-862: Consider adding edge cases to pre-programmed distribution tests.

While the test comprehensively covers the happy path, consider adding test cases for:

  • Invalid timestamp values (e.g., past dates, duplicate timestamps)
  • Out-of-order timestamps
  • Empty distribution maps
  • Overlapping distributions

813-821: Consider extracting token balance verification to a helper function.

The token balance verification logic is duplicated across multiple test cases. Consider extracting it to a helper function to improve maintainability and reduce code duplication:

fn assert_no_token_balance(
    platform: &TestPlatform,
    token_id: [u8; 32],
    identity_id: [u8; 32],
    platform_version: &PlatformVersion,
) {
    let token_balance = platform
        .drive
        .fetch_identity_token_balance(
            token_id,
            identity_id.to_buffer(),
            None,
            platform_version,
        )
        .expect("expected to fetch token balance");
    assert_eq!(token_balance, None);
}

Also applies to: 952-960, 1064-1073, 1180-1188, 1316-1324, 1445-1453, 1704-1712, 1833-1841, 1964-1972


868-961: Enhance error messages in test assertions.

The test cases for error conditions could benefit from more descriptive error messages in the assertions. Consider adding detailed messages that explain the expected failure condition:

assert_matches!(
    processing_result.execution_results().as_slice(),
    [StateTransitionExecutionResult::PaidConsensusError(
        ConsensusError::BasicError(BasicError::InvalidTokenBaseSupplyError(_)),
        _
    )],
    "Expected InvalidTokenBaseSupplyError when base supply exceeds maximum"
);

Also applies to: 964-1074, 1077-1189

packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.m (1)

15069-15145: Consider adding documentation for pagination parameters.

While the implementation is correct, adding documentation about the pagination behavior (limit, startAtInfo) would help API consumers understand the query parameters better.

Would you like me to generate documentation comments explaining the pagination parameters and their usage?

packages/dapi-grpc/protos/platform/v0/platform.proto (1)

1421-1436: New Request Message Implementation
The newly added GetTokenPreProgrammedDistributionsRequest message is implemented consistently with other request messages (using a nested V0 message and oneof versioning). The fields are clearly defined with appropriate types and field numbers.

  • The token_id, start_at_info (which encapsulates start-time and start-recipient details), and limit fields are set up properly.
  • Nitpick: For enhanced naming consistency with the response (which uses recipient_id), consider renaming the start_recipient field within StartAtInfo to start_recipient_id if it represents an identifier. This can help avoid any ambiguity between a recipient's identity and other potential data.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 93f7d44 and b39565f.

📒 Files selected for processing (73)
  • packages/dapi-grpc/clients/platform/v0/java/org/dash/platform/dapi/v0/PlatformGrpc.java (9 hunks)
  • packages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.js (3 hunks)
  • packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.h (2 hunks)
  • packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.m (2 hunks)
  • packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbrpc.h (3 hunks)
  • packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbrpc.m (1 hunks)
  • packages/dapi-grpc/clients/platform/v0/python/platform_pb2_grpc.py (4 hunks)
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (1 hunks)
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.js (3 hunks)
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.d.ts (3 hunks)
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.js (2 hunks)
  • packages/dapi-grpc/protos/platform/v0/platform.proto (2 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_distribution_key.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/encode.rs (3 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs (2 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_recipient.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/methods/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/methods/v0/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/reward_distribution_type/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/methods.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/methods/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/methods/v0/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/mod.rs (1 hunks)
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/mod.rs (0 hunks)
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/mod.rs (0 hunks)
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs (0 hunks)
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs (1 hunks)
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs (0 hunks)
  • packages/rs-dpp/src/tokens/token_event.rs (2 hunks)
  • packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs (4 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs (3 hunks)
  • packages/rs-drive-abci/src/query/service.rs (2 hunks)
  • packages/rs-drive-abci/src/query/token_queries/mod.rs (1 hunks)
  • packages/rs-drive-abci/src/query/token_queries/token_pre_programmed_distributions/mod.rs (1 hunks)
  • packages/rs-drive-abci/src/query/token_queries/token_pre_programmed_distributions/v0/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/initialization/v1/mod.rs (2 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/add_perpetual_distribution/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/add_perpetual_distribution/v0/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/add_pre_programmed_distribution/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/add_pre_programmed_distribution/v0/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/fetch/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/fetch/pre_programmed_distributions/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/prove/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/prove/pre_programmed_distributions/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/distribution/queries.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/estimated_costs/for_root_token_ms_interval_distribution/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/estimated_costs/for_root_token_ms_interval_distribution/v0/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/estimated_costs/for_token_pre_programmed_distribution/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/estimated_costs/for_token_pre_programmed_distribution/v0/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/mod.rs (1 hunks)
  • packages/rs-drive/src/drive/tokens/paths.rs (3 hunks)
  • packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs (1 hunks)
  • packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs (1 hunks)
  • packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs (1 hunks)
  • packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs (1 hunks)
  • packages/rs-drive/src/verify/tokens/mod.rs (1 hunks)
  • packages/rs-drive/src/verify/tokens/verify_token_pre_programmed_distributions/mod.rs (1 hunks)
  • packages/rs-drive/src/verify/tokens/verify_token_pre_programmed_distributions/v0/mod.rs (1 hunks)
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs (1 hunks)
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs (1 hunks)
  • packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs (1 hunks)
  • packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs (1 hunks)
  • packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs (3 hunks)
  • packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs (4 hunks)
  • packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs (1 hunks)
  • packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs (1 hunks)
  • packages/rs-platform-version/src/version/mocks/v2_test.rs (1 hunks)
💤 Files with no reviewable changes (4)
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs
✅ Files skipped from review due to trivial changes (4)
  • packages/rs-drive-abci/src/query/token_queries/mod.rs
  • packages/rs-drive/src/verify/tokens/mod.rs
  • packages/rs-dpp/src/data_contract/associated_token/mod.rs
  • packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/mod.rs
🧰 Additional context used
📓 Learnings (3)
packages/rs-drive/src/drive/tokens/estimated_costs/for_token_pre_programmed_distribution/mod.rs (1)
Learnt from: QuantumExplorer
PR: dashpay/platform#2431
File: packages/rs-drive/src/drive/tokens/system/fetch_token_total_aggregated_identity_balances/v0/mod.rs:42-50
Timestamp: 2025-01-19T07:36:09.383Z
Learning: The `add_estimation_costs_for_token_balances` method in Drive is a properly implemented estimation logic method used for token balance operations, and the warning about incomplete estimation logic was incorrect.
packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs (1)
Learnt from: shumkov
PR: dashpay/platform#2422
File: packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs:152-163
Timestamp: 2025-01-15T08:09:59.365Z
Learning: In the `transition_to_version_8` function, errors from `grove_get_path_query` when retrieving active contested resource votes are intentionally logged and ignored (returning `Ok(())`) to allow the protocol upgrade to proceed despite query failures.
packages/rs-drive/src/drive/tokens/estimated_costs/for_token_pre_programmed_distribution/v0/mod.rs (1)
Learnt from: QuantumExplorer
PR: dashpay/platform#2431
File: packages/rs-drive/src/drive/tokens/system/fetch_token_total_aggregated_identity_balances/v0/mod.rs:42-50
Timestamp: 2025-01-19T07:36:09.383Z
Learning: The `add_estimation_costs_for_token_balances` method in Drive is a properly implemented estimation logic method used for token balance operations, and the warning about incomplete estimation logic was incorrect.
🔇 Additional comments (89)
packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/mod.rs (2)

2-2: LGTM! Import changes align with new functionality.

The addition of ProtocolError and platform serialization traits supports the enhanced token distribution functionality.

Also applies to: 5-5


15-30: Verify the unversioned serialization decision.

The enum is marked as unversioned for platform serialization. Please confirm this is intentional, as versioning is typically important for maintaining backward compatibility in distributed systems.

✅ Verification successful

Unversioned serialization is consistently applied across the codebase.

The grep output confirms that the use of #[platform_serialize(unversioned)] is not unique to TokenPerpetualDistribution but is part of a design choice used in many similar enums and structs (e.g., in identity, asset lock, extended epochs, errors, etc.). This consistency indicates that the decision to mark these types as unversioned is intentional and aligned with the overall serialization strategy.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if other similar enums in the codebase are also unversioned
# to ensure consistency in serialization approach.

echo "Searching for other platform_serialize attributes..."
rg --type rust "platform_serialize.*unversioned" -B 2 -A 2

echo "Searching for TokenPerpetualDistribution usage..."
rg --type rust "TokenPerpetualDistribution" -B 2 -A 2

Length of output: 65884

packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs (1)

5-5: LGTM!

The removal of unused imports RecipientKeyIndex and SenderKeyIndex is appropriate as they are not referenced in the code.

packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs (1)

12-12: LGTM!

The removal of unused imports is appropriate as they are not referenced in the trait definitions.

packages/rs-dpp/src/tokens/token_event.rs (1)

8-9: Verify the encapsulation of key index types.

The removal of RecipientKeyIndex and SenderKeyIndex imports suggests that these types are now encapsulated within SharedEncryptedNote. Please ensure that:

  1. The SharedEncryptedNote type properly encapsulates these key index types
  2. The key index values extracted from token_event_shared_encrypted_note are compatible with the property types in the BTreeMap

Run the following script to verify the type definitions:

Also applies to: 24-24

✅ Verification successful

Encapsulation of Key Index Types Verified

  • The generated platform protobuf definitions for SharedEncryptedNote (as seen in the Objective-C and TypeScript client files) include both senderKeyIndex and recipientKeyIndex fields.
  • These fields are typed as unsigned integers (uint32), which is consistent with their use in Rust (e.g., when mapping to a BTreeMap).
  • There is no evidence that the removal of the standalone RecipientKeyIndex and SenderKeyIndex types has adversely affected type compatibility.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the encapsulation of key index types in SharedEncryptedNote

# Test: Search for SharedEncryptedNote definition
ast-grep --pattern 'struct SharedEncryptedNote {
  $$$
}'

# Test: Search for key index type usage in SharedEncryptedNote
rg -A 5 'SharedEncryptedNote'

Length of output: 74392

packages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.js (3)

380-390: New exports for token distribution messages
These newly introduced export symbols appear consistent with the existing structure and naming conventions. No issues found.


54816-56514: Auto-generated response classes appear consistent
These definitions and nested message fields closely follow typical JspB patterns. Everything looks in order, with no obvious concerns regarding correctness or security.


5126-5294: Validate the 'limit' field usage
Although this code is auto-generated, the limit parameter could lead to unexpectedly large or zero-length queries. Please verify that consuming parts of the codebase handle out-of-range or zero values appropriately.

Below is a script to locate references of GetTokenPreProgrammedDistributionsRequestV0 in the repository, which may reveal any limit-handling logic:

packages/dapi-grpc/clients/platform/v0/web/platform_pb.js (3)

380-390: No issues found.
This block simply exports the newly defined proto symbols for the token distribution messages.


5126-5294: All good.
These additions are auto-generated classes and references for GetTokenPreProgrammedDistributionsRequest. If changes are necessary, please update the corresponding .proto file rather than modifying compiled output.


54816-56514: Minor grammatical note and general approval.
The docstrings contain a small grammatical slip ("When of these fields' value is set"), but as this code is auto-generated, any text fixes should be applied in the original .proto definitions. Functionality and structure appear correct.

packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/mod.rs (3)

1-1: No issues with introducing the mod methods; statement.


14-15: Field introduction looks good.
Defining distribution_recipient alongside distribution_type is a clear and maintainable approach for representing token distribution details.


22-24: Formatted string usage is appropriate.
The custom Display implementation is simple and sufficient. If advanced formatting is needed in the future, consider structuring the output more formally (e.g., JSON-like).

packages/rs-drive-abci/src/query/token_queries/token_pre_programmed_distributions/mod.rs (4)

1-13: Imports and module structure look well-organized.
The new dependencies and module references appear consistent with the rest of the codebase. No issues found.


22-29: Good handling of the optional version field.
Using the else clause to return a decoding error when the version is missing is a clear and explicit approach to error handling.


39-49: Version boundary checks are well implemented.
Ensuring the feature version is within the supported range avoids potential runtime errors. This is a good pattern for future expansions.


51-64: Suggest adding dedicated test coverage.
While the match on request versions looks correct, consider adding unit tests or integration tests to verify behavior for valid and invalid inputs, including boundary cases for the version field.

packages/rs-drive/src/verify/tokens/verify_token_pre_programmed_distributions/mod.rs (3)

1-2: New module file recognized.
No issues with declaring mod v0; or adding high-level imports.


17-46: Comprehensive documentation.
The doc comments concisely explain the method’s purpose, parameters, and errors. This clarity helps maintainers and users alike.


49-70: Version-based dispatch is consistent with the rest of the codebase.
Providing explicit error handling for unsupported versions is good for maintainability. Future expansions can extend the match with additional version branches.

packages/rs-drive/src/drive/tokens/distribution/add_pre_programmed_distribution/mod.rs (1)

40-40: Double-check overflow checks.
The comment mentions preventing overflow for token amounts by ensuring they don’t exceed i64::MAX. Verify that the actual code in v0 logic consistently enforces this constraint at insertion time.

packages/rs-drive/src/drive/tokens/distribution/fetch/pre_programmed_distributions/mod.rs (1)

65-73: Validate 8-byte assumption for distribution timestamps.
Popping the last path component and expecting 8 bytes in big-endian is correct given the documentation, but consider explicit test cases that confirm the system behaves as expected when the size is incorrect (e.g., corruption scenarios).

packages/rs-drive/src/verify/tokens/verify_token_pre_programmed_distributions/v0/mod.rs (1)

16-116: LGTM overall

No issues stand out in this method. The approach to grouping the proved key-value pairs by timestamp and verifying negative token amounts is comprehensive.

packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/encode.rs (1)

21-34: Confirm variant ordering consistency.
When new variants are introduced (e.g., FixedAmount, StepDecreasingAmount), ensure that all related decoding/borrow-decoding logic matches the updated variant indices to avoid misalignment during encoding/decoding.

packages/rs-drive/src/drive/tokens/paths.rs (1)

457-476: Validate boundary cases for interval calculations.

The logic for calculating the next interval (by doing block_info.height - block_info.height % interval + interval, etc.) appears correct. However, consider edge cases around very large block heights or epoch indexes to ensure no off-by-one or overflow conditions arise.

packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs (3)

27-31: Imports look consistent.

The references to new token paths and distribution constants appear correct and fulfill the usage in transition_to_version_9.


103-195: Check for potential key ID overflow and add logging for empty key sets.

  1. If last_key_id is already near the maximum allowable key ID, adding 1 could overflow. Consider introducing safeguards or bounds checks.
  2. You silently skip masternodes with no existing keys. A small log message might be helpful to track such cases for debugging.

396-399: Confirm storage requirements for distribution data.

You are inserting an Element::empty_tree() for [TOKEN_DISTRIBUTIONS_KEY]. If you expect aggregated calculations on tokens under this subtree, verify that a big sum tree (e.g., Element::empty_big_sum_tree()) is not more appropriate.

packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs (1)

12-17: LGTM! Well-organized module structure.

The new modules for token distribution cost estimation are well-organized and follow consistent naming and documentation patterns.

packages/rs-dpp/src/data_contract/associated_token/token_distribution_key.rs (1)

8-31: LGTM! Well-structured key composition.

The enum and struct definitions are well-designed with appropriate trait derivations. However, let's verify the usage of unversioned serialization.

Let's verify if there are any other structs in the codebase that use versioned serialization for similar token-related keys:

✅ Verification successful

Let's gather additional details before finalizing the review. The previous command didn’t produce any output, so I'll run an enhanced search to check for instances of platform_serialize with both versioned and unversioned parameters in the repository.


Verification: Consistent Use of Unversioned Serialization in Token-Related Keys

After reviewing the repository:

  • The TokenDistributionKey struct in packages/rs-dpp/src/data_contract/associated_token/token_distribution_key.rs employs #[platform_serialize(unversioned)].
  • Similar token-related structs across the codebase also consistently use #[platform_serialize(unversioned)], with no instances of #[platform_serialize(versioned)] in comparable contexts.

The serialization strategy is consistent and as expected.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for token-related structs with platform_serialize attribute
ast-grep --pattern 'struct $name {
  $$$
}

#[platform_serialize($_)]'

Length of output: 72


Script:

#!/bin/bash
echo "Searching for instances using #[platform_serialize(versioned)]..."
rg '#\[platform_serialize\(versioned\)' -n .

echo "Searching for instances using #[platform_serialize(unversioned)]..."
rg '#\[platform_serialize\(unversioned\)' -n .

Length of output: 31943

packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_recipient.rs (1)

6-15: Verify the necessity of PartialOrd trait.

The enum derives PartialOrd, but it's not clear why ordering would be needed for distribution recipient types. Consider removing it unless there's a specific use case.

Let's search for usage of ordering operations on TokenDistributionRecipient:

✅ Verification successful

PartialOrd appears to be unnecessary for TokenDistributionRecipient.
Our search did not reveal any ordering comparisons or operations (such as <, >, or partial_cmp) involving this enum. If there's no intended sorting or comparison logic elsewhere that depends on it, consider removing the PartialOrd derivation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for comparisons of TokenDistributionRecipient
rg "TokenDistributionRecipient.*(<|>|<=|>=|cmp|partial_cmp)" -A 3

Length of output: 1523

packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/methods/v0/mod.rs (1)

23-24: LGTM! Clear documentation of interval type flexibility.

The comment effectively explains the use of u64 for different interval types (time, block, epoch).

packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/methods/mod.rs (2)

26-40: Add validation in add_distribution method.

Consider adding validation for:

  • Non-negative token amounts
  • Future timestamps
  • Duplicate recipient checks within the same timestamp

This will help prevent invalid distributions from being added.


10-15: LGTM! Efficient implementation of distributions getter.

The use of BTreeMap provides ordered access to distributions, and pattern matching ensures proper version handling.

packages/rs-drive/src/drive/tokens/estimated_costs/for_root_token_ms_interval_distribution/mod.rs (1)

20-38: LGTM! Well-structured version handling.

The implementation correctly:

  • Matches against the version
  • Delegates to version-specific implementation
  • Returns appropriate error for unknown versions
packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs (1)

46-49: LGTM! Clear and consistent version configuration.

The version configuration:

  • Properly initializes new distribution methods
  • Maintains consistency with existing version numbering
  • Uses descriptive field names
packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/methods/mod.rs (1)

38-44: LGTM! Clean method implementation.

The next_interval implementation:

  • Correctly delegates to version-specific logic
  • Maintains consistent pattern matching style
packages/rs-drive/src/drive/tokens/distribution/add_perpetual_distribution/mod.rs (1)

29-52: LGTM! Well-structured version handling and error management.

The implementation:

  • Properly handles version dispatch
  • Provides clear error information
  • Follows consistent implementation pattern
packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs (1)

11-11: LGTM! Good encapsulation practice.

The visibility change from pub(crate) to pub(super) appropriately restricts access to only the parent module, improving encapsulation.

packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/reward_distribution_type/mod.rs (1)

18-44: LGTM! Clear and informative Display implementation.

The Display implementation provides human-readable output that clearly shows all relevant distribution parameters.

packages/rs-drive/src/drive/tokens/distribution/prove/pre_programmed_distributions/mod.rs (1)

11-31: LGTM! Comprehensive documentation.

The documentation clearly explains the method's purpose, parameters, and return value. Good explanation of the nested mapping structure.

packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs (2)

11-18: LGTM! Well-structured versioning additions.

The new DriveTokenDistributionMethodVersions struct and its integration into existing structures follows the established versioning pattern consistently.


32-32: LGTM! Consistent feature versioning.

The addition of pre_programmed_distributions to both fetch and prove versions maintains symmetry in the versioning system.

Also applies to: 45-45

packages/rs-drive/src/drive/tokens/estimated_costs/for_root_token_ms_interval_distribution/v0/mod.rs (1)

18-23: LGTM! Well-structured method signature.

The method is well-defined with appropriate generic constraints and clear parameter types. The use of ExactSizeIterator is a good choice as it allows pre-allocation optimizations.

packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs (1)

48-48: LGTM! Consistent version initialization.

The new field follows the established pattern of initializing feature versions to 0.

packages/rs-drive/src/drive/tokens/distribution/queries.rs (1)

7-24: LGTM! Comprehensive documentation.

The struct documentation clearly explains the purpose and usage of each field, with good examples of how the start_at_recipient field affects query behavior.

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs (1)

34-34: LGTM! Consistent feature versioning.

The new field follows the established pattern of using FeatureVersionBounds for versioning token-related queries.

packages/rs-drive/src/drive/tokens/estimated_costs/for_token_pre_programmed_distribution/v0/mod.rs (1)

27-33: LGTM! Well-structured generic implementation.

The function signature is well-designed with generic type parameter I bounded by appropriate traits (IntoIterator and ExactSizeIterator), allowing for flexible usage with different timestamp collections.

packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs (1)

66-66: LGTM! Consistent field addition.

The new field follows the established pattern and naming convention of the struct, using the appropriate type for version tracking.

packages/rs-drive/src/drive/tokens/distribution/fetch/mod.rs (1)

35-51: LGTM! Clean and well-structured implementation.

The public function provides a clean interface while properly delegating to the internal implementation.

packages/rs-drive/src/drive/initialization/v1/mod.rs (1)

65-89: LGTM! Good optimization of path reuse.

The code efficiently reuses the tokens_root_path variable instead of repeatedly calling tokens_root_path_vec().

packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs (1)

6-8: Verify the impact of removing SenderKeyIndex import.

The removal of SenderKeyIndex from the imports suggests a change in how token transfers are handled. Please ensure that this removal is intentional and doesn't affect any functionality.

Run the following script to verify the usage of SenderKeyIndex:

✅ Verification successful

Removal of SenderKeyIndex in the rs-drive module is safe.
The search shows that SenderKeyIndex remains used in the rs-dpp modules handling token transfers, while it is not referenced in the rs-drive file. The removal appears intentional and should not affect the functionality of the rs-drive module.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if SenderKeyIndex is used in the codebase.

# Test: Search for any remaining usage of SenderKeyIndex in the file.
ast-grep --pattern $'SenderKeyIndex'

Length of output: 775

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs (1)

107-111: LGTM! The new field is properly initialized.

The addition of token_pre_programmed_distributions with appropriate version bounds aligns with the broader token distribution enhancements.

packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs (1)

134-135: LGTM! The new cost estimation fields are properly initialized.

The addition of for_token_pre_programmed_distribution and for_root_token_ms_interval_distribution with version 0 aligns with the broader token distribution enhancements.

packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs (3)

10-21: LGTM! The FixedAmount variant is well-designed and documented.

The implementation provides a simple and effective way to emit a fixed amount of tokens per period. The documentation clearly explains the formula, use case, and provides a practical example.


23-39: LGTM! The StepDecreasingAmount variant is well-designed for Bitcoin/Dash-like emission models.

The implementation effectively models decreasing token emissions with:

  • Clear documentation of formula and use cases
  • Practical examples referencing Bitcoin and Dash Core models
  • Safe floating-point arithmetic using NotNan<f64>

179-194: LGTM! The display formatting is clear and informative.

The fmt::Display implementation for both new variants:

  • Provides clear, human-readable output
  • Includes all relevant parameters
  • Uses appropriate precision for floating-point values
packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs (1)

73-74: LGTM! The new cost estimation fields align with token distribution feature.

The addition of for_token_pre_programmed_distribution and for_root_token_ms_interval_distribution fields to the DriveIdentityCostEstimationMethodVersions struct is well-structured and follows the existing pattern.

packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs (1)

19-19: LGTM! Improved encapsulation with tighter visibility.

The change from pub(crate) to pub(super) appropriately restricts the method's visibility to the parent module, following Rust's best practices for encapsulation.

packages/rs-platform-version/src/version/mocks/v2_test.rs (1)

245-249: LGTM! Test version configuration aligns with token distribution feature.

The addition of token_pre_programmed_distributions to the test platform version configuration is consistent with other feature version bounds and properly initialized.

packages/rs-drive-abci/src/query/service.rs (1)

40-41: LGTM! The implementation follows established patterns.

The new get_token_pre_programmed_distributions method is well-integrated into the service, following the same patterns as other query methods for consistency and proper error handling.

Also applies to: 680-690

packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.d.ts (1)

340-347: LGTM! Type definitions are well-structured.

The new type definition and static property for token pre-programmed distributions follow TypeScript best practices and maintain consistency with existing patterns.

Also applies to: 433-433

packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbrpc.h (1)

90-91: LGTM! Objective-C implementation is robust and consistent.

The new class declarations and method implementations properly handle memory management with nullable annotations and maintain consistency across both modern and legacy protocols.

Also applies to: 295-297, 636-641

packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.js (1)

346-353: LGTM! JavaScript client implementation is well-structured.

The new method implementation follows established patterns for unary RPC calls with proper error handling and cleanup. The code maintains consistency with other client methods.

Also applies to: 1554-1583

packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbrpc.m (1)

878-896: LGTM! Well-structured implementation of the new gRPC method.

The implementation follows the established pattern and includes all necessary components for the gRPC client method.

packages/dapi-grpc/clients/platform/v0/python/platform_pb2_grpc.py (2)

202-206: LGTM! Well-structured stub implementation.

The gRPC stub implementation follows the established pattern and correctly configures the unary-unary channel.


1357-1373: LGTM! Well-structured experimental API implementation.

The static method implementation follows the established pattern and includes all necessary parameters for the gRPC call.

packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs (1)

148-149: LGTM! New imports support token distribution functionality.

The added imports for TokenAmount, TimestampMillis, Identifier, and BTreeMap are appropriate for implementing token distribution features.

Also applies to: 163-164, 171-171

packages/dapi-grpc/clients/platform/v0/java/org/dash/platform/dapi/v0/PlatformGrpc.java (8)

1165-1194: LGTM! Method descriptor declaration follows gRPC best practices.

The method descriptor declaration for getTokenPreProgrammedDistributions is properly implemented with:

  • Correct volatile field declaration
  • Thread-safe initialization using double-checked locking
  • Proper request/response type definitions
  • Appropriate method type (UNARY)

1673-1678: LGTM! Service implementation is correctly defined.

The abstract method implementation in PlatformImplBase follows the standard gRPC pattern for unary methods.


2347-2353: LGTM! Async stub implementation is properly defined.

The async stub implementation correctly uses asyncUnaryCall for non-blocking operations.


2684-2689: LGTM! Blocking stub implementation is properly defined.

The blocking stub implementation correctly uses blockingUnaryCall for synchronous operations.


3052-3058: LGTM! Future stub implementation is properly defined.

The future stub implementation correctly uses futureUnaryCall for returning ListenableFuture.


3138-3138: LGTM! Method ID and subsequent constants are properly incremented.

The method ID constant is correctly defined and subsequent method IDs are properly incremented.

Also applies to: 3139-3143


3310-3313: LGTM! Method handler case is properly implemented.

The method handler case in the switch statement correctly delegates to the service implementation.


3432-3432: LGTM! Service descriptor builder is properly updated.

The service descriptor builder correctly includes the new method.

packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.h (3)

1-2: Important: This is an auto-generated file.

The warning at the top indicates this file should not be manually edited as it's generated by the protocol buffer compiler.


197-202: New token distribution classes added.

The following classes have been added to support token pre-programmed distributions:

  • Request/response message types
  • Support for pagination via StartAtInfo
  • Support for both timed and regular distributions
  • Proof verification capabilities

5861-6031: Token distribution implementation looks good.

The implementation includes:

  • Proper request/response message structures
  • Pagination support
  • Proof verification
  • Handling of both timed and regular distributions
packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (1)

7042-7283: LGTM! Well-structured message types for token pre-programmed distributions.

The implementation provides a robust TypeScript interface for token distribution functionality with:

  • Proper versioning support with V0 message types
  • Well-structured request parameters including tokenId, pagination and filtering options
  • Comprehensive response types for distribution entries with timestamps and amounts
  • Strong type safety through TypeScript definitions
packages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.m (7)

268-275: LGTM! Class declarations are complete and well-structured.

The declarations follow proper protocol buffer naming conventions and include all necessary components for token distribution functionality.


15012-15068: LGTM! Thread-safe implementation with proper memory management.

The implementation correctly handles:

  • Thread-safe descriptor initialization
  • Proper storage structure for fields
  • Version one-of case management

15214-15270: LGTM! Consistent implementation pattern.

The response implementation maintains consistency with the request implementation, including proper thread safety and version handling.


15271-15344: LGTM! Complete response structure with proper type safety.

The implementation correctly handles:

  • Proof verification data
  • Response metadata
  • Result one-of case management

15408-15463: LGTM! Proper array management with timestamp support.

The implementation correctly handles:

  • Distribution array management
  • Timestamp field
  • Memory management for repeated fields

15465-15509: LGTM! Proper implementation of repeated message fields.

The implementation correctly handles the array of timed distributions with proper memory management and type safety.


15147-15212: Consider adding timestamp validation.

The StartAtInfo implementation could benefit from validation to ensure startTimeMs is within a reasonable range.

packages/dapi-grpc/protos/platform/v0/platform.proto (1)

1438-1463: New Response Message Implementation
The new GetTokenPreProgrammedDistributionsResponse message is well structured:

  • The nested messages (TokenDistributionEntry, TokenTimedDistributionEntry, and TokenDistributions) clearly break down the response data.
  • The oneof result correctly provides either a full set of token distributions or a cryptographic proof, following the established pattern elsewhere in the file.
  • The inclusion of ResponseMetadata further ensures that blockchain state context accompanies the response.
    Overall, the design is consistent with existing patterns in the protocol definitions.

Comment on lines +42 to +50
pub(crate) fn add_estimation_costs_for_token_pre_programmed_distribution<'a, I>(
token_id: [u8; 32],
times: I,
estimated_costs_only_with_layer_info: &mut HashMap<KeyInfoPath, EstimatedLayerInformation>,
drive_version: &DriveVersion,
) -> Result<(), Error>
where
I: IntoIterator<Item = &'a TimestampMillis> + ExactSizeIterator,
{
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Insufficient Test Coverage for Token Pre-programmed Distribution Estimation Function
The search results only reveal production code references to add_estimation_costs_for_token_pre_programmed_distribution (and its v0 variant) with no clear dedicated unit or integration tests specifically targeting its behavior. This suggests that explicit test coverage for the estimation pathway is lacking. It is recommended to add tests to verify that this function computes estimation costs as expected, helping safeguard it against future inadvertent changes.

  • Verify if any existing tests indirectly cover this behavior, and if not, add dedicated unit tests.
  • Consider integration tests if the function’s context within the drive token distribution workflow warrants end-to-end validation.
🔗 Analysis chain

Consider verifying test coverage for the new estimation function.
While the logic looks sound, adding unit tests (and possibly integration tests) would help ensure that future changes don't break this estimation pathway.

You can run a search to confirm the presence of test files referencing this method:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for test references to the added method in the codebase.

rg -A 5 "add_estimation_costs_for_token_pre_programmed_distribution" --threads 1

Length of output: 3501

Comment on lines +28 to +29
/// - `previous_batch_operations`: If provided, contains previously executed batch operations
/// that should be taken into account.
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Discrepancy Found in Documentation Parameter
It appears that the documentation for previous_batch_operations in
packages/rs-drive/src/drive/tokens/distribution/add_pre_programmed_distribution/mod.rs
does not match the method signature since the parameter is not actually included.
Please update the docstring to accurately reflect the parameters in use.

  • Remove or modify the doc comment for previous_batch_operations if it is not needed.
  • Verify the corresponding function signature and any related implementation if previous_batch_operations should be added instead.
🔗 Analysis chain

Confirm usage of previous_batch_operations.
The documentation mentions a parameter to handle previously executed batch operations, but it's not included in the method signature. Ensure that the docstring accurately matches the parameters and usage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check references to `previous_batch_operations` to confirm usage or remove from docstring if unused.

rg -A 2 "previous_batch_operations"

Length of output: 46387

Comment on lines +75 to +81
let sum_item = element.as_sum_item_value()?;
if sum_item < 0 {
return Err(Error::Drive(DriveError::CorruptedDriveState(
"negative token amount in pre-programmed distribution".to_string(),
)));
}
let token_amount: TokenAmount = sum_item as TokenAmount;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential overflow for large sums.
Even though negative amounts are disallowed, consider what happens if the sum item is larger than i64::MAX. GroveDB might pass a value that’s too big for a 64-bit signed integer, resulting in unexpected behavior.

Potential fix (conceptual example):

-if sum_item < 0 {
-    return Err(Error::Drive(DriveError::CorruptedDriveState(
-        "negative token amount in pre-programmed distribution".to_string(),
-    )));
-}
+if sum_item < 0 || sum_item > i64::MAX as i128 {
+    return Err(Error::Drive(DriveError::CorruptedDriveState(
+        "invalid or overly large token amount in pre-programmed distribution".to_string(),
+    )));
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let sum_item = element.as_sum_item_value()?;
if sum_item < 0 {
return Err(Error::Drive(DriveError::CorruptedDriveState(
"negative token amount in pre-programmed distribution".to_string(),
)));
}
let token_amount: TokenAmount = sum_item as TokenAmount;
let sum_item = element.as_sum_item_value()?;
if sum_item < 0 || sum_item > i64::MAX as i128 {
return Err(Error::Drive(DriveError::CorruptedDriveState(
"invalid or overly large token amount in pre-programmed distribution".to_string(),
)));
}
let token_amount: TokenAmount = sum_item as TokenAmount;

Comment on lines +30 to +42
pub(super) fn add_pre_programmed_distributions_v0(
&self,
token_id: [u8; 32],
owner_id: [u8; 32],
distribution: &TokenPreProgrammedDistribution,
block_info: &BlockInfo,
estimated_costs_only_with_layer_info: &mut Option<
HashMap<KeyInfoPath, EstimatedLayerInformation>,
>,
batch_operations: &mut Vec<LowLevelDriveOperation>,
transaction: TransactionArg,
platform_version: &PlatformVersion,
) -> Result<(), Error> {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor for clarity.
The method add_pre_programmed_distributions_v0 is quite large and handles multiple steps (cost estimation, tree insertion, references, etc.). Splitting these into focused helper functions could improve readability and maintainability.

Comment on lines +10 to +12
RewardDistributionType::BlockBasedDistribution(interval, _, _) => {
block_info.height - block_info.height % interval + interval
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Overflow risk in BlockBasedDistribution – Add checked arithmetic

The block-based branch in the next_interval method currently computes the next interval using:

block_info.height - block_info.height % interval + interval

Without overflow protection, if block_info.height is near the maximum value for its type (likely u64), the addition could overflow. Even though our current test configuration doesn’t use extremely large interval values, it’s a good safety measure to use checked arithmetic. Consider refactoring as suggested:

block_info.height
    .checked_sub(block_info.height % interval)
    .and_then(|h| h.checked_add(interval))
    .expect("Block interval calculation overflow")
  • Location: packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/methods.rs in the RewardDistributionType::BlockBasedDistribution branch of next_interval.
🔗 Analysis chain

Add overflow protection for block-based interval calculation.

The current implementation might overflow for very large intervals. Consider adding checks:

Consider this safer implementation:

-                block_info.height - block_info.height % interval + interval
+                block_info.height.checked_sub(block_info.height % interval)
+                    .and_then(|h| h.checked_add(interval))
+                    .expect("Block interval calculation overflow")

I'll gather additional context from the repository to better understand how the block-based interval calculation is used and whether overflow checks are necessary. In particular, I'll inspect the definition of the RewardDistributionType enum, the implementation of the next_interval method, and the type definition for block_info.height.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for large interval values in tests or configurations
rg -A 5 "BlockBasedDistribution\(" | grep -E "[0-9]{10,}"

Length of output: 59


Script:

#!/bin/bash
echo "Searching for RewardDistributionType enum definition..."
rg -A 20 "enum RewardDistributionType" --color=never

echo "---------------------------------------------------------"

echo "Searching for next_interval method definition..."
rg -A 20 "fn next_interval" --color=never

echo "---------------------------------------------------------"

echo "Searching for block_info.height occurrences..."
rg -A 5 "block_info.height" --color=never packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/methods.rs

Length of output: 8258

start_at_recipient,
}) => {
let mut query = Query::new_single_query_item(QueryItem::RangeFrom(
start_at_time.to_be_bytes().to_vec()..,
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use safe vector operations instead of unsafe slicing.

The code uses unsafe vector slicing with .. operator in multiple places:

start_at_time.to_be_bytes().to_vec()..
start_at_recipient.to_vec()..

Consider using into_iter() or other safe alternatives to avoid potential runtime panics.

Also applies to: 63-63, 67-67

Comment on lines +15351 to +15406
#pragma mark - GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry

@implementation GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry

@dynamic recipientId;
@dynamic amount;

typedef struct GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry__storage_ {
uint32_t _has_storage_[1];
NSData *recipientId;
uint64_t amount;
} GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry__storage_;

// This method is threadsafe because it is initially called
// in +initialize for each subclass.
+ (GPBDescriptor *)descriptor {
static GPBDescriptor *descriptor = nil;
if (!descriptor) {
static GPBMessageFieldDescription fields[] = {
{
.name = "recipientId",
.dataTypeSpecific.clazz = Nil,
.number = GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry_FieldNumber_RecipientId,
.hasIndex = 0,
.offset = (uint32_t)offsetof(GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry__storage_, recipientId),
.flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero),
.dataType = GPBDataTypeBytes,
},
{
.name = "amount",
.dataTypeSpecific.clazz = Nil,
.number = GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry_FieldNumber_Amount,
.hasIndex = 1,
.offset = (uint32_t)offsetof(GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry__storage_, amount),
.flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero),
.dataType = GPBDataTypeUInt64,
},
};
GPBDescriptor *localDescriptor =
[GPBDescriptor allocDescriptorForClass:[GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry class]
rootClass:[PlatformRoot class]
file:PlatformRoot_FileDescriptor()
fields:fields
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0_TokenDistributionEntry__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)];
[localDescriptor setupContainingMessageClass:GPBObjCClass(GetTokenPreProgrammedDistributionsResponse_GetTokenPreProgrammedDistributionsResponseV0)];
#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
}

@end
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Amount validation is not currently implemented.

  • The Objective-C implementation for TokenDistributionEntry does not include any logic to validate the amount field.
  • A search for validation-related keywords (e.g., validateAmount) in the repository yielded no relevant results.
🔗 Analysis chain

Consider adding amount validation.

The TokenDistributionEntry implementation could benefit from validation to ensure the amount is within acceptable ranges.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for amount validation in the codebase
rg -A 5 "amount.*valid|validateAmount"

Length of output: 871

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