@unruggable/gateways
Version:
Trustless Ethereum Multichain CCIP-Read Gateway
98 lines (97 loc) • 4.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReverseOPRollup = exports.L1_BLOCK_ABI = void 0;
const rollup_js_1 = require("../rollup.cjs");
const utils_js_1 = require("../utils.cjs");
const EthProver_js_1 = require("../eth/EthProver.cjs");
const rlp_js_1 = require("../rlp.cjs");
const utils_1 = require("ethers/utils");
const contract_1 = require("ethers/contract");
const abi_1 = require("ethers/abi");
exports.L1_BLOCK_ABI = new abi_1.Interface([
`function number() view returns (uint256)`,
]);
// https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L1Block.sol
// TODO: should these be settings?
// (the contract needs to know SLOT_HASH)
const SLOT_NUMBER = 0n;
const SLOT_HASH = 2n;
const L1Block = '0x4200000000000000000000000000000000000015'; // default deployment
// TODO: switch this to using previousBeaconRoot
// see: test/research/eip-4788/
// im using chain1 as mainnet and chain2 as op
// however the proving is from chain2 to chain1
// either rename chain1/chain2 to chainCall/chainData
// or add direction: 1=>2 or 2=>1
// 20241116: testName() has reverse, but not a feature of the Rollup yet
class ReverseOPRollup extends rollup_js_1.AbstractRollup {
commitStep;
L1Block;
//readonly storageSlot: bigint; // using const SLOT_* instead
constructor(providers, config, // relax
commitStep = 1) {
super(providers);
this.commitStep = commitStep;
//this.latestBlockTag = 'latest'; // 20240922: not necessary
this.L1Block = new contract_1.Contract(config.L1Block ?? L1Block, exports.L1_BLOCK_ABI, this.provider2);
}
async findL2Block(l1BlockNumber) {
let b = (await this.provider2.getBlockNumber()) + 1;
let a = Math.max(0, b - utils_js_1.EVM_BLOCKHASH_DEPTH);
while (a < b) {
const middle = Math.floor((a + b) / 2);
const value = await this.provider2.getStorage(this.L1Block.target, SLOT_NUMBER, middle);
const block = BigInt((0, utils_1.dataSlice)(value, 24, 32)); // uint64
if (block == l1BlockNumber)
return BigInt(middle);
if (block > l1BlockNumber) {
b = middle;
}
else {
a = middle + 1;
}
}
throw new Error(`unable to find block: ${l1BlockNumber}`);
}
async fetchLatestCommitIndex() {
return (0, rollup_js_1.align)(await this.L1Block.number({ blockTag: this.latestBlockTag }), this.commitStep);
}
async _fetchParentCommitIndex(commit) {
return (0, rollup_js_1.align)(commit.index - 1n, this.commitStep);
}
async _fetchCommit(index) {
const prover = new EthProver_js_1.EthProver(this.provider1, index);
const prover2 = new EthProver_js_1.EthProver(this.provider2, await this.findL2Block(index));
const [l1BlockInfo, l2BlockInfo, proof] = await Promise.all([
prover.fetchBlock(),
prover2.fetchBlock(),
prover2.fetchProofs(this.L1Block.target, [SLOT_HASH]),
]);
return {
index,
rlpEncodedL1Block: (0, rlp_js_1.encodeRlpBlock)(l1BlockInfo),
rlpEncodedL2Block: (0, rlp_js_1.encodeRlpBlock)(l2BlockInfo),
accountProof: EthProver_js_1.EthProver.encodeProof(proof.accountProof),
storageProof: EthProver_js_1.EthProver.encodeProof(proof.storageProof[0].proof),
prover,
};
}
encodeWitness(commit, proofSeq) {
return utils_js_1.ABI_CODER.encode(['(bytes, bytes, bytes, bytes, bytes[], bytes)'], [
[
commit.rlpEncodedL1Block,
commit.rlpEncodedL2Block,
commit.accountProof,
commit.storageProof,
proofSeq.proofs,
proofSeq.order,
],
]);
}
windowFromSec(sec) {
// finalization is not on chain
// L1 block time is 12 sec
return Math.ceil(sec / utils_js_1.MAINNET_BLOCK_SEC);
}
}
exports.ReverseOPRollup = ReverseOPRollup;