UNPKG

@unruggable/gateways

Version:

Trustless Ethereum Multichain CCIP-Read Gateway

86 lines (85 loc) 3.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ZKEVMProver = void 0; const constants_1 = require("ethers/constants"); const vm_js_1 = require("../vm.cjs"); const utils_js_1 = require("../utils.cjs"); const types_js_1 = require("./types.cjs"); class ZKEVMProver extends vm_js_1.BlockProver { static isContract = types_js_1.isContract; static encodeProof = types_js_1.encodeProof; static latest = this._createLatest(); async isContract(target) { target = target.toLowerCase(); if (this.fast) { return this.cache.get(target, async () => { const code = await this.provider.getCode(target, this.block); return code.length > 2; }); } return (0, types_js_1.isContract)(await this.getProofs(target)); } async getStorage(target, slot, fast = this.fast) { target = target.toLowerCase(); // check to see if we know this target isn't a contract without invoking provider // this is almost equivalent to: await isContract(target) const accountProof = await this.proofLRU.touch(target); if (accountProof && !(0, types_js_1.isContract)(accountProof)) { return constants_1.ZeroHash; } // check to see if we've already have a proof for this value const storageKey = (0, vm_js_1.makeStorageKey)(target, slot); const storageProof = await this.proofLRU.touch(storageKey); if (storageProof) { return (0, utils_js_1.toPaddedHex)(storageProof.value); } if (fast) { return this.cache.get(storageKey, () => this.provider.getStorage(target, slot, this.block)); } const proofs = await this.getProofs(target, [slot]); return (0, types_js_1.isContract)(proofs) ? (0, utils_js_1.toPaddedHex)(proofs.storageProof[0].value) : constants_1.ZeroHash; } async _proveNeed(need, accountRef, slotRefs) { const m = [...slotRefs]; const accountProof = await this.proofLRU.touch(need.target); if (accountProof && !(0, types_js_1.isContract)(accountProof)) m.length = 0; if (!m.length && !need.required) return; const proofs = await this.getProofs(need.target, m.map(([slot]) => slot)); if (need.required) { accountRef.proof = (0, types_js_1.encodeProof)(proofs.codeHashProof); } if ((0, types_js_1.isContract)(proofs)) { m.forEach(([, ref], i) => (ref.proof = (0, types_js_1.encodeProof)(proofs.storageProof[i].proof))); } } async getProofs(target, slots = []) { // TODO: fix me const proofs = await this.fetchProofs(target, slots); this.checkStorageProofs((0, types_js_1.isContract)(proofs), slots, proofs.storageProof); return proofs; } async fetchProofs(target, slots = []) { const ps = []; for (let i = 0;;) { ps.push(this.provider.send('zkevm_getProof', [ target, slots .slice(i, (i += this.proofBatchSize)) .map((slot) => (0, utils_js_1.toPaddedHex)(slot)), this.block, ])); if (i >= slots.length) break; } const vs = await Promise.all(ps); for (let i = 1; i < vs.length; i++) { vs[0].storageProof.push(...vs[i].storageProof); } return vs[0]; } } exports.ZKEVMProver = ZKEVMProver;