mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-07-09 09:49:26 +00:00
replace RLN specific Result with generic Result (#4011)
This commit is contained in:
parent
21569ef884
commit
0a1700e239
@ -10,7 +10,7 @@ logScope:
|
||||
|
||||
proc hasDuplicate*(
|
||||
rlnPeer: Rln, epoch: Epoch, proofMetadata: ProofMetadata
|
||||
): RlnResult[bool] =
|
||||
): Result[bool, string] =
|
||||
## returns true if there is another message in the `nullifierLog` of the `rlnPeer` with the same
|
||||
## epoch and nullifier as `proofMetadata`'s epoch and nullifier
|
||||
## otherwise, returns false
|
||||
@ -32,7 +32,7 @@ proc hasDuplicate*(
|
||||
|
||||
proc updateLog*(
|
||||
rlnPeer: Rln, epoch: Epoch, proofMetadata: ProofMetadata
|
||||
): RlnResult[void] =
|
||||
): Result[void, string] =
|
||||
## saves supplied proofMetadata `proofMetadata`
|
||||
## in the `nullifierLog` of the `rlnPeer`
|
||||
## Returns an error if it cannot update the log
|
||||
|
||||
@ -56,7 +56,7 @@ proc toRLNSignal*(wakumessage: WakuMessage): seq[byte] =
|
||||
|
||||
proc generateRLNProof*(
|
||||
rln: Rln, input: seq[byte], senderEpochTime: float64
|
||||
): Future[RlnResult[seq[byte]]] {.async.} =
|
||||
): Future[Result[seq[byte], string]] {.async.} =
|
||||
let epoch = rln.calcEpoch(senderEpochTime)
|
||||
let nonce = rln.nonceManager.getNonce().valueOr:
|
||||
return err("could not get new message id to generate an rln proof: " & $error)
|
||||
|
||||
@ -5,11 +5,8 @@ import ../waku_core, ../waku_keystore, ../common/protobuf
|
||||
|
||||
export waku_keystore, waku_core
|
||||
|
||||
type RlnResult*[T] = Result[T, string]
|
||||
|
||||
## RLN is a Nim wrapper for the data types used in zerokit RLN
|
||||
type RlnRaw* {.incompleteStruct.} = object
|
||||
type RlnInstanceResult* = RlnResult[ptr RlnRaw]
|
||||
|
||||
type
|
||||
MerkleNode* = array[32, byte]
|
||||
@ -72,14 +69,10 @@ type ProofMetadata* = object
|
||||
shareY*: MerkleNode
|
||||
externalNullifier*: Nullifier
|
||||
|
||||
type
|
||||
MessageValidationResult* {.pure.} = enum
|
||||
Valid
|
||||
Invalid
|
||||
Spam
|
||||
|
||||
MerkleNodeResult* = RlnResult[MerkleNode]
|
||||
RateLimitProofResult* = RlnResult[RateLimitProof]
|
||||
type MessageValidationResult* {.pure.} = enum
|
||||
Valid
|
||||
Invalid
|
||||
Spam
|
||||
|
||||
# Protobufs enc and init
|
||||
proc init*(T: type RateLimitProof, buffer: seq[byte]): ProtoResult[T] =
|
||||
|
||||
@ -183,7 +183,7 @@ proc monitorEpochs(rln: Rln) {.async.} =
|
||||
|
||||
proc mount(
|
||||
conf: WakuRlnConfig, registrationHandler = none(RegistrationHandler)
|
||||
): Future[RlnResult[Rln]] {.async.} =
|
||||
): Future[Result[Rln, string]] {.async.} =
|
||||
var
|
||||
groupManager: GroupManager
|
||||
rln: Rln
|
||||
@ -258,7 +258,7 @@ proc isReady*(rlnPeer: Rln): Future[bool] {.async.} =
|
||||
|
||||
proc new*(
|
||||
T: type Rln, conf: WakuRlnConfig, registrationHandler = none(RegistrationHandler)
|
||||
): Future[RlnResult[Rln]] {.async.} =
|
||||
): Future[Result[Rln, string]] {.async.} =
|
||||
## Mounts the rln-relay protocol on the node.
|
||||
## The rln-relay protocol can be mounted in two modes: on-chain and off-chain.
|
||||
## Returns an error if the rln-relay protocol could not be mounted.
|
||||
|
||||
@ -318,14 +318,14 @@ proc vecToSeq*(data: Vec_uint8): seq[byte] =
|
||||
if result.len > 0:
|
||||
copyMem(addr result[0], data.dataPtr, result.len)
|
||||
|
||||
proc seqToFixed32*(data: openArray[byte]): RlnResult[array[32, byte]] =
|
||||
proc seqToFixed32*(data: openArray[byte]): Result[array[32, byte], string] =
|
||||
if data.len != FieldElementSize:
|
||||
return err("Expected 32 bytes, got " & $data.len)
|
||||
var output: array[32, byte]
|
||||
copyMem(addr output[0], unsafeAddr data[0], FieldElementSize)
|
||||
ok(output)
|
||||
|
||||
proc cfrToBytesLe*(cfr: ptr CFr): RlnResult[array[32, byte]] =
|
||||
proc cfrToBytesLe*(cfr: ptr CFr): Result[array[32, byte], string] =
|
||||
let bytes = ffi_cfr_to_bytes_le(cfr)
|
||||
defer:
|
||||
ffi_vec_u8_free(bytes)
|
||||
@ -333,7 +333,7 @@ proc cfrToBytesLe*(cfr: ptr CFr): RlnResult[array[32, byte]] =
|
||||
return err("Invalid field byte length: " & $bytes.len)
|
||||
seqToFixed32(vecToSeq(bytes))
|
||||
|
||||
proc bytesToCfrLe*(data: openArray[byte]): RlnResult[ptr CFr] =
|
||||
proc bytesToCfrLe*(data: openArray[byte]): Result[ptr CFr, string] =
|
||||
## Allocate a ptr CFr from raw bytes. Caller MUST ffi_cfr_free(x).
|
||||
var vec = toVecUint8(data)
|
||||
let res = ffi_bytes_le_to_cfr(addr vec)
|
||||
@ -343,7 +343,7 @@ proc bytesToCfrLe*(data: openArray[byte]): RlnResult[ptr CFr] =
|
||||
|
||||
proc cfrResultToBytes*(
|
||||
res: CResultCFrPtrVecU8, prefix: string
|
||||
): RlnResult[array[32, byte]] =
|
||||
): Result[array[32, byte], string] =
|
||||
## Consume a CResultCFrPtrVecU8: read bytes if ok, free the CFr, or
|
||||
## propagate the error (also freeing the error string).
|
||||
if res.ok.isNil:
|
||||
@ -352,7 +352,7 @@ proc cfrResultToBytes*(
|
||||
ffi_cfr_free(res.ok)
|
||||
cfrToBytesLe(res.ok)
|
||||
|
||||
proc hashToFieldLe*(data: openArray[byte]): RlnResult[ptr CFr] =
|
||||
proc hashToFieldLe*(data: openArray[byte]): Result[ptr CFr, string] =
|
||||
## Caller MUST ffi_cfr_free the returned ptr.
|
||||
var vec = toVecUint8(data)
|
||||
let cfr = ffi_hash_to_field_le(addr vec)
|
||||
@ -360,7 +360,7 @@ proc hashToFieldLe*(data: openArray[byte]): RlnResult[ptr CFr] =
|
||||
return err("Failed to hash to field")
|
||||
ok(cfr)
|
||||
|
||||
proc poseidonPairLe*(a, b: openArray[byte]): RlnResult[array[32, byte]] =
|
||||
proc poseidonPairLe*(a, b: openArray[byte]): Result[array[32, byte], string] =
|
||||
## Poseidon hash of exactly two 32-byte field elements (little-endian).
|
||||
## zerokit v2 FFI only exposes pair-input Poseidon; unary is not supported.
|
||||
let aPtr = bytesToCfrLe(a).valueOr:
|
||||
|
||||
@ -12,9 +12,9 @@ logScope:
|
||||
# Forward decl; body defined below.
|
||||
proc generateExternalNullifier*(
|
||||
epoch: Epoch, rlnIdentifier: RlnIdentifier
|
||||
): RlnResult[ExternalNullifier]
|
||||
): Result[ExternalNullifier, string]
|
||||
|
||||
proc toRootVec(validRoots: seq[MerkleNode]): RlnResult[Vec_CFr] =
|
||||
proc toRootVec(validRoots: seq[MerkleNode]): Result[Vec_CFr, string] =
|
||||
## Caller MUST ffi_vec_cfr_free the returned Vec_CFr.
|
||||
var roots = ffi_vec_cfr_new(csize_t(validRoots.len))
|
||||
for root in validRoots:
|
||||
@ -27,7 +27,7 @@ proc toRootVec(validRoots: seq[MerkleNode]): RlnResult[Vec_CFr] =
|
||||
|
||||
proc proofPtrToRateLimitProof(
|
||||
proofPtr: ptr FFI_RLNProof, epoch: Epoch, rlnIdentifier: RlnIdentifier
|
||||
): RlnResult[RateLimitProof] =
|
||||
): Result[RateLimitProof, string] =
|
||||
var proofHandle = proofPtr
|
||||
let proofBytesRes = ffi_rln_proof_to_bytes_le(addr proofHandle)
|
||||
if hasError(proofBytesRes.err):
|
||||
@ -93,7 +93,7 @@ proc proofPtrToRateLimitProof(
|
||||
|
||||
ok(output)
|
||||
|
||||
proc parseCredentialVec(vec: var Vec_CFr): RlnResult[IdentityCredential] =
|
||||
proc parseCredentialVec(vec: var Vec_CFr): Result[IdentityCredential, string] =
|
||||
## Vec_CFr order: idTrapdoor, idNullifier, idSecretHash, idCommitment.
|
||||
if int(ffi_vec_cfr_len(addr vec)) != 4:
|
||||
return err("Unexpected credential element count")
|
||||
@ -120,13 +120,13 @@ proc parseCredentialVec(vec: var Vec_CFr): RlnResult[IdentityCredential] =
|
||||
)
|
||||
)
|
||||
|
||||
proc membershipKeyGen*(): RlnResult[IdentityCredential] =
|
||||
proc membershipKeyGen*(): Result[IdentityCredential, string] =
|
||||
var vec = ffi_extended_key_gen()
|
||||
defer:
|
||||
ffi_vec_cfr_free(vec)
|
||||
parseCredentialVec(vec)
|
||||
|
||||
proc createRLNInstanceLocal(): RlnInstanceResult =
|
||||
proc createRLNInstanceLocal(): Result[ptr RlnRaw, string] =
|
||||
## Creates a stateless RLN instance (no local Merkle tree).
|
||||
let res = ffi_rln_new()
|
||||
if res.ok.isNil():
|
||||
@ -135,18 +135,18 @@ proc createRLNInstanceLocal(): RlnInstanceResult =
|
||||
return err(msg)
|
||||
ok(res.ok)
|
||||
|
||||
proc createRLNInstance*(): RlnInstanceResult =
|
||||
proc createRLNInstance*(): Result[ptr RlnRaw, string] =
|
||||
## Wraps createRLNInstanceLocal with metrics timing.
|
||||
var res: RlnInstanceResult
|
||||
var res: Result[ptr RlnRaw, string]
|
||||
waku_rln_instance_creation_duration_seconds.nanosecondTime:
|
||||
res = createRLNInstanceLocal()
|
||||
return res
|
||||
|
||||
proc poseidon*(left, right: seq[byte]): RlnResult[array[32, byte]] =
|
||||
proc poseidon*(left, right: seq[byte]): Result[array[32, byte], string] =
|
||||
## Poseidon hash of exactly 2 inputs; zerokit v2 FFI only exposes the pair variant.
|
||||
poseidonPairLe(left, right)
|
||||
|
||||
proc toLeaf*(rateCommitment: RateCommitment): RlnResult[seq[byte]] =
|
||||
proc toLeaf*(rateCommitment: RateCommitment): Result[seq[byte], string] =
|
||||
let idCommitment = rateCommitment.idCommitment
|
||||
var userMessageLimit: array[32, byte]
|
||||
try:
|
||||
@ -164,7 +164,7 @@ proc toLeaf*(rateCommitment: RateCommitment): RlnResult[seq[byte]] =
|
||||
retLeaf[i] = leaf[i]
|
||||
return ok(retLeaf)
|
||||
|
||||
proc toLeaves*(rateCommitments: seq[RateCommitment]): RlnResult[seq[seq[byte]]] =
|
||||
proc toLeaves*(rateCommitments: seq[RateCommitment]): Result[seq[seq[byte]], string] =
|
||||
var leaves = newSeq[seq[byte]]()
|
||||
for rateCommitment in rateCommitments:
|
||||
let leaf = toLeaf(rateCommitment).valueOr:
|
||||
@ -174,7 +174,7 @@ proc toLeaves*(rateCommitments: seq[RateCommitment]): RlnResult[seq[seq[byte]]]
|
||||
|
||||
proc generateExternalNullifier*(
|
||||
epoch: Epoch, rlnIdentifier: RlnIdentifier
|
||||
): RlnResult[ExternalNullifier] =
|
||||
): Result[ExternalNullifier, string] =
|
||||
## externalNullifier = Poseidon(H(epoch), H(rlnIdentifier)); H = ffi_hash_to_field_le.
|
||||
let epochFr = hashToFieldLe(@epoch).valueOr:
|
||||
return err("Failed to hash epoch to field: " & error)
|
||||
@ -194,7 +194,7 @@ proc generateExternalNullifier*(
|
||||
"Failed to serialize external nullifier: " & e
|
||||
)
|
||||
|
||||
proc extractMetadata*(proof: RateLimitProof): RlnResult[ProofMetadata] =
|
||||
proc extractMetadata*(proof: RateLimitProof): Result[ProofMetadata, string] =
|
||||
let externalNullifier = generateExternalNullifier(proof.epoch, proof.rlnIdentifier).valueOr:
|
||||
return err("Failed to compute external nullifier: " & error)
|
||||
return ok(
|
||||
@ -206,7 +206,9 @@ proc extractMetadata*(proof: RateLimitProof): RlnResult[ProofMetadata] =
|
||||
)
|
||||
)
|
||||
|
||||
proc buildPathElementsVec(pathElements: seq[byte], depth: int): RlnResult[Vec_CFr] =
|
||||
proc buildPathElementsVec(
|
||||
pathElements: seq[byte], depth: int
|
||||
): Result[Vec_CFr, string] =
|
||||
## Caller MUST ffi_vec_cfr_free the returned Vec_CFr.
|
||||
var vec = ffi_vec_cfr_new(csize_t(depth))
|
||||
for i in 0 ..< depth:
|
||||
@ -222,7 +224,9 @@ proc buildPathElementsVec(pathElements: seq[byte], depth: int): RlnResult[Vec_CF
|
||||
ffi_cfr_free(element)
|
||||
ok(vec)
|
||||
|
||||
proc buildWitnessInput(witness: RLNWitnessInput): RlnResult[ptr FFI_RLNWitnessInput] =
|
||||
proc buildWitnessInput(
|
||||
witness: RLNWitnessInput
|
||||
): Result[ptr FFI_RLNWitnessInput, string] =
|
||||
## ffi_rln_witness_input_new copies all inputs, so the intermediate CFrs/vecs
|
||||
## are freed here. Caller MUST ffi_rln_witness_input_free the returned handle.
|
||||
let depth = witness.identity_path_index.len
|
||||
@ -287,7 +291,7 @@ proc generateRlnProofWithWitness*(
|
||||
witness: RLNWitnessInput,
|
||||
epoch: Epoch,
|
||||
rlnIdentifier: RlnIdentifier,
|
||||
): RlnResult[RateLimitProof] =
|
||||
): Result[RateLimitProof, string] =
|
||||
let witnessHandle = buildWitnessInput(witness).valueOr:
|
||||
return
|
||||
err("failed call to buildWitnessInput in generateRlnProofWithWitness: " & error)
|
||||
@ -306,7 +310,7 @@ proc generateRlnProofWithWitness*(
|
||||
|
||||
proc buildRlnProof(
|
||||
proof: RateLimitProof, externalNullifier: ExternalNullifier
|
||||
): RlnResult[ptr FFI_RLNProof] =
|
||||
): Result[ptr FFI_RLNProof, string] =
|
||||
## ffi_rln_proof_new copies all inputs, so the intermediate CFrs are freed
|
||||
## here. Caller MUST ffi_rln_proof_free the returned handle.
|
||||
var groth16Vec = toVecUint8(proof.proof)
|
||||
@ -345,7 +349,7 @@ proc verifyRlnProof*(
|
||||
proof: RateLimitProof,
|
||||
signal: openArray[byte],
|
||||
validRoots: seq[MerkleNode],
|
||||
): RlnResult[bool] =
|
||||
): Result[bool, string] =
|
||||
if validRoots.len == 0:
|
||||
return err("verifyRlnProof requires at least one valid root (stateless mode)")
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import std/options
|
||||
import std/tempfiles
|
||||
import results
|
||||
|
||||
import
|
||||
logos_delivery/waku/rln,
|
||||
@ -8,12 +9,12 @@ import
|
||||
protocol_metrics, nonce_manager,
|
||||
]
|
||||
|
||||
proc createRLNInstanceWrapper*(): RlnInstanceResult =
|
||||
proc createRLNInstanceWrapper*(): Result[ptr RlnRaw, string] =
|
||||
return createRlnInstance()
|
||||
|
||||
proc unsafeAppendRLNProof*(
|
||||
rlnPeer: Rln, msg: var WakuMessage, epoch: Epoch, messageId: MessageId
|
||||
): RlnResult[void] =
|
||||
): Result[void, string] =
|
||||
## Test helper derived from the publish-path proof flow.
|
||||
## - Skips nonce validation to intentionally allow generating "bad" message IDs for tests.
|
||||
## - Forces a real-time on-chain Merkle root refresh via `updateRoots()` and fetches Merkle
|
||||
|
||||
@ -37,7 +37,7 @@ proc generateCredentials*(): IdentityCredential =
|
||||
|
||||
proc getRateCommitment*(
|
||||
idCredential: IdentityCredential, userMessageLimit: UserMessageLimit
|
||||
): RlnResult[RawRateCommitment] =
|
||||
): Result[RawRateCommitment, string] =
|
||||
return RateCommitment(
|
||||
idCommitment: idCredential.idCommitment, userMessageLimit: userMessageLimit
|
||||
).toLeaf()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user