-
Notifications
You must be signed in to change notification settings - Fork 14
41/WAKU2-RLN-CONTRACT: Raw spec #522
Changes from all commits
bee51cd
e026c9b
98df664
bd5ddec
35a97b8
b3d454f
c9edd11
6cfa7a0
e384a14
cdaa21a
dd53832
1155d3c
977f0d0
01e3705
158edb6
4a17144
bd53546
601ddc6
6cb579c
66347f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,105 @@ | ||||||||
--- | ||||||||
slug: 41 | ||||||||
title: 41/WAKU2-RLN-CONTRACT | ||||||||
name: Rate Limiting Nullifier Membership Contract | ||||||||
status: raw | ||||||||
category: Standards Track | ||||||||
tags: RLN | ||||||||
editor: Keshav Gupta <keshav@status.im> | ||||||||
contributors: | ||||||||
--- | ||||||||
|
||||||||
# Abstract | ||||||||
The following standard specifies a standard API for Rate Limiting Nullifier Contract that manages membership of the participants in a peer-to-peer messaging group. | ||||||||
This API is intended to be used in conjunction with [17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/). | ||||||||
Peers that violate the messaging rate in a relay network, | ||||||||
like explained in [11/WAKU2-RELAY](https://rfc.vac.dev/spec/11/), | ||||||||
are considered spammers and their messages are considered spam. | ||||||||
Spammers are financially punished and removed from the system. | ||||||||
Rate limiting nullifier (RLN), like explained in [32/RLN](https://rfc.vac.dev/spec/32/), | ||||||||
a construct based on zero-knowledge proofs that provides an anonymous rate-limited signaling/messaging framework suitable for decentralized (and centralized) environments. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
|
||||||||
# Background / Rationale / Motivation | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In here, we need more details on how each membership is represented, the relation between user sk and pk. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refer 977f0d0 |
||||||||
|
||||||||
This contract serves as the basis for the implementation of RLN membership. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The spec should not depends on its abstract. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading it again, I'd add at least one introductory sentence at the beginning of this section. |
||||||||
New members can be registered by depositing a stake of valuable funds. | ||||||||
They can also be slashed if they misbehave like spamming in a peer-to-peer pseudo-anonymous messaging network. | ||||||||
Peers MUST be registered to the RLN group to be able to publish messages. | ||||||||
Each peer has an RLN key pair denoted by `secret` and `pubkey`. | ||||||||
The state of the membership contract contains the list of registered members' public identity keys i.e., `pubkeys`. | ||||||||
For the registration, a peer creates a transaction that invokes the registration function of the contract via which registers its `pubkey` in the group. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
The peer who has the secret key `secret` associated with a registered `pubkey` would be able to withdraw a portion the staked fund by providing valid proof. | ||||||||
|
||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Coming back to my first comment on this section, I'd reorganize this section. Starting with
is a bit confusing. |
||||||||
|
||||||||
# Theory / Semantics | ||||||||
|
||||||||
As explained in [17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/), | ||||||||
all peers who want to publish the message in the spam protected peer-to-peer network MUST register for membership to the RLN group. | ||||||||
This is done via the `register` function of the RLN membership contract. | ||||||||
If a registered member of the RLN group spams messages in the network then its secret key get exposed which can be used to slash its membership from the group. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
This is done by calling the `withdraw` function of the RLN membership contract, which removes the member from the Merkle tree thereby revoking its rights to send any messages. | ||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In a future draft (or at least for the stable function), I'd expect a more in depth explanation here. |
||||||||
# Contract Specification | ||||||||
|
||||||||
### Constructor | ||||||||
|
||||||||
* `constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher) public` | ||||||||
* `membershipDeposit` sets the amount of ETH that must be deposited to `register` to the RLN group. | ||||||||
* `depth` is the depth of the Merkle tree that determines the maximum number of members to the RLN group. | ||||||||
* `_poseidonHasher` is the address of the poseidon hasher contract used in the `hash` function. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably it's a good idea to include a reference to the poseidon hasher contract in the implementations section There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refer dd53832 |
||||||||
|
||||||||
### Methods | ||||||||
|
||||||||
* register: This function registers the `pubkey` to the list of members. | ||||||||
For successful registration, ETH equal to the amount specified in `membershipDeposit` MUST be paid while calling this function. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the condition There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be better addressed as an issue in the contract implementation rather than the RFC? |
||||||||
This function MUST fire the `MemberRegistered` event. | ||||||||
* `function register(uint256 pubkey) external payable` | ||||||||
|
||||||||
|
||||||||
|
||||||||
* registerBatch: This function registers multiple `pubkeys` to the list of members. | ||||||||
For succesful registration, ETH equal to the amount specified in `membershipDeposit * pubkeys.length` MUST be paid while calling this function. | ||||||||
This function MUST fire the `MemberRegistered` event for each registered member. | ||||||||
* `function registerBatch(uint256[] calldata pubkeys) external payable` | ||||||||
|
||||||||
|
||||||||
* withdraw: This function accepts the `secret` of the public key at index`_pubkeyIndex` to withdraw the ETH equal to the`membershipDeposit` to the `receiver` address. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From what is written above and here, it seems like a spammer could prepare lots of spam messages (that would eventually slash him) while preparing a transaction to withdraw the deposit to another address in his possession. In fact, by knowing in advance that he will be slashed, he can front-run relayers to get the deposit. AFAIR, we discussed that the amount withdrawn should be less than the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, this is a well-known issue re RLN slashing model and the followings are the identified countermeasures:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A new PR of this RFC will be created once #485 issue is solved and vacp2p/rln-contract#5 PR on the RLN contract is approved |
||||||||
This function MUST remove the associated member from the list of members. | ||||||||
This function MUST fire the `MemberWithdrawn` event. | ||||||||
* `function withdraw(uint256 secret, uint256 _pubkeyIndex, address payable receiver) external` | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is more a contract issue, but I find confusing using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. I'd suggest changing this even for the raw spec. |
||||||||
|
||||||||
|
||||||||
* withdrawBatch: This function accepts multiple `secrets` of the public keys at the indices `pubkeyIndexes` to withdraw the ETH equal to the `membershipDeposit * secrets.length` to the `receiver` address. | ||||||||
This function MUST remove the associated members from the list of members. | ||||||||
This function MUST fire the `MemberWithdrawn` event for each member slashed from the group. | ||||||||
* `function withdrawBatch(uint256[] calldata secrets, uint256[] calldata pubkeyIndexes, address payable[] calldata receivers) external` | ||||||||
|
||||||||
|
||||||||
### Events | ||||||||
|
||||||||
* MemberRegistered: MUST trigger when a member is registered to the RLN group. | ||||||||
* `event MemberRegistered(uint256 indexed pubkey, uint256 indexed index)` | ||||||||
|
||||||||
|
||||||||
* MemberWithdrawn: MUST trigger when a member is slashed from the RLN group. | ||||||||
* `event MemberWithdrawn(uint256 indexed pubkey, uint256 indexed index)` | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, this is a contract issue: why emitting the pubkey? The index should be enough to correctly identify the slashed key and save gas. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The pk may be needed for cases that the event listeners do not have the whole Merkle tree stored. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And then why it should listen to such event? I think the main goal is to update the local copy of the Merkle tree, but for this you just need to delete the previous leaf at the slashed index (but the leaf has to correctly be there, unless is last leaf added, in order to correctly recompute the root) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is true that in the current implementation, we keep the Merkle tree and emitting the pk may not be necessary, but consider the case that instead of replacing the leaf, a blacklist of Pks is maintained. Emitting the pk gives the flexibility for such solutions. |
||||||||
|
||||||||
|
||||||||
# Example Implementation | ||||||||
|
||||||||
Complete implementation of this contract can be found at https://github.com/vacp2p/rln-contract | ||||||||
|
||||||||
The contract for Poseidon Hasher can be found at https://github.com/vacp2p/rln-contract/blob/main/contracts/PoseidonHasher.sol | ||||||||
|
||||||||
## References | ||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of referencing the implementation of the contract via a github link, what do you think of adding the solidity source code just like it is done in the ethereum ERCs? otherwise, it might be a good idea to reference an specific commit / branch, so this spec matches the contract at an specific point in time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will this make the RFC too long or clunky? But I do agree that specific changes to the RFC can be mapped to the specific commits/branch of the contract implementation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd not put an implementation here, as such specs should be implementation detail agnostic. If you want to link the implementation. I'd add a new subsection "Example Implementation". You could also add an appendix that contains the whole source code. |
||||||||
1. [17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/) | ||||||||
2. [11/WAKU2-RELAY](https://rfc.vac.dev/spec/11/) | ||||||||
3. [32/RLN](https://rfc.vac.dev/spec/32/) | ||||||||
|
||||||||
# Copyright | ||||||||
|
||||||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). | ||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.