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(rln-relay-v2): update C FFI api's and serde #2385

Merged
merged 4 commits into from
Feb 1, 2024

Conversation

rymnc
Copy link
Contributor

@rymnc rymnc commented Jan 31, 2024

  • feat(rln-relay-v2): integrate new ffi bindings, serde
  • chore: use ExtendedRateLimitProof to describe epoch + rlnIdentifier

Description

This PR introduces the changes required for serde, and creates a new type ExtendedRateLimitProof which contains all metadata required to verify a proof.

Changes

  • updates the c ffi api
  • updates serde to include userMessageLimit and messageId
  • new type ExtendedRateLimitProof which includes epoch and rlnIdentifier in calculation of the externalNullifier

Issue

closes #2377 and #2378

@rymnc rymnc force-pushed the update-rln-ffi-bindings branch 2 times, most recently from 4b327c1 to e0fd50d Compare January 31, 2024 06:23
Copy link

github-actions bot commented Jan 31, 2024

You can find the image built from this PR at

quay.io/wakuorg/nwaku-pr:2385

Built from 4d72fa9

@rymnc rymnc linked an issue Jan 31, 2024 that may be closed by this pull request
when defined(rln_v2):
const
# pre-processed "rln/waku-rln-relay/v2.0.0" to array[32, byte]
DefaultRlnIdentifier*: RlnIdentifier = [114, 108, 110, 47, 119, 97, 107, 117,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

imo this is the best way to have the DefaultRlnIdentifier stored - if we do decide to have it as a command line argument for rln-relay we can process it into an array of 32 bytes at that point.

@@ -53,33 +53,60 @@ proc encodeLengthPrefix*(input: openArray[byte]): seq[byte] =
output = concat(@len, @input)
return output

proc serialize*(idSecretHash: IdentitySecretHash,
when defined(rln_v2):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

had to dupe the function because args are different

Copy link
Contributor

Choose a reason for hiding this comment

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

have the hunch that having rlnv2 behind a flag will end up being more problematic than using a branch (where we completely replace v1 with v2)

Copy link
Collaborator

Choose a reason for hiding this comment

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

IMO, having a flag is much clearer and less error-prone than a separate branch.

Comment on lines 56 to 70
when defined(rln_v2):
## the external nullifier used for the generation of the `proof` (derived from poseidon([epoch, rln_identifier]))
externalNullifier*: ExternalNullifier
else:
## the epoch used for the generation of the `proof`
epoch*: Epoch
## Application specific RLN Identifier
rlnIdentifier*: RlnIdentifier

when defined(rln_v2):
type ExtendedRateLimitProof* = ref object of RateLimitProof
## epoch is the epoch for which the proof is generated
epoch*: Epoch
## rlnIdentifier is the identifier of the RLN application
rlnIdentifier*: RlnIdentifier
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The distinction between the two is made because now, RateLimitProof contains the proof with the public inputs/outputs. epoch and rlnIdentifier are no longer public inputs, and must not be confused this way. ExtendedRateLimitProof is what should be sent on the wire.

@rymnc rymnc marked this pull request as ready for review January 31, 2024 07:36
@rymnc rymnc mentioned this pull request Jan 31, 2024
17 tasks
Copy link
Contributor

@alrevuelta alrevuelta left a comment

Choose a reason for hiding this comment

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

lgtm

when defined(rln_v2):
type ExtendedRateLimitProof* = ref object of RateLimitProof
## epoch is the epoch for which the proof is generated
epoch*: Epoch
Copy link
Contributor

Choose a reason for hiding this comment

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

why is the epoch inside ExtendedRateLimitProof instead of RateLimitProof. I mean, both rln v1 and v2 should have this field, so? same for rlnIdentifier?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the difference between rln-v1 and v2 also includes that the epoch and rlnIdentifier is not passed into the circuit, instead the externalNullifier is directly passed in after computing it from the epoch and rlnIdentifier. the RateLimitProof struct properly defines this behaviour, and ExtendedRateLimitProof includes them so that a receiving node can ensure the epoch is not too old, and that the rlnIdentifier is the same as they one they're validating for.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I have the impression that the ExtendedRateLimitProof type is not needed. Could we only keep the RateLimitProof with the following?

    ## the epoch used for the generation of the `proof`
    epoch*: Epoch
    ## Application specific RLN Identifier
    rlnIdentifier*: RlnIdentifier
when defined(rln_v2):
    ## the external nullifier used for the generation of the `proof` (derived from poseidon([epoch, rln_identifier]))
    externalNullifier*: ExternalNullifier

I think a good strategy to ease the future migration to rln_v2 is to keep a clear separation. Having such inheritance is some kind of messy IMO. Let me know if this is not feasible by another constraint that I'm missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I understand the concern, and I thought of this approach initially as well. however, RateLimitProof and ExtendedRateLimitProof serve 2 entirely different functions, and it's better to separate their concerns.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed in 561a967

@@ -53,33 +53,60 @@ proc encodeLengthPrefix*(input: openArray[byte]): seq[byte] =
output = concat(@len, @input)
return output

proc serialize*(idSecretHash: IdentitySecretHash,
when defined(rln_v2):
Copy link
Contributor

Choose a reason for hiding this comment

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

have the hunch that having rlnv2 behind a flag will end up being more problematic than using a branch (where we completely replace v1 with v2)

Copy link
Collaborator

@Ivansete-status Ivansete-status left a comment

Choose a reason for hiding this comment

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

Thanks for this! I've added a few comments/questions that I hope you find useful :)

@@ -15,7 +18,7 @@ const
# inputs of the membership contract constructor
# TODO may be able to make these constants private and put them inside the waku_rln_relay_utils
const
MembershipFee* = 1000000000000000.u256
MembershipFee* = 0.u256
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shall we indicate which units are being considered either in the const name or in a comment? Maybe wei?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed in 561a967

# Custom data types defined for waku rln relay -------------------------
type RateLimitProof* = object
type RateLimitProof* = object of RootObj
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we don't need inheritance as per my comment below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed in 561a967

@@ -53,33 +53,60 @@ proc encodeLengthPrefix*(input: openArray[byte]): seq[byte] =
output = concat(@len, @input)
return output

proc serialize*(idSecretHash: IdentitySecretHash,
when defined(rln_v2):
Copy link
Collaborator

Choose a reason for hiding this comment

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

IMO, having a flag is much clearer and less error-prone than a separate branch.

when defined(rln_v2):
type ExtendedRateLimitProof* = ref object of RateLimitProof
## epoch is the epoch for which the proof is generated
epoch*: Epoch
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have the impression that the ExtendedRateLimitProof type is not needed. Could we only keep the RateLimitProof with the following?

    ## the epoch used for the generation of the `proof`
    epoch*: Epoch
    ## Application specific RLN Identifier
    rlnIdentifier*: RlnIdentifier
when defined(rln_v2):
    ## the external nullifier used for the generation of the `proof` (derived from poseidon([epoch, rln_identifier]))
    externalNullifier*: ExternalNullifier

I think a good strategy to ease the future migration to rln_v2 is to keep a clear separation. Having such inheritance is some kind of messy IMO. Let me know if this is not feasible by another constraint that I'm missing.


return output
when defined(rln_v2):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it be possible to only have one encode implementation if we only had RateLimitProof?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed in 561a967

rlnIdentifier*: RlnIdentifier
when defined(rln_v2):
## the external nullifier used for the generation of the `proof` (derived from poseidon([epoch, rln_identifier]))
externalNullifier*: ExternalNullifier
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is is possible to use a different attribute name? externalNullifier is also part of the ProofMetadata and it is more difficult to follow its references.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's the same field/value though

## input_buffer is serialized as input_data as [ id_key<32> | path_elements<Vec<32>> | identity_path_index<Vec<1>> | x<32> | epoch<32> | rln_identifier<32> ]
## input_buffer is serialized as input_data as [ identity_secret<32> | user_message_limit<32> | message_id<32> | path_elements<Vec<32>> | identity_path_index<Vec<1>> | x<32> | external_nullifier<32> ]
Copy link
Collaborator

Choose a reason for hiding this comment

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

We are changing the param definition but this actually depends on the zerokit/rln implementation being used, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, I can add a note which mentions what is the serde pattern for v1 and v2 respectively if you'd like.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed in 561a967

Copy link
Collaborator

@Ivansete-status Ivansete-status left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for it 🥳

@rymnc rymnc merged commit b88facd into master Feb 1, 2024
9 of 10 checks passed
@rymnc rymnc deleted the update-rln-ffi-bindings branch February 1, 2024 18:56
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.

rln-v2: Update serde for proof generation and commitment insertion rln-v2: Update C FFI api's
3 participants