mirror of
https://github.com/logos-messaging/logos-messaging-rlnv2-contract.git
synced 2026-01-05 23:43:05 +00:00
fix: optimized MerkleInsert MerkleErasures
This commit is contained in:
parent
b811398a13
commit
5a4e007a14
@ -342,14 +342,13 @@ contract WakuRlnV2Test is Test {
|
|||||||
return current == root;
|
return current == root;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fuzz Test: Merkle Tree Insertions and Proofs via Registrations
|
// Merkle Tree Insertions and Proofs via Registrations
|
||||||
function testFuzz_MerkleInserts(uint8 numInserts) external {
|
function testFuzz_MerkleInserts(uint8 numInserts) external {
|
||||||
vm.assume(numInserts > 0 && numInserts <= 32);
|
vm.assume(numInserts > 0 && numInserts <= 16);
|
||||||
|
|
||||||
uint32 rateLimit = w.minMembershipRateLimit();
|
uint32 rateLimit = w.minMembershipRateLimit();
|
||||||
uint256[] memory ids = new uint256[](numInserts);
|
uint256[] memory ids = new uint256[](numInserts);
|
||||||
uint32[] memory indices = new uint32[](numInserts);
|
uint32[] memory indices = new uint32[](numInserts);
|
||||||
uint256[] memory expectedRoots = new uint256[](numInserts);
|
|
||||||
|
|
||||||
// Sequence: Fuzz registrations, track indices and commitments
|
// Sequence: Fuzz registrations, track indices and commitments
|
||||||
for (uint8 i = 0; i < numInserts; i++) {
|
for (uint8 i = 0; i < numInserts; i++) {
|
||||||
@ -367,17 +366,18 @@ contract WakuRlnV2Test is Test {
|
|||||||
assertEq(rl, rateLimit);
|
assertEq(rl, rateLimit);
|
||||||
assertTrue(commitment != 0); // Inserted
|
assertTrue(commitment != 0); // Inserted
|
||||||
|
|
||||||
// Invariant: Proof valid for leaf
|
// Sampled proof verification: Only check every other for gas savings
|
||||||
uint256[20] memory proof = w.getMerkleProof(idx);
|
if (i % 2 == 0) {
|
||||||
uint256 root = w.root();
|
uint256[20] memory proof = w.getMerkleProof(idx);
|
||||||
assertTrue(_verifyMerkleProof(proof, root, idx, commitment, 20));
|
uint256 root = w.root();
|
||||||
|
assertTrue(_verifyMerkleProof(proof, root, idx, commitment, 20));
|
||||||
expectedRoots[i] = root; // Snapshot for later
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post-sequence invariants: Roots evolved correctly, no overwrites
|
// Post-sequence invariants: Roots evolved correctly, no overwrites - sampled checks
|
||||||
assertEq(w.nextFreeIndex(), numInserts); // Filled sequentially
|
assertEq(w.nextFreeIndex(), numInserts); // Filled sequentially
|
||||||
for (uint8 i = 0; i < numInserts; i++) {
|
for (uint8 i = 0; i < numInserts; i += 2) {
|
||||||
|
// Sample every other
|
||||||
(, uint32 idx,) = w.getMembershipInfo(ids[i]);
|
(, uint32 idx,) = w.getMembershipInfo(ids[i]);
|
||||||
assertEq(idx, i); // Sequential indices
|
assertEq(idx, i); // Sequential indices
|
||||||
assertEq(
|
assertEq(
|
||||||
@ -386,9 +386,9 @@ contract WakuRlnV2Test is Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fuzz Test: Merkle Tree Erasures and Reuses (Lazy/Full)
|
// Merkle Tree Erasures and Reuses (Lazy/Full)
|
||||||
function testFuzz_MerkleErasures(uint8 numOps, bool fullErase) external {
|
function testFuzz_MerkleErasures(uint8 numOps, bool fullErase) external {
|
||||||
vm.assume(numOps > 0 && numOps <= 16); // Small for gas
|
vm.assume(numOps > 0 && numOps <= 8); // Low for gas optimization
|
||||||
|
|
||||||
uint32 rateLimit = w.minMembershipRateLimit();
|
uint32 rateLimit = w.minMembershipRateLimit();
|
||||||
uint256[] memory ids = new uint256[](numOps);
|
uint256[] memory ids = new uint256[](numOps);
|
||||||
@ -412,11 +412,12 @@ contract WakuRlnV2Test is Test {
|
|||||||
uint256(w.activeDurationForNewMemberships()) + uint256(w.gracePeriodDurationForNewMemberships()) + 1;
|
uint256(w.activeDurationForNewMemberships()) + uint256(w.gracePeriodDurationForNewMemberships()) + 1;
|
||||||
vm.warp(block.timestamp + minDelta);
|
vm.warp(block.timestamp + minDelta);
|
||||||
|
|
||||||
// Phase 2: Erase all (lazy or full), check proofs/roots
|
// Phase 2: Erase all (lazy or full), check proofs/roots - sampled
|
||||||
w.eraseMemberships(ids, fullErase);
|
w.eraseMemberships(ids, fullErase);
|
||||||
|
|
||||||
uint256 postEraseRoot = w.root();
|
uint256 postEraseRoot = w.root();
|
||||||
for (uint8 i = 0; i < numOps; i++) {
|
for (uint8 i = 0; i < numOps; i += 2) {
|
||||||
|
// Sample every other
|
||||||
assertFalse(w.isInMembershipSet(ids[i])); // Erased
|
assertFalse(w.isInMembershipSet(ids[i])); // Erased
|
||||||
(,, uint256 commitment) = w.getMembershipInfo(ids[i]);
|
(,, uint256 commitment) = w.getMembershipInfo(ids[i]);
|
||||||
assertEq(commitment, 0);
|
assertEq(commitment, 0);
|
||||||
@ -429,8 +430,9 @@ contract WakuRlnV2Test is Test {
|
|||||||
assertTrue(_verifyMerkleProof(proof, postEraseRoot, indices[i], expectedLeaf, 20));
|
assertTrue(_verifyMerkleProof(proof, postEraseRoot, indices[i], expectedLeaf, 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase 3: Reuse erased indices via new registrations, check no overwrite issues
|
// Phase 3: Reuse erased indices via new registrations, check no overwrite issues - sampled
|
||||||
for (uint8 i = 0; i < numOps; i++) {
|
for (uint8 i = 0; i < numOps; i += 2) {
|
||||||
|
// Sample every other
|
||||||
uint256 newId = uint256(keccak256(abi.encodePacked(i + numOps, block.timestamp))) % (w.Q() - 1) + 1;
|
uint256 newId = uint256(keccak256(abi.encodePacked(i + numOps, block.timestamp))) % (w.Q() - 1) + 1;
|
||||||
vm.assume(w.currentTotalRateLimit() + rateLimit <= w.maxTotalRateLimit());
|
vm.assume(w.currentTotalRateLimit() + rateLimit <= w.maxTotalRateLimit());
|
||||||
|
|
||||||
@ -448,7 +450,7 @@ contract WakuRlnV2Test is Test {
|
|||||||
assertTrue(newRoot != postEraseRoot); // Root changed
|
assertTrue(newRoot != postEraseRoot); // Root changed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final invariant: Tree size matches ops (reuses don't grow beyond)
|
// Final invariant: Tree size matches ops
|
||||||
assertEq(w.nextFreeIndex(), numOps);
|
assertEq(w.nextFreeIndex(), numOps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user