Skip to content

RLN on mainnet - Implementation Roadmap #11

@s-tikhomirov

Description

@s-tikhomirov

This document outlines the steps to implement the mainnet-ready RLN smart contract as in the specification based on its current implementation deployed on testnet.

Implementation Stages

We suggest implementing the specification in multiple stages. The primary goal of this stage-based approach is to limit the scope of each stage, simplifying both implementation and testing.

Each stage description includes a membership state transition diagram representing the contract's state at the end of that stage (if it differs from the previous stage). After completing all stages, the diagram must match the one defined in the specification.

Note: membership states don't have to be stored explicitly. It is up to the implementation to either store membership states or derive the current state just-in-time based on timestamps and other data. The only requirement is that the contract behaves in the way described in the specification.

Add Rate-Limiting Constraints

Implement rate-limiting constraints on individual memberships and the entire membership tree.

Suggested steps:

  • Define constraints on the minimum and maximum rate limits for a single membership.
  • Define constraints on the maximum rate limit for all memberships in the tree.
  • Enforce these constraints during membership registration.

Stub Membership State Management

Introduce the necessary fields and data structures for storing membership states and related data.

Each membership must store:

  • Its current state.
  • The timestamp when the state was assigned.
  • The timestamp when the state becomes invalid.
  • The address of the membership holder (msg.sender during registration).

Assign the Active state to a membership upon successful registration.

graph TD;
    NonExistent --> |"register"| Active;
Loading

Time-Related Membership State Updates

Membership state transitions can result from either time progression or user transactions. This stage focuses on time-based state updates.

Two time-based state transitions are implemented:

  • From Active to GracePeriod.
  • From GracePeriod to Expired.
graph TD;
    NonExistent --> |"register"| Active;
    Active -.-> |"time T passed"| GracePeriod;
    GracePeriod -.-> |"time G passed"| Expired;
Loading

Suggested steps:

  • Define an internal state transition function:
    • Include a modifier to check that msg.sender is the membership holder.
    • Add modifiers to enforce constraints based on the current and new states (e.g., onlyActiveState, onlyGracePeriodState).
  • Implement a function to update membership states when sufficient time has passed.

Membership Extensions

A membership holder may extend their membership by sending an extension transaction. An extension returns the membership to the Active state and is only possible from the GracePeriod state. This stage excludes deposit-related conditions.

graph TD;
    NonExistent --> |"register"| Active;
    Active -.-> |"time T passed"| GracePeriod;
    GracePeriod --> |"extend"| Active;
    GracePeriod -.-> |"time G passed"| Expired;
Loading

Suggested steps:

  • Add a public extend function.
  • Verify that msg.sender is the membership holder.
  • If the membership state is recorded as GracePeriod, and sufficient time has passed for its transition to Expired, update the state to Expired.
  • Check if the membership is in GracePeriod.
  • If all conditions are met, extend the membership.

Add Membership Deposit Lock-Up and Withdrawal

To register a membership, a user must lock up a deposit. When a membership enters the GracePeriod, the holder may choose to either extend it or withdraw the deposit.

graph TD;
    NonExistent --> |"register"| Active;
    Active -.-> |"time T passed"| GracePeriod;
    GracePeriod --> |"extend"| Active;
    GracePeriod -.-> |"time G passed"| Expired;
    GracePeriod --> |"withdraw"| Expired;
Loading

Note: In the final state transition diagram, a withdraw action from GracePeriod leads to the Erased state instead of Expired. However, since membership erasure is not yet implemented at this stage, the Expired state is temporarily reused as the destination for both transitions from GracePeriod.

Suggested steps:

  • Add data structures to store deposit data, including membership, amount, and the time deposited.
  • Implement a function that calculates the required deposit amount based on the rate limit and a reference price (the price for 1 message per epoch). Ensure careful handling of monetary rounding.
  • Enforce the deposit requirement during membership registration.
  • Add a public withdraw function for deposit withdrawal:
    • Verify that msg.sender is the membership holder.
    • Check if the membership state is outdated and update it if necessary.
    • Enforce the conditions defined in the specification.
    • Upon successful withdrawal, update the membership state and associated metadata.

Erase Membership from the Tree After Deposit Withdrawal

A membership is erased either upon deposit withdrawal or when its slot is overwritten by another membership. This stage implements erasing the membership upon withdrawal.

graph TD;
    NonExistent --> |"register"| Active;
    Active -.-> |"time T passed"| GracePeriod;
    GracePeriod --> |"extend"| Active;
    GracePeriod -.-> |"time G passed"| Expired;
    GracePeriod --> |"withdraw"| Erased;
    Expired --> |"withdraw"| Erased;
Loading

Suggested steps:

  • Implement an internal function to erase membership data from the tree.
  • Modify the withdraw function so that it transitions from GracePeriod to Erased instead of Expired.
  • Add support for withdraw from an Expired membership.

Reuse Tree Slots of Expired Memberships

Implement deposit withdrawal after the membership associated with that deposit is erased from the tree.

graph TD;
    NonExistent --> |"register"| Active;
    Active -.-> |"time T passed"| GracePeriod;
    GracePeriod --> |"extend"| Active;
    GracePeriod -.-> |"time G passed"| Expired;
    GracePeriod --> |"withdraw"| Erased;
    Expired --> |"withdraw"| Erased;
    Expired --> |"another membership reuses slot"| ErasedAwaitsWithdrawal;
    ErasedAwaitsWithdrawal --> |"withdraw"| Erased;
Loading

Suggested steps:

  • Add a data structure to store information about ErasedAwaitsWithdrawal memberships and their deposits.
  • Enable deposit withdrawal for holders of such memberships.

The state transition diagram should now match the final form as in the specification.

UPD 2024-09-25: a change in the state diagram has been suggested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions