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

Refinements of RLN on mainnet spec #34

Merged
merged 20 commits into from
Oct 15, 2024
Merged
Changes from 6 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f15b30a
clarify terminology: epoch length vs period
s-tikhomirov Aug 30, 2024
586d70b
clarify parameter update implications for existing memberships
s-tikhomirov Aug 30, 2024
818ce98
clarify definition of tx sender as membership keeper
s-tikhomirov Aug 30, 2024
82b4bc7
clarify handling of call chains from EOAs
s-tikhomirov Aug 30, 2024
8d7a41b
clarify slot reuse: from spec-level to impl-level decision
s-tikhomirov Aug 30, 2024
2a1b433
clarify membership unit price definition
s-tikhomirov Sep 9, 2024
dfe5e53
separate "membership set" and "Merkle tree" as its impl in the spec
s-tikhomirov Sep 25, 2024
5ef1d30
separate withdraw and erase (in line with the implementation)
s-tikhomirov Sep 25, 2024
258a07e
clarify functionality table
s-tikhomirov Sep 25, 2024
0f9d680
edit membership registration section for clarity
s-tikhomirov Sep 25, 2024
fd91933
edit for clarity
s-tikhomirov Sep 25, 2024
3a1aabb
clarify types of state transitions in the diagram
s-tikhomirov Sep 25, 2024
ca0c416
rename "expiration term" to "active state duration"
s-tikhomirov Sep 25, 2024
eb4dfd6
clarify requirements: A>0, G >=0
s-tikhomirov Sep 27, 2024
cc1a917
fix: add semantic break
s-tikhomirov Sep 30, 2024
090c65c
make spec less strict on overwriting memberships
s-tikhomirov Sep 30, 2024
7c29616
retain remaining grace period time on membership extention
s-tikhomirov Sep 30, 2024
66945c7
unify holder and keeper terms - only use holder (fixes #41)
s-tikhomirov Oct 1, 2024
b8ea666
unify overwrite / reuse terminology
s-tikhomirov Oct 1, 2024
80ba2bd
define period boundaries: start inclusive, end exclusive
s-tikhomirov Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 51 additions & 16 deletions standards/core/rln-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,37 @@ The contract MUST provide the following functionalities:
- withdraw a deposit.

A membership _holder_ is the entity that controls the secret associated with the respective RLN commitment.
A membership _keeper_ is the entity that controls the Ethereum address used to register that membership.
A membership _keeper_ is the sender of the transaction that registered that membership.
Transaction sender in this context is defined as `msg.sender` in Solidity semantics.
The contract MUST support transactions sent directly from externally-owned accounts (EOA).
The contract MAY support transactions sent from an EOA via a chain of contract calls,
in which case the last contract in the call chain MAY be designated as the membership keeper.
The contract MAY also support meta-transactions sent via paymasters or relayers,
which MAY require additional authentication-related logic.

The holder and the keeper MAY be different entities for the same membership.
When authorizing membership-related requests,
the contract SHOULD distinguish between the keeper and non-keepers,
and MAY also use additional criteria.

Contract parameters and their RECOMMENDED values for the initial mainnet deployment are as follows:

| Parameter | Symbol | Value | Units |
| ------------------------------------------------------- | --------- | -------- | -------------------- |
| Epoch length | `epoch` | `10` | minutes |
| Maximum total rate limit of all memberships in the tree | `R_{max}` | `160000` | messages per `epoch` |
| Minimum rate limit of one membership | `r_{min}` | `20` | messages per `epoch` |
| Maximum rate limit of one membership | `r_{max}` | `600` | messages per `epoch` |
| Membership price for `1` message per epoch | `p_u` | `0.05` | `USD` |
| Membership expiration term | `T` | `180` | days |
| Membership grace period | `G` | `30` | days |
| Accepted tokens | | `DAI` | |
| Parameter | Symbol | Value | Units |
| --------------------------------------------------------- | --------- | -------- | ------------------ |
| Epoch length | `t_{ep}` | `600` | seconds |
| Maximum total rate limit of all memberships in the tree | `R_{max}` | `160000` | messages per epoch |
| Minimum rate limit of one membership | `r_{min}` | `20` | messages per epoch |
| Maximum rate limit of one membership | `r_{max}` | `600` | messages per epoch |
| Membership expiration term | `T` | `180` | days |
| Membership grace period | `G` | `30` | days |
| Membership price for `1` message per epoch for period `T` | `p_u` | `0.05` | `USD` |
| Accepted tokens | | `DAI` | |

The pricing function SHOULD be linear in the rate limit per epoch.

Note: epoch length means the same as `period` as defined in [17/WAKU2-RLN-RELAY](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/17/rln-relay.md).
This specification uses the term "epoch length" instead of "period" to avoid confusion with "grace period".

## Membership lifecycle

Any existing membership MUST always be in exactly one of the following states:
Expand Down Expand Up @@ -127,22 +137,32 @@ Availability of membership-specific functionalities[^2] MUST be as follows:

### Register a membership

Membership registration is subject to the following conditions:
- If there are _Expired_ memberships in the RLN tree, the new membership MUST overwrite an _Expired_ membership.
- The new membership SHOULD overwrite the membership that has been _Expired_ for the longest time.
Let us define the following aggregate rate limits:
- `R_{active}` is the total rate limit of all _Active_ memberships;
- `R_{grace_period}` is the total rate limit of all _GracePeriod_ memberships;
- `R_{expired}` is the total rate limit of all _Expired_ memberships;
- `r` is the requested rate limit of a new membership.

Let `R_{free} = R_{max} - R_{active} - R_{grace_period} - R_{expired}` be the free rate limit that is available without overwriting _Expired_ slots.

Membership registration is subject to the following requirements:
- If `r <= R_{free}`, the new membership MUST be registered (assuming all other necessary conditions hold). The new membership MAY overwrite one or multiple _Expired_ memberships.
s-tikhomirov marked this conversation as resolved.
Show resolved Hide resolved
- If `r > R_{free}`:
- if `r > R_{free} + R_{expired}`, registration MUST fail;
- if `r <= R_{free} + R_{expired}`, the new membership MUST be registered by overwriting some _Expired_ memberships.
- The sender of the registration transaction MAY specify a list of _Expired_ memberships whose slots will be overwritten. If the list is not provided, the contract MAY use any criteria to select _Expired_ memberships to overwrite (see Implementation Suggestions).
- If a new membership A overwrites an _Expired_ membership B:
- membership B MUST become _ErasedAwaitsWithdrawal_;
- the current total rate limit MUST be decremented by the rate limit of membership B;
- the contract MUST take all necessary steps to ensure that the keeper of membership B can withdraw their deposit later.
- Registration MUST fail if the total rate limit of _Active_, _GracePeriod_, and _Expired_ memberships, including the one being created, would exceed `R_{max}`.
- Registration MUST fail if the requested rate limit for a new membership is lower than `r_{min}` or higher than `r_{max}`.
- The keeper MUST lock up a deposit to register a membership.
- The keeper MUST specify the rate limit[^3] of a membership at registration time.
- The size of the deposit MUST depend on the specified rate limit.
- In case of a successful registration:
- the new membership MUST become _Active_;
- the new membership MUST have an expiration time `T` and a grace period `G`;
- the current total rate limit MUST be incremented by the rate limit of the new membership.
- A membership MUST have an expiration time `T` and a grace period `G`.

[^3]: A user-facing application SHOULD suggest default rate limits to the keeper (see Implementation Suggestions).

Expand All @@ -167,6 +187,10 @@ Deposit withdrawal is subject to the following conditions:

At initial mainnet deployment, the contract MUST have an _Owner_.
The _Owner_ MUST be able to change the values of all contract parameters.
The updated parameter values MUST apply to all new memberships.
The parameters of existing memberships MUST NOT change if the _Owner_ updates global parameters.
The contract MAY restrict extensions for memberships created before the latest parameter update.

The _Owner_ MUST be able to pause any of the following contract functionalities:
- register a membership;
- extend a membership;
Expand All @@ -180,6 +204,17 @@ and the membership set SHOULD be migrated.

## Implementation Suggestions

### Choosing Which _Expired_ Memberships to Overwrite

When registering a new membership, the smart contract may need to decide which _Expired_ memberships to overwrite.
The criteria for this selection can vary depending on the implementation.

Key considerations include:
- To minimize gas costs, it's better to overwrite a single high-rate membership rather than multiple low-rate ones.
- To encourage timely withdrawals, it's better to overwrite memberships that have been _Expired_ for a long time.

Choose a reason for hiding this comment

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

Do we agree @richard-ramos that for now, we don't include this feature in the smart contract?

Copy link
Member

@richard-ramos richard-ramos Sep 13, 2024

Choose a reason for hiding this comment

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

The way it works right now is that you can:

  • Specify the memberships you want to expire
  • If you don't specify:
    • If there's enough space in the tree / enough rate limit: create the membership
    • Otherwise, attempt to free it.

Since for any option ideally the client should call estimateGas to determine which option is cheaper, and the smart contract's been already modified to support this scenario, we can keep it. Unless we want to remove the tracking of the membership age ordering in the smart contract completely? (i.e. we will not know in the smart contract what's the oldest membership to expire). If so, then, cool. It means less gas for the user, and nwaku can track the age of the memberships then, and choose which memberships to expire.

Choose a reason for hiding this comment

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

nwaku can track the age of the membership

Are you saying that nwaku would need to listen to emit events from the smart contract? I think we definitely do not want that as the whole point of onchain tree was to not have to load all events.

However, can the solution be:

  • membership and some age information are stored in contract
  • BUT they are not ordered

Meaning that it's cheaper to insert or expire (no ordering at insertion). But it's possible to get all data from the contract API (no tracing of emitted events).
The ordering can then be done by the applicaiton (nwaku, jswaku) etc

Copy link
Member

Choose a reason for hiding this comment

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

Sure! no need to use events. There's already a function that would let you iterate over all the memberships registered. Also perhaps in the future we might want to integrate with the graph and obtain this information from there too.

I'll propose the changes on a separate branch from waku-org/waku-rlnv2-contract#13 so it's possible to compare both options. I do think not having to track the ordering in the contract will be very beneficial due to reduced costs


### Considerations for User-facing Applications

User-facing applications SHOULD suggest one or more rate limits (tiers) to simplify user selection among the following RECOMMENDED options:
- `20` messages per epoch as low-tier;
- `200` messages per epoch as mid-tier;
Expand Down
Loading