Tanya S d3cf24f7a2 feat: Update implementation for new contract abi (#3390)
* update RLN contract abi functions and procs

* Clean up debugging lines

* Use more descriptive object field names for MembershipInfo

* Fix formatting

* fix group_manager after rebase to use new contract method sig

* Fix linting for group_manager.nim

* Test idcommitment to BE and debug logs

* Improve IdCommitment logging

* Update all keystore credentials to use BE format

* Add workaround for groupmanager web3 eth_call

* Add await to sendEthCallWithChainID

* Add error handling for failed eth_call

* Improve error handling for eth_call workaround

* Revert keystore credentials back to using LE

* Update toRateCommitment proc to use LE instead of BE

* Add IdCommitment to calldata as BE

* feat: Update rln contract deployment and tests (#3408)

* update RLN contract abi functions and procs

* update waku-rlnv2-contract submodule commit to latest

* Add RlnV2 contract deployment using forge scripts

* Clean up output of forge script command, debug logs to trace, warn to error

* Move TestToken deployment to own proc

* first implementation of token minting and approval

* Update rln tests with usermessagelimit new minimum

* Clean up code and error handling

* Rework RLN tests WIP

* Fix RLN test for new contract

* RLN Tests updated

* Fix formatting

* Improve error logs

* Fix error message formatting

* Fix linting

* Add pnpm dependency installation for rln tests

* Update test dependencies in makefile

* Minor updates, error messages etc

* Code cleanup and change some debug logging to trace

* Improve handling of Result return value

* Use absolute path for waku-rlnv2-contract

* Simplify token approval and balance check

* Remove unused Anvil options

* Add additional checks for stopAnvil process

* Fix anvil process call to null

* Add lock to tests for rln_group_manager_onchain

* Debug for forge command

* Verify paths

* Install pnpm as global

* Cleanup anvil running procs

* Add check before installing anvil

* CLean up onchain group_manager

* Add proc to setup environment for contract deployer

* Refactoring and improved error handling

* Fix anvil install directory string

* Fix linting in test_range_split

* Add const for the contract address length

* Add separate checks for why Approval transaction fails

* Update RLN contract address and chainID for TWN
2025-06-20 11:46:08 +02:00

243 lines
7.4 KiB
Nim
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import unittest, nimcrypto, std/sequtils, results
import ../../waku/waku_store_sync/[reconciliation, common]
import ../../waku/waku_store_sync/storage/seq_storage
import ../../waku/waku_core/message/digest
proc toDigest(s: string): WakuMessageHash =
let d = nimcrypto.keccak256.digest((s & "").toOpenArrayByte(0, (s.len - 1)))
var res: WakuMessageHash
for i in 0 .. 31:
res[i] = d.data[i]
return res
proc `..`(a, b: SyncID): Slice[SyncID] =
Slice[SyncID](a: a, b: b)
suite "Waku Sync reconciliation":
test "fan-out: eight fingerprint sub-ranges for large slice":
const N = 2_048
const mismatchI = 70
let local = SeqStorage.new(@[])
let remote = SeqStorage.new(@[])
var baseHashMismatch: WakuMessageHash
var remoteHashMismatch: WakuMessageHash
for i in 0 ..< N:
let ts = 1000 + i
let hashLocal = toDigest("msg" & $i)
local.insert(SyncID(time: ts, hash: hashLocal)).isOkOr:
assert false, "failed to insert hash: " & $error
var hashRemote = hashLocal
if i == mismatchI:
baseHashMismatch = hashLocal
remoteHashMismatch = toDigest("msg" & $i & "_x")
hashRemote = remoteHashMismatch
remote.insert(SyncID(time: ts, hash: hashRemote)).isOkOr:
assert false, "failed to insert hash: " & $error
var z: WakuMessageHash
let whole = SyncID(time: 1000, hash: z) .. SyncID(time: 1000 + N - 1, hash: z)
check local.computeFingerprint(whole) != remote.computeFingerprint(whole)
let remoteFp = remote.computeFingerprint(whole)
let payload = RangesData(
cluster: 0,
shards: @[0],
ranges: @[(whole, RangeType.Fingerprint)],
fingerprints: @[remoteFp],
itemSets: @[],
)
var toSend, toRecv: seq[WakuMessageHash]
let reply = local.processPayload(payload, toSend, toRecv)
check reply.ranges.len == 8
check reply.ranges.allIt(it[1] == RangeType.Fingerprint)
check reply.itemSets.len == 0
check reply.fingerprints.len == 8
let mismTime = 1000 + mismatchI
var covered = false
for (slc, _) in reply.ranges:
if mismTime >= slc.a.time and mismTime <= slc.b.time:
covered = true
break
check covered
check toSend.len == 0
check toRecv.len == 0
test "splits mismatched fingerprint into two sub-ranges then item-set":
const threshold = 4
const partitions = 2
let local = SeqStorage.new(@[], threshold = threshold, partitions = partitions)
let remote = SeqStorage.new(@[], threshold = threshold, partitions = partitions)
var mismatchHash: WakuMessageHash
for i in 0 ..< 8:
let t = 1000 + i
let baseHash = toDigest("msg" & $i)
var localHash = baseHash
var remoteHash = baseHash
if i == 3:
mismatchHash = toDigest("msg" & $i & "_x")
localHash = mismatchHash
discard local.insert (SyncID(time: t, hash: localHash))
discard remote.insert(SyncID(time: t, hash: remoteHash))
var zeroHash: WakuMessageHash
let wholeRange =
SyncID(time: 1000, hash: zeroHash) .. SyncID(time: 1007, hash: zeroHash)
var toSend, toRecv: seq[WakuMessageHash]
let payload = RangesData(
cluster: 0,
shards: @[0],
ranges: @[(wholeRange, RangeType.Fingerprint)],
fingerprints: @[remote.computeFingerprint(wholeRange)],
itemSets: @[],
)
let reply = local.processPayload(payload, toSend, toRecv)
check reply.ranges.len == partitions
check reply.itemSets.len == partitions
check reply.itemSets.anyIt(
it.elements.anyIt(it.hash == mismatchHash and it.time == 1003)
)
test "second round when N =2048 & local ":
const N = 2_048
const mismatchI = 70
let local = SeqStorage.new(@[])
let remote = SeqStorage.new(@[])
var baseHashMismatch, remoteHashMismatch: WakuMessageHash
for i in 0 ..< N:
let ts = 1000 + i
let hashLocal = toDigest("msg" & $i)
local.insert(SyncID(time: ts, hash: hashLocal)).isOkOr:
assert false, "failed to insert hash: " & $error
var hashRemote = hashLocal
if i == mismatchI:
baseHashMismatch = hashLocal
remoteHashMismatch = toDigest("msg" & $i & "_x")
hashRemote = remoteHashMismatch
remote.insert(SyncID(time: ts, hash: hashRemote)).isOkOr:
assert false, "failed to insert hash: " & $error
var zero: WakuMessageHash
let sliceWhole =
SyncID(time: 1000, hash: zero) .. SyncID(time: 1000 + N - 1, hash: zero)
check local.computeFingerprint(sliceWhole) != remote.computeFingerprint(sliceWhole)
let payload1 = RangesData(
cluster: 0,
shards: @[0],
ranges: @[(sliceWhole, RangeType.Fingerprint)],
fingerprints: @[remote.computeFingerprint(sliceWhole)],
itemSets: @[],
)
var toSend, toRecv: seq[WakuMessageHash]
let reply1 = local.processPayload(payload1, toSend, toRecv)
check reply1.ranges.len == 8
check reply1.ranges.allIt(it[1] == RangeType.Fingerprint)
let mismTime = 1000 + mismatchI
var subSlice: Slice[SyncID]
for (sl, _) in reply1.ranges:
if mismTime >= sl.a.time and mismTime <= sl.b.time:
subSlice = sl
break
check subSlice.a.time != 0
let payload2 = RangesData(
cluster: 0,
shards: @[0],
ranges: @[(subSlice, RangeType.Fingerprint)],
fingerprints: @[remote.computeFingerprint(subSlice)],
itemSets: @[],
)
var toSend2, toRecv2: seq[WakuMessageHash]
let reply2 = local.processPayload(payload2, toSend2, toRecv2)
check reply2.ranges.len == 8
check reply2.ranges.allIt(it[1] == RangeType.ItemSet)
check reply2.itemSets.len == 8
var matchCount = 0
for iset in reply2.itemSets:
if iset.elements.anyIt(it.time == mismTime and it.hash == baseHashMismatch):
inc matchCount
check not iset.elements.anyIt(it.hash == remoteHashMismatch)
check matchCount == 1
check toSend2.len == 0
check toRecv2.len == 0
test "second-round payload remote":
let local = SeqStorage.new(@[])
let remote = SeqStorage.new(@[])
var baseHash: WakuMessageHash
var alteredHash: WakuMessageHash
for i in 0 ..< 8:
let ts = 1000 + i
let hashLocal = toDigest("msg" & $i)
local.insert(SyncID(time: ts, hash: hashLocal)).isOkOr:
assert false, "failed to insert hash: " & $error
var hashRemote = hashLocal
if i == 3:
baseHash = hashLocal
alteredHash = toDigest("msg" & $i & "_x")
hashRemote = alteredHash
remote.insert(SyncID(time: ts, hash: hashRemote)).isOkOr:
assert false, "failed to insert hash: " & $error
var zero: WakuMessageHash
let slice = SyncID(time: 1000, hash: zero) .. SyncID(time: 1007, hash: zero)
check local.computeFingerprint(slice) != remote.computeFingerprint(slice)
var toSend1, toRecv1: seq[WakuMessageHash]
let pay1 = RangesData(
cluster: 0,
shards: @[0],
ranges: @[(slice, RangeType.Fingerprint)],
fingerprints: @[remote.computeFingerprint(slice)],
itemSets: @[],
)
let rep1 = local.processPayload(pay1, toSend1, toRecv1)
check rep1.ranges.len == 1
check rep1.ranges[0][1] == RangeType.ItemSet
check toSend1.len == 0
check toRecv1.len == 0
var toSend2, toRecv2: seq[WakuMessageHash]
discard remote.processPayload(rep1, toSend2, toRecv2)
check toSend2.len == 1
check toSend2[0] == alteredHash
check toRecv2.len == 1
check toRecv2[0] == baseHash