mirror of
https://github.com/vacp2p/vac.dev.git
synced 2026-01-06 21:34:17 -05:00
feat(rlog: rln light verifiers): init (#136)
* feat(rlog: rln light verifiers): init * fix: alter title to be more descriptive * fix: title case * fix: title for metrics * fix: capitalized m * fix: capitalized c * fix: comma in number * fix: wording for number of rpc calls * fix: comma in 2k blocks * fix: remove comma between leaves & it * fix: capitalization for billion gas * fix: remove commas * fix: remove main * fix: remove comma number of leaves * fix: better wording on gas cost * fix: remove comma between subtree & and * fix: comma wording * fix: remove comma after subtree * fix: comma in insertion section * fix: section on syncing * fix: s/which/this * fix: remove comma in gas cost section * fix: future work fixes * fix: conclusion fix p1 * fix: conclusion fix p2 * fix: intro comma * fix: intro commas p2
This commit is contained in:
committed by
GitHub
parent
503b54921e
commit
b0e56396d6
160
rlog/2024-04-20-rln-light-verifiers.mdx
Normal file
160
rlog/2024-04-20-rln-light-verifiers.mdx
Normal file
@@ -0,0 +1,160 @@
|
||||
---
|
||||
title: 'Verifying RLN Proofs in Light Clients with Subtrees'
|
||||
date: 2024-04-20 12:00:00
|
||||
authors: p1ge0nh8er
|
||||
published: true
|
||||
slug: rln-light-verifiers
|
||||
categories: research
|
||||
|
||||
toc_min_heading_level: 2
|
||||
toc_max_heading_level: 4
|
||||
---
|
||||
|
||||
How resource-restricted devices can verify RLN proofs fast and efficiently.
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
## Introduction
|
||||
|
||||
Recommended previous reading: [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention).
|
||||
|
||||
This post expands upon ideas described in the previous post,
|
||||
focusing on how resource-restricted devices can verify RLN proofs fast and efficiently.
|
||||
|
||||
Previously, it was required to fetch all the memberships from the smart contract,
|
||||
construct the merkle tree locally,
|
||||
and derive the merkle root,
|
||||
which is subsequently used to verify RLN proofs.
|
||||
|
||||
This process is not feasible for resource-restricted devices since it involves a lot of RPC calls, computation and fault tolerance.
|
||||
One cannot expect a mobile phone to fetch all the memberships from the smart contract and construct the merkle tree locally.
|
||||
|
||||
## Constraints and requirements
|
||||
|
||||
An alternative solution to the one proposed in this post is to construct the merkle tree on-chain,
|
||||
and have the root accessible with a single RPC call.
|
||||
However, this approach increases gas costs for inserting new memberships and _may_ not be feasible until it is optimized further with batching mechanisms, etc.
|
||||
|
||||
The other methods have been explored in more depth [here](https://hackmd.io/@rymnc/rln-tree-storages).
|
||||
|
||||
Following are the requirements and constraints for the solution proposed in this post:
|
||||
|
||||
1. Cheap membership insertions.
|
||||
2. As few RPC calls as possible to reduce startup time.
|
||||
3. Merkle root of the tree is available on-chain.
|
||||
4. No centralized services to sequence membership insertions.
|
||||
5. Map inserted commitments to the block in which they were inserted.
|
||||
|
||||
## Metrics on sync time for a tree with 2,653 leaves
|
||||
|
||||
The following metrics are based on the current implementation of RLN in the Waku gen0 network.
|
||||
|
||||
### Test bench
|
||||
|
||||
- Hardware: Macbook Air M2, 16GB RAM
|
||||
- Network: 120 Megabits/sec
|
||||
- Nwaku commit: [e61e4ff](https://github.com/waku-org/nwaku/tree/e61e4ff90a235657a7dc4248f5be41b6e031e98c)
|
||||
- RLN membership set contract: [0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4](https://sepolia.etherscan.io/address/0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4#code)
|
||||
- Deployed block number: 4,230,716
|
||||
- RLN Membership set depth: 20
|
||||
- Hash function: PoseidonT3 (which is a gas guzzler)
|
||||
- Max size of the membership set: 2^20 = 1,048,576 leaves
|
||||
|
||||
### Metrics
|
||||
|
||||
- Time to sync the whole tree: 4 minutes
|
||||
- RPC calls: 702
|
||||
- Number of leaves: 2,653
|
||||
|
||||
One can argue that the time to sync the tree at the current state is not _that_ bad.
|
||||
However, the number of RPC calls is a concern,
|
||||
which scales linearly with the number of blocks since the contract was deployed
|
||||
This is because the implementation fetches all events from the contract,
|
||||
chunking 2,000 blocks at a time.
|
||||
This is done to avoid hitting the block limit of 10,000 events per call,
|
||||
which is a limitation of popular RPC providers.
|
||||
|
||||
## Proposed solution
|
||||
|
||||
From a theoretical perspective,
|
||||
one could construct the merkle tree on-chain,
|
||||
in a view call, in-memory.
|
||||
However, this is not feasible due to the gas costs associated with it.
|
||||
|
||||
To compute the root of a Merkle tree with $2^{20}$ leaves it costs approximately 2 billion gas.
|
||||
With Infura and Alchemy capping the gas limit to 350M and 550M gas respectively,
|
||||
it is not possible to compute the root of the tree in a single call.
|
||||
|
||||
Acknowledging that [Polygon Miden](https://polygon.technology/blog/polygon-miden-state-model) and [Penumbra](https://penumbra.zone/blog/tiered-commitment-tree/) both make use of a tiered commitment tree,
|
||||
we propose a similar approach for RLN.
|
||||
|
||||
A tiered commitment tree is a tree which is sharded into multiple smaller subtrees,
|
||||
each of which is a tree in itself.
|
||||
This allows scaling in terms of the number of leaves,
|
||||
as well as reducing state bloat by just storing the root of a subtree when it is full instead of all its leaves.
|
||||
|
||||
Here, the question arises:
|
||||
What is the maximum number of leaves in a subtree with which the root can be computed in a single call?
|
||||
|
||||
It costs approximately 217M gas to compute the root of a Merkle tree with $2^{10}$ leaves.
|
||||
|
||||
This is a feasible number for a single call,
|
||||
and hence we propose a tiered commitment tree with a maximum of $2^{10}$ leaves in a subtree and the number of subtrees is $2^{10}$.
|
||||
Therefore, the maximum number of leaves in the tree is $2^{20}$ (the same as the current implementation).
|
||||
|
||||

|
||||
|
||||
### Insertion
|
||||
|
||||
When a commitment is inserted into the tree it is first inserted into the first subtree.
|
||||
When the first subtree is full the next insertions go into the second subtree and so on.
|
||||
|
||||
### Syncing
|
||||
|
||||
When syncing the tree,
|
||||
one only needs to fetch the roots of the subtrees.
|
||||
The root of the full tree can be computed in-memory or on-chain.
|
||||
|
||||
This allows us to derive the following relation:
|
||||
|
||||
$$
|
||||
number\_of\_rpc\_calls = number\_of\_filled\_subtrees + 1
|
||||
$$
|
||||
|
||||
This is a significant improvement over the current implementation,
|
||||
which requires fetching all the memberships from the smart contract.
|
||||
|
||||
### Gas costs
|
||||
|
||||
The gas costs for inserting a commitment into the tree are the same as the current implementation except it consists of an extra SSTORE operation to store the `shardIndex` of the commitment.
|
||||
|
||||
### Events
|
||||
|
||||
The events emitted by the contract are the same as the current implementation,
|
||||
appending the `shardIndex` of the commitment.
|
||||
|
||||
### Proof of concept
|
||||
|
||||
A proof of concept implementation of the tiered commitment tree is available [here](https://github.com/vacp2p/rln-contract/pull/37),
|
||||
and is deployed on Sepolia at [0xE7987c70B54Ff32f0D5CBbAA8c8Fc1cAf632b9A5](https://sepolia.etherscan.io/address/0xE7987c70B54Ff32f0D5CBbAA8c8Fc1cAf632b9A5).
|
||||
|
||||
It is compatible with the current implementation of the RLN verifier.
|
||||
|
||||
## Future work
|
||||
|
||||
1. Optimize the gas costs of the tiered commitment tree.
|
||||
2. Explore using different number of leaves under a given node in the tree (currently set to 2).
|
||||
|
||||
## Conclusion
|
||||
|
||||
The tiered commitment tree is a promising approach to reduce the number of RPC calls required to sync the tree and reduce the gas costs associated with computing the root of the tree.
|
||||
Consequently, it allows for a more scalable and efficient RLN verifier.
|
||||
|
||||
## References
|
||||
|
||||
- [RLN Circuits](https://github.com/rate-limiting-nullifier/circom-rln)
|
||||
- [Zerokit](https://github.com/vacp2p/zerokit)
|
||||
- [RLN-V1 RFC](https://rfc.vac.dev/spec/32/)
|
||||
- [RLN-V2 RFC](https://rfc.vac.dev/spec/58/)
|
||||
- [RLN Implementers guide](https://hackmd.io/7cBCMU5hS5OYv8PTaW2wAQ?view)
|
||||
- [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention)
|
||||
BIN
static/img/light-rln-verifiers.png
Normal file
BIN
static/img/light-rln-verifiers.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Reference in New Issue
Block a user