@accumulators/merkle-mountain-range
Advanced tools
Comparing version 3.0.10 to 3.1.1
@@ -9,5 +9,5 @@ import { AppendResult, PeaksFormattingOptions, Proof, ProofOptions, PeaksOptions } from "./types"; | ||
append(value: string): Promise<AppendResult>; | ||
getProof(leafIndex: number, options?: ProofOptions): Promise<Proof>; | ||
getProofs(leavesIds: number[], options?: ProofOptions): Promise<Proof[]>; | ||
verifyProof(proof: Proof, leafValue: string, options?: ProofOptions): Promise<boolean>; | ||
getProof(elementIndex: number, options?: ProofOptions): Promise<Proof>; | ||
getProofs(elementsIds: number[], options?: ProofOptions): Promise<Proof[]>; | ||
verifyProof(proof: Proof, elementValue: string, options?: ProofOptions): Promise<boolean>; | ||
getPeaks(options?: PeaksOptions): Promise<string[]>; | ||
@@ -17,4 +17,5 @@ bagThePeaks(elementsCount?: number): Promise<string>; | ||
static mapLeafIndexToElementIndex(leafIndex: number): number; | ||
static mapElementIndexToLeafIndex(elementIndex: number): number; | ||
retrievePeaksHashes(peaksIdxs: number[], formattingOpts?: PeaksFormattingOptions): Promise<string[]>; | ||
clear(): Promise<void>; | ||
} |
@@ -26,3 +26,3 @@ "use strict"; | ||
let lastElementIdx = await this.elementsCount.increment(); | ||
const leafIndex = lastElementIdx; | ||
const leafElementIndex = lastElementIdx; | ||
await this.hashes.set(value, lastElementIdx); | ||
@@ -47,16 +47,16 @@ peaks.push(value); | ||
elementsCount: lastElementIdx, | ||
leafIndex, | ||
elementIndex: leafElementIndex, | ||
rootHash, | ||
}; | ||
} | ||
async getProof(leafIndex, options = {}) { | ||
if (leafIndex < 1) | ||
async getProof(elementIndex, options = {}) { | ||
if (elementIndex < 1) | ||
throw new Error("Index must be greater than 1"); | ||
const { elementsCount, formattingOpts } = options; | ||
const treeSize = elementsCount ?? (await this.elementsCount.get()); | ||
if (leafIndex > treeSize) | ||
if (elementIndex > treeSize) | ||
throw new Error("Index must be less than the tree tree size"); | ||
const peaks = (0, helpers_1.findPeaks)(treeSize); | ||
const siblings = []; | ||
let index = leafIndex; | ||
let index = elementIndex; | ||
while (!peaks.includes(index)) { | ||
@@ -75,4 +75,4 @@ const isRight = (0, helpers_1.getHeight)(index + 1) == (0, helpers_1.getHeight)(index) + 1; | ||
return { | ||
leafIndex: leafIndex, | ||
leafHash: await this.hashes.get(leafIndex), | ||
elementIndex, | ||
elementHash: await this.hashes.get(elementIndex), | ||
siblingsHashes, | ||
@@ -83,16 +83,16 @@ peaksHashes, | ||
} | ||
async getProofs(leavesIds, options = {}) { | ||
async getProofs(elementsIds, options = {}) { | ||
const { elementsCount, formattingOpts } = options; | ||
const treeSize = elementsCount ?? (await this.elementsCount.get()); | ||
leavesIds.forEach((leafIndex) => { | ||
if (leafIndex < 1) | ||
elementsIds.forEach((elementIndex) => { | ||
if (elementIndex < 1) | ||
throw new Error("Index must be greater than 1"); | ||
if (leafIndex > treeSize) | ||
if (elementIndex > treeSize) | ||
throw new Error("Index must be less than the tree tree size"); | ||
}); | ||
const peaks = (0, helpers_1.findPeaks)(treeSize); | ||
const siblingsPerLeaf = new Map(); | ||
for (const leafIndex of leavesIds) { | ||
const siblingsPerElement = new Map(); | ||
for (const elementIndex of elementsIds) { | ||
const siblings = []; | ||
let index = leafIndex; | ||
let index = elementIndex; | ||
while (!peaks.includes(index)) { | ||
@@ -104,10 +104,10 @@ const isRight = (0, helpers_1.getHeight)(index + 1) == (0, helpers_1.getHeight)(index) + 1; | ||
} | ||
siblingsPerLeaf.set(leafIndex, siblings); | ||
siblingsPerElement.set(elementIndex, siblings); | ||
} | ||
const peaksHashes = await this.retrievePeaksHashes(peaks, formattingOpts?.peaks); | ||
const allSiblingsHashes = await this.hashes.getMany(Array.from(siblingsPerLeaf.values()).flat()); | ||
const leafHashes = await this.hashes.getMany(leavesIds); | ||
const allSiblingsHashes = await this.hashes.getMany(Array.from(siblingsPerElement.values()).flat()); | ||
const elementHashes = await this.hashes.getMany(elementsIds); | ||
const proofs = []; | ||
for (const leafIndex of leavesIds) { | ||
const siblings = siblingsPerLeaf.get(leafIndex); | ||
for (const elementIndex of elementsIds) { | ||
const siblings = siblingsPerElement.get(elementIndex); | ||
let siblingsHashes = []; | ||
@@ -122,4 +122,4 @@ for (const sibling of siblings) { | ||
proofs.push({ | ||
leafIndex: leafIndex, | ||
leafHash: leafHashes.get(leafIndex.toString()), | ||
elementIndex, | ||
elementHash: elementHashes.get(elementIndex.toString()), | ||
siblingsHashes, | ||
@@ -132,3 +132,3 @@ peaksHashes, | ||
} | ||
async verifyProof(proof, leafValue, options = {}) { | ||
async verifyProof(proof, elementValue, options = {}) { | ||
const { elementsCount, formattingOpts } = options; | ||
@@ -143,11 +143,11 @@ const treeSize = elementsCount ?? (await this.elementsCount.get()); | ||
} | ||
let { leafIndex, siblingsHashes } = proof; | ||
if (leafIndex < 1) | ||
let { elementIndex, siblingsHashes } = proof; | ||
if (elementIndex < 1) | ||
throw new Error("Index must be greater than 1"); | ||
if (leafIndex > treeSize) | ||
if (elementIndex > treeSize) | ||
throw new Error("Index must be in the tree"); | ||
let hash = leafValue; | ||
let hash = elementValue; | ||
for (const proofHash of siblingsHashes) { | ||
const isRight = (0, helpers_1.getHeight)(leafIndex + 1) == (0, helpers_1.getHeight)(leafIndex) + 1; | ||
leafIndex = isRight ? leafIndex + 1 : leafIndex + (0, helpers_1.parentOffset)((0, helpers_1.getHeight)(leafIndex)); | ||
const isRight = (0, helpers_1.getHeight)(elementIndex + 1) == (0, helpers_1.getHeight)(elementIndex) + 1; | ||
elementIndex = isRight ? elementIndex + 1 : elementIndex + (0, helpers_1.parentOffset)((0, helpers_1.getHeight)(elementIndex)); | ||
hash = isRight ? this.hasher.hash([proofHash, hash]) : this.hasher.hash([hash, proofHash]); | ||
@@ -193,4 +193,19 @@ } | ||
static mapLeafIndexToElementIndex(leafIndex) { | ||
return 2 * leafIndex - 1 - this.countOnes(leafIndex - 1); | ||
return 2 * leafIndex + 1 - this.countOnes(leafIndex); | ||
} | ||
static mapElementIndexToLeafIndex(elementIndex) { | ||
elementIndex--; | ||
let outputIndex = 0; | ||
for (let i = (0, helpers_1.bitLength)(elementIndex) - 1; i >= 0; i--) { | ||
const subTreeSize = (2 << i) - 1; | ||
if (subTreeSize <= elementIndex) { | ||
elementIndex -= subTreeSize; | ||
outputIndex += 1 << i; | ||
} | ||
} | ||
if (elementIndex != 0) { | ||
throw new Error("Provided index is not a leaf"); | ||
} | ||
return outputIndex; | ||
} | ||
async retrievePeaksHashes(peaksIdxs, formattingOpts) { | ||
@@ -197,0 +212,0 @@ const hashes = await this.hashes.getMany(peaksIdxs); |
export declare const findPeaks: (elementsCount: number) => number[]; | ||
export declare const isPeak: (leafIndex: number, peaks: number[]) => boolean; | ||
export declare const isPeak: (elementIndex: number, peaks: number[]) => boolean; | ||
export declare function bitLength(num: number): number; | ||
@@ -4,0 +4,0 @@ export declare function allOnes(num: number): boolean; |
@@ -35,3 +35,3 @@ "use strict"; | ||
exports.findPeaks = findPeaks; | ||
const isPeak = (leafIndex, peaks) => peaks.indexOf(leafIndex) !== -1; | ||
const isPeak = (elementIndex, peaks) => peaks.indexOf(elementIndex) !== -1; | ||
exports.isPeak = isPeak; | ||
@@ -38,0 +38,0 @@ function bitLength(num) { |
export type AppendResult = { | ||
leavesCount: number; | ||
elementsCount: number; | ||
leafIndex: number; | ||
elementIndex: number; | ||
rootHash: string; | ||
}; |
import { PeaksFormattingOptions, ProofFormattingOptions } from "./formatting"; | ||
export interface Proof { | ||
leafIndex: number; | ||
leafHash: string; | ||
elementIndex: number; | ||
elementHash: string; | ||
siblingsHashes: string[]; | ||
@@ -6,0 +6,0 @@ peaksHashes: string[]; |
{ | ||
"name": "@accumulators/merkle-mountain-range", | ||
"version": "3.0.10", | ||
"version": "3.1.1", | ||
"description": "A TypeScript implementation of Merkle Mountain Ranges", | ||
@@ -43,3 +43,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "404bcd731e1785f083db7155676d4fd8bec05432" | ||
"gitHead": "f51d8939a94d2b9f19f51e456b9f2655f56e388a" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
55713
706