mirror of https://github.com/waku-org/nwaku.git
feat(rlnv2): clean fork of rlnv2 (#2828)
* chore(rlnv2): contract interface changes (#2770) * fix: tests * fix: remove stuint[32] * chore(submodule): update zerokit submodule to v0.5.1 (#2782) * fix: remove cond comp for lightpush test * fix: ci and nonceManager
This commit is contained in:
parent
31daabab84
commit
a02832fe12
|
@ -54,12 +54,11 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
rln_version: [1, 2]
|
|
||||||
os: [ubuntu-latest, macos-13]
|
os: [ubuntu-latest, macos-13]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|
||||||
name: build-${{ matrix.os }}-rln-v${{ matrix.rln_version }}
|
name: build-${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
@ -78,7 +77,7 @@ jobs:
|
||||||
key: ${{ runner.os }}-vendor-modules-${{ steps.submodules.outputs.hash }}
|
key: ${{ runner.os }}-vendor-modules-${{ steps.submodules.outputs.hash }}
|
||||||
|
|
||||||
- name: Build binaries
|
- name: Build binaries
|
||||||
run: make RLN_V${{matrix.rln_version}}=true V=1 QUICK_AND_DIRTY_COMPILER=1 all tools
|
run: make V=1 QUICK_AND_DIRTY_COMPILER=1 all tools
|
||||||
|
|
||||||
test:
|
test:
|
||||||
needs: changes
|
needs: changes
|
||||||
|
@ -86,12 +85,11 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
rln_version: [1, 2]
|
|
||||||
os: [ubuntu-latest, macos-13]
|
os: [ubuntu-latest, macos-13]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|
||||||
name: test-${{ matrix.os }}-rln-v${{ matrix.rln_version }}
|
name: test-${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
@ -120,7 +118,7 @@ jobs:
|
||||||
export MAKEFLAGS="-j1"
|
export MAKEFLAGS="-j1"
|
||||||
export NIMFLAGS="--colors:off -d:chronicles_colors:none"
|
export NIMFLAGS="--colors:off -d:chronicles_colors:none"
|
||||||
|
|
||||||
make RLN_V${{matrix.rln_version}}=true V=1 LOG_LEVEL=DEBUG QUICK_AND_DIRTY_COMPILER=1 POSTGRES=$postgres_enabled test testwakunode2
|
make V=1 LOG_LEVEL=DEBUG QUICK_AND_DIRTY_COMPILER=1 POSTGRES=$postgres_enabled test testwakunode2
|
||||||
|
|
||||||
build-docker-image:
|
build-docker-image:
|
||||||
needs: changes
|
needs: changes
|
||||||
|
|
|
@ -22,12 +22,11 @@ jobs:
|
||||||
build-docker-image:
|
build-docker-image:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
rln_version : [1, 2]
|
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|
||||||
name: docker-build-${{ matrix.os }}-rln-v${{ matrix.rln_version }}
|
name: docker-build-${{ matrix.os }}
|
||||||
outputs:
|
outputs:
|
||||||
image: ${{ steps.build.outputs.image }}
|
image: ${{ steps.build.outputs.image }}
|
||||||
steps:
|
steps:
|
||||||
|
@ -67,12 +66,12 @@ jobs:
|
||||||
if: ${{ steps.secrets.outcome == 'success' }}
|
if: ${{ steps.secrets.outcome == 'success' }}
|
||||||
run: |
|
run: |
|
||||||
|
|
||||||
make RLN_V${{matrix.rln_version}}=true -j${NPROC} V=1 QUICK_AND_DIRTY_COMPILER=1 NIMFLAGS="-d:disableMarchNative -d:postgres" wakunode2
|
make -j${NPROC} V=1 QUICK_AND_DIRTY_COMPILER=1 NIMFLAGS="-d:disableMarchNative -d:postgres" wakunode2
|
||||||
|
|
||||||
SHORT_REF=$(git rev-parse --short HEAD)
|
SHORT_REF=$(git rev-parse --short HEAD)
|
||||||
|
|
||||||
TAG=$([ "${PR_NUMBER}" == "" ] && echo "${SHORT_REF}" || echo "${PR_NUMBER}")
|
TAG=$([ "${PR_NUMBER}" == "" ] && echo "${SHORT_REF}" || echo "${PR_NUMBER}")
|
||||||
IMAGE=quay.io/wakuorg/nwaku-pr:${TAG}-rln-v${{matrix.rln_version}}
|
IMAGE=quay.io/wakuorg/nwaku-pr:${TAG}
|
||||||
|
|
||||||
echo "image=${IMAGE}" >> $GITHUB_OUTPUT
|
echo "image=${IMAGE}" >> $GITHUB_OUTPUT
|
||||||
echo "commit_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
echo "commit_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
|
|
@ -143,7 +143,7 @@
|
||||||
path = vendor/zerokit
|
path = vendor/zerokit
|
||||||
url = https://github.com/vacp2p/zerokit.git
|
url = https://github.com/vacp2p/zerokit.git
|
||||||
ignore = dirty
|
ignore = dirty
|
||||||
branch = v0.3.4
|
branch = v0.5.1
|
||||||
[submodule "vendor/nim-regex"]
|
[submodule "vendor/nim-regex"]
|
||||||
path = vendor/nim-regex
|
path = vendor/nim-regex
|
||||||
url = https://github.com/nitely/nim-regex.git
|
url = https://github.com/nitely/nim-regex.git
|
||||||
|
|
17
Makefile
17
Makefile
|
@ -136,14 +136,10 @@ clean: | clean-libbacktrace
|
||||||
##################
|
##################
|
||||||
## RLN ##
|
## RLN ##
|
||||||
##################
|
##################
|
||||||
.PHONY: librln shouldUseRLNV2
|
.PHONY: librln
|
||||||
|
|
||||||
LIBRLN_BUILDDIR := $(CURDIR)/vendor/zerokit
|
LIBRLN_BUILDDIR := $(CURDIR)/vendor/zerokit
|
||||||
ifeq ($(RLN_V2),true)
|
LIBRLN_VERSION := v0.5.1
|
||||||
LIBRLN_VERSION := v0.4.4
|
|
||||||
else
|
|
||||||
LIBRLN_VERSION := v0.3.7
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
LIBRLN_FILE := rln.lib
|
LIBRLN_FILE := rln.lib
|
||||||
|
@ -155,12 +151,7 @@ $(LIBRLN_FILE):
|
||||||
echo -e $(BUILD_MSG) "$@" && \
|
echo -e $(BUILD_MSG) "$@" && \
|
||||||
./scripts/build_rln.sh $(LIBRLN_BUILDDIR) $(LIBRLN_VERSION) $(LIBRLN_FILE)
|
./scripts/build_rln.sh $(LIBRLN_BUILDDIR) $(LIBRLN_VERSION) $(LIBRLN_FILE)
|
||||||
|
|
||||||
shouldUseRLNV2:
|
librln: | $(LIBRLN_FILE)
|
||||||
ifeq ($(RLN_V2),true)
|
|
||||||
$(eval NIM_PARAMS += -d:rln_v2)
|
|
||||||
endif
|
|
||||||
|
|
||||||
librln: | $(LIBRLN_FILE) shouldUseRLNV2
|
|
||||||
$(eval NIM_PARAMS += --passL:$(LIBRLN_FILE) --passL:-lm)
|
$(eval NIM_PARAMS += --passL:$(LIBRLN_FILE) --passL:-lm)
|
||||||
|
|
||||||
clean-librln:
|
clean-librln:
|
||||||
|
@ -320,7 +311,7 @@ endif
|
||||||
|
|
||||||
rebuild-nat-libs: | clean-cross nat-libs
|
rebuild-nat-libs: | clean-cross nat-libs
|
||||||
|
|
||||||
libwaku-android-precheck: shouldUseRLNV2
|
libwaku-android-precheck:
|
||||||
ifndef ANDROID_NDK_HOME
|
ifndef ANDROID_NDK_HOME
|
||||||
$(error ANDROID_NDK_HOME is not set)
|
$(error ANDROID_NDK_HOME is not set)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -542,27 +542,16 @@ proc processInput(rfd: AsyncFD, rng: ref HmacDrbgContext) {.async.} =
|
||||||
|
|
||||||
echo "rln-relay preparation is in progress..."
|
echo "rln-relay preparation is in progress..."
|
||||||
|
|
||||||
when defined(rln_v2):
|
let rlnConf = WakuRlnConfig(
|
||||||
let rlnConf = WakuRlnConfig(
|
rlnRelayDynamic: conf.rlnRelayDynamic,
|
||||||
rlnRelayDynamic: conf.rlnRelayDynamic,
|
rlnRelayCredIndex: conf.rlnRelayCredIndex,
|
||||||
rlnRelayCredIndex: conf.rlnRelayCredIndex,
|
rlnRelayEthContractAddress: conf.rlnRelayEthContractAddress,
|
||||||
rlnRelayEthContractAddress: conf.rlnRelayEthContractAddress,
|
rlnRelayEthClientAddress: string(conf.rlnRelayethClientAddress),
|
||||||
rlnRelayEthClientAddress: string(conf.rlnRelayethClientAddress),
|
rlnRelayCredPath: conf.rlnRelayCredPath,
|
||||||
rlnRelayCredPath: conf.rlnRelayCredPath,
|
rlnRelayCredPassword: conf.rlnRelayCredPassword,
|
||||||
rlnRelayCredPassword: conf.rlnRelayCredPassword,
|
rlnRelayUserMessageLimit: conf.rlnRelayUserMessageLimit,
|
||||||
rlnRelayUserMessageLimit: conf.rlnRelayUserMessageLimit,
|
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
||||||
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let rlnConf = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: conf.rlnRelayDynamic,
|
|
||||||
rlnRelayCredIndex: conf.rlnRelayCredIndex,
|
|
||||||
rlnRelayEthContractAddress: conf.rlnRelayEthContractAddress,
|
|
||||||
rlnRelayEthClientAddress: string(conf.rlnRelayethClientAddress),
|
|
||||||
rlnRelayCredPath: conf.rlnRelayCredPath,
|
|
||||||
rlnRelayCredPassword: conf.rlnRelayCredPassword,
|
|
||||||
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
|
||||||
)
|
|
||||||
|
|
||||||
waitFor node.mountRlnRelay(rlnConf, spamHandler = some(spamHandler))
|
waitFor node.mountRlnRelay(rlnConf, spamHandler = some(spamHandler))
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,9 @@ host_triplet=$(rustc --version --verbose | awk '/host:/{print $2}')
|
||||||
|
|
||||||
tarball="${host_triplet}"
|
tarball="${host_triplet}"
|
||||||
|
|
||||||
# use arkzkey feature for v0.4.4
|
# use arkzkey feature for v0.5.1
|
||||||
# TODO: update this script in the future when arkzkey is default
|
# TODO: update this script in the future when arkzkey is default
|
||||||
if [[ "${rln_version}" == "v0.4.4" ]]; then
|
if [[ "${rln_version}" == "v0.5.1" ]]; then
|
||||||
tarball+="-arkzkey-rln.tar.gz"
|
tarball+="-arkzkey-rln.tar.gz"
|
||||||
else
|
else
|
||||||
tarball+="-rln.tar.gz"
|
tarball+="-rln.tar.gz"
|
||||||
|
@ -52,6 +52,6 @@ else
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# if submodule version = version in Makefile, build rln
|
# if submodule version = version in Makefile, build rln
|
||||||
cargo build --release -p rln --manifest-path "${build_dir}/rln/Cargo.toml"
|
cargo build --release -p rln --manifest-path "${build_dir}/rln/Cargo.toml" --features arkzkey
|
||||||
cp "${build_dir}/target/release/librln.a" "${output_filename}"
|
cp "${build_dir}/target/release/librln.a" "${output_filename}"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -135,21 +135,14 @@ suite "RLN Proofs as a Lightpush Service":
|
||||||
client = newTestWakuNode(clientKey, ValidIpAddress.init("0.0.0.0"), Port(0))
|
client = newTestWakuNode(clientKey, ValidIpAddress.init("0.0.0.0"), Port(0))
|
||||||
|
|
||||||
# mount rln-relay
|
# mount rln-relay
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig = WakuRlnConfig(
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"),
|
|
||||||
)
|
|
||||||
|
|
||||||
await allFutures(server.start(), client.start())
|
await allFutures(server.start(), client.start())
|
||||||
await server.start()
|
await server.start()
|
||||||
|
|
|
@ -95,51 +95,25 @@ proc sendRlnMessage*(
|
||||||
let isCompleted = await completionFuture.withTimeout(FUTURE_TIMEOUT)
|
let isCompleted = await completionFuture.withTimeout(FUTURE_TIMEOUT)
|
||||||
return isCompleted
|
return isCompleted
|
||||||
|
|
||||||
when defined(rln_v2):
|
proc sendRlnMessageWithInvalidProof*(
|
||||||
proc sendRlnMessageWithInvalidProof*(
|
client: WakuNode,
|
||||||
client: WakuNode,
|
pubsubTopic: string,
|
||||||
pubsubTopic: string,
|
contentTopic: string,
|
||||||
contentTopic: string,
|
completionFuture: Future[bool],
|
||||||
completionFuture: Future[bool],
|
payload: seq[byte] = "Hello".toBytes(),
|
||||||
payload: seq[byte] = "Hello".toBytes(),
|
): Future[bool] {.async.} =
|
||||||
): Future[bool] {.async.} =
|
let
|
||||||
let
|
extraBytes: seq[byte] = @[byte(1), 2, 3]
|
||||||
extraBytes: seq[byte] = @[byte(1), 2, 3]
|
rateLimitProofRes = client.wakuRlnRelay.groupManager.generateProof(
|
||||||
rateLimitProofRes = client.wakuRlnRelay.groupManager.generateProof(
|
concat(payload, extraBytes),
|
||||||
concat(payload, extraBytes),
|
# we add extra bytes to invalidate proof verification against original payload
|
||||||
# we add extra bytes to invalidate proof verification against original payload
|
client.wakuRlnRelay.getCurrentEpoch(),
|
||||||
client.wakuRlnRelay.getCurrentEpoch(),
|
messageId = MessageId(0),
|
||||||
messageId = MessageId(0),
|
)
|
||||||
)
|
rateLimitProof = rateLimitProofRes.get().encode().buffer
|
||||||
rateLimitProof = rateLimitProofRes.get().encode().buffer
|
message =
|
||||||
message = WakuMessage(
|
WakuMessage(payload: @payload, contentTopic: contentTopic, proof: rateLimitProof)
|
||||||
payload: @payload, contentTopic: contentTopic, proof: rateLimitProof
|
|
||||||
)
|
|
||||||
|
|
||||||
discard await client.publish(some(pubsubTopic), message)
|
discard await client.publish(some(pubsubTopic), message)
|
||||||
let isCompleted = await completionFuture.withTimeout(FUTURE_TIMEOUT)
|
let isCompleted = await completionFuture.withTimeout(FUTURE_TIMEOUT)
|
||||||
return isCompleted
|
return isCompleted
|
||||||
|
|
||||||
else:
|
|
||||||
proc sendRlnMessageWithInvalidProof*(
|
|
||||||
client: WakuNode,
|
|
||||||
pubsubTopic: string,
|
|
||||||
contentTopic: string,
|
|
||||||
completionFuture: Future[bool],
|
|
||||||
payload: seq[byte] = "Hello".toBytes(),
|
|
||||||
): Future[bool] {.async.} =
|
|
||||||
let
|
|
||||||
extraBytes: seq[byte] = @[byte(1), 2, 3]
|
|
||||||
rateLimitProofRes = client.wakuRlnRelay.groupManager.generateProof(
|
|
||||||
concat(payload, extraBytes),
|
|
||||||
# we add extra bytes to invalidate proof verification against original payload
|
|
||||||
client.wakuRlnRelay.getCurrentEpoch(),
|
|
||||||
)
|
|
||||||
rateLimitProof = rateLimitProofRes.get().encode().buffer
|
|
||||||
message = WakuMessage(
|
|
||||||
payload: @payload, contentTopic: contentTopic, proof: rateLimitProof
|
|
||||||
)
|
|
||||||
|
|
||||||
discard await client.publish(some(pubsubTopic), message)
|
|
||||||
let isCompleted = await completionFuture.withTimeout(FUTURE_TIMEOUT)
|
|
||||||
return isCompleted
|
|
||||||
|
|
|
@ -14,14 +14,11 @@ proc unsafeAppendRLNProof*(
|
||||||
let input = msg.toRLNSignal()
|
let input = msg.toRLNSignal()
|
||||||
let epoch = rlnPeer.calcEpoch(senderEpochTime)
|
let epoch = rlnPeer.calcEpoch(senderEpochTime)
|
||||||
|
|
||||||
when defined(rln_v2):
|
# we do not fetch a nonce from the nonce manager,
|
||||||
# we do not fetch a nonce from the nonce manager,
|
# instead we use 0 as the nonce
|
||||||
# instead we use 0 as the nonce
|
let proof = rlnPeer.groupManager.generateProof(input, epoch, 0).valueOr:
|
||||||
let proof = rlnPeer.groupManager.generateProof(input, epoch, 0).valueOr:
|
return err("could not generate rln-v2 proof: " & $error)
|
||||||
return err("could not generate rln-v2 proof: " & $error)
|
|
||||||
else:
|
|
||||||
let proof = rlnPeer.groupManager.generateProof(input, epoch).valueOr:
|
|
||||||
return err("could not generate rln proof: " & $error)
|
|
||||||
|
|
||||||
msg.proof = proof.encode().buffer
|
msg.proof = proof.encode().buffer
|
||||||
return ok()
|
return ok()
|
||||||
|
|
|
@ -5,7 +5,5 @@ import
|
||||||
./test_rln_group_manager_static,
|
./test_rln_group_manager_static,
|
||||||
./test_waku_rln_relay,
|
./test_waku_rln_relay,
|
||||||
./test_wakunode_rln_relay,
|
./test_wakunode_rln_relay,
|
||||||
./test_rln_nonce_manager
|
./test_rln_nonce_manager,
|
||||||
|
./test_rln_serde
|
||||||
when defined(rln_v2):
|
|
||||||
import ./rln_v2/test_rln_relay_v2_serde
|
|
||||||
|
|
|
@ -30,13 +30,12 @@ proc generateCredentials(rlnInstance: ptr RLN): IdentityCredential =
|
||||||
let credRes = membershipKeyGen(rlnInstance)
|
let credRes = membershipKeyGen(rlnInstance)
|
||||||
return credRes.get()
|
return credRes.get()
|
||||||
|
|
||||||
when defined(rln_v2):
|
proc getRateCommitment(
|
||||||
proc getRateCommitment(
|
idCredential: IdentityCredential, userMessageLimit: UserMessageLimit
|
||||||
idCredential: IdentityCredential, userMessageLimit: UserMessageLimit
|
): RlnRelayResult[RawRateCommitment] =
|
||||||
): RateCommitment =
|
return RateCommitment(
|
||||||
return RateCommitment(
|
idCommitment: idCredential.idCommitment, userMessageLimit: userMessageLimit
|
||||||
idCommitment: idCredential.idCommitment, userMessageLimit: userMessageLimit
|
).toLeaf()
|
||||||
)
|
|
||||||
|
|
||||||
proc generateCredentials(rlnInstance: ptr RLN, n: int): seq[IdentityCredential] =
|
proc generateCredentials(rlnInstance: ptr RLN, n: int): seq[IdentityCredential] =
|
||||||
var credentials: seq[IdentityCredential]
|
var credentials: seq[IdentityCredential]
|
||||||
|
@ -61,48 +60,38 @@ proc uploadRLNContract*(ethClientAddress: string): Future[Address] {.async.} =
|
||||||
let balance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
|
let balance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
|
||||||
debug "Initial account balance: ", balance
|
debug "Initial account balance: ", balance
|
||||||
|
|
||||||
when defined(rln_v2):
|
# deploy poseidon hasher bytecode
|
||||||
# deploy registry contract with its constructor inputs
|
let poseidonT3Receipt = await web3.deployContract(PoseidonT3)
|
||||||
let receipt = await web3.deployContract(RegistryContractCode)
|
let poseidonT3Address = poseidonT3Receipt.contractAddress.get()
|
||||||
else:
|
let poseidonAddressStripped = strip0xPrefix($poseidonT3Address)
|
||||||
# deploy the poseidon hash contract and gets its address
|
|
||||||
let
|
|
||||||
hasherReceipt = await web3.deployContract(PoseidonHasherCode)
|
|
||||||
hasherAddress = hasherReceipt.contractAddress.get
|
|
||||||
debug "hasher address: ", hasherAddress
|
|
||||||
|
|
||||||
# encode registry contract inputs to 32 bytes zero-padded
|
# deploy lazy imt bytecode
|
||||||
let
|
let lazyImtReceipt = await web3.deployContract(LazyIMT.replace("__$PoseidonT3$__", poseidonAddressStripped))
|
||||||
hasherAddressEncoded = encode(hasherAddress).data
|
let lazyImtAddress = lazyImtReceipt.contractAddress.get()
|
||||||
# this is the contract constructor input
|
let lazyImtAddressStripped = strip0xPrefix($lazyImtAddress)
|
||||||
contractInput = hasherAddressEncoded
|
|
||||||
|
|
||||||
debug "encoded hasher address: ", hasherAddressEncoded
|
# deploy waku rlnv2 contract
|
||||||
debug "encoded contract input:", contractInput
|
let wakuRlnContractReceipt = await web3.deployContract(WakuRlnV2Contract.replace("__$PoseidonT3$__", poseidonAddressStripped).replace("__$LazyIMT$__", lazyImtAddressStripped))
|
||||||
|
let wakuRlnContractAddress = wakuRlnContractReceipt.contractAddress.get()
|
||||||
|
let wakuRlnAddressStripped = strip0xPrefix($wakuRlnContractAddress)
|
||||||
|
|
||||||
# deploy registry contract with its constructor inputs
|
debug "Address of the deployed rlnv2 contract: ", wakuRlnContractAddress
|
||||||
let receipt =
|
|
||||||
await web3.deployContract(RegistryContractCode, contractInput = contractInput)
|
|
||||||
|
|
||||||
let contractAddress = receipt.contractAddress.get()
|
# need to send concat: impl & init_bytes
|
||||||
|
let contractInput = encode(wakuRlnContractAddress).data & Erc1967ProxyContractInput
|
||||||
|
debug "contractInput", contractInput
|
||||||
|
let proxyReceipt = await web3.deployContract(Erc1967Proxy, contractInput = contractInput)
|
||||||
|
|
||||||
|
debug "proxy receipt", proxyReceipt
|
||||||
|
let proxyAddress = proxyReceipt.contractAddress.get()
|
||||||
|
|
||||||
debug "Address of the deployed registry contract: ", contractAddress
|
|
||||||
|
|
||||||
let registryContract = web3.contractSender(WakuRlnRegistry, contractAddress)
|
|
||||||
when defined(rln_v2):
|
|
||||||
let initReceipt = await registryContract.initialize().send()
|
|
||||||
let newStorageReceipt = await registryContract.newStorage(20.u256).send()
|
|
||||||
else:
|
|
||||||
let newStorageReceipt = await registryContract.newStorage().send()
|
|
||||||
|
|
||||||
debug "Receipt of the newStorage transaction: ", newStorageReceipt
|
|
||||||
let newBalance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
|
let newBalance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
|
||||||
debug "Account balance after the contract deployment: ", newBalance
|
debug "Account balance after the contract deployment: ", newBalance
|
||||||
|
|
||||||
await web3.close()
|
await web3.close()
|
||||||
debug "disconnected from ", ethClientAddress
|
debug "disconnected from ", ethClientAddress
|
||||||
|
|
||||||
return contractAddress
|
return proxyAddress
|
||||||
|
|
||||||
proc createEthAccount(): Future[(keys.PrivateKey, Address)] {.async.} =
|
proc createEthAccount(): Future[(keys.PrivateKey, Address)] {.async.} =
|
||||||
let web3 = await newWeb3(EthClient)
|
let web3 = await newWeb3(EthClient)
|
||||||
|
@ -187,7 +176,7 @@ proc stopAnvil(runAnvil: Process) {.used.} =
|
||||||
proc setup(): Future[OnchainGroupManager] {.async.} =
|
proc setup(): Future[OnchainGroupManager] {.async.} =
|
||||||
let rlnInstanceRes =
|
let rlnInstanceRes =
|
||||||
createRlnInstance(tree_path = genTempPath("rln_tree", "group_manager_onchain"))
|
createRlnInstance(tree_path = genTempPath("rln_tree", "group_manager_onchain"))
|
||||||
require:
|
check:
|
||||||
rlnInstanceRes.isOk()
|
rlnInstanceRes.isOk()
|
||||||
|
|
||||||
let rlnInstance = rlnInstanceRes.get()
|
let rlnInstance = rlnInstanceRes.get()
|
||||||
|
@ -223,8 +212,7 @@ suite "Onchain group manager":
|
||||||
|
|
||||||
check:
|
check:
|
||||||
manager.ethRpc.isSome()
|
manager.ethRpc.isSome()
|
||||||
manager.rlnContract.isSome()
|
manager.wakuRlnContract.isSome()
|
||||||
manager.membershipFee.isSome()
|
|
||||||
manager.initialized
|
manager.initialized
|
||||||
manager.rlnContractDeployedBlockNumber > 0
|
manager.rlnContractDeployedBlockNumber > 0
|
||||||
|
|
||||||
|
@ -287,6 +275,8 @@ suite "Onchain group manager":
|
||||||
asyncTest "startGroupSync: should sync to the state of the group":
|
asyncTest "startGroupSync: should sync to the state of the group":
|
||||||
let manager = await setup()
|
let manager = await setup()
|
||||||
let credentials = generateCredentials(manager.rlnInstance)
|
let credentials = generateCredentials(manager.rlnInstance)
|
||||||
|
let rateCommitment = getRateCommitment(credentials, UserMessageLimit(1)).valueOr:
|
||||||
|
raiseAssert $error
|
||||||
(await manager.init()).isOkOr:
|
(await manager.init()).isOkOr:
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
|
|
||||||
|
@ -297,28 +287,17 @@ suite "Onchain group manager":
|
||||||
|
|
||||||
proc generateCallback(fut: Future[void]): OnRegisterCallback =
|
proc generateCallback(fut: Future[void]): OnRegisterCallback =
|
||||||
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
||||||
require:
|
check:
|
||||||
registrations.len == 1
|
registrations.len == 1
|
||||||
registrations[0].index == 0
|
registrations[0].index == 0
|
||||||
when defined(rln_v2):
|
registrations[0].rateCommitment == rateCommitment
|
||||||
require:
|
|
||||||
registrations[0].rateCommitment ==
|
|
||||||
getRateCommitment(credentials, UserMessageLimit(1))
|
|
||||||
else:
|
|
||||||
require:
|
|
||||||
registrations[0].idCommitment == credentials.idCommitment
|
|
||||||
require:
|
|
||||||
registrations[0].index == 0
|
|
||||||
fut.complete()
|
fut.complete()
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
try:
|
try:
|
||||||
manager.onRegister(generateCallback(fut))
|
manager.onRegister(generateCallback(fut))
|
||||||
when defined(rln_v2):
|
await manager.register(credentials, UserMessageLimit(1))
|
||||||
await manager.register(credentials, UserMessageLimit(1))
|
|
||||||
else:
|
|
||||||
await manager.register(credentials)
|
|
||||||
(await manager.startGroupSync()).isOkOr:
|
(await manager.startGroupSync()).isOkOr:
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
|
@ -355,19 +334,12 @@ suite "Onchain group manager":
|
||||||
): OnRegisterCallback =
|
): OnRegisterCallback =
|
||||||
var futureIndex = 0
|
var futureIndex = 0
|
||||||
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
||||||
when defined(rln_v2):
|
let rateCommitment = getRateCommitment(credentials[futureIndex], UserMessageLimit(1))
|
||||||
if registrations.len == 1 and
|
if registrations.len == 1 and
|
||||||
registrations[0].rateCommitment ==
|
registrations[0].rateCommitment == rateCommitment.get() and
|
||||||
getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) and
|
registrations[0].index == MembershipIndex(futureIndex):
|
||||||
registrations[0].index == MembershipIndex(futureIndex):
|
futs[futureIndex].complete()
|
||||||
futs[futureIndex].complete()
|
futureIndex += 1
|
||||||
futureIndex += 1
|
|
||||||
else:
|
|
||||||
if registrations.len == 1 and
|
|
||||||
registrations[0].idCommitment == credentials[futureIndex].idCommitment and
|
|
||||||
registrations[0].index == MembershipIndex(futureIndex):
|
|
||||||
futs[futureIndex].complete()
|
|
||||||
futureIndex += 1
|
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
|
@ -377,10 +349,7 @@ suite "Onchain group manager":
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
|
|
||||||
for i in 0 ..< credentials.len():
|
for i in 0 ..< credentials.len():
|
||||||
when defined(rln_v2):
|
await manager.register(credentials[i], UserMessageLimit(1))
|
||||||
await manager.register(credentials[i], UserMessageLimit(1))
|
|
||||||
else:
|
|
||||||
await manager.register(credentials[i])
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
@ -399,14 +368,11 @@ suite "Onchain group manager":
|
||||||
let dummyCommitment = default(IDCommitment)
|
let dummyCommitment = default(IDCommitment)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
when defined(rln_v2):
|
await manager.register(
|
||||||
await manager.register(
|
RateCommitment(
|
||||||
RateCommitment(
|
idCommitment: dummyCommitment, userMessageLimit: UserMessageLimit(1)
|
||||||
idCommitment: dummyCommitment, userMessageLimit: UserMessageLimit(1)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
)
|
||||||
await manager.register(dummyCommitment)
|
|
||||||
except CatchableError:
|
except CatchableError:
|
||||||
assert true
|
assert true
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -426,14 +392,11 @@ suite "Onchain group manager":
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
|
|
||||||
try:
|
try:
|
||||||
when defined(rln_v2):
|
await manager.register(
|
||||||
await manager.register(
|
RateCommitment(
|
||||||
RateCommitment(
|
idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1)
|
||||||
idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
)
|
||||||
await manager.register(idCommitment)
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false,
|
assert false,
|
||||||
"exception raised when calling register: " & getCurrentExceptionMsg()
|
"exception raised when calling register: " & getCurrentExceptionMsg()
|
||||||
|
@ -448,23 +411,16 @@ suite "Onchain group manager":
|
||||||
asyncTest "register: callback is called":
|
asyncTest "register: callback is called":
|
||||||
let manager = await setup()
|
let manager = await setup()
|
||||||
|
|
||||||
let idCommitment = generateCredentials(manager.rlnInstance).idCommitment
|
let idCredentials = generateCredentials(manager.rlnInstance)
|
||||||
|
let idCommitment = idCredentials.idCommitment
|
||||||
|
|
||||||
let fut = newFuture[void]()
|
let fut = newFuture[void]()
|
||||||
|
|
||||||
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
||||||
require:
|
let rateCommitment = getRateCommitment(idCredentials, UserMessageLimit(1))
|
||||||
|
check:
|
||||||
registrations.len == 1
|
registrations.len == 1
|
||||||
when defined(rln_v2):
|
registrations[0].rateCommitment == rateCommitment.get()
|
||||||
require:
|
|
||||||
registrations[0].rateCommitment ==
|
|
||||||
RateCommitment(
|
|
||||||
idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
require:
|
|
||||||
registrations[0].idCommitment == idCommitment
|
|
||||||
require:
|
|
||||||
registrations[0].index == 0
|
registrations[0].index == 0
|
||||||
fut.complete()
|
fut.complete()
|
||||||
|
|
||||||
|
@ -474,18 +430,15 @@ suite "Onchain group manager":
|
||||||
try:
|
try:
|
||||||
(await manager.startGroupSync()).isOkOr:
|
(await manager.startGroupSync()).isOkOr:
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
when defined(rln_v2):
|
await manager.register(
|
||||||
await manager.register(
|
RateCommitment(
|
||||||
RateCommitment(
|
idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1)
|
||||||
idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
)
|
||||||
await manager.register(idCommitment)
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||||
|
|
||||||
check await fut.withTimeout(5.seconds)
|
await fut
|
||||||
|
|
||||||
await manager.stop()
|
await manager.stop()
|
||||||
|
|
||||||
|
@ -511,29 +464,20 @@ suite "Onchain group manager":
|
||||||
let fut = newFuture[void]()
|
let fut = newFuture[void]()
|
||||||
|
|
||||||
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
||||||
when defined(rln_v2):
|
if registrations.len == 1 and
|
||||||
if registrations.len == 1 and
|
registrations[0].rateCommitment ==
|
||||||
registrations[0].rateCommitment ==
|
getRateCommitment(credentials, UserMessageLimit(1)).get() and
|
||||||
getRateCommitment(credentials, UserMessageLimit(1)) and
|
registrations[0].index == 0:
|
||||||
registrations[0].index == 0:
|
manager.idCredentials = some(credentials)
|
||||||
manager.idCredentials = some(credentials)
|
fut.complete()
|
||||||
fut.complete()
|
|
||||||
else:
|
|
||||||
if registrations.len == 1 and
|
|
||||||
registrations[0].idCommitment == credentials.idCommitment and
|
|
||||||
registrations[0].index == 0:
|
|
||||||
manager.idCredentials = some(credentials)
|
|
||||||
fut.complete()
|
|
||||||
|
|
||||||
manager.onRegister(callback)
|
manager.onRegister(callback)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
(await manager.startGroupSync()).isOkOr:
|
(await manager.startGroupSync()).isOkOr:
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
when defined(rln_v2):
|
await manager.register(credentials, UserMessageLimit(1))
|
||||||
await manager.register(credentials, UserMessageLimit(1))
|
|
||||||
else:
|
|
||||||
await manager.register(credentials)
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
@ -546,14 +490,11 @@ suite "Onchain group manager":
|
||||||
debug "epoch in bytes", epochHex = epoch.inHex()
|
debug "epoch in bytes", epochHex = epoch.inHex()
|
||||||
|
|
||||||
# generate proof
|
# generate proof
|
||||||
when defined(rln_v2):
|
let validProofRes = manager.generateProof(
|
||||||
let validProofRes = manager.generateProof(
|
data = messageBytes, epoch = epoch, messageId = MessageId(1)
|
||||||
data = messageBytes, epoch = epoch, messageId = MessageId(1)
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let validProofRes = manager.generateProof(data = messageBytes, epoch = epoch)
|
|
||||||
|
|
||||||
require:
|
check:
|
||||||
validProofRes.isOk()
|
validProofRes.isOk()
|
||||||
let validProof = validProofRes.get()
|
let validProof = validProofRes.get()
|
||||||
|
|
||||||
|
@ -576,8 +517,7 @@ suite "Onchain group manager":
|
||||||
## Assume the registration occured out of band
|
## Assume the registration occured out of band
|
||||||
manager.idCredentials = some(credentials)
|
manager.idCredentials = some(credentials)
|
||||||
manager.membershipIndex = some(MembershipIndex(0))
|
manager.membershipIndex = some(MembershipIndex(0))
|
||||||
when defined(rln_v2):
|
manager.userMessageLimit = some(UserMessageLimit(1))
|
||||||
manager.userMessageLimit = some(UserMessageLimit(1))
|
|
||||||
|
|
||||||
let messageBytes = "Hello".toBytes()
|
let messageBytes = "Hello".toBytes()
|
||||||
|
|
||||||
|
@ -586,15 +526,10 @@ suite "Onchain group manager":
|
||||||
debug "epoch in bytes", epochHex = epoch.inHex()
|
debug "epoch in bytes", epochHex = epoch.inHex()
|
||||||
|
|
||||||
# generate proof
|
# generate proof
|
||||||
when defined(rln_v2):
|
let validProof = manager.generateProof(
|
||||||
let validProofRes = manager.generateProof(
|
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
||||||
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
).valueOr:
|
||||||
)
|
raiseAssert $error
|
||||||
else:
|
|
||||||
let validProofRes = manager.generateProof(data = messageBytes, epoch = epoch)
|
|
||||||
require:
|
|
||||||
validProofRes.isOk()
|
|
||||||
let validProof = validProofRes.get()
|
|
||||||
|
|
||||||
# validate the root (should be false)
|
# validate the root (should be false)
|
||||||
let validated = manager.validateRoot(validProof.merkleRoot)
|
let validated = manager.validateRoot(validProof.merkleRoot)
|
||||||
|
@ -612,29 +547,20 @@ suite "Onchain group manager":
|
||||||
let fut = newFuture[void]()
|
let fut = newFuture[void]()
|
||||||
|
|
||||||
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
||||||
when defined(rln_v2):
|
if registrations.len == 1 and
|
||||||
if registrations.len == 1 and
|
registrations[0].rateCommitment ==
|
||||||
registrations[0].rateCommitment ==
|
getRateCommitment(credentials, UserMessageLimit(1)).get() and
|
||||||
getRateCommitment(credentials, UserMessageLimit(1)) and
|
registrations[0].index == 0:
|
||||||
registrations[0].index == 0:
|
manager.idCredentials = some(credentials)
|
||||||
manager.idCredentials = some(credentials)
|
fut.complete()
|
||||||
fut.complete()
|
|
||||||
else:
|
|
||||||
if registrations.len == 1 and
|
|
||||||
registrations[0].idCommitment == credentials.idCommitment and
|
|
||||||
registrations[0].index == 0:
|
|
||||||
manager.idCredentials = some(credentials)
|
|
||||||
fut.complete()
|
|
||||||
|
|
||||||
manager.onRegister(callback)
|
manager.onRegister(callback)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
(await manager.startGroupSync()).isOkOr:
|
(await manager.startGroupSync()).isOkOr:
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
when defined(rln_v2):
|
await manager.register(credentials, UserMessageLimit(1))
|
||||||
await manager.register(credentials, UserMessageLimit(1))
|
|
||||||
else:
|
|
||||||
await manager.register(credentials)
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||||
await fut
|
await fut
|
||||||
|
@ -646,23 +572,16 @@ suite "Onchain group manager":
|
||||||
debug "epoch in bytes", epochHex = epoch.inHex()
|
debug "epoch in bytes", epochHex = epoch.inHex()
|
||||||
|
|
||||||
# generate proof
|
# generate proof
|
||||||
when defined(rln_v2):
|
let validProof = manager.generateProof(
|
||||||
let validProofRes = manager.generateProof(
|
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
||||||
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
).valueOr:
|
||||||
)
|
raiseAssert $error
|
||||||
else:
|
|
||||||
let validProofRes = manager.generateProof(data = messageBytes, epoch = epoch)
|
|
||||||
require:
|
|
||||||
validProofRes.isOk()
|
|
||||||
let validProof = validProofRes.get()
|
|
||||||
|
|
||||||
# verify the proof (should be true)
|
# verify the proof (should be true)
|
||||||
let verifiedRes = manager.verifyProof(messageBytes, validProof)
|
let verified = manager.verifyProof(messageBytes, validProof).valueOr:
|
||||||
require:
|
raiseAssert $error
|
||||||
verifiedRes.isOk()
|
|
||||||
|
|
||||||
check:
|
check: verified
|
||||||
verifiedRes.get()
|
|
||||||
await manager.stop()
|
await manager.stop()
|
||||||
|
|
||||||
asyncTest "verifyProof: should reject invalid proof":
|
asyncTest "verifyProof: should reject invalid proof":
|
||||||
|
@ -675,10 +594,8 @@ suite "Onchain group manager":
|
||||||
let idCredential = generateCredentials(manager.rlnInstance)
|
let idCredential = generateCredentials(manager.rlnInstance)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
when defined(rln_v2):
|
await manager.register(RateCommitment(idCommitment: idCredential.idCommitment,
|
||||||
await manager.register(getRateCommitment(idCredential, UserMessageLimit(1)))
|
userMessageLimit: UserMessageLimit(1)))
|
||||||
else:
|
|
||||||
await manager.register(idCredential.idCommitment)
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false,
|
assert false,
|
||||||
"exception raised when calling startGroupSync: " & getCurrentExceptionMsg()
|
"exception raised when calling startGroupSync: " & getCurrentExceptionMsg()
|
||||||
|
@ -688,8 +605,7 @@ suite "Onchain group manager":
|
||||||
## Assume the registration occured out of band
|
## Assume the registration occured out of band
|
||||||
manager.idCredentials = some(idCredential2)
|
manager.idCredentials = some(idCredential2)
|
||||||
manager.membershipIndex = some(MembershipIndex(0))
|
manager.membershipIndex = some(MembershipIndex(0))
|
||||||
when defined(rln_v2):
|
manager.userMessageLimit = some(UserMessageLimit(1))
|
||||||
manager.userMessageLimit = some(UserMessageLimit(1))
|
|
||||||
|
|
||||||
let messageBytes = "Hello".toBytes()
|
let messageBytes = "Hello".toBytes()
|
||||||
|
|
||||||
|
@ -698,14 +614,11 @@ suite "Onchain group manager":
|
||||||
debug "epoch in bytes", epochHex = epoch.inHex()
|
debug "epoch in bytes", epochHex = epoch.inHex()
|
||||||
|
|
||||||
# generate proof
|
# generate proof
|
||||||
when defined(rln_v2):
|
let invalidProofRes = manager.generateProof(
|
||||||
let invalidProofRes = manager.generateProof(
|
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
||||||
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let invalidProofRes = manager.generateProof(data = messageBytes, epoch = epoch)
|
|
||||||
|
|
||||||
require:
|
check:
|
||||||
invalidProofRes.isOk()
|
invalidProofRes.isOk()
|
||||||
let invalidProof = invalidProofRes.get()
|
let invalidProof = invalidProofRes.get()
|
||||||
|
|
||||||
|
@ -734,19 +647,12 @@ suite "Onchain group manager":
|
||||||
): OnRegisterCallback =
|
): OnRegisterCallback =
|
||||||
var futureIndex = 0
|
var futureIndex = 0
|
||||||
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
|
||||||
when defined(rln_v2):
|
if registrations.len == 1 and
|
||||||
if registrations.len == 1 and
|
registrations[0].rateCommitment ==
|
||||||
registrations[0].rateCommitment ==
|
getRateCommitment(credentials[futureIndex], UserMessageLimit(1)).get() and
|
||||||
getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) and
|
registrations[0].index == MembershipIndex(futureIndex):
|
||||||
registrations[0].index == MembershipIndex(futureIndex):
|
futs[futureIndex].complete()
|
||||||
futs[futureIndex].complete()
|
futureIndex += 1
|
||||||
futureIndex += 1
|
|
||||||
else:
|
|
||||||
if registrations.len == 1 and
|
|
||||||
registrations[0].idCommitment == credentials[futureIndex].idCommitment and
|
|
||||||
registrations[0].index == MembershipIndex(futureIndex):
|
|
||||||
futs[futureIndex].complete()
|
|
||||||
futureIndex += 1
|
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
|
@ -756,17 +662,14 @@ suite "Onchain group manager":
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
|
|
||||||
for i in 0 ..< credentials.len():
|
for i in 0 ..< credentials.len():
|
||||||
when defined(rln_v2):
|
await manager.register(credentials[i], UserMessageLimit(1))
|
||||||
await manager.register(credentials[i], UserMessageLimit(1))
|
|
||||||
else:
|
|
||||||
await manager.register(credentials[i])
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||||
|
|
||||||
await allFutures(futures)
|
await allFutures(futures)
|
||||||
|
|
||||||
# At this point, we should have a full root queue, 5 roots, and partial buffer of 1 root
|
# At this point, we should have a full root queue, 5 roots, and partial buffer of 1 root
|
||||||
require:
|
check:
|
||||||
manager.validRoots.len() == credentialCount - 1
|
manager.validRoots.len() == credentialCount - 1
|
||||||
manager.validRootBuffer.len() == 1
|
manager.validRootBuffer.len() == 1
|
||||||
|
|
||||||
|
|
|
@ -94,14 +94,11 @@ suite "Static group manager":
|
||||||
let dummyCommitment = default(IDCommitment)
|
let dummyCommitment = default(IDCommitment)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
when defined(rln_v2):
|
await manager.register(
|
||||||
await manager.register(
|
RateCommitment(
|
||||||
RateCommitment(
|
idCommitment: dummyCommitment, userMessageLimit: DefaultUserMessageLimit
|
||||||
idCommitment: dummyCommitment, userMessageLimit: DefaultUserMessageLimit
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
)
|
||||||
await manager.register(dummyCommitment)
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
assert true
|
assert true
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
|
@ -117,14 +114,11 @@ suite "Static group manager":
|
||||||
let merkleRootBefore = manager.rlnInstance.getMerkleRoot().valueOr:
|
let merkleRootBefore = manager.rlnInstance.getMerkleRoot().valueOr:
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
try:
|
try:
|
||||||
when defined(rln_v2):
|
await manager.register(
|
||||||
await manager.register(
|
RateCommitment(
|
||||||
RateCommitment(
|
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
|
||||||
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
)
|
||||||
await manager.register(idCommitment)
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||||
let merkleRootAfter = manager.rlnInstance.getMerkleRoot().valueOr:
|
let merkleRootAfter = manager.rlnInstance.getMerkleRoot().valueOr:
|
||||||
|
@ -143,15 +137,10 @@ suite "Static group manager":
|
||||||
require:
|
require:
|
||||||
registrations.len == 1
|
registrations.len == 1
|
||||||
registrations[0].index == 10
|
registrations[0].index == 10
|
||||||
when defined(rln_v2):
|
registrations[0].rateCommitment ==
|
||||||
require:
|
RateCommitment(
|
||||||
registrations[0].rateCommitment ==
|
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
|
||||||
RateCommitment(
|
).toLeaf().get()
|
||||||
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
require:
|
|
||||||
registrations[0].idCommitment == idCommitment
|
|
||||||
callbackCalled = true
|
callbackCalled = true
|
||||||
fut.complete()
|
fut.complete()
|
||||||
|
|
||||||
|
@ -161,14 +150,11 @@ suite "Static group manager":
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
(await manager.startGroupSync()).isOkOr:
|
(await manager.startGroupSync()).isOkOr:
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
when defined(rln_v2):
|
await manager.register(
|
||||||
await manager.register(
|
RateCommitment(
|
||||||
RateCommitment(
|
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
|
||||||
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
)
|
||||||
await manager.register(idCommitment)
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
@ -215,15 +201,11 @@ suite "Static group manager":
|
||||||
require:
|
require:
|
||||||
withdrawals.len == 1
|
withdrawals.len == 1
|
||||||
withdrawals[0].index == 0
|
withdrawals[0].index == 0
|
||||||
when defined(rln_v2):
|
withdrawals[0].rateCommitment ==
|
||||||
require:
|
RateCommitment(
|
||||||
withdrawals[0].rateCommitment ==
|
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
|
||||||
RateCommitment(
|
).toLeaf().get()
|
||||||
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
require:
|
|
||||||
withdrawals[0].idCommitment == idCommitment
|
|
||||||
callbackCalled = true
|
callbackCalled = true
|
||||||
fut.complete()
|
fut.complete()
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ else:
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
import
|
import
|
||||||
../rln/waku_rln_relay_utils,
|
./rln/waku_rln_relay_utils,
|
||||||
../../../waku/waku_keystore/protocol_types,
|
../../waku/waku_keystore/protocol_types,
|
||||||
../../../waku/waku_rln_relay,
|
../../waku/waku_rln_relay,
|
||||||
../../../waku/waku_rln_relay/rln
|
../../waku/waku_rln_relay/rln
|
||||||
|
|
||||||
import testutils/unittests
|
import testutils/unittests
|
||||||
import stew/results, stint
|
import stew/results, stint
|
|
@ -525,14 +525,11 @@ suite "Waku rln relay":
|
||||||
let rln = rlnInstance.get()
|
let rln = rlnInstance.get()
|
||||||
|
|
||||||
# create a Merkle tree
|
# create a Merkle tree
|
||||||
when defined(rln_v2):
|
let rateCommitments =
|
||||||
let rateCommitments =
|
groupIDCommitments.mapIt(RateCommitment(idCommitment: it, userMessageLimit: 20))
|
||||||
groupIDCommitments.mapIt(RateCommitment(idCommitment: it, userMessageLimit: 20))
|
let leaves = rateCommitments.toLeaves().valueOr:
|
||||||
let leaves = rateCommitments.toLeaves().valueOr:
|
raiseAssert $error
|
||||||
raiseAssert $error
|
let membersAdded = rln.insertMembers(0, leaves)
|
||||||
let membersAdded = rln.insertMembers(0, leaves)
|
|
||||||
else:
|
|
||||||
let membersAdded = rln.insertMembers(0, groupIDCommitments)
|
|
||||||
|
|
||||||
assert membersAdded, "members should be added"
|
assert membersAdded, "members should be added"
|
||||||
let rawRoot = rln.getMerkleRoot().valueOr:
|
let rawRoot = rln.getMerkleRoot().valueOr:
|
||||||
|
@ -691,21 +688,14 @@ suite "Waku rln relay":
|
||||||
asyncTest "validateMessageAndUpdateLog test":
|
asyncTest "validateMessageAndUpdateLog test":
|
||||||
let index = MembershipIndex(5)
|
let index = MembershipIndex(5)
|
||||||
|
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig = WakuRlnConfig(
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(index),
|
||||||
rlnRelayCredIndex: some(index),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_2"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_2"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(index),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_2"),
|
|
||||||
)
|
|
||||||
let wakuRlnRelay = (await WakuRlnRelay.new(wakuRlnConfig)).valueOr:
|
let wakuRlnRelay = (await WakuRlnRelay.new(wakuRlnConfig)).valueOr:
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
|
|
||||||
|
@ -749,40 +739,25 @@ suite "Waku rln relay":
|
||||||
let index1 = MembershipIndex(5)
|
let index1 = MembershipIndex(5)
|
||||||
let index2 = MembershipIndex(6)
|
let index2 = MembershipIndex(6)
|
||||||
|
|
||||||
when defined(rln_v2):
|
let rlnConf1 = WakuRlnConfig(
|
||||||
let rlnConf1 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(index1),
|
||||||
rlnRelayCredIndex: some(index1),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_3"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_3"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let rlnConf1 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(index1),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_3"),
|
|
||||||
)
|
|
||||||
|
|
||||||
let wakuRlnRelay1 = (await WakuRlnRelay.new(rlnConf1)).valueOr:
|
let wakuRlnRelay1 = (await WakuRlnRelay.new(rlnConf1)).valueOr:
|
||||||
raiseAssert "failed to create waku rln relay: " & $error
|
raiseAssert "failed to create waku rln relay: " & $error
|
||||||
|
|
||||||
when defined(rln_v2):
|
let rlnConf2 = WakuRlnConfig(
|
||||||
let rlnConf2 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(index2),
|
||||||
rlnRelayCredIndex: some(index2),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_4"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_4"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let rlnConf2 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(index2),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_4"),
|
|
||||||
)
|
|
||||||
let wakuRlnRelay2 = (await WakuRlnRelay.new(rlnConf2)).valueOr:
|
let wakuRlnRelay2 = (await WakuRlnRelay.new(rlnConf2)).valueOr:
|
||||||
raiseAssert "failed to create waku rln relay: " & $error
|
raiseAssert "failed to create waku rln relay: " & $error
|
||||||
# get the current epoch time
|
# get the current epoch time
|
||||||
|
|
|
@ -40,21 +40,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
await node1.mountRelay(@[DefaultPubsubTopic])
|
await node1.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig1 = WakuRlnConfig(
|
||||||
let wakuRlnConfig1 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig1 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"),
|
|
||||||
)
|
|
||||||
await node1.mountRlnRelay(wakuRlnConfig1)
|
await node1.mountRlnRelay(wakuRlnConfig1)
|
||||||
|
|
||||||
await node1.start()
|
await node1.start()
|
||||||
|
@ -62,21 +55,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
# node 2
|
# node 2
|
||||||
await node2.mountRelay(@[DefaultPubsubTopic])
|
await node2.mountRelay(@[DefaultPubsubTopic])
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig2 = WakuRlnConfig(
|
||||||
let wakuRlnConfig2 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(2.uint),
|
||||||
rlnRelayCredIndex: some(2.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_2"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_2"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig2 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(2.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_2"),
|
|
||||||
)
|
|
||||||
await node2.mountRlnRelay(wakuRlnConfig2)
|
await node2.mountRlnRelay(wakuRlnConfig2)
|
||||||
|
|
||||||
await node2.start()
|
await node2.start()
|
||||||
|
@ -84,21 +70,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
# node 3
|
# node 3
|
||||||
await node3.mountRelay(@[DefaultPubsubTopic])
|
await node3.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig3 = WakuRlnConfig(
|
||||||
let wakuRlnConfig3 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(3.uint),
|
||||||
rlnRelayCredIndex: some(3.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_3"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_3"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig3 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(3.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_3"),
|
|
||||||
)
|
|
||||||
await node3.mountRlnRelay(wakuRlnConfig3)
|
await node3.mountRlnRelay(wakuRlnConfig3)
|
||||||
|
|
||||||
await node3.start()
|
await node3.start()
|
||||||
|
@ -162,21 +141,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
|
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
for index, node in nodes:
|
for index, node in nodes:
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig = WakuRlnConfig(
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(index.uint + 1),
|
||||||
rlnRelayCredIndex: some(index.uint + 1),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_" & $(index + 1)),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_" & $(index + 1)),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(index.uint + 1),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_" & $(index + 1)),
|
|
||||||
)
|
|
||||||
await node.mountRlnRelay(wakuRlnConfig)
|
await node.mountRlnRelay(wakuRlnConfig)
|
||||||
|
|
||||||
# start them
|
# start them
|
||||||
|
@ -263,21 +235,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
await node1.mountRelay(@[DefaultPubsubTopic])
|
await node1.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig1 = WakuRlnConfig(
|
||||||
let wakuRlnConfig1 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_4"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_4"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig1 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_4"),
|
|
||||||
)
|
|
||||||
await node1.mountRlnRelay(wakuRlnConfig1)
|
await node1.mountRlnRelay(wakuRlnConfig1)
|
||||||
|
|
||||||
await node1.start()
|
await node1.start()
|
||||||
|
@ -285,21 +250,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
# node 2
|
# node 2
|
||||||
await node2.mountRelay(@[DefaultPubsubTopic])
|
await node2.mountRelay(@[DefaultPubsubTopic])
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig2 = WakuRlnConfig(
|
||||||
let wakuRlnConfig2 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(2.uint),
|
||||||
rlnRelayCredIndex: some(2.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_5"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_5"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig2 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(2.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_5"),
|
|
||||||
)
|
|
||||||
await node2.mountRlnRelay(wakuRlnConfig2)
|
await node2.mountRlnRelay(wakuRlnConfig2)
|
||||||
|
|
||||||
await node2.start()
|
await node2.start()
|
||||||
|
@ -307,21 +265,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
# node 3
|
# node 3
|
||||||
await node3.mountRelay(@[DefaultPubsubTopic])
|
await node3.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig3 = WakuRlnConfig(
|
||||||
let wakuRlnConfig3 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(3.uint),
|
||||||
rlnRelayCredIndex: some(3.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_6"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_6"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig3 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(3.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_6"),
|
|
||||||
)
|
|
||||||
await node3.mountRlnRelay(wakuRlnConfig3)
|
await node3.mountRlnRelay(wakuRlnConfig3)
|
||||||
await node3.start()
|
await node3.start()
|
||||||
|
|
||||||
|
@ -354,17 +305,11 @@ procSuite "WakuNode - RLN relay":
|
||||||
input = concat(payload, contentTopicBytes)
|
input = concat(payload, contentTopicBytes)
|
||||||
extraBytes: seq[byte] = @[byte(1), 2, 3]
|
extraBytes: seq[byte] = @[byte(1), 2, 3]
|
||||||
|
|
||||||
when defined(rln_v2):
|
let nonceManager = node1.wakuRlnRelay.nonceManager
|
||||||
let nonceManager = node1.wakuRlnRelay.nonceManager
|
let rateLimitProofRes = node1.wakuRlnRelay.groupManager.generateProof(
|
||||||
let rateLimitProofRes = node1.wakuRlnRelay.groupManager.generateProof(
|
concat(input, extraBytes), epoch, MessageId(0)
|
||||||
concat(input, extraBytes), epoch, MessageId(0)
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let rateLimitProofRes = node1.wakuRlnRelay.groupManager.generateProof(
|
|
||||||
concat(input, extraBytes),
|
|
||||||
# we add extra bytes to invalidate proof verification against original payload
|
|
||||||
epoch,
|
|
||||||
)
|
|
||||||
assert rateLimitProofRes.isOk(), $rateLimitProofRes.error
|
assert rateLimitProofRes.isOk(), $rateLimitProofRes.error
|
||||||
# check the proof is generated correctly outside when block to avoid duplication
|
# check the proof is generated correctly outside when block to avoid duplication
|
||||||
let rateLimitProof = rateLimitProofRes.get().encode().buffer
|
let rateLimitProof = rateLimitProofRes.get().encode().buffer
|
||||||
|
@ -406,21 +351,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
await node1.mountRelay(@[DefaultPubsubTopic])
|
await node1.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig1 = WakuRlnConfig(
|
||||||
let wakuRlnConfig1 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_7"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_7"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig1 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_7"),
|
|
||||||
)
|
|
||||||
await node1.mountRlnRelay(wakuRlnConfig1)
|
await node1.mountRlnRelay(wakuRlnConfig1)
|
||||||
|
|
||||||
await node1.start()
|
await node1.start()
|
||||||
|
@ -429,21 +367,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
await node2.mountRelay(@[DefaultPubsubTopic])
|
await node2.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig2 = WakuRlnConfig(
|
||||||
let wakuRlnConfig2 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(2.uint),
|
||||||
rlnRelayCredIndex: some(2.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_8"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_8"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig2 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(2.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_8"),
|
|
||||||
)
|
|
||||||
await node2.mountRlnRelay(wakuRlnConfig2)
|
await node2.mountRlnRelay(wakuRlnConfig2)
|
||||||
await node2.start()
|
await node2.start()
|
||||||
|
|
||||||
|
@ -451,21 +382,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
await node3.mountRelay(@[DefaultPubsubTopic])
|
await node3.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig3 = WakuRlnConfig(
|
||||||
let wakuRlnConfig3 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(3.uint),
|
||||||
rlnRelayCredIndex: some(3.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_9"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_9"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig3 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(3.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_9"),
|
|
||||||
)
|
|
||||||
await node3.mountRlnRelay(wakuRlnConfig3)
|
await node3.mountRlnRelay(wakuRlnConfig3)
|
||||||
|
|
||||||
await node3.start()
|
await node3.start()
|
||||||
|
@ -562,21 +486,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
await node1.mountRelay(@[DefaultPubsubTopic])
|
await node1.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig1 = WakuRlnConfig(
|
||||||
let wakuRlnConfig1 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_10"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_10"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig1 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_10"),
|
|
||||||
)
|
|
||||||
await node1.mountRlnRelay(wakuRlnConfig1)
|
await node1.mountRlnRelay(wakuRlnConfig1)
|
||||||
|
|
||||||
await node1.start()
|
await node1.start()
|
||||||
|
@ -585,21 +502,14 @@ procSuite "WakuNode - RLN relay":
|
||||||
await node2.mountRelay(@[DefaultPubsubTopic])
|
await node2.mountRelay(@[DefaultPubsubTopic])
|
||||||
|
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig2 = WakuRlnConfig(
|
||||||
let wakuRlnConfig2 = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(2.uint),
|
||||||
rlnRelayCredIndex: some(2.uint),
|
rlnRelayUserMessageLimit: 1,
|
||||||
rlnRelayUserMessageLimit: 1,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_11"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_11"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig2 = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(2.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_11"),
|
|
||||||
)
|
|
||||||
await node2.mountRlnRelay(wakuRlnConfig2)
|
await node2.mountRlnRelay(wakuRlnConfig2)
|
||||||
|
|
||||||
await node2.start()
|
await node2.start()
|
||||||
|
|
|
@ -219,21 +219,14 @@ suite "Waku v2 Rest API - Relay":
|
||||||
let node = testWakuNode()
|
let node = testWakuNode()
|
||||||
await node.start()
|
await node.start()
|
||||||
await node.mountRelay()
|
await node.mountRelay()
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig = WakuRlnConfig(
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 20,
|
||||||
rlnRelayUserMessageLimit: 20,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
|
||||||
)
|
|
||||||
await node.mountRlnRelay(wakuRlnConfig)
|
await node.mountRlnRelay(wakuRlnConfig)
|
||||||
|
|
||||||
# RPC server setup
|
# RPC server setup
|
||||||
|
@ -443,21 +436,14 @@ suite "Waku v2 Rest API - Relay":
|
||||||
let node = testWakuNode()
|
let node = testWakuNode()
|
||||||
await node.start()
|
await node.start()
|
||||||
await node.mountRelay()
|
await node.mountRelay()
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig = WakuRlnConfig(
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 20,
|
||||||
rlnRelayUserMessageLimit: 20,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
|
||||||
)
|
|
||||||
await node.mountRlnRelay(wakuRlnConfig)
|
await node.mountRlnRelay(wakuRlnConfig)
|
||||||
|
|
||||||
# RPC server setup
|
# RPC server setup
|
||||||
|
@ -502,21 +488,14 @@ suite "Waku v2 Rest API - Relay":
|
||||||
let node = testWakuNode()
|
let node = testWakuNode()
|
||||||
await node.start()
|
await node.start()
|
||||||
await node.mountRelay()
|
await node.mountRelay()
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig = WakuRlnConfig(
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 20,
|
||||||
rlnRelayUserMessageLimit: 20,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
|
||||||
)
|
|
||||||
await node.mountRlnRelay(wakuRlnConfig)
|
await node.mountRlnRelay(wakuRlnConfig)
|
||||||
|
|
||||||
# RPC server setup
|
# RPC server setup
|
||||||
|
@ -557,21 +536,14 @@ suite "Waku v2 Rest API - Relay":
|
||||||
let node = testWakuNode()
|
let node = testWakuNode()
|
||||||
await node.start()
|
await node.start()
|
||||||
await node.mountRelay()
|
await node.mountRelay()
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig = WakuRlnConfig(
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 20,
|
||||||
rlnRelayUserMessageLimit: 20,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
|
||||||
)
|
|
||||||
await node.mountRlnRelay(wakuRlnConfig)
|
await node.mountRlnRelay(wakuRlnConfig)
|
||||||
|
|
||||||
# RPC server setup
|
# RPC server setup
|
||||||
|
@ -619,21 +591,14 @@ suite "Waku v2 Rest API - Relay":
|
||||||
let node = testWakuNode()
|
let node = testWakuNode()
|
||||||
await node.start()
|
await node.start()
|
||||||
await node.mountRelay()
|
await node.mountRelay()
|
||||||
when defined(rln_v2):
|
let wakuRlnConfig = WakuRlnConfig(
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
rlnRelayDynamic: false,
|
||||||
rlnRelayDynamic: false,
|
rlnRelayCredIndex: some(1.uint),
|
||||||
rlnRelayCredIndex: some(1.uint),
|
rlnRelayUserMessageLimit: 20,
|
||||||
rlnRelayUserMessageLimit: 20,
|
rlnEpochSizeSec: 1,
|
||||||
rlnEpochSizeSec: 1,
|
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let wakuRlnConfig = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: false,
|
|
||||||
rlnRelayCredIndex: some(1.uint),
|
|
||||||
rlnEpochSizeSec: 1,
|
|
||||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"),
|
|
||||||
)
|
|
||||||
await node.mountRlnRelay(wakuRlnConfig)
|
await node.mountRlnRelay(wakuRlnConfig)
|
||||||
|
|
||||||
# RPC server setup
|
# RPC server setup
|
||||||
|
|
|
@ -67,10 +67,7 @@ proc doRlnKeystoreGenerator*(conf: WakuNodeConf) =
|
||||||
|
|
||||||
# 5. register on-chain
|
# 5. register on-chain
|
||||||
try:
|
try:
|
||||||
when defined(rln_v2):
|
waitFor groupManager.register(credential, conf.rlnRelayUserMessageLimit)
|
||||||
waitFor groupManager.register(credential, conf.rlnRelayUserMessageLimit)
|
|
||||||
else:
|
|
||||||
waitFor groupManager.register(credential)
|
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
error "failure while registering credentials on-chain",
|
error "failure while registering credentials on-chain",
|
||||||
error = getCurrentExceptionMsg()
|
error = getCurrentExceptionMsg()
|
||||||
|
@ -82,27 +79,18 @@ proc doRlnKeystoreGenerator*(conf: WakuNodeConf) =
|
||||||
chainId = $groupManager.chainId.get(),
|
chainId = $groupManager.chainId.get(),
|
||||||
contractAddress = conf.rlnRelayEthContractAddress,
|
contractAddress = conf.rlnRelayEthContractAddress,
|
||||||
membershipIndex = groupManager.membershipIndex.get()
|
membershipIndex = groupManager.membershipIndex.get()
|
||||||
when defined(rln_v2):
|
info "Your user message limit is", userMessageLimit = conf.rlnRelayUserMessageLimit
|
||||||
info "Your user message limit is", userMessageLimit = conf.rlnRelayUserMessageLimit
|
|
||||||
|
|
||||||
# 6. write to keystore
|
# 6. write to keystore
|
||||||
when defined(rln_v2):
|
let keystoreCred = KeystoreMembership(
|
||||||
let keystoreCred = KeystoreMembership(
|
membershipContract: MembershipContract(
|
||||||
membershipContract: MembershipContract(
|
chainId: $groupManager.chainId.get(), address: conf.rlnRelayEthContractAddress
|
||||||
chainId: $groupManager.chainId.get(), address: conf.rlnRelayEthContractAddress
|
),
|
||||||
),
|
treeIndex: groupManager.membershipIndex.get(),
|
||||||
treeIndex: groupManager.membershipIndex.get(),
|
identityCredential: credential,
|
||||||
identityCredential: credential,
|
userMessageLimit: conf.rlnRelayUserMessageLimit,
|
||||||
userMessageLimit: conf.rlnRelayUserMessageLimit,
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let keystoreCred = KeystoreMembership(
|
|
||||||
membershipContract: MembershipContract(
|
|
||||||
chainId: $groupManager.chainId.get(), address: conf.rlnRelayEthContractAddress
|
|
||||||
),
|
|
||||||
treeIndex: groupManager.membershipIndex.get(),
|
|
||||||
identityCredential: credential,
|
|
||||||
)
|
|
||||||
|
|
||||||
let persistRes = addMembershipCredentials(
|
let persistRes = addMembershipCredentials(
|
||||||
conf.rlnRelayCredPath, keystoreCred, conf.rlnRelayCredPassword, RLNAppInfo
|
conf.rlnRelayCredPath, keystoreCred, conf.rlnRelayCredPassword, RLNAppInfo
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0ad1ed296d49e85598e0ec0bae7c220885e47912
|
Subproject commit 85d71a5427ee78528d6420c04b67c7825e3c6e91
|
|
@ -195,31 +195,18 @@ proc setupProtocols(
|
||||||
quit(QuitFailure)
|
quit(QuitFailure)
|
||||||
|
|
||||||
if conf.rlnRelay:
|
if conf.rlnRelay:
|
||||||
when defined(rln_v2):
|
let rlnConf = WakuRlnConfig(
|
||||||
let rlnConf = WakuRlnConfig(
|
rlnRelayDynamic: conf.rlnRelayDynamic,
|
||||||
rlnRelayDynamic: conf.rlnRelayDynamic,
|
rlnRelayCredIndex: conf.rlnRelayCredIndex,
|
||||||
rlnRelayCredIndex: conf.rlnRelayCredIndex,
|
rlnRelayEthContractAddress: conf.rlnRelayEthContractAddress,
|
||||||
rlnRelayEthContractAddress: conf.rlnRelayEthContractAddress,
|
rlnRelayEthClientAddress: string(conf.rlnRelayethClientAddress),
|
||||||
rlnRelayEthClientAddress: string(conf.rlnRelayethClientAddress),
|
rlnRelayCredPath: conf.rlnRelayCredPath,
|
||||||
rlnRelayCredPath: conf.rlnRelayCredPath,
|
rlnRelayCredPassword: conf.rlnRelayCredPassword,
|
||||||
rlnRelayCredPassword: conf.rlnRelayCredPassword,
|
rlnRelayTreePath: conf.rlnRelayTreePath,
|
||||||
rlnRelayTreePath: conf.rlnRelayTreePath,
|
rlnRelayUserMessageLimit: conf.rlnRelayUserMessageLimit,
|
||||||
rlnRelayUserMessageLimit: conf.rlnRelayUserMessageLimit,
|
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
||||||
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
onFatalErrorAction: onFatalErrorAction,
|
||||||
onFatalErrorAction: onFatalErrorAction,
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
let rlnConf = WakuRlnConfig(
|
|
||||||
rlnRelayDynamic: conf.rlnRelayDynamic,
|
|
||||||
rlnRelayCredIndex: conf.rlnRelayCredIndex,
|
|
||||||
rlnRelayEthContractAddress: conf.rlnRelayEthContractAddress,
|
|
||||||
rlnRelayEthClientAddress: string(conf.rlnRelayethClientAddress),
|
|
||||||
rlnRelayCredPath: conf.rlnRelayCredPath,
|
|
||||||
rlnRelayCredPassword: conf.rlnRelayCredPassword,
|
|
||||||
rlnRelayTreePath: conf.rlnRelayTreePath,
|
|
||||||
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
|
||||||
onFatalErrorAction: onFatalErrorAction,
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
waitFor node.mountRlnRelay(rlnConf)
|
waitFor node.mountRlnRelay(rlnConf)
|
||||||
|
|
|
@ -15,9 +15,7 @@ type
|
||||||
IdentitySecretHash* = seq[byte] #array[32, byte]
|
IdentitySecretHash* = seq[byte] #array[32, byte]
|
||||||
# hash of identity key as defined ed in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
|
# hash of identity key as defined ed in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
|
||||||
IDCommitment* = seq[byte] #array[32, byte]
|
IDCommitment* = seq[byte] #array[32, byte]
|
||||||
|
UserMessageLimit* = uint64
|
||||||
when defined(rln_v2):
|
|
||||||
type UserMessageLimit* = uint64
|
|
||||||
|
|
||||||
type IdentityCredential* = object
|
type IdentityCredential* = object
|
||||||
idTrapdoor*: IdentityTrapdoor
|
idTrapdoor*: IdentityTrapdoor
|
||||||
|
@ -103,45 +101,24 @@ type KeystoreMembership* = ref object of RootObj
|
||||||
membershipContract*: MembershipContract
|
membershipContract*: MembershipContract
|
||||||
treeIndex*: MembershipIndex
|
treeIndex*: MembershipIndex
|
||||||
identityCredential*: IdentityCredential
|
identityCredential*: IdentityCredential
|
||||||
when defined(rln_v2):
|
userMessageLimit*: UserMessageLimit
|
||||||
userMessageLimit*: UserMessageLimit
|
|
||||||
|
|
||||||
when defined(rln_v2):
|
proc `$`*(m: KeystoreMembership): string =
|
||||||
proc `$`*(m: KeystoreMembership): string =
|
return
|
||||||
return
|
"KeystoreMembership(chainId: " & m.membershipContract.chainId &
|
||||||
"KeystoreMembership(chainId: " & m.membershipContract.chainId &
|
", contractAddress: " & m.membershipContract.address & ", treeIndex: " &
|
||||||
", contractAddress: " & m.membershipContract.address & ", treeIndex: " &
|
$m.treeIndex & ", userMessageLimit: " & $m.userMessageLimit &
|
||||||
$m.treeIndex & ", userMessageLimit: " & $m.userMessageLimit &
|
", identityCredential: " & $m.identityCredential & ")"
|
||||||
", identityCredential: " & $m.identityCredential & ")"
|
|
||||||
|
|
||||||
else:
|
proc `==`*(x, y: KeystoreMembership): bool =
|
||||||
proc `$`*(m: KeystoreMembership): string =
|
return
|
||||||
return
|
x.membershipContract.chainId == y.membershipContract.chainId and
|
||||||
"KeystoreMembership(chainId: " & m.membershipContract.chainId &
|
x.membershipContract.address == y.membershipContract.address and
|
||||||
", contractAddress: " & m.membershipContract.address & ", treeIndex: " &
|
x.treeIndex == y.treeIndex and x.userMessageLimit == y.userMessageLimit and
|
||||||
$m.treeIndex & ", identityCredential: " & $m.identityCredential & ")"
|
x.identityCredential.idTrapdoor == y.identityCredential.idTrapdoor and
|
||||||
|
x.identityCredential.idNullifier == y.identityCredential.idNullifier and
|
||||||
when defined(rln_v2):
|
x.identityCredential.idSecretHash == y.identityCredential.idSecretHash and
|
||||||
proc `==`*(x, y: KeystoreMembership): bool =
|
x.identityCredential.idCommitment == y.identityCredential.idCommitment
|
||||||
return
|
|
||||||
x.membershipContract.chainId == y.membershipContract.chainId and
|
|
||||||
x.membershipContract.address == y.membershipContract.address and
|
|
||||||
x.treeIndex == y.treeIndex and x.userMessageLimit == y.userMessageLimit and
|
|
||||||
x.identityCredential.idTrapdoor == y.identityCredential.idTrapdoor and
|
|
||||||
x.identityCredential.idNullifier == y.identityCredential.idNullifier and
|
|
||||||
x.identityCredential.idSecretHash == y.identityCredential.idSecretHash and
|
|
||||||
x.identityCredential.idCommitment == y.identityCredential.idCommitment
|
|
||||||
|
|
||||||
else:
|
|
||||||
proc `==`*(x, y: KeystoreMembership): bool =
|
|
||||||
return
|
|
||||||
x.membershipContract.chainId == y.membershipContract.chainId and
|
|
||||||
x.membershipContract.address == y.membershipContract.address and
|
|
||||||
x.treeIndex == y.treeIndex and
|
|
||||||
x.identityCredential.idTrapdoor == y.identityCredential.idTrapdoor and
|
|
||||||
x.identityCredential.idNullifier == y.identityCredential.idNullifier and
|
|
||||||
x.identityCredential.idSecretHash == y.identityCredential.idSecretHash and
|
|
||||||
x.identityCredential.idCommitment == y.identityCredential.idCommitment
|
|
||||||
|
|
||||||
proc hash*(m: KeystoreMembership): string =
|
proc hash*(m: KeystoreMembership): string =
|
||||||
# hash together the chainId, address and treeIndex
|
# hash together the chainId, address and treeIndex
|
||||||
|
|
|
@ -27,14 +27,13 @@ const
|
||||||
|
|
||||||
const DefaultRlnTreePath* = "rln_tree.db"
|
const DefaultRlnTreePath* = "rln_tree.db"
|
||||||
|
|
||||||
when defined(rln_v2):
|
const
|
||||||
const
|
# pre-processed "rln/waku-rln-relay/v2.0.0" to array[32, byte]
|
||||||
# pre-processed "rln/waku-rln-relay/v2.0.0" to array[32, byte]
|
DefaultRlnIdentifier*: RlnIdentifier = [
|
||||||
DefaultRlnIdentifier*: RlnIdentifier = [
|
114, 108, 110, 47, 119, 97, 107, 117, 45, 114, 108, 110, 45, 114, 101, 108, 97,
|
||||||
114, 108, 110, 47, 119, 97, 107, 117, 45, 114, 108, 110, 45, 114, 101, 108, 97,
|
121, 47, 118, 50, 46, 48, 46, 48, 0, 0, 0, 0, 0, 0, 0,
|
||||||
121, 47, 118, 50, 46, 48, 46, 48, 0, 0, 0, 0, 0, 0, 0,
|
]
|
||||||
]
|
DefaultUserMessageLimit* = UserMessageLimit(20)
|
||||||
DefaultUserMessageLimit* = UserMessageLimit(20)
|
|
||||||
|
|
||||||
# temporary variables to test waku-rln-relay performance in the static group mode
|
# temporary variables to test waku-rln-relay performance in the static group mode
|
||||||
const
|
const
|
||||||
|
@ -60048,15 +60047,11 @@ const StaticGroupKeys* =
|
||||||
]
|
]
|
||||||
|
|
||||||
# StaticGroupMerkleRoot is the root of the Merkle tree constructed from the StaticGroupKeys above
|
# StaticGroupMerkleRoot is the root of the Merkle tree constructed from the StaticGroupKeys above
|
||||||
# only identity commitments are used for the Merkle tree construction
|
|
||||||
# rln-v2: rate commitments are used for the Merkle tree construction, defaulting the UserMessageLimit to 20
|
# rln-v2: rate commitments are used for the Merkle tree construction, defaulting the UserMessageLimit to 20
|
||||||
# the root is created locally, using createMembershipList proc from waku_rln_relay_utils module, and the result is hardcoded in here
|
# the root is created locally, using createMembershipList proc from waku_rln_relay_utils module, and the result is hardcoded in here
|
||||||
when defined(rln_v2):
|
const StaticGroupMerkleRoot* =
|
||||||
const StaticGroupMerkleRoot* =
|
"2c149e48886b5ba3da2edf8db8d7a364ae7a25618489c04cf0c0380f7cdd4d6f"
|
||||||
"2c149e48886b5ba3da2edf8db8d7a364ae7a25618489c04cf0c0380f7cdd4d6f"
|
|
||||||
else:
|
|
||||||
const StaticGroupMerkleRoot* =
|
|
||||||
"1e534adab58f7d300aaeecae57a25e0a0b18c368a09f720280da92b288950901"
|
|
||||||
|
|
||||||
const MaxClockGapSeconds* = 20.0 # the maximum clock difference between peers in seconds
|
const MaxClockGapSeconds* = 20.0 # the maximum clock difference between peers in seconds
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -30,9 +30,8 @@ proc inHex*(
|
||||||
valueHex = "0" & valueHex
|
valueHex = "0" & valueHex
|
||||||
return toLowerAscii(valueHex)
|
return toLowerAscii(valueHex)
|
||||||
|
|
||||||
when defined(rln_v2):
|
proc toUserMessageLimit*(v: UInt256): UserMessageLimit =
|
||||||
proc toUserMessageLimit*(v: UInt256): UserMessageLimit =
|
return cast[UserMessageLimit](v)
|
||||||
return cast[UserMessageLimit](v)
|
|
||||||
|
|
||||||
proc encodeLengthPrefix*(input: openArray[byte]): seq[byte] =
|
proc encodeLengthPrefix*(input: openArray[byte]): seq[byte] =
|
||||||
## returns length prefixed version of the input
|
## returns length prefixed version of the input
|
||||||
|
@ -56,75 +55,47 @@ proc serialize*(v: uint64): array[32, byte] =
|
||||||
discard output.copyFrom(bytes)
|
discard output.copyFrom(bytes)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
when defined(rln_v2):
|
proc serialize*(
|
||||||
proc serialize*(
|
idSecretHash: IdentitySecretHash,
|
||||||
idSecretHash: IdentitySecretHash,
|
memIndex: MembershipIndex,
|
||||||
memIndex: MembershipIndex,
|
userMessageLimit: UserMessageLimit,
|
||||||
userMessageLimit: UserMessageLimit,
|
messageId: MessageId,
|
||||||
messageId: MessageId,
|
externalNullifier: ExternalNullifier,
|
||||||
externalNullifier: ExternalNullifier,
|
msg: openArray[byte],
|
||||||
msg: openArray[byte],
|
): seq[byte] =
|
||||||
): seq[byte] =
|
## a private proc to convert RateLimitProof and the data to a byte seq
|
||||||
## a private proc to convert RateLimitProof and the data to a byte seq
|
## this conversion is used in the proofGen proc
|
||||||
## this conversion is used in the proofGen proc
|
## the serialization is done as instructed in https://github.com/kilic/rln/blob/7ac74183f8b69b399e3bc96c1ae8ab61c026dc43/src/public.rs#L146
|
||||||
## the serialization is done as instructed in https://github.com/kilic/rln/blob/7ac74183f8b69b399e3bc96c1ae8ab61c026dc43/src/public.rs#L146
|
## [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
||||||
## [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
let memIndexBytes = toBytes(uint64(memIndex), Endianness.littleEndian)
|
||||||
let memIndexBytes = toBytes(uint64(memIndex), Endianness.littleEndian)
|
let userMessageLimitBytes = userMessageLimit.serialize()
|
||||||
let userMessageLimitBytes = userMessageLimit.serialize()
|
let messageIdBytes = messageId.serialize()
|
||||||
let messageIdBytes = messageId.serialize()
|
let lenPrefMsg = encodeLengthPrefix(msg)
|
||||||
let lenPrefMsg = encodeLengthPrefix(msg)
|
let output = concat(
|
||||||
let output = concat(
|
@idSecretHash,
|
||||||
@idSecretHash,
|
@memIndexBytes,
|
||||||
@memIndexBytes,
|
@userMessageLimitBytes,
|
||||||
@userMessageLimitBytes,
|
@messageIdBytes,
|
||||||
@messageIdBytes,
|
@externalNullifier,
|
||||||
@externalNullifier,
|
lenPrefMsg,
|
||||||
lenPrefMsg,
|
)
|
||||||
)
|
return output
|
||||||
return output
|
|
||||||
|
|
||||||
else:
|
|
||||||
proc serialize*(
|
|
||||||
idSecretHash: IdentitySecretHash,
|
|
||||||
memIndex: MembershipIndex,
|
|
||||||
epoch: Epoch,
|
|
||||||
msg: openArray[byte],
|
|
||||||
): seq[byte] =
|
|
||||||
## a private proc to convert RateLimitProof and the data to a byte seq
|
|
||||||
## this conversion is used in the proofGen proc
|
|
||||||
## the serialization is done as instructed in https://github.com/kilic/rln/blob/7ac74183f8b69b399e3bc96c1ae8ab61c026dc43/src/public.rs#L146
|
|
||||||
## [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
|
||||||
let memIndexBytes = toBytes(uint64(memIndex), Endianness.littleEndian)
|
|
||||||
let lenPrefMsg = encodeLengthPrefix(msg)
|
|
||||||
let output = concat(@idSecretHash, @memIndexBytes, @epoch, lenPrefMsg)
|
|
||||||
return output
|
|
||||||
|
|
||||||
proc serialize*(proof: RateLimitProof, data: openArray[byte]): seq[byte] =
|
proc serialize*(proof: RateLimitProof, data: openArray[byte]): seq[byte] =
|
||||||
## a private proc to convert RateLimitProof and data to a byte seq
|
## a private proc to convert RateLimitProof and data to a byte seq
|
||||||
## this conversion is used in the proof verification proc
|
## this conversion is used in the proof verification proc
|
||||||
## [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
|
## [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
|
||||||
let lenPrefMsg = encodeLengthPrefix(@data)
|
let lenPrefMsg = encodeLengthPrefix(@data)
|
||||||
when defined(rln_v2):
|
var proofBytes = concat(
|
||||||
var proofBytes = concat(
|
@(proof.proof),
|
||||||
@(proof.proof),
|
@(proof.merkleRoot),
|
||||||
@(proof.merkleRoot),
|
@(proof.externalNullifier),
|
||||||
@(proof.externalNullifier),
|
@(proof.shareX),
|
||||||
@(proof.shareX),
|
@(proof.shareY),
|
||||||
@(proof.shareY),
|
@(proof.nullifier),
|
||||||
@(proof.nullifier),
|
lenPrefMsg,
|
||||||
lenPrefMsg,
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
var proofBytes = concat(
|
|
||||||
@(proof.proof),
|
|
||||||
@(proof.merkleRoot),
|
|
||||||
@(proof.epoch),
|
|
||||||
@(proof.shareX),
|
|
||||||
@(proof.shareY),
|
|
||||||
@(proof.nullifier),
|
|
||||||
@(proof.rlnIdentifier),
|
|
||||||
lenPrefMsg,
|
|
||||||
)
|
|
||||||
|
|
||||||
return proofBytes
|
return proofBytes
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,7 @@ export options, chronos, results, protocol_types, protocol_metrics, deques
|
||||||
|
|
||||||
type Membership* = object
|
type Membership* = object
|
||||||
index*: MembershipIndex
|
index*: MembershipIndex
|
||||||
when defined(rln_v2):
|
rateCommitment*: RawRateCommitment
|
||||||
rateCommitment*: RateCommitment
|
|
||||||
else:
|
|
||||||
idCommitment*: IDCommitment
|
|
||||||
|
|
||||||
type OnRegisterCallback* = proc(registrations: seq[Membership]): Future[void] {.gcsafe.}
|
type OnRegisterCallback* = proc(registrations: seq[Membership]): Future[void] {.gcsafe.}
|
||||||
type OnWithdrawCallback* = proc(withdrawals: seq[Membership]): Future[void] {.gcsafe.}
|
type OnWithdrawCallback* = proc(withdrawals: seq[Membership]): Future[void] {.gcsafe.}
|
||||||
|
@ -35,8 +32,7 @@ type GroupManager* = ref object of RootObj
|
||||||
latestIndex*: MembershipIndex
|
latestIndex*: MembershipIndex
|
||||||
validRoots*: Deque[MerkleNode]
|
validRoots*: Deque[MerkleNode]
|
||||||
onFatalErrorAction*: OnFatalErrorHandler
|
onFatalErrorAction*: OnFatalErrorHandler
|
||||||
when defined(rln_v2):
|
userMessageLimit*: Option[UserMessageLimit]
|
||||||
userMessageLimit*: Option[UserMessageLimit]
|
|
||||||
|
|
||||||
# This proc is used to initialize the group manager
|
# This proc is used to initialize the group manager
|
||||||
# Any initialization logic should be implemented here
|
# Any initialization logic should be implemented here
|
||||||
|
@ -53,61 +49,35 @@ method startGroupSync*(
|
||||||
# This proc is used to register a new identity commitment into the merkle tree
|
# This proc is used to register a new identity commitment into the merkle tree
|
||||||
# The user may or may not have the identity secret to this commitment
|
# The user may or may not have the identity secret to this commitment
|
||||||
# It should be used when detecting new members in the group, and syncing the group state
|
# It should be used when detecting new members in the group, and syncing the group state
|
||||||
when defined(rln_v2):
|
method register*(
|
||||||
method register*(
|
g: GroupManager, rateCommitment: RateCommitment
|
||||||
g: GroupManager, rateCommitment: RateCommitment
|
): Future[void] {.base, async: (raises: [Exception]).} =
|
||||||
): Future[void] {.base, async: (raises: [Exception]).} =
|
raise newException(
|
||||||
raise newException(
|
CatchableError, "register proc for " & $g.type & " is not implemented yet"
|
||||||
CatchableError, "register proc for " & $g.type & " is not implemented yet"
|
)
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
method register*(
|
|
||||||
g: GroupManager, idCommitment: IDCommitment
|
|
||||||
): Future[void] {.base, async: (raises: [Exception]).} =
|
|
||||||
raise newException(
|
|
||||||
CatchableError, "register proc for " & $g.type & " is not implemented yet"
|
|
||||||
)
|
|
||||||
|
|
||||||
# This proc is used to register a new identity commitment into the merkle tree
|
# This proc is used to register a new identity commitment into the merkle tree
|
||||||
# The user should have the identity secret to this commitment
|
# The user should have the identity secret to this commitment
|
||||||
# It should be used when the user wants to join the group
|
# It should be used when the user wants to join the group
|
||||||
when defined(rln_v2):
|
method register*(
|
||||||
method register*(
|
g: GroupManager,
|
||||||
g: GroupManager,
|
credentials: IdentityCredential,
|
||||||
credentials: IdentityCredential,
|
userMessageLimit: UserMessageLimit,
|
||||||
userMessageLimit: UserMessageLimit,
|
): Future[void] {.base, async: (raises: [Exception]).} =
|
||||||
): Future[void] {.base, async: (raises: [Exception]).} =
|
raise newException(
|
||||||
raise newException(
|
CatchableError, "register proc for " & $g.type & " is not implemented yet"
|
||||||
CatchableError, "register proc for " & $g.type & " is not implemented yet"
|
)
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
method register*(
|
|
||||||
g: GroupManager, credentials: IdentityCredential
|
|
||||||
): Future[void] {.base, async: (raises: [Exception]).} =
|
|
||||||
raise newException(
|
|
||||||
CatchableError, "register proc for " & $g.type & " is not implemented yet"
|
|
||||||
)
|
|
||||||
|
|
||||||
# This proc is used to register a batch of new identity commitments into the merkle tree
|
# This proc is used to register a batch of new identity commitments into the merkle tree
|
||||||
# The user may or may not have the identity secret to these commitments
|
# The user may or may not have the identity secret to these commitments
|
||||||
# It should be used when detecting a batch of new members in the group, and syncing the group state
|
# It should be used when detecting a batch of new members in the group, and syncing the group state
|
||||||
when defined(rln_v2):
|
method registerBatch*(
|
||||||
method registerBatch*(
|
g: GroupManager, rateCommitments: seq[RawRateCommitment]
|
||||||
g: GroupManager, rateCommitments: seq[RateCommitment]
|
): Future[void] {.base, async: (raises: [Exception]).} =
|
||||||
): Future[void] {.base, async: (raises: [Exception]).} =
|
raise newException(
|
||||||
raise newException(
|
CatchableError, "registerBatch proc for " & $g.type & " is not implemented yet"
|
||||||
CatchableError, "registerBatch proc for " & $g.type & " is not implemented yet"
|
)
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
method registerBatch*(
|
|
||||||
g: GroupManager, idCommitments: seq[IDCommitment]
|
|
||||||
): Future[void] {.base, async: (raises: [Exception]).} =
|
|
||||||
raise newException(
|
|
||||||
CatchableError, "registerBatch proc for " & $g.type & " is not implemented yet"
|
|
||||||
)
|
|
||||||
|
|
||||||
# This proc is used to set a callback that will be called when a new identity commitment is registered
|
# This proc is used to set a callback that will be called when a new identity commitment is registered
|
||||||
# The callback may be called multiple times, and should be used to for any post processing
|
# The callback may be called multiple times, and should be used to for any post processing
|
||||||
|
@ -133,25 +103,15 @@ method withdrawBatch*(
|
||||||
)
|
)
|
||||||
|
|
||||||
# This proc is used to insert and remove a set of commitments from the merkle tree
|
# This proc is used to insert and remove a set of commitments from the merkle tree
|
||||||
when defined(rln_v2):
|
method atomicBatch*(
|
||||||
method atomicBatch*(
|
g: GroupManager,
|
||||||
g: GroupManager,
|
rateCommitments: seq[RateCommitment],
|
||||||
rateCommitments: seq[RateCommitment],
|
toRemoveIndices: seq[MembershipIndex],
|
||||||
toRemoveIndices: seq[MembershipIndex],
|
): Future[void] {.base, async: (raises: [Exception]).} =
|
||||||
): Future[void] {.base, async: (raises: [Exception]).} =
|
raise newException(
|
||||||
raise newException(
|
CatchableError, "atomicBatch proc for " & $g.type & " is not implemented yet"
|
||||||
CatchableError, "atomicBatch proc for " & $g.type & " is not implemented yet"
|
)
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
method atomicBatch*(
|
|
||||||
g: GroupManager,
|
|
||||||
idCommitments: seq[IDCommitment],
|
|
||||||
toRemoveIndices: seq[MembershipIndex],
|
|
||||||
): Future[void] {.base, async: (raises: [Exception]).} =
|
|
||||||
raise newException(
|
|
||||||
CatchableError, "atomicBatch proc for " & $g.type & " is not implemented yet"
|
|
||||||
)
|
|
||||||
|
|
||||||
method stop*(g: GroupManager): Future[void] {.base, async.} =
|
method stop*(g: GroupManager): Future[void] {.base, async.} =
|
||||||
raise
|
raise
|
||||||
|
@ -216,55 +176,34 @@ method verifyProof*(
|
||||||
return err("proof verification failed: " & $proofVerifyRes.error())
|
return err("proof verification failed: " & $proofVerifyRes.error())
|
||||||
return ok(proofVerifyRes.value())
|
return ok(proofVerifyRes.value())
|
||||||
|
|
||||||
when defined(rln_v2):
|
method generateProof*(
|
||||||
method generateProof*(
|
g: GroupManager,
|
||||||
g: GroupManager,
|
data: openArray[byte],
|
||||||
data: openArray[byte],
|
epoch: Epoch,
|
||||||
epoch: Epoch,
|
messageId: MessageId,
|
||||||
messageId: MessageId,
|
rlnIdentifier = DefaultRlnIdentifier,
|
||||||
rlnIdentifier = DefaultRlnIdentifier,
|
): GroupManagerResult[RateLimitProof] {.base, gcsafe, raises: [].} =
|
||||||
): GroupManagerResult[RateLimitProof] {.base, gcsafe, raises: [].} =
|
## generates a proof for the given data and epoch
|
||||||
## generates a proof for the given data and epoch
|
## the proof is generated using the current merkle root
|
||||||
## the proof is generated using the current merkle root
|
if g.idCredentials.isNone():
|
||||||
if g.idCredentials.isNone():
|
return err("identity credentials are not set")
|
||||||
return err("identity credentials are not set")
|
if g.membershipIndex.isNone():
|
||||||
if g.membershipIndex.isNone():
|
return err("membership index is not set")
|
||||||
return err("membership index is not set")
|
if g.userMessageLimit.isNone():
|
||||||
if g.userMessageLimit.isNone():
|
return err("user message limit is not set")
|
||||||
return err("user message limit is not set")
|
waku_rln_proof_generation_duration_seconds.nanosecondTime:
|
||||||
waku_rln_proof_generation_duration_seconds.nanosecondTime:
|
let proof = proofGen(
|
||||||
let proof = proofGen(
|
rlnInstance = g.rlnInstance,
|
||||||
rlnInstance = g.rlnInstance,
|
data = data,
|
||||||
data = data,
|
membership = g.idCredentials.get(),
|
||||||
membership = g.idCredentials.get(),
|
index = g.membershipIndex.get(),
|
||||||
index = g.membershipIndex.get(),
|
epoch = epoch,
|
||||||
epoch = epoch,
|
userMessageLimit = g.userMessageLimit.get(),
|
||||||
userMessageLimit = g.userMessageLimit.get(),
|
messageId = messageId,
|
||||||
messageId = messageId,
|
).valueOr:
|
||||||
).valueOr:
|
return err("proof generation failed: " & $error)
|
||||||
return err("proof generation failed: " & $error)
|
return ok(proof)
|
||||||
return ok(proof)
|
|
||||||
|
|
||||||
else:
|
|
||||||
method generateProof*(
|
|
||||||
g: GroupManager, data: openArray[byte], epoch: Epoch
|
|
||||||
): GroupManagerResult[RateLimitProof] {.base, gcsafe, raises: [].} =
|
|
||||||
## generates a proof for the given data and epoch
|
|
||||||
## the proof is generated using the current merkle root
|
|
||||||
if g.idCredentials.isNone():
|
|
||||||
return err("identity credentials are not set")
|
|
||||||
if g.membershipIndex.isNone():
|
|
||||||
return err("membership index is not set")
|
|
||||||
waku_rln_proof_generation_duration_seconds.nanosecondTime:
|
|
||||||
let proof = proofGen(
|
|
||||||
rlnInstance = g.rlnInstance,
|
|
||||||
data = data,
|
|
||||||
memKeys = g.idCredentials.get(),
|
|
||||||
memIndex = g.membershipIndex.get(),
|
|
||||||
epoch = epoch,
|
|
||||||
).valueOr:
|
|
||||||
return err("proof generation failed: " & $error)
|
|
||||||
return ok(proof)
|
|
||||||
|
|
||||||
method isReady*(g: GroupManager): Future[bool] {.base, async.} =
|
method isReady*(g: GroupManager): Future[bool] {.base, async.} =
|
||||||
raise newException(
|
raise newException(
|
||||||
|
|
|
@ -31,74 +31,34 @@ logScope:
|
||||||
topics = "waku rln_relay onchain_group_manager"
|
topics = "waku rln_relay onchain_group_manager"
|
||||||
|
|
||||||
# using the when predicate does not work within the contract macro, hence need to dupe
|
# using the when predicate does not work within the contract macro, hence need to dupe
|
||||||
when defined(rln_v2):
|
contract(WakuRlnContract):
|
||||||
contract(WakuRlnRegistry):
|
# this serves as an entrypoint into the rln membership set
|
||||||
# this describes the storage slot to use
|
proc register(
|
||||||
proc usingStorageIndex(): Uint16 {.pure.}
|
idCommitment: UInt256, userMessageLimit: UInt32
|
||||||
# this map contains the address of a given storage slot
|
)
|
||||||
proc storages(index: Uint16): Address {.pure.}
|
# Initializes the implementation contract (only used in unit tests)
|
||||||
# this serves as an entrypoint into the rln storage contract
|
proc initialize(maxMessageLimit: UInt256)
|
||||||
proc register(
|
# this event is raised when a new member is registered
|
||||||
storageIndex: Uint16, idCommitment: Uint256, userMessageLimit: Uint256
|
proc MemberRegistered(
|
||||||
)
|
rateCommitment: UInt256, index: Uint32
|
||||||
|
) {.event.}
|
||||||
|
|
||||||
# this creates a new storage on the rln registry
|
# this function denotes existence of a given user
|
||||||
proc newStorage(maxMessageLimit: Uint256)
|
proc memberExists(idCommitment: Uint256): UInt256 {.view.}
|
||||||
# Initializes the implementation contract (only used in unit tests)
|
# this constant describes the next index of a new member
|
||||||
proc initialize()
|
proc commitmentIndex(): UInt256 {.view.}
|
||||||
|
# this constant describes the block number this contract was deployed on
|
||||||
# membership contract interface
|
proc deployedBlockNumber(): UInt256 {.view.}
|
||||||
contract(RlnStorage):
|
|
||||||
# this event is raised when a new member is registered
|
|
||||||
proc MemberRegistered(
|
|
||||||
idCommitment: Uint256, userMessageLimit: Uint256, index: Uint256
|
|
||||||
) {.event.}
|
|
||||||
|
|
||||||
# this constant contains the membership deposit of the contract
|
|
||||||
proc MEMBERSHIP_DEPOSIT(): Uint256 {.pure.}
|
|
||||||
# this map denotes existence of a given user
|
|
||||||
proc memberExists(idCommitment: Uint256): Uint256 {.view.}
|
|
||||||
# this constant describes the next index of a new member
|
|
||||||
proc idCommitmentIndex(): Uint256 {.view.}
|
|
||||||
# this constant describes the block number this contract was deployed on
|
|
||||||
proc deployedBlockNumber(): Uint256 {.view.}
|
|
||||||
else:
|
|
||||||
contract(WakuRlnRegistry):
|
|
||||||
# this describes the storage slot to use
|
|
||||||
proc usingStorageIndex(): Uint16 {.pure.}
|
|
||||||
# this map contains the address of a given storage slot
|
|
||||||
proc storages(index: Uint16): Address {.pure.}
|
|
||||||
# this serves as an entrypoint into the rln storage contract
|
|
||||||
proc register(storageIndex: Uint16, idCommitment: Uint256)
|
|
||||||
# this creates a new storage on the rln registry
|
|
||||||
proc newStorage()
|
|
||||||
|
|
||||||
# membership contract interface
|
|
||||||
contract(RlnStorage):
|
|
||||||
# this event is raised when a new member is registered
|
|
||||||
proc MemberRegistered(idCommitment: Uint256, index: Uint256) {.event.}
|
|
||||||
# this constant contains the membership deposit of the contract
|
|
||||||
proc MEMBERSHIP_DEPOSIT(): Uint256 {.pure.}
|
|
||||||
# this map denotes existence of a given user
|
|
||||||
proc memberExists(idCommitment: Uint256): Uint256 {.view.}
|
|
||||||
# this constant describes the next index of a new member
|
|
||||||
proc idCommitmentIndex(): Uint256 {.view.}
|
|
||||||
# this constant describes the block number this contract was deployed on
|
|
||||||
proc deployedBlockNumber(): Uint256 {.view.}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
RegistryContractWithSender = Sender[WakuRlnRegistry]
|
WakuRlnContractWithSender = Sender[WakuRlnContract]
|
||||||
RlnContractWithSender = Sender[RlnStorage]
|
|
||||||
OnchainGroupManager* = ref object of GroupManager
|
OnchainGroupManager* = ref object of GroupManager
|
||||||
ethClientUrl*: string
|
ethClientUrl*: string
|
||||||
ethPrivateKey*: Option[string]
|
ethPrivateKey*: Option[string]
|
||||||
ethContractAddress*: string
|
ethContractAddress*: string
|
||||||
ethRpc*: Option[Web3]
|
ethRpc*: Option[Web3]
|
||||||
rlnContract*: Option[RlnContractWithSender]
|
|
||||||
rlnContractDeployedBlockNumber*: BlockNumber
|
rlnContractDeployedBlockNumber*: BlockNumber
|
||||||
registryContract*: Option[RegistryContractWithSender]
|
wakuRlnContract*: Option[WakuRlnContractWithSender]
|
||||||
usingStorageIndex: Option[Uint16]
|
|
||||||
membershipFee*: Option[Uint256]
|
|
||||||
latestProcessedBlock*: BlockNumber
|
latestProcessedBlock*: BlockNumber
|
||||||
registrationTxHash*: Option[TxHash]
|
registrationTxHash*: Option[TxHash]
|
||||||
chainId*: Option[Quantity]
|
chainId*: Option[Quantity]
|
||||||
|
@ -157,212 +117,109 @@ proc setMetadata*(
|
||||||
return err("failed to persist rln metadata: " & getCurrentExceptionMsg())
|
return err("failed to persist rln metadata: " & getCurrentExceptionMsg())
|
||||||
return ok()
|
return ok()
|
||||||
|
|
||||||
when defined(rln_v2):
|
method atomicBatch*(
|
||||||
method atomicBatch*(
|
g: OnchainGroupManager,
|
||||||
g: OnchainGroupManager,
|
start: MembershipIndex,
|
||||||
start: MembershipIndex,
|
rateCommitments = newSeq[RawRateCommitment](),
|
||||||
rateCommitments = newSeq[RateCommitment](),
|
toRemoveIndices = newSeq[MembershipIndex](),
|
||||||
toRemoveIndices = newSeq[MembershipIndex](),
|
): Future[void] {.async: (raises: [Exception]), base.} =
|
||||||
): Future[void] {.async: (raises: [Exception]), base.} =
|
initializedGuard(g)
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
# convert the rateCommitment struct to a leaf value
|
waku_rln_membership_insertion_duration_seconds.nanosecondTime:
|
||||||
let leaves = rateCommitments.toLeaves().valueOr:
|
let operationSuccess =
|
||||||
raise newException(
|
g.rlnInstance.atomicWrite(some(start), rateCommitments, toRemoveIndices)
|
||||||
ValueError, "failed to convert rateCommitments to leaves: " & $error
|
if not operationSuccess:
|
||||||
)
|
raise newException(CatchableError, "atomic batch operation failed")
|
||||||
|
# TODO: when slashing is enabled, we need to track slashed members
|
||||||
|
waku_rln_number_registered_memberships.set(int64(g.rlnInstance.leavesSet()))
|
||||||
|
|
||||||
waku_rln_membership_insertion_duration_seconds.nanosecondTime:
|
if g.registerCb.isSome():
|
||||||
let operationSuccess =
|
var membersSeq = newSeq[Membership]()
|
||||||
g.rlnInstance.atomicWrite(some(start), leaves, toRemoveIndices)
|
for i in 0 ..< rateCommitments.len:
|
||||||
if not operationSuccess:
|
var index = start + MembershipIndex(i)
|
||||||
raise newException(CatchableError, "atomic batch operation failed")
|
debug "registering member to callback", rateCommitment = rateCommitments[i], index = index
|
||||||
# TODO: when slashing is enabled, we need to track slashed members
|
let member = Membership(rateCommitment: rateCommitments[i], index: index)
|
||||||
waku_rln_number_registered_memberships.set(int64(g.rlnInstance.leavesSet()))
|
membersSeq.add(member)
|
||||||
|
await g.registerCb.get()(membersSeq)
|
||||||
|
|
||||||
if g.registerCb.isSome():
|
g.validRootBuffer = g.slideRootQueue()
|
||||||
var membersSeq = newSeq[Membership]()
|
|
||||||
for i in 0 ..< rateCommitments.len:
|
|
||||||
var index = start + MembershipIndex(i)
|
|
||||||
trace "registering member", rateCommitment = rateCommitments[i], index = index
|
|
||||||
let member = Membership(rateCommitment: rateCommitments[i], index: index)
|
|
||||||
membersSeq.add(member)
|
|
||||||
await g.registerCb.get()(membersSeq)
|
|
||||||
|
|
||||||
g.validRootBuffer = g.slideRootQueue()
|
method register*(
|
||||||
|
g: OnchainGroupManager, rateCommitment: RateCommitment
|
||||||
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
|
initializedGuard(g)
|
||||||
|
|
||||||
else:
|
try:
|
||||||
method atomicBatch*(
|
let leaf = rateCommitment.toLeaf().get()
|
||||||
g: OnchainGroupManager,
|
await g.registerBatch(@[leaf])
|
||||||
start: MembershipIndex,
|
except CatchableError:
|
||||||
idCommitments = newSeq[IDCommitment](),
|
raise newException(ValueError, getCurrentExceptionMsg())
|
||||||
toRemoveIndices = newSeq[MembershipIndex](),
|
|
||||||
): Future[void] {.async: (raises: [Exception]), base.} =
|
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
waku_rln_membership_insertion_duration_seconds.nanosecondTime:
|
|
||||||
let operationSuccess =
|
|
||||||
g.rlnInstance.atomicWrite(some(start), idCommitments, toRemoveIndices)
|
|
||||||
if not operationSuccess:
|
|
||||||
raise newException(ValueError, "atomic batch operation failed")
|
|
||||||
# TODO: when slashing is enabled, we need to track slashed members
|
|
||||||
waku_rln_number_registered_memberships.set(int64(g.rlnInstance.leavesSet()))
|
|
||||||
|
|
||||||
if g.registerCb.isSome():
|
method registerBatch*(
|
||||||
var membersSeq = newSeq[Membership]()
|
g: OnchainGroupManager, rateCommitments: seq[RawRateCommitment]
|
||||||
for i in 0 ..< idCommitments.len:
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
var index = start + MembershipIndex(i)
|
initializedGuard(g)
|
||||||
trace "registering member", idCommitment = idCommitments[i], index = index
|
|
||||||
let member = Membership(idCommitment: idCommitments[i], index: index)
|
|
||||||
membersSeq.add(member)
|
|
||||||
await g.registerCb.get()(membersSeq)
|
|
||||||
|
|
||||||
g.validRootBuffer = g.slideRootQueue()
|
await g.atomicBatch(g.latestIndex, rateCommitments)
|
||||||
|
g.latestIndex += MembershipIndex(rateCommitments.len)
|
||||||
|
|
||||||
when defined(rln_v2):
|
method register*(
|
||||||
method register*(
|
g: OnchainGroupManager,
|
||||||
g: OnchainGroupManager, rateCommitment: RateCommitment
|
identityCredential: IdentityCredential,
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
userMessageLimit: UserMessageLimit,
|
||||||
initializedGuard(g)
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
|
initializedGuard(g)
|
||||||
|
|
||||||
await g.registerBatch(@[rateCommitment])
|
let ethRpc = g.ethRpc.get()
|
||||||
|
let wakuRlnContract = g.wakuRlnContract.get()
|
||||||
|
|
||||||
else:
|
var gasPrice: int
|
||||||
method register*(
|
g.retryWrapper(gasPrice, "Failed to get gas price"):
|
||||||
g: OnchainGroupManager, idCommitment: IDCommitment
|
int(await ethRpc.provider.eth_gasPrice()) * 2
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
let idCommitment = identityCredential.idCommitment.toUInt256()
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
await g.registerBatch(@[idCommitment])
|
debug "registering the member",
|
||||||
|
idCommitment = idCommitment,
|
||||||
|
userMessageLimit = userMessageLimit
|
||||||
|
var txHash: TxHash
|
||||||
|
g.retryWrapper(txHash, "Failed to register the member"):
|
||||||
|
await wakuRlnContract
|
||||||
|
.register(idCommitment, userMessageLimit.stuint(32))
|
||||||
|
.send(gasPrice = gasPrice)
|
||||||
|
|
||||||
when defined(rln_v2):
|
# wait for the transaction to be mined
|
||||||
method registerBatch*(
|
var tsReceipt: ReceiptObject
|
||||||
g: OnchainGroupManager, rateCommitments: seq[RateCommitment]
|
g.retryWrapper(tsReceipt, "Failed to get the transaction receipt"):
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
await ethRpc.getMinedTransactionReceipt(txHash)
|
||||||
initializedGuard(g)
|
debug "registration transaction mined", txHash = txHash
|
||||||
|
g.registrationTxHash = some(txHash)
|
||||||
|
# the receipt topic holds the hash of signature of the raised events
|
||||||
|
# TODO: make this robust. search within the event list for the event
|
||||||
|
debug "ts receipt", tsReceipt
|
||||||
|
let firstTopic = tsReceipt.logs[0].topics[0]
|
||||||
|
# the hash of the signature of MemberRegistered(uint256,uint32) event is equal to the following hex value
|
||||||
|
if firstTopic !=
|
||||||
|
cast[FixedBytes[32]](keccak256.digest(
|
||||||
|
"MemberRegistered(uint256,uint32)"
|
||||||
|
).data):
|
||||||
|
raise newException(ValueError, "unexpected event signature")
|
||||||
|
|
||||||
await g.atomicBatch(g.latestIndex, rateCommitments)
|
# the arguments of the raised event i.e., MemberRegistered are encoded inside the data field
|
||||||
g.latestIndex += MembershipIndex(rateCommitments.len)
|
# data = rateCommitment encoded as 256 bits || index encoded as 32 bits
|
||||||
|
let arguments = tsReceipt.logs[0].data
|
||||||
|
debug "tx log data", arguments = arguments
|
||||||
|
let
|
||||||
|
# In TX log data, uints are encoded in big endian
|
||||||
|
membershipIndex = UInt256.fromBytesBE(arguments[32 ..^ 1])
|
||||||
|
|
||||||
else:
|
debug "parsed membershipIndex", membershipIndex
|
||||||
method registerBatch*(
|
g.userMessageLimit = some(userMessageLimit)
|
||||||
g: OnchainGroupManager, idCommitments: seq[IDCommitment]
|
g.membershipIndex = some(membershipIndex.toMembershipIndex())
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
await g.atomicBatch(g.latestIndex, idCommitments)
|
# don't handle member insertion into the tree here, it will be handled by the event listener
|
||||||
g.latestIndex += MembershipIndex(idCommitments.len)
|
return
|
||||||
|
|
||||||
when defined(rln_v2):
|
|
||||||
method register*(
|
|
||||||
g: OnchainGroupManager,
|
|
||||||
identityCredential: IdentityCredential,
|
|
||||||
userMessageLimit: UserMessageLimit,
|
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
let ethRpc = g.ethRpc.get()
|
|
||||||
let registryContract = g.registryContract.get()
|
|
||||||
let membershipFee = g.membershipFee.get()
|
|
||||||
|
|
||||||
var gasPrice: int
|
|
||||||
g.retryWrapper(gasPrice, "Failed to get gas price"):
|
|
||||||
int(await ethRpc.provider.eth_gasPrice()) * 2
|
|
||||||
let idCommitment = identityCredential.idCommitment.toUInt256()
|
|
||||||
|
|
||||||
let storageIndex = g.usingStorageIndex.get()
|
|
||||||
debug "registering the member",
|
|
||||||
idCommitment = idCommitment,
|
|
||||||
storageIndex = storageIndex,
|
|
||||||
userMessageLimit = userMessageLimit
|
|
||||||
var txHash: TxHash
|
|
||||||
g.retryWrapper(txHash, "Failed to register the member"):
|
|
||||||
await registryContract
|
|
||||||
.register(storageIndex, idCommitment, u256(userMessageLimit))
|
|
||||||
.send(gasPrice = gasPrice)
|
|
||||||
|
|
||||||
# wait for the transaction to be mined
|
|
||||||
var tsReceipt: ReceiptObject
|
|
||||||
g.retryWrapper(tsReceipt, "Failed to get the transaction receipt"):
|
|
||||||
await ethRpc.getMinedTransactionReceipt(txHash)
|
|
||||||
debug "registration transaction mined", txHash = txHash
|
|
||||||
g.registrationTxHash = some(txHash)
|
|
||||||
# the receipt topic holds the hash of signature of the raised events
|
|
||||||
# TODO: make this robust. search within the event list for the event
|
|
||||||
let firstTopic = tsReceipt.logs[0].topics[0]
|
|
||||||
# the hash of the signature of MemberRegistered(uint256,uint256,uint256) event is equal to the following hex value
|
|
||||||
if firstTopic !=
|
|
||||||
cast[FixedBytes[32]](keccak256.digest(
|
|
||||||
"MemberRegistered(uint256,uint256,uint256)"
|
|
||||||
).data):
|
|
||||||
raise newException(ValueError, "unexpected event signature")
|
|
||||||
|
|
||||||
# the arguments of the raised event i.e., MemberRegistered are encoded inside the data field
|
|
||||||
# data = pk encoded as 256 bits || index encoded as 256 bits || userMessageLimit encoded as 256 bits
|
|
||||||
let arguments = tsReceipt.logs[0].data
|
|
||||||
debug "tx log data", arguments = arguments
|
|
||||||
let
|
|
||||||
argumentsBytes = arguments
|
|
||||||
# In TX log data, uints are encoded in big endian
|
|
||||||
membershipIndex = UInt256.fromBytesBE(argumentsBytes[64 ..^ 1])
|
|
||||||
|
|
||||||
g.userMessageLimit = some(userMessageLimit)
|
|
||||||
g.membershipIndex = some(membershipIndex.toMembershipIndex())
|
|
||||||
|
|
||||||
# don't handle member insertion into the tree here, it will be handled by the event listener
|
|
||||||
return
|
|
||||||
|
|
||||||
else:
|
|
||||||
method register*(
|
|
||||||
g: OnchainGroupManager, credentials: IdentityCredential
|
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
let ethRpc = g.ethRpc.get()
|
|
||||||
let registryContract = g.registryContract.get()
|
|
||||||
let membershipFee = g.membershipFee.get()
|
|
||||||
|
|
||||||
var gasPrice: int
|
|
||||||
g.retryWrapper(gasPrice, "Failed to get gas price"):
|
|
||||||
int(await ethRpc.provider.eth_gasPrice()) * 2
|
|
||||||
let idCommitment = credentials.idCommitment.toUInt256()
|
|
||||||
|
|
||||||
let storageIndex = g.usingStorageIndex.get()
|
|
||||||
debug "registering the member",
|
|
||||||
idCommitment = idCommitment, storageIndex = storageIndex
|
|
||||||
var txHash: TxHash
|
|
||||||
g.retryWrapper(txHash, "Failed to register the member"):
|
|
||||||
await registryContract.register(storageIndex, idCommitment).send(
|
|
||||||
gasPrice = gasPrice
|
|
||||||
)
|
|
||||||
|
|
||||||
# wait for the transaction to be mined
|
|
||||||
var tsReceipt: ReceiptObject
|
|
||||||
g.retryWrapper(tsReceipt, "Failed to get the transaction receipt"):
|
|
||||||
await ethRpc.getMinedTransactionReceipt(txHash)
|
|
||||||
debug "registration transaction mined", txHash = txHash
|
|
||||||
g.registrationTxHash = some(txHash)
|
|
||||||
# the receipt topic holds the hash of signature of the raised events
|
|
||||||
# TODO: make this robust. search within the event list for the event
|
|
||||||
let firstTopic = tsReceipt.logs[0].topics[0]
|
|
||||||
# the hash of the signature of MemberRegistered(uint256,uint256) event is equal to the following hex value
|
|
||||||
if firstTopic !=
|
|
||||||
cast[FixedBytes[32]](keccak256.digest("MemberRegistered(uint256,uint256)").data):
|
|
||||||
raise newException(ValueError, "unexpected event signature")
|
|
||||||
|
|
||||||
# the arguments of the raised event i.e., MemberRegistered are encoded inside the data field
|
|
||||||
# data = pk encoded as 256 bits || index encoded as 256 bits
|
|
||||||
let arguments = tsReceipt.logs[0].data
|
|
||||||
debug "tx log data", arguments = arguments
|
|
||||||
let
|
|
||||||
argumentsBytes = arguments
|
|
||||||
# In TX log data, uints are encoded in big endian
|
|
||||||
eventIndex = UInt256.fromBytesBE(argumentsBytes[32 ..^ 1])
|
|
||||||
|
|
||||||
g.membershipIndex = some(eventIndex.toMembershipIndex())
|
|
||||||
|
|
||||||
# don't handle member insertion into the tree here, it will be handled by the event listener
|
|
||||||
return
|
|
||||||
|
|
||||||
method withdraw*(
|
method withdraw*(
|
||||||
g: OnchainGroupManager, idCommitment: IDCommitment
|
g: OnchainGroupManager, idCommitment: IDCommitment
|
||||||
|
@ -381,10 +238,8 @@ proc parseEvent(
|
||||||
): GroupManagerResult[Membership] =
|
): GroupManagerResult[Membership] =
|
||||||
## parses the `data` parameter of the `MemberRegistered` event `log`
|
## parses the `data` parameter of the `MemberRegistered` event `log`
|
||||||
## returns an error if it cannot parse the `data` parameter
|
## returns an error if it cannot parse the `data` parameter
|
||||||
var idComm: UInt256
|
var rateCommitment: UInt256
|
||||||
var index: UInt256
|
var index: UInt256
|
||||||
when defined(rln_v2):
|
|
||||||
var userMessageLimit: UInt256
|
|
||||||
var data: string
|
var data: string
|
||||||
# Remove the 0x prefix
|
# Remove the 0x prefix
|
||||||
try:
|
try:
|
||||||
|
@ -396,29 +251,17 @@ proc parseEvent(
|
||||||
)
|
)
|
||||||
var offset = 0
|
var offset = 0
|
||||||
try:
|
try:
|
||||||
# Parse the idComm
|
# Parse the rateCommitment
|
||||||
offset += decode(data, offset, idComm)
|
offset += decode(data, offset, rateCommitment)
|
||||||
when defined(rln_v2):
|
|
||||||
# Parse the userMessageLimit
|
|
||||||
offset += decode(data, offset, userMessageLimit)
|
|
||||||
# Parse the index
|
# Parse the index
|
||||||
offset += decode(data, offset, index)
|
offset += decode(data, offset, index)
|
||||||
when defined(rln_v2):
|
return ok(
|
||||||
return ok(
|
Membership(
|
||||||
Membership(
|
rateCommitment: rateCommitment.toRateCommitment(),
|
||||||
rateCommitment: RateCommitment(
|
index: index.toMembershipIndex(),
|
||||||
idCommitment: idComm.toIDCommitment(),
|
|
||||||
userMessageLimit: userMessageLimit.toUserMessageLimit(),
|
|
||||||
),
|
|
||||||
index: index.toMembershipIndex(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return ok(
|
|
||||||
Membership(
|
|
||||||
idCommitment: idComm.toIDCommitment(), index: index.toMembershipIndex()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
except CatchableError:
|
except CatchableError:
|
||||||
return err("failed to parse the data field of the MemberRegistered event")
|
return err("failed to parse the data field of the MemberRegistered event")
|
||||||
|
|
||||||
|
@ -456,11 +299,11 @@ proc getRawEvents(
|
||||||
initializedGuard(g)
|
initializedGuard(g)
|
||||||
|
|
||||||
let ethRpc = g.ethRpc.get()
|
let ethRpc = g.ethRpc.get()
|
||||||
let rlnContract = g.rlnContract.get()
|
let wakuRlnContract = g.wakuRlnContract.get()
|
||||||
|
|
||||||
var events: JsonNode
|
var events: JsonNode
|
||||||
g.retryWrapper(events, "Failed to get the events"):
|
g.retryWrapper(events, "Failed to get the events"):
|
||||||
await rlnContract.getJsonLogs(
|
await wakuRlnContract.getJsonLogs(
|
||||||
MemberRegistered,
|
MemberRegistered,
|
||||||
fromBlock = some(fromBlock.blockId()),
|
fromBlock = some(fromBlock.blockId()),
|
||||||
toBlock = some(toBlock.blockId()),
|
toBlock = some(toBlock.blockId()),
|
||||||
|
@ -501,24 +344,15 @@ proc handleEvents(
|
||||||
try:
|
try:
|
||||||
let startIndex = blockTable[blockNumber].filterIt(not it[1])[0][0].index
|
let startIndex = blockTable[blockNumber].filterIt(not it[1])[0][0].index
|
||||||
let removalIndices = members.filterIt(it[1]).mapIt(it[0].index)
|
let removalIndices = members.filterIt(it[1]).mapIt(it[0].index)
|
||||||
when defined(rln_v2):
|
let rateCommitments = members.mapIt(it[0].rateCommitment)
|
||||||
let rateCommitments = members.mapIt(it[0].rateCommitment)
|
await g.atomicBatch(
|
||||||
await g.atomicBatch(
|
start = startIndex,
|
||||||
start = startIndex,
|
rateCommitments = rateCommitments,
|
||||||
rateCommitments = rateCommitments,
|
toRemoveIndices = removalIndices,
|
||||||
toRemoveIndices = removalIndices,
|
)
|
||||||
)
|
g.latestIndex = startIndex + MembershipIndex(rateCommitments.len)
|
||||||
g.latestIndex = startIndex + MembershipIndex(rateCommitments.len)
|
trace "new members added to the Merkle tree", commitments = rateCommitments.mapIt(it.inHex)
|
||||||
trace "new members added to the Merkle tree", commitments = rateCommitments
|
|
||||||
else:
|
|
||||||
let idCommitments = members.mapIt(it[0].idCommitment)
|
|
||||||
await g.atomicBatch(
|
|
||||||
start = startIndex,
|
|
||||||
idCommitments = idCommitments,
|
|
||||||
toRemoveIndices = removalIndices,
|
|
||||||
)
|
|
||||||
g.latestIndex = startIndex + MembershipIndex(idCommitments.len)
|
|
||||||
trace "new members added to the Merkle tree", commitments = idCommitments
|
|
||||||
except CatchableError:
|
except CatchableError:
|
||||||
error "failed to insert members into the tree", error = getCurrentExceptionMsg()
|
error "failed to insert members into the tree", error = getCurrentExceptionMsg()
|
||||||
raise newException(ValueError, "failed to insert members into the tree")
|
raise newException(ValueError, "failed to insert members into the tree")
|
||||||
|
@ -720,23 +554,11 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.}
|
||||||
ethRpc.defaultAccount =
|
ethRpc.defaultAccount =
|
||||||
ethRpc.privateKey.get().toPublicKey().toCanonicalAddress().Address
|
ethRpc.privateKey.get().toPublicKey().toCanonicalAddress().Address
|
||||||
|
|
||||||
let registryAddress = web3.fromHex(web3.Address, g.ethContractAddress)
|
let contractAddress = web3.fromHex(web3.Address, g.ethContractAddress)
|
||||||
let registryContract = ethRpc.contractSender(WakuRlnRegistry, registryAddress)
|
let wakuRlnContract = ethRpc.contractSender(WakuRlnContract, contractAddress)
|
||||||
|
|
||||||
# get the current storage index
|
|
||||||
var usingStorageIndex: Uint16
|
|
||||||
g.retryWrapper(usingStorageIndex, "Failed to get the storage index"):
|
|
||||||
await registryContract.usingStorageIndex().call()
|
|
||||||
|
|
||||||
g.usingStorageIndex = some(usingStorageIndex)
|
|
||||||
var rlnContractAddress: Address
|
|
||||||
g.retryWrapper(rlnContractAddress, "Failed to get the rln contract address"):
|
|
||||||
await registryContract.storages(usingStorageIndex).call()
|
|
||||||
let rlnContract = ethRpc.contractSender(RlnStorage, rlnContractAddress)
|
|
||||||
|
|
||||||
g.ethRpc = some(ethRpc)
|
g.ethRpc = some(ethRpc)
|
||||||
g.rlnContract = some(rlnContract)
|
g.wakuRlnContract = some(wakuRlnContract)
|
||||||
g.registryContract = some(registryContract)
|
|
||||||
|
|
||||||
if g.keystorePath.isSome() and g.keystorePassword.isSome():
|
if g.keystorePath.isSome() and g.keystorePassword.isSome():
|
||||||
if not fileExists(g.keystorePath.get()):
|
if not fileExists(g.keystorePath.get()):
|
||||||
|
@ -759,11 +581,10 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.}
|
||||||
return err("failed to get the keystore credentials: " & $error)
|
return err("failed to get the keystore credentials: " & $error)
|
||||||
|
|
||||||
g.membershipIndex = some(keystoreCred.treeIndex)
|
g.membershipIndex = some(keystoreCred.treeIndex)
|
||||||
when defined(rln_v2):
|
g.userMessageLimit = some(keystoreCred.userMessageLimit)
|
||||||
g.userMessageLimit = some(keystoreCred.userMessageLimit)
|
|
||||||
# now we check on the contract if the commitment actually has a membership
|
# now we check on the contract if the commitment actually has a membership
|
||||||
try:
|
try:
|
||||||
let membershipExists = await rlnContract
|
let membershipExists = await wakuRlnContract
|
||||||
.memberExists(keystoreCred.identityCredential.idCommitment.toUInt256())
|
.memberExists(keystoreCred.identityCredential.idCommitment.toUInt256())
|
||||||
.call()
|
.call()
|
||||||
if membershipExists == 0:
|
if membershipExists == 0:
|
||||||
|
@ -786,16 +607,10 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.}
|
||||||
g.latestProcessedBlock = metadata.lastProcessedBlock
|
g.latestProcessedBlock = metadata.lastProcessedBlock
|
||||||
g.validRoots = metadata.validRoots.toDeque()
|
g.validRoots = metadata.validRoots.toDeque()
|
||||||
|
|
||||||
# check if the contract exists by calling a static function
|
|
||||||
var membershipFee: Uint256
|
|
||||||
g.retryWrapper(membershipFee, "Failed to get the membership deposit"):
|
|
||||||
await rlnContract.MEMBERSHIP_DEPOSIT().call()
|
|
||||||
g.membershipFee = some(membershipFee)
|
|
||||||
|
|
||||||
var deployedBlockNumber: Uint256
|
var deployedBlockNumber: Uint256
|
||||||
g.retryWrapper(deployedBlockNumber, "Failed to get the deployed block number"):
|
g.retryWrapper(deployedBlockNumber, "Failed to get the deployed block number"):
|
||||||
await rlnContract.deployedBlockNumber().call()
|
await wakuRlnContract.deployedBlockNumber().call()
|
||||||
debug "using rln storage", deployedBlockNumber, rlnContractAddress
|
debug "using rln contract", deployedBlockNumber, rlnContractAddress = contractAddress
|
||||||
g.rlnContractDeployedBlockNumber = cast[BlockNumber](deployedBlockNumber)
|
g.rlnContractDeployedBlockNumber = cast[BlockNumber](deployedBlockNumber)
|
||||||
g.latestProcessedBlock = max(g.latestProcessedBlock, g.rlnContractDeployedBlockNumber)
|
g.latestProcessedBlock = max(g.latestProcessedBlock, g.rlnContractDeployedBlockNumber)
|
||||||
|
|
||||||
|
|
|
@ -33,25 +33,18 @@ method init*(g: StaticGroupManager): Future[GroupManagerResult[void]] {.async.}
|
||||||
"Invalid membership index. Must be within 0 and " & $(groupSize - 1) & "but was " &
|
"Invalid membership index. Must be within 0 and " & $(groupSize - 1) & "but was " &
|
||||||
$membershipIndex
|
$membershipIndex
|
||||||
)
|
)
|
||||||
when defined(rln_v2):
|
g.userMessageLimit = some(DefaultUserMessageLimit)
|
||||||
g.userMessageLimit = some(DefaultUserMessageLimit)
|
|
||||||
|
|
||||||
g.idCredentials = some(groupKeys[membershipIndex])
|
g.idCredentials = some(groupKeys[membershipIndex])
|
||||||
# Seed the received commitments into the merkle tree
|
# Seed the received commitments into the merkle tree
|
||||||
when defined(rln_v2):
|
let rateCommitments = groupKeys.mapIt(
|
||||||
let rateCommitments = groupKeys.mapIt(
|
RateCommitment(
|
||||||
RateCommitment(
|
idCommitment: it.idCommitment, userMessageLimit: g.userMessageLimit.get()
|
||||||
idCommitment: it.idCommitment, userMessageLimit: g.userMessageLimit.get()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
let leaves = rateCommitments.toLeaves().valueOr:
|
)
|
||||||
return err("Failed to convert rate commitments to leaves: " & $error)
|
let leaves = rateCommitments.toLeaves().valueOr:
|
||||||
let membersInserted = g.rlnInstance.insertMembers(g.latestIndex, leaves)
|
return err("Failed to convert rate commitments to leaves: " & $error)
|
||||||
else:
|
let membersInserted = g.rlnInstance.insertMembers(g.latestIndex, leaves)
|
||||||
let idCommitments = groupKeys.mapIt(it.idCommitment)
|
|
||||||
let membersInserted = g.rlnInstance.insertMembers(g.latestIndex, idCommitments)
|
|
||||||
if not membersInserted:
|
|
||||||
return err("Failed to insert members into the merkle tree")
|
|
||||||
|
|
||||||
discard g.slideRootQueue()
|
discard g.slideRootQueue()
|
||||||
|
|
||||||
|
@ -68,127 +61,65 @@ method startGroupSync*(
|
||||||
# No-op
|
# No-op
|
||||||
return ok()
|
return ok()
|
||||||
|
|
||||||
when defined(rln_v2):
|
method register*(
|
||||||
method register*(
|
g: StaticGroupManager, rateCommitment: RateCommitment
|
||||||
g: StaticGroupManager, rateCommitment: RateCommitment
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
initializedGuard(g)
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
await g.registerBatch(@[rateCommitment])
|
let leaf = rateCommitment.toLeaf().get()
|
||||||
|
|
||||||
else:
|
await g.registerBatch(@[leaf])
|
||||||
method register*(
|
|
||||||
g: StaticGroupManager, idCommitment: IDCommitment
|
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
await g.registerBatch(@[idCommitment])
|
|
||||||
|
|
||||||
when defined(rln_v2):
|
method registerBatch*(
|
||||||
method registerBatch*(
|
g: StaticGroupManager, rateCommitments: seq[RawRateCommitment]
|
||||||
g: StaticGroupManager, rateCommitments: seq[RateCommitment]
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
initializedGuard(g)
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
let leavesRes = rateCommitments.toLeaves()
|
let membersInserted = g.rlnInstance.insertMembers(g.latestIndex + 1, rateCommitments)
|
||||||
if not leavesRes.isOk():
|
if not membersInserted:
|
||||||
raise newException(ValueError, "Failed to convert rate commitments to leaves")
|
raise newException(ValueError, "Failed to insert members into the merkle tree")
|
||||||
let leaves = cast[seq[seq[byte]]](leavesRes.get())
|
|
||||||
|
|
||||||
let membersInserted = g.rlnInstance.insertMembers(g.latestIndex + 1, leaves)
|
if g.registerCb.isSome():
|
||||||
if not membersInserted:
|
var memberSeq = newSeq[Membership]()
|
||||||
raise newException(ValueError, "Failed to insert members into the merkle tree")
|
for i in 0 ..< rateCommitments.len:
|
||||||
|
memberSeq.add(
|
||||||
if g.registerCb.isSome():
|
Membership(
|
||||||
var memberSeq = newSeq[Membership]()
|
rateCommitment: rateCommitments[i],
|
||||||
for i in 0 ..< rateCommitments.len:
|
index: g.latestIndex + MembershipIndex(i) + 1,
|
||||||
memberSeq.add(
|
|
||||||
Membership(
|
|
||||||
rateCommitment: rateCommitments[i],
|
|
||||||
index: g.latestIndex + MembershipIndex(i) + 1,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
await g.registerCb.get()(memberSeq)
|
)
|
||||||
|
await g.registerCb.get()(memberSeq)
|
||||||
|
|
||||||
discard g.slideRootQueue()
|
discard g.slideRootQueue()
|
||||||
|
|
||||||
g.latestIndex += MembershipIndex(rateCommitments.len)
|
g.latestIndex += MembershipIndex(rateCommitments.len)
|
||||||
|
return
|
||||||
|
|
||||||
return
|
method withdraw*(
|
||||||
|
g: StaticGroupManager, idSecretHash: IdentitySecretHash
|
||||||
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
|
initializedGuard(g)
|
||||||
|
|
||||||
else:
|
let groupKeys = g.groupKeys
|
||||||
method registerBatch*(
|
|
||||||
g: StaticGroupManager, idCommitments: seq[IDCommitment]
|
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
let membersInserted = g.rlnInstance.insertMembers(g.latestIndex + 1, idCommitments)
|
for i in 0 ..< groupKeys.len:
|
||||||
if not membersInserted:
|
if groupKeys[i].idSecretHash == idSecretHash:
|
||||||
raise newException(ValueError, "Failed to insert members into the merkle tree")
|
let idCommitment = groupKeys[i].idCommitment
|
||||||
|
let index = MembershipIndex(i)
|
||||||
|
let rateCommitment = RateCommitment(
|
||||||
|
idCommitment: idCommitment, userMessageLimit: g.userMessageLimit.get()
|
||||||
|
).toLeaf().valueOr:
|
||||||
|
raise newException(ValueError, "Failed to parse rateCommitment")
|
||||||
|
let memberRemoved = g.rlnInstance.removeMember(index)
|
||||||
|
if not memberRemoved:
|
||||||
|
raise newException(ValueError, "Failed to remove member from the merkle tree")
|
||||||
|
|
||||||
if g.registerCb.isSome():
|
if g.withdrawCb.isSome():
|
||||||
var memberSeq = newSeq[Membership]()
|
let withdrawCb = g.withdrawCb.get()
|
||||||
for i in 0 ..< idCommitments.len:
|
await withdrawCb(@[Membership(rateCommitment: rateCommitment, index: index)])
|
||||||
memberSeq.add(
|
|
||||||
Membership(
|
|
||||||
idCommitment: idCommitments[i],
|
|
||||||
index: g.latestIndex + MembershipIndex(i) + 1,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
await g.registerCb.get()(memberSeq)
|
|
||||||
|
|
||||||
discard g.slideRootQueue()
|
return
|
||||||
|
|
||||||
g.latestIndex += MembershipIndex(idCommitments.len)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
when defined(rln_v2):
|
|
||||||
method withdraw*(
|
|
||||||
g: StaticGroupManager, idSecretHash: IdentitySecretHash
|
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
let groupKeys = g.groupKeys
|
|
||||||
|
|
||||||
for i in 0 ..< groupKeys.len:
|
|
||||||
if groupKeys[i].idSecretHash == idSecretHash:
|
|
||||||
let idCommitment = groupKeys[i].idCommitment
|
|
||||||
let index = MembershipIndex(i)
|
|
||||||
let rateCommitment = RateCommitment(
|
|
||||||
idCommitment: idCommitment, userMessageLimit: g.userMessageLimit.get()
|
|
||||||
)
|
|
||||||
let memberRemoved = g.rlnInstance.removeMember(index)
|
|
||||||
if not memberRemoved:
|
|
||||||
raise newException(ValueError, "Failed to remove member from the merkle tree")
|
|
||||||
|
|
||||||
if g.withdrawCb.isSome():
|
|
||||||
let withdrawCb = g.withdrawCb.get()
|
|
||||||
await withdrawCb(@[Membership(rateCommitment: rateCommitment, index: index)])
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
else:
|
|
||||||
method withdraw*(
|
|
||||||
g: StaticGroupManager, idSecretHash: IdentitySecretHash
|
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
|
||||||
initializedGuard(g)
|
|
||||||
|
|
||||||
let groupKeys = g.groupKeys
|
|
||||||
|
|
||||||
for i in 0 ..< groupKeys.len:
|
|
||||||
if groupKeys[i].idSecretHash == idSecretHash:
|
|
||||||
let idCommitment = groupKeys[i].idCommitment
|
|
||||||
let index = MembershipIndex(i)
|
|
||||||
let memberRemoved = g.rlnInstance.removeMember(index)
|
|
||||||
if not memberRemoved:
|
|
||||||
raise newException(ValueError, "Failed to remove member from the merkle tree")
|
|
||||||
|
|
||||||
if g.withdrawCb.isSome():
|
|
||||||
let withdrawCb = g.withdrawCb.get()
|
|
||||||
await withdrawCb((@[Membership(idCommitment: idCommitment, index: index)]))
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
method withdrawBatch*(
|
method withdrawBatch*(
|
||||||
g: StaticGroupManager, idSecretHashes: seq[IdentitySecretHash]
|
g: StaticGroupManager, idSecretHashes: seq[IdentitySecretHash]
|
||||||
|
|
|
@ -45,12 +45,13 @@ proc getNonce*(n: NonceManager): NonceManagerResult[Nonce] =
|
||||||
|
|
||||||
if now - n.lastNonceTime >= n.epoch:
|
if now - n.lastNonceTime >= n.epoch:
|
||||||
retNonce = 0
|
retNonce = 0
|
||||||
|
n.lastNonceTime = now
|
||||||
|
|
||||||
n.nextNonce = retNonce + 1
|
n.nextNonce = retNonce + 1
|
||||||
n.lastNonceTime = now
|
|
||||||
|
|
||||||
if retNonce >= n.nonceLimit:
|
if retNonce >= n.nonceLimit:
|
||||||
return err(
|
return err(
|
||||||
NonceManagerError(
|
NonceManagerError(
|
||||||
kind: NonceLimitReached,
|
kind: NonceLimitReached,
|
||||||
error:
|
error:
|
||||||
"Nonce limit reached. Please wait for the next epoch. requested nonce: " &
|
"Nonce limit reached. Please wait for the next epoch. requested nonce: " &
|
||||||
|
|
|
@ -3,7 +3,7 @@ when (NimMajor, NimMinor) < (1, 4):
|
||||||
else:
|
else:
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
import std/[options, tables, deques], stew/arrayops, chronos, web3, eth/keys
|
import std/[options, tables, deques], stew/arrayops, stint, chronos, web3, eth/keys
|
||||||
import ../waku_core, ../waku_keystore, ../common/protobuf
|
import ../waku_core, ../waku_keystore, ../common/protobuf
|
||||||
|
|
||||||
export waku_keystore, waku_core
|
export waku_keystore, waku_core
|
||||||
|
@ -16,20 +16,20 @@ type RLNResult* = RlnRelayResult[ptr RLN]
|
||||||
|
|
||||||
type
|
type
|
||||||
MerkleNode* = array[32, byte]
|
MerkleNode* = array[32, byte]
|
||||||
# Each node of the Merkle tee is a Poseidon hash which is a 32 byte value
|
# Each node of the Merkle tree is a Poseidon hash which is a 32 byte value
|
||||||
Nullifier* = array[32, byte]
|
Nullifier* = array[32, byte]
|
||||||
Epoch* = array[32, byte]
|
Epoch* = array[32, byte]
|
||||||
RlnIdentifier* = array[32, byte]
|
RlnIdentifier* = array[32, byte]
|
||||||
ZKSNARK* = array[128, byte]
|
ZKSNARK* = array[128, byte]
|
||||||
|
MessageId* = uint64
|
||||||
when defined(rln_v2):
|
ExternalNullifier* = array[32, byte]
|
||||||
type
|
RateCommitment* = object
|
||||||
MessageId* = uint64
|
|
||||||
ExternalNullifier* = array[32, byte]
|
|
||||||
|
|
||||||
type RateCommitment* = object
|
|
||||||
idCommitment*: IDCommitment
|
idCommitment*: IDCommitment
|
||||||
userMessageLimit*: UserMessageLimit
|
userMessageLimit*: UserMessageLimit
|
||||||
|
RawRateCommitment* = seq[byte]
|
||||||
|
|
||||||
|
proc toRateCommitment*(rateCommitmentUint: UInt256): RawRateCommitment =
|
||||||
|
return RawRateCommitment(@(rateCommitmentUint.toBytesLE()))
|
||||||
|
|
||||||
# Custom data types defined for waku rln relay -------------------------
|
# Custom data types defined for waku rln relay -------------------------
|
||||||
type RateLimitProof* = object
|
type RateLimitProof* = object
|
||||||
|
@ -51,9 +51,8 @@ type RateLimitProof* = object
|
||||||
epoch*: Epoch
|
epoch*: Epoch
|
||||||
## Application specific RLN Identifier
|
## Application specific RLN Identifier
|
||||||
rlnIdentifier*: RlnIdentifier
|
rlnIdentifier*: RlnIdentifier
|
||||||
when defined(rln_v2):
|
## the external nullifier used for the generation of the `proof` (derived from poseidon([epoch, rln_identifier]))
|
||||||
## the external nullifier used for the generation of the `proof` (derived from poseidon([epoch, rln_identifier]))
|
externalNullifier*: ExternalNullifier
|
||||||
externalNullifier*: ExternalNullifier
|
|
||||||
|
|
||||||
type ProofMetadata* = object
|
type ProofMetadata* = object
|
||||||
nullifier*: Nullifier
|
nullifier*: Nullifier
|
||||||
|
|
|
@ -161,32 +161,31 @@ proc poseidon*(data: seq[seq[byte]]): RlnRelayResult[array[32, byte]] =
|
||||||
|
|
||||||
return ok(output)
|
return ok(output)
|
||||||
|
|
||||||
when defined(rln_v2):
|
proc toLeaf*(rateCommitment: RateCommitment): RlnRelayResult[seq[byte]] =
|
||||||
proc toLeaf*(rateCommitment: RateCommitment): RlnRelayResult[seq[byte]] =
|
let idCommitment = rateCommitment.idCommitment
|
||||||
let idCommitment = rateCommitment.idCommitment
|
var userMessageLimit: array[32, byte]
|
||||||
var userMessageLimit: array[32, byte]
|
try:
|
||||||
try:
|
discard userMessageLimit.copyFrom(
|
||||||
discard userMessageLimit.copyFrom(
|
toBytes(rateCommitment.userMessageLimit, Endianness.littleEndian)
|
||||||
toBytes(rateCommitment.userMessageLimit, Endianness.littleEndian)
|
)
|
||||||
)
|
except CatchableError:
|
||||||
except CatchableError:
|
return err(
|
||||||
return err(
|
"could not convert the user message limit to bytes: " & getCurrentExceptionMsg()
|
||||||
"could not convert the user message limit to bytes: " & getCurrentExceptionMsg()
|
)
|
||||||
)
|
let leaf = poseidon(@[@idCommitment, @userMessageLimit]).valueOr:
|
||||||
let leaf = poseidon(@[@idCommitment, @userMessageLimit]).valueOr:
|
return err("could not convert the rate commitment to a leaf")
|
||||||
return err("could not convert the rate commitment to a leaf")
|
var retLeaf = newSeq[byte](leaf.len)
|
||||||
var retLeaf = newSeq[byte](leaf.len)
|
for i in 0 ..< leaf.len:
|
||||||
for i in 0 ..< leaf.len:
|
retLeaf[i] = leaf[i]
|
||||||
retLeaf[i] = leaf[i]
|
return ok(retLeaf)
|
||||||
return ok(retLeaf)
|
|
||||||
|
|
||||||
proc toLeaves*(rateCommitments: seq[RateCommitment]): RlnRelayResult[seq[seq[byte]]] =
|
proc toLeaves*(rateCommitments: seq[RateCommitment]): RlnRelayResult[seq[seq[byte]]] =
|
||||||
var leaves = newSeq[seq[byte]]()
|
var leaves = newSeq[seq[byte]]()
|
||||||
for rateCommitment in rateCommitments:
|
for rateCommitment in rateCommitments:
|
||||||
let leaf = toLeaf(rateCommitment).valueOr:
|
let leaf = toLeaf(rateCommitment).valueOr:
|
||||||
return err("could not convert the rate commitment to a leaf: " & $error)
|
return err("could not convert the rate commitment to a leaf: " & $error)
|
||||||
leaves.add(leaf)
|
leaves.add(leaf)
|
||||||
return ok(leaves)
|
return ok(leaves)
|
||||||
|
|
||||||
proc extractMetadata*(proof: RateLimitProof): RlnRelayResult[ProofMetadata] =
|
proc extractMetadata*(proof: RateLimitProof): RlnRelayResult[ProofMetadata] =
|
||||||
let externalNullifier = poseidon(@[@(proof.epoch), @(proof.rlnIdentifier)]).valueOr:
|
let externalNullifier = poseidon(@[@(proof.epoch), @(proof.rlnIdentifier)]).valueOr:
|
||||||
|
@ -200,151 +199,81 @@ proc extractMetadata*(proof: RateLimitProof): RlnRelayResult[ProofMetadata] =
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
when defined(rln_v2):
|
proc proofGen*(
|
||||||
proc proofGen*(
|
rlnInstance: ptr RLN,
|
||||||
rlnInstance: ptr RLN,
|
data: openArray[byte],
|
||||||
data: openArray[byte],
|
membership: IdentityCredential,
|
||||||
membership: IdentityCredential,
|
userMessageLimit: UserMessageLimit,
|
||||||
userMessageLimit: UserMessageLimit,
|
messageId: MessageId,
|
||||||
messageId: MessageId,
|
index: MembershipIndex,
|
||||||
index: MembershipIndex,
|
epoch: Epoch,
|
||||||
epoch: Epoch,
|
rlnIdentifier = DefaultRlnIdentifier,
|
||||||
rlnIdentifier = DefaultRlnIdentifier,
|
): RateLimitProofResult =
|
||||||
): RateLimitProofResult =
|
# obtain the external nullifier
|
||||||
# obtain the external nullifier
|
let externalNullifierRes = poseidon(@[@(epoch), @(rlnIdentifier)])
|
||||||
let externalNullifierRes = poseidon(@[@(epoch), @(rlnIdentifier)])
|
|
||||||
|
|
||||||
if externalNullifierRes.isErr():
|
if externalNullifierRes.isErr():
|
||||||
return err("could not construct the external nullifier")
|
return err("could not construct the external nullifier")
|
||||||
|
|
||||||
# serialize inputs
|
# serialize inputs
|
||||||
let serializedInputs = serialize(
|
let serializedInputs = serialize(
|
||||||
idSecretHash = membership.idSecretHash,
|
idSecretHash = membership.idSecretHash,
|
||||||
memIndex = index,
|
memIndex = index,
|
||||||
userMessageLimit = userMessageLimit,
|
userMessageLimit = userMessageLimit,
|
||||||
messageId = messageId,
|
messageId = messageId,
|
||||||
externalNullifier = externalNullifierRes.get(),
|
externalNullifier = externalNullifierRes.get(),
|
||||||
msg = data,
|
msg = data,
|
||||||
)
|
)
|
||||||
var inputBuffer = toBuffer(serializedInputs)
|
var inputBuffer = toBuffer(serializedInputs)
|
||||||
|
|
||||||
debug "input buffer ", inputBuffer = repr(inputBuffer)
|
debug "input buffer ", inputBuffer = repr(inputBuffer)
|
||||||
|
|
||||||
# generate the proof
|
# generate the proof
|
||||||
var proof: Buffer
|
var proof: Buffer
|
||||||
let proofIsSuccessful = generate_proof(rlnInstance, addr inputBuffer, addr proof)
|
let proofIsSuccessful = generate_proof(rlnInstance, addr inputBuffer, addr proof)
|
||||||
# check whether the generate_proof call is done successfully
|
# check whether the generate_proof call is done successfully
|
||||||
if not proofIsSuccessful:
|
if not proofIsSuccessful:
|
||||||
return err("could not generate the proof")
|
return err("could not generate the proof")
|
||||||
|
|
||||||
var proofValue = cast[ptr array[320, byte]](proof.`ptr`)
|
var proofValue = cast[ptr array[320, byte]](proof.`ptr`)
|
||||||
let proofBytes: array[320, byte] = proofValue[]
|
let proofBytes: array[320, byte] = proofValue[]
|
||||||
debug "proof content", proofHex = proofValue[].toHex
|
debug "proof content", proofHex = proofValue[].toHex
|
||||||
|
|
||||||
## parse the proof as [ proof<128> | root<32> | external_nullifier<32> | share_x<32> | share_y<32> | nullifier<32> ]
|
## parse the proof as [ proof<128> | root<32> | external_nullifier<32> | share_x<32> | share_y<32> | nullifier<32> ]
|
||||||
|
|
||||||
let
|
let
|
||||||
proofOffset = 128
|
proofOffset = 128
|
||||||
rootOffset = proofOffset + 32
|
rootOffset = proofOffset + 32
|
||||||
externalNullifierOffset = rootOffset + 32
|
externalNullifierOffset = rootOffset + 32
|
||||||
shareXOffset = externalNullifierOffset + 32
|
shareXOffset = externalNullifierOffset + 32
|
||||||
shareYOffset = shareXOffset + 32
|
shareYOffset = shareXOffset + 32
|
||||||
nullifierOffset = shareYOffset + 32
|
nullifierOffset = shareYOffset + 32
|
||||||
|
|
||||||
var
|
var
|
||||||
zkproof: ZKSNARK
|
zkproof: ZKSNARK
|
||||||
proofRoot, shareX, shareY: MerkleNode
|
proofRoot, shareX, shareY: MerkleNode
|
||||||
externalNullifier: ExternalNullifier
|
externalNullifier: ExternalNullifier
|
||||||
nullifier: Nullifier
|
nullifier: Nullifier
|
||||||
|
|
||||||
discard zkproof.copyFrom(proofBytes[0 .. proofOffset - 1])
|
discard zkproof.copyFrom(proofBytes[0 .. proofOffset - 1])
|
||||||
discard proofRoot.copyFrom(proofBytes[proofOffset .. rootOffset - 1])
|
discard proofRoot.copyFrom(proofBytes[proofOffset .. rootOffset - 1])
|
||||||
discard
|
discard
|
||||||
externalNullifier.copyFrom(proofBytes[rootOffset .. externalNullifierOffset - 1])
|
externalNullifier.copyFrom(proofBytes[rootOffset .. externalNullifierOffset - 1])
|
||||||
discard shareX.copyFrom(proofBytes[externalNullifierOffset .. shareXOffset - 1])
|
discard shareX.copyFrom(proofBytes[externalNullifierOffset .. shareXOffset - 1])
|
||||||
discard shareY.copyFrom(proofBytes[shareXOffset .. shareYOffset - 1])
|
discard shareY.copyFrom(proofBytes[shareXOffset .. shareYOffset - 1])
|
||||||
discard nullifier.copyFrom(proofBytes[shareYOffset .. nullifierOffset - 1])
|
discard nullifier.copyFrom(proofBytes[shareYOffset .. nullifierOffset - 1])
|
||||||
|
|
||||||
let output = RateLimitProof(
|
let output = RateLimitProof(
|
||||||
proof: zkproof,
|
proof: zkproof,
|
||||||
merkleRoot: proofRoot,
|
merkleRoot: proofRoot,
|
||||||
externalNullifier: externalNullifier,
|
externalNullifier: externalNullifier,
|
||||||
epoch: epoch,
|
epoch: epoch,
|
||||||
rlnIdentifier: rlnIdentifier,
|
rlnIdentifier: rlnIdentifier,
|
||||||
shareX: shareX,
|
shareX: shareX,
|
||||||
shareY: shareY,
|
shareY: shareY,
|
||||||
nullifier: nullifier,
|
nullifier: nullifier,
|
||||||
)
|
)
|
||||||
return ok(output)
|
return ok(output)
|
||||||
|
|
||||||
else:
|
|
||||||
proc proofGen*(
|
|
||||||
rlnInstance: ptr RLN,
|
|
||||||
data: openArray[byte],
|
|
||||||
memKeys: IdentityCredential,
|
|
||||||
memIndex: MembershipIndex,
|
|
||||||
epoch: Epoch,
|
|
||||||
): RateLimitProofResult =
|
|
||||||
# serialize inputs
|
|
||||||
let serializedInputs = serialize(
|
|
||||||
idSecretHash = memKeys.idSecretHash,
|
|
||||||
memIndex = memIndex,
|
|
||||||
epoch = epoch,
|
|
||||||
msg = data,
|
|
||||||
)
|
|
||||||
var inputBuffer = toBuffer(serializedInputs)
|
|
||||||
|
|
||||||
debug "input buffer ", inputBuffer = repr(inputBuffer)
|
|
||||||
|
|
||||||
# generate the proof
|
|
||||||
var proof: Buffer
|
|
||||||
let proofIsSuccessful = generate_proof(rlnInstance, addr inputBuffer, addr proof)
|
|
||||||
# check whether the generate_proof call is done successfully
|
|
||||||
if not proofIsSuccessful:
|
|
||||||
return err("could not generate the proof")
|
|
||||||
|
|
||||||
var proofValue = cast[ptr array[320, byte]](proof.`ptr`)
|
|
||||||
let proofBytes: array[320, byte] = proofValue[]
|
|
||||||
debug "proof content", proofHex = proofValue[].toHex
|
|
||||||
|
|
||||||
## parse the proof as [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> ]
|
|
||||||
|
|
||||||
let
|
|
||||||
proofOffset = 128
|
|
||||||
rootOffset = proofOffset + 32
|
|
||||||
epochOffset = rootOffset + 32
|
|
||||||
shareXOffset = epochOffset + 32
|
|
||||||
shareYOffset = shareXOffset + 32
|
|
||||||
nullifierOffset = shareYOffset + 32
|
|
||||||
rlnIdentifierOffset = nullifierOffset + 32
|
|
||||||
|
|
||||||
var
|
|
||||||
zkproof: ZKSNARK
|
|
||||||
proofRoot, shareX, shareY: MerkleNode
|
|
||||||
epoch: Epoch
|
|
||||||
nullifier: Nullifier
|
|
||||||
rlnIdentifier: RlnIdentifier
|
|
||||||
|
|
||||||
discard zkproof.copyFrom(proofBytes[0 .. proofOffset - 1])
|
|
||||||
discard proofRoot.copyFrom(proofBytes[proofOffset .. rootOffset - 1])
|
|
||||||
discard epoch.copyFrom(proofBytes[rootOffset .. epochOffset - 1])
|
|
||||||
discard shareX.copyFrom(proofBytes[epochOffset .. shareXOffset - 1])
|
|
||||||
discard shareY.copyFrom(proofBytes[shareXOffset .. shareYOffset - 1])
|
|
||||||
discard nullifier.copyFrom(proofBytes[shareYOffset .. nullifierOffset - 1])
|
|
||||||
discard
|
|
||||||
rlnIdentifier.copyFrom(proofBytes[nullifierOffset .. rlnIdentifierOffset - 1])
|
|
||||||
|
|
||||||
let output = RateLimitProof(
|
|
||||||
proof: zkproof,
|
|
||||||
merkleRoot: proofRoot,
|
|
||||||
epoch: epoch,
|
|
||||||
shareX: shareX,
|
|
||||||
shareY: shareY,
|
|
||||||
nullifier: nullifier,
|
|
||||||
rlnIdentifier: rlnIdentifier,
|
|
||||||
)
|
|
||||||
|
|
||||||
return ok(output)
|
|
||||||
|
|
||||||
# validRoots should contain a sequence of roots in the acceptable windows.
|
# validRoots should contain a sequence of roots in the acceptable windows.
|
||||||
# As default, it is set to an empty sequence of roots. This implies that the validity check for the proof's root is skipped
|
# As default, it is set to an empty sequence of roots. This implies that the validity check for the proof's root is skipped
|
||||||
|
@ -357,14 +286,13 @@ proc proofVerify*(
|
||||||
## verifies the proof, returns an error if the proof verification fails
|
## verifies the proof, returns an error if the proof verification fails
|
||||||
## returns true if the proof is valid
|
## returns true if the proof is valid
|
||||||
var normalizedProof = proof
|
var normalizedProof = proof
|
||||||
when defined(rln_v2):
|
# when we do this, we ensure that we compute the proof for the derived value
|
||||||
# when we do this, we ensure that we compute the proof for the derived value
|
# of the externalNullifier. The proof verification will fail if a malicious peer
|
||||||
# of the externalNullifier. The proof verification will fail if a malicious peer
|
# attaches invalid epoch+rlnidentifier pair
|
||||||
# attaches invalid epoch+rlnidentifier pair
|
normalizedProof.externalNullifier = poseidon(
|
||||||
normalizedProof.externalNullifier = poseidon(
|
@[@(proof.epoch), @(proof.rlnIdentifier)]
|
||||||
@[@(proof.epoch), @(proof.rlnIdentifier)]
|
).valueOr:
|
||||||
).valueOr:
|
return err("could not construct the external nullifier")
|
||||||
return err("could not construct the external nullifier")
|
|
||||||
var
|
var
|
||||||
proofBytes = serialize(normalizedProof, data)
|
proofBytes = serialize(normalizedProof, data)
|
||||||
proofBuffer = proofBytes.toBuffer()
|
proofBuffer = proofBytes.toBuffer()
|
||||||
|
|
|
@ -23,10 +23,8 @@ import
|
||||||
./conversion_utils,
|
./conversion_utils,
|
||||||
./constants,
|
./constants,
|
||||||
./protocol_types,
|
./protocol_types,
|
||||||
./protocol_metrics
|
./protocol_metrics,
|
||||||
|
./nonce_manager
|
||||||
when defined(rln_v2):
|
|
||||||
import ./nonce_manager
|
|
||||||
|
|
||||||
import
|
import
|
||||||
../common/error_handling,
|
../common/error_handling,
|
||||||
|
@ -47,8 +45,7 @@ type WakuRlnConfig* = object
|
||||||
rlnRelayTreePath*: string
|
rlnRelayTreePath*: string
|
||||||
rlnEpochSizeSec*: uint64
|
rlnEpochSizeSec*: uint64
|
||||||
onFatalErrorAction*: OnFatalErrorHandler
|
onFatalErrorAction*: OnFatalErrorHandler
|
||||||
when defined(rln_v2):
|
rlnRelayUserMessageLimit*: uint64
|
||||||
rlnRelayUserMessageLimit*: uint64
|
|
||||||
|
|
||||||
proc createMembershipList*(
|
proc createMembershipList*(
|
||||||
rln: ptr RLN, n: int
|
rln: ptr RLN, n: int
|
||||||
|
@ -93,8 +90,7 @@ type WakuRLNRelay* = ref object of RootObj
|
||||||
rlnMaxEpochGap*: uint64
|
rlnMaxEpochGap*: uint64
|
||||||
groupManager*: GroupManager
|
groupManager*: GroupManager
|
||||||
onFatalErrorAction*: OnFatalErrorHandler
|
onFatalErrorAction*: OnFatalErrorHandler
|
||||||
when defined(rln_v2):
|
nonceManager*: NonceManager
|
||||||
nonceManager*: NonceManager
|
|
||||||
|
|
||||||
proc calcEpoch*(rlnPeer: WakuRLNRelay, t: float64): Epoch =
|
proc calcEpoch*(rlnPeer: WakuRLNRelay, t: float64): Epoch =
|
||||||
## gets time `t` as `flaot64` with subseconds resolution in the fractional part
|
## gets time `t` as `flaot64` with subseconds resolution in the fractional part
|
||||||
|
@ -307,14 +303,11 @@ proc appendRLNProof*(
|
||||||
let input = msg.toRLNSignal()
|
let input = msg.toRLNSignal()
|
||||||
let epoch = rlnPeer.calcEpoch(senderEpochTime)
|
let epoch = rlnPeer.calcEpoch(senderEpochTime)
|
||||||
|
|
||||||
when defined(rln_v2):
|
let nonce = rlnPeer.nonceManager.getNonce().valueOr:
|
||||||
let nonce = rlnPeer.nonceManager.getNonce().valueOr:
|
return err("could not get new message id to generate an rln proof: " & $error)
|
||||||
return err("could not get new message id to generate an rln proof: " & $error)
|
let proof = rlnPeer.groupManager.generateProof(input, epoch, nonce).valueOr:
|
||||||
let proof = rlnPeer.groupManager.generateProof(input, epoch, nonce).valueOr:
|
return err("could not generate rln-v2 proof: " & $error)
|
||||||
return err("could not generate rln-v2 proof: " & $error)
|
|
||||||
else:
|
|
||||||
let proof = rlnPeer.groupManager.generateProof(input, epoch).valueOr:
|
|
||||||
return err("could not generate rln proof: " & $error)
|
|
||||||
|
|
||||||
msg.proof = proof.encode().buffer
|
msg.proof = proof.encode().buffer
|
||||||
return ok()
|
return ok()
|
||||||
|
@ -445,28 +438,18 @@ proc mount(
|
||||||
(await groupManager.startGroupSync()).isOkOr:
|
(await groupManager.startGroupSync()).isOkOr:
|
||||||
return err("could not start the group sync: " & $error)
|
return err("could not start the group sync: " & $error)
|
||||||
|
|
||||||
when defined(rln_v2):
|
return ok(
|
||||||
return ok(
|
WakuRLNRelay(
|
||||||
WakuRLNRelay(
|
groupManager: groupManager,
|
||||||
groupManager: groupManager,
|
nonceManager:
|
||||||
nonceManager:
|
NonceManager.init(conf.rlnRelayUserMessageLimit, conf.rlnEpochSizeSec.float),
|
||||||
NonceManager.init(conf.rlnRelayUserMessageLimit, conf.rlnEpochSizeSec.float),
|
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
||||||
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
rlnMaxEpochGap:
|
||||||
rlnMaxEpochGap:
|
max(uint64(MaxClockGapSeconds / float64(conf.rlnEpochSizeSec)), 1),
|
||||||
max(uint64(MaxClockGapSeconds / float64(conf.rlnEpochSizeSec)), 1),
|
onFatalErrorAction: conf.onFatalErrorAction,
|
||||||
onFatalErrorAction: conf.onFatalErrorAction,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return ok(
|
|
||||||
WakuRLNRelay(
|
|
||||||
groupManager: groupManager,
|
|
||||||
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
|
||||||
rlnMaxEpochGap:
|
|
||||||
max(uint64(MaxClockGapSeconds / float64(conf.rlnEpochSizeSec)), 1),
|
|
||||||
onFatalErrorAction: conf.onFatalErrorAction,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
proc isReady*(rlnPeer: WakuRLNRelay): Future[bool] {.async: (raises: [Exception]).} =
|
proc isReady*(rlnPeer: WakuRLNRelay): Future[bool] {.async: (raises: [Exception]).} =
|
||||||
## returns true if the rln-relay protocol is ready to relay messages
|
## returns true if the rln-relay protocol is ready to relay messages
|
||||||
|
|
Loading…
Reference in New Issue