@waku/rln
Version:
RLN (Rate Limiting Nullifier) implementation for Waku
75 lines • 2.73 kB
JavaScript
class RootPerBlock {
root;
blockNumber;
constructor(root, blockNumber) {
this.root = root;
this.blockNumber = blockNumber;
}
}
const maxBufferSize = 20;
export class MerkleRootTracker {
acceptableRootWindowSize;
validMerkleRoots = new Array();
merkleRootBuffer = new Array();
constructor(acceptableRootWindowSize, initialRoot) {
this.acceptableRootWindowSize = acceptableRootWindowSize;
this.pushRoot(0, initialRoot);
}
backFill(fromBlockNumber) {
if (this.validMerkleRoots.length == 0)
return;
let numBlocks = 0;
for (let i = this.validMerkleRoots.length - 1; i >= 0; i--) {
if (this.validMerkleRoots[i].blockNumber >= fromBlockNumber) {
numBlocks++;
}
}
if (numBlocks == 0)
return;
const olderBlock = fromBlockNumber < this.validMerkleRoots[0].blockNumber;
// Remove last roots
let rootsToPop = numBlocks;
if (this.validMerkleRoots.length < rootsToPop) {
rootsToPop = this.validMerkleRoots.length;
}
this.validMerkleRoots = this.validMerkleRoots.slice(0, this.validMerkleRoots.length - rootsToPop);
if (this.merkleRootBuffer.length == 0)
return;
if (olderBlock) {
const idx = this.merkleRootBuffer.findIndex((x) => x.blockNumber == fromBlockNumber);
if (idx > -1) {
this.merkleRootBuffer = this.merkleRootBuffer.slice(0, idx);
}
}
// Backfill the tree's acceptable roots
let rootsToRestore = this.acceptableRootWindowSize - this.validMerkleRoots.length;
if (this.merkleRootBuffer.length < rootsToRestore) {
rootsToRestore = this.merkleRootBuffer.length;
}
for (let i = 0; i < rootsToRestore; i++) {
const x = this.merkleRootBuffer.pop();
if (x)
this.validMerkleRoots.unshift(x);
}
}
pushRoot(blockNumber, root) {
this.validMerkleRoots.push(new RootPerBlock(root, blockNumber));
// Maintain valid merkle root window
if (this.validMerkleRoots.length > this.acceptableRootWindowSize) {
const x = this.validMerkleRoots.shift();
if (x)
this.merkleRootBuffer.push(x);
}
// Maintain merkle root buffer
if (this.merkleRootBuffer.length > maxBufferSize) {
this.merkleRootBuffer.shift();
}
}
roots() {
return this.validMerkleRoots.map((x) => x.root);
}
buffer() {
return this.merkleRootBuffer.map((x) => x.root);
}
}
//# sourceMappingURL=root_tracker.js.map