UNPKG

@waku/rln

Version:

RLN (Rate Limiting Nullifier) implementation for Waku

75 lines 2.73 kB
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