import { InterruptableSleep } from '@polyaztec/barretenberg/sleep';
import { MemoryFifo, Semaphore } from '@polyaztec/barretenberg/fifo';
import { createDebugLogger } from '@polyaztec/barretenberg/log';
export class BlockDownloader {
    constructor(rollupProvider, maxQueueSize, initialTreeSize) {
        this.rollupProvider = rollupProvider;
        this.running = false;
        this.from = 0;
        this.interruptableSleep = new InterruptableSleep();
        this.queue = new MemoryFifo();
        this.debug = createDebugLogger('bb:block_downloader');
        this.semaphore = new Semaphore(maxQueueSize);
        // Choosing 55 as an initial chunk to insert if starting from 0, is an aztec-connect optimisation.
        // The aztec-connect genesis data consists of 73 rollups.
        // Initially inserting 55 brings us to 128, after which we work with chunks of 128 rollups.
        // If not synching from zero, the chunk size is whatever takes us up to the next 128 alignment.
        // This allows for optimal subtree insertions in the client side merkle tree for better sync performance.
        this.genesisTake = 128 - (initialTreeSize % 128);
    }
    start(from = 0) {
        this.debug(`starting downloading from block ${from}...`);
        this.from = from;
        if (this.running) {
            this.interruptableSleep.interrupt();
            return;
        }
        this.running = true;
        const fn = async () => {
            while (this.running) {
                try {
                    // If requesting from block 0, then take the fixed number of blocks to take us to 128 (genesisTake)
                    // Otherwise, take blocks as required to get us to a 128 aligned boundary starting from block (128 - initialTreeSize).
                    // e.g. we are trying to get to blocks 183, 311, 439 etc....
                    const takeValue = this.from < this.genesisTake ? this.genesisTake - this.from : 128 - ((this.from - this.genesisTake) % 128);
                    const blocks = await this.rollupProvider.getBlocks(this.from, takeValue);
                    if (!blocks.length) {
                        await this.interruptableSleep.sleep(10000);
                        continue;
                    }
                    this.debug(`downloaded blocks ${this.from} to ${this.from + blocks.length - 1}.`);
                    // Blocks if there are maxQueueSize results in the queue, until released after the callback.
                    await this.semaphore.acquire();
                    this.queue.put(blocks);
                    this.from += blocks.length;
                }
                catch (err) {
                    console.log(err);
                    await this.interruptableSleep.sleep(10000);
                }
            }
        };
        this.runningPromise = fn();
    }
    async stop() {
        this.running = false;
        this.interruptableSleep.interrupt();
        this.queue.cancel();
        await this.runningPromise;
    }
    async getBlocks() {
        const blocks = await this.queue.get();
        if (!blocks) {
            return [];
        }
        this.semaphore.release();
        return blocks;
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfZG93bmxvYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlX3Nkay9ibG9ja19kb3dubG9hZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRW5FLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDckUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFaEUsTUFBTSxPQUFPLGVBQWU7SUFVMUIsWUFBb0IsY0FBOEIsRUFBRSxZQUFvQixFQUFFLGVBQXVCO1FBQTdFLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQVIxQyxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2hCLFNBQUksR0FBRyxDQUFDLENBQUM7UUFDVCx1QkFBa0IsR0FBRyxJQUFJLGtCQUFrQixFQUFFLENBQUM7UUFFOUMsVUFBSyxHQUFHLElBQUksVUFBVSxFQUFXLENBQUM7UUFFbEMsVUFBSyxHQUFHLGlCQUFpQixDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFHdkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QyxrR0FBa0c7UUFDbEcseURBQXlEO1FBQ3pELDJGQUEyRjtRQUMzRiwrRkFBK0Y7UUFDL0YseUdBQXlHO1FBQ3pHLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxHQUFHLENBQUMsZUFBZSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUM7UUFDbkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsSUFBSSxLQUFLLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUVqQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDaEIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BDLE9BQU87U0FDUjtRQUVELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBRXBCLE1BQU0sRUFBRSxHQUFHLEtBQUssSUFBSSxFQUFFO1lBQ3BCLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDbkIsSUFBSTtvQkFDRixtR0FBbUc7b0JBQ25HLHNIQUFzSDtvQkFDdEgsNERBQTREO29CQUM1RCxNQUFNLFNBQVMsR0FDYixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztvQkFDN0csTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO29CQUV6RSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRTt3QkFDbEIsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUMzQyxTQUFTO3FCQUNWO29CQUVELElBQUksQ0FBQyxLQUFLLENBQUMscUJBQXFCLElBQUksQ0FBQyxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBRWxGLDRGQUE0RjtvQkFDNUYsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUUvQixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDO2lCQUM1QjtnQkFBQyxPQUFPLEdBQUcsRUFBRTtvQkFDWixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNqQixNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQzVDO2FBQ0Y7UUFDSCxDQUFDLENBQUM7UUFFRixJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSTtRQUNmLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNwQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3BCLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQztJQUM1QixDQUFDO0lBRU0sS0FBSyxDQUFDLFNBQVM7UUFDcEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDWCxPQUFPLEVBQUUsQ0FBQztTQUNYO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN6QixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0NBQ0YifQ==