import { MemoryMerkleTree } from '@polyaztec/barretenberg/merkle_tree';
import { RollupProofData } from '@polyaztec/barretenberg/rollup_proof';
import { WorldStateConstants } from '@polyaztec/barretenberg/world_state';
import { Mutex } from 'async-mutex';
/**
 * Block Context is designed to wrap a block received from the rollup provider
 * and percolate through the sdk, existing for the duration that the block is 'processed'.
 * It provides an opportunity for 'once per block' caching/optimsation across all entities interested in the block
 * Requires mutex protection due to the concurrent nature of user states
 */
export class BlockContext {
    constructor(block, rollup, pedersen) {
        this.block = block;
        this.rollup = rollup;
        this.pedersen = pedersen;
        this.mutex = new Mutex();
    }
    static fromBlock(block, pedersen) {
        return new BlockContext(block, RollupProofData.decode(block.encodedRollupProofData), pedersen);
    }
    /**
     * Provides the hash path at the given index of the block's immutable sub-tree
     * Will validate that the index provided is within the range encapsulated by the sub-tree
     * Lazy initialises the sub-tree from the rollup's input notes so the tree is built
     * at most once
     */
    async getBlockSubtreeHashPath(index) {
        await this.mutex.acquire();
        try {
            if (!this.subtree) {
                const numNotesInFullRollup = WorldStateConstants.NUM_NEW_DATA_TREE_NOTES_PER_TX * this.block.rollupSize;
                this.startIndex = this.rollup.dataStartIndex;
                const maxIndex = this.startIndex + numNotesInFullRollup;
                if (index < this.startIndex || index >= maxIndex) {
                    throw new Error('Index out of bounds.');
                }
                const notes = this.rollup.innerProofData.flatMap(x => [x.noteCommitment1, x.noteCommitment2]);
                const allNotes = [...notes, ...Array(numNotesInFullRollup - notes.length).fill(MemoryMerkleTree.ZERO_ELEMENT)];
                this.subtree = await MemoryMerkleTree.new(allNotes, this.pedersen);
            }
            return this.subtree.getHashPath(index - this.startIndex);
        }
        finally {
            this.mutex.release();
        }
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ibG9ja19jb250ZXh0L2Jsb2NrX2NvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFcEM7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUt2QixZQUFtQixLQUFZLEVBQVMsTUFBdUIsRUFBVSxRQUFrQjtRQUF4RSxVQUFLLEdBQUwsS0FBSyxDQUFPO1FBQVMsV0FBTSxHQUFOLE1BQU0sQ0FBaUI7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBSm5GLFVBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO0lBSWtFLENBQUM7SUFFL0YsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFZLEVBQUUsUUFBa0I7UUFDL0MsT0FBTyxJQUFJLFlBQVksQ0FBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNqRyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxLQUFLLENBQUMsdUJBQXVCLENBQUMsS0FBYTtRQUNoRCxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDM0IsSUFBSTtZQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO2dCQUNqQixNQUFNLG9CQUFvQixHQUFHLG1CQUFtQixDQUFDLDhCQUE4QixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO2dCQUN4RyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDO2dCQUM3QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLG9CQUFvQixDQUFDO2dCQUN4RCxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxJQUFJLEtBQUssSUFBSSxRQUFRLEVBQUU7b0JBQ2hELE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztpQkFDekM7Z0JBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO2dCQUM5RixNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQUcsS0FBSyxFQUFFLEdBQUcsS0FBSyxDQUFDLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztnQkFDL0csSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3BFO1lBQ0QsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVcsQ0FBQyxDQUFDO1NBQzNEO2dCQUFTO1lBQ1IsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUN0QjtJQUNILENBQUM7Q0FDRiJ9