Skip to content

Commit

Permalink
Add Scroll integration (#42)
Browse files Browse the repository at this point in the history
* Make testResolver work

* Update bun.lockb

* Add coinType

* Make text record work

* Add hardhat-storage-layout

* Use the real Resolver contracts

* Add contenthash

* Add comment

* Update README

* Change the license to ENS labs

* Remove console.log

* Add an explanation

* typo

* Remove L1Verifier.sol

* Remove L1Verifier.sol

* Rename test

* Add hardhat-deploy

* Add deployment script

* Remove deployment addresses

* Apply suggestions from code review

Add indentation

Co-authored-by: Nick Johnson <[email protected]>

* Add immutable and constants

* Remove getStatic

* Fix the wrong constants

* Update bun.lockb

* Remove contracts-bedrock

* Update bun.lockb

* Add bun

* Remove package-lock.json

* update bun.lockb

* Use BrowserProvider

* Revert to use fork

* Put immutable and constant together

* Use bytes20 instead

* Apply suggestions from code review

Co-authored-by: Nick Johnson <[email protected]>

* Remove gasLimit and gas

* Add test for the empty record

* Remove remote

* Remove RECORD_VERSIONS_REF constant

* Copy crosschain resolver to crosschain reverse resolver

* Rename the function name

* Add crosschain reverse registrar

* Update README.md

* Replace OwnedResolver with DelegatableResolverFactory

* replace target with targets

* Add isAuthorised

* Add test for setTarget

* Modify deployment code

* Remove getTarget and add TargetSet event

* WIP: Adding NameWrapper into test

* Use L2ReverseRegistrar

* Revert L1Resolver.sol and update L1ReverseResolver.sol storage slot location

* Update storage slot info

* Enable ccip read on name

* Add clearRecords and fixed typo

* Fix failing test temporarily

* Update ens-contracts

* Update bun

* Commit bun

* Update ens-contracts on crosschain-reverse-resolver

* Recreate bun.lockb

* Crosschain resolver with reverse registrar with deploy script (#18)

* Update deploy scripts

* Remove console.log

* Remove blank space from the file

* Add deployment script

* Update deployment readme

* Add getname

* Add setname

* Add setup script

* Add getaddr

* Add approve

* Fix wildcard for subname

* Update bun

* Deploy l2 reverse registrar to base goerli

* Add base deployment

* Added instruction on subname registrar

* Added instruction on how to register names

* Add support interface (#21)

* Add support interface

* Use ens-contracts IExtendedResolver

* Add support interface to reverse registrar

* Change test name

* Update L1 deployment contract address for base and OP

* Remove offset from getTarget

* Inherit Interfaces

* Inherit interfaces for ReverseResolver

* Add ERC165 signature

* Add metadata (#22)

* Add Metadata service

* Add MetadataChanged event, change setTarget argument and TargetSet event

* Update bun.lockb

* Update bun.lockb

* Remove comment

* remove id function and get rid of node from TargetSet

* Update comment, link to ENSIP16 and add variable name on the return argument of metadata function

* Fix failing tests

* Remove resolver name from metadata

* Update comment and move MetadataChanged

* Remove id

* Arb deployment (#23)

* Add support interface

* Use ens-contracts IExtendedResolver

* Add support interface to reverse registrar

* Change test name

* Update L1 deployment contract address for base and OP

* Add arbitrum deployment script and deployed contract info

* Update README

* Add IERC165

* Remove DelegatableResolverRegistrar

* Add Sepolia verifier contracts and gateway deployment details (#26)

* Add OP sepolia gateway info

* Add deployed addresses for base

* Add arbitrum sepolia deployment address

* Remove console.log

* Update comment

* Add environment on wrangler.toml

* Add .wrangler to gitignore

* Copy arb-gateway to scroll-gateway

* Replace arb to scroll

* Rename from arb to scroll

* replace arb to scroll

* Rename from Arb to Scroll

* Modify ScrollProofService

* Add scroll- to workspace

* Update rollupABI

* Sepolia resolvers (#27)

* Add crosschain resolver details

* Updated @ensdomains/ens-contracts ensdomains/ens-contracts#feature/crosschain-resolver-with-reverse-registrar to the latest commit

* Change slot

* Add ReverseRegistrar deployment details

* Update reverse registrar deployed addresses

* Add Op sepolia reverse registrar deployment info

* Added L1Resolver contract deployment details

* Remove comment out

* Add bun.lockb

* Update bun.lockb

* Change ens- ontracts to point to l2-deployment branch

* Fix failing test

* Update bun.lockb

* Add L2ReverseRegistrar to deps.sol on crosschain-resolver (was throwing error)

* Fix failing test

* Remove unused subheader

* Redeploy base l1 resolver

* Update README.md

* Added Base Reverse Resolver contract address

* Add Arbitrum Reverse Resolver deployement

* Redeploy ArbL1ReverseResolver with correct L2 Resolver Address

* Redeploy l2 contracts with official reverse record namespace (cointype.reverse)

* Sepolia resolvers with analytics (#30)

* WIP

* Fix errors

* Ignore favicon

* Update bun.lockb

* Fix lint error

* Update gateway url

* Add console.log

* Changed endpoint

* Update apiEndpoint

* Add sender and calldata to props

* Move Tracker to evm-gateway

* Revert "Move Tracker to evm-gateway"

This reverts commit 5d3ba37.

* WIP

* Downgrade to 4.20231121.0

* Bump it to the latest

* Add type

* Replace tracker with @ensdomains/server-analytics

* Pass custom apiEndpoint and props

* Add GATEWAY_DOMAIN and ENDPOINT_URL

* Point to correct branch

* Fix CORS problem

* Add gateway log tracker to OP

* Fix lint error

* Update readme

* Default reverse resolver (#33)

* Change ens-contracts to use default-reverse-resolver

* Add suport for DefaultReverseResolver

* Add hexToAddress to extract address

* Add faulback to name function

* Add fallback for text

* Use imported IDefaultReverseResolver

* Update bun.lockb and README

* Update comment

* Move DefaultReverseResolver

* Add DefaultReverseResolver

* Update bun.lockb

* Add support for resolve on DefaultReverseResolver

* Deployed new contracts

* Add setdefaultname

* Update README.md

* Update README.md

* Remove console.log

* Point to default-reverse-resolver-2

* Reswitch to default-reverse-resolver

* Update bun.ockb

* Add whitespace

* Check if invalid address

* Override .text

* Fix  TypeError: ambiguous function error

* Re-point to default-reverse-resolver

* Added wait

* Update storage location after removing Owner

* Added wait on crosschain resolver

* Use L2ReverseRevolver and fix broken test

* Update ens-contracts branch

* Eip 5559 support (#34)

* Add IResolverSetter

* Simplify metadata function

* Fix failing tests

* Add test for EIP 5559

* Added wait

* Rename from IResolverSetter to IAddrSetter

* Add resolveDeferral

* Store chainId directly

* Rename from resolveDeferral to setAddr

* Remove crosschain-resolver and crosschain-reverse-resolver

* Add .yalc to .gitignore

* v0.1.0-beta.1

* Pushed all versions to 0.1.0-beta.2

* Add repo info and bump to beta.3

* Add links to arb related repos

* Remove old deployment info

* Revert removed scripts

* Recreate bun.lockb

* Remove console.log and tidy up props

* Update package

* Fix worker error

* Rename to makeScrollGateway

* Make simple proofs for fixed values test pass

* Fix linting error

* Fix linting error

* remove log result util (#40)

* remove log result util

* bump server-analytics version, update types and functions

* bypass frozen-lockfile flag for deps update

* bypass frozen-lockfile flag for deps update

* lint

* revert frozen-lockfile flag

* keep  rozen-lockfile disabled

* lint

* Pass  multiple storage slots

* Rename sepoliaforbase to sepoliaForBase

* Update op-gateway/README.md

Co-authored-by: Nick Johnson <[email protected]>

* Add EVMProofHelper2

* move propsDecoder (#41)

* move propsDecoder

* Add Request as type

* Update workers-types

* Fix lint error

* Add compressProof

* Make scroll verifier working

* Add estimateCCIPReadCallbackGas

  ScrollVerifier
Gas estimate 2418085
    ✔ simple proofs for fixed values (2652ms)
Gas estimate 2419066
    ✔ simple proofs for dynamic values (1641ms)
Gas estimate 2282506
    ✔ nested proofs for dynamic values (1800ms)
Gas estimate 4773362
    ✔ nested proofs for long dynamic values (1960ms)
Gas estimate 3607123
    ✔ nested proofs with lookbehind (2488ms)
Gas estimate 3527831
    ✔ nested proofs with lookbehind for dynamic values (1810ms)
Gas estimate 2353134
    ✔ mappings with variable-length keys (1721ms)
Gas estimate 3608890
    ✔ nested proofs of mappings with variable-length keys (2086ms)
Gas estimate 2223797
    ✔ treats uninitialized storage elements as zeroes (1534ms)
Gas estimate 2228241
    ✔ treats uninitialized dynamic values as empty strings (1800ms)

* Pass compressedProof as storageProof

* Create MerkleTrieProofHelper

* Remove nested array from StateProof.storageProofs

* Simplify log tracker on scroll gateway worker

* Remove wrong comment

* Update comment and documentation

* Remove unused cache from scroll-gateway

* Remove L2_ROLLUP and L1_PROVIDER_URL

* Fix linting error

* Update evm-gateway/src/utils.ts

Co-authored-by: Nick Johnson <[email protected]>

* Update evm-verifier/contracts/MerkleTrieProofHelper.sol

Co-authored-by: Nick Johnson <[email protected]>

* Fix error

* Add SEARCH_URL

* Add StateRootMismatch error

* Change l2 rollup address

---------

Co-authored-by: Nick Johnson <[email protected]>
Co-authored-by: tate <[email protected]>
Co-authored-by: Muhammed Tanrıkulu <[email protected]>
  • Loading branch information
4 people authored May 27, 2024
1 parent aa21d87 commit 14ebd3f
Show file tree
Hide file tree
Showing 47 changed files with 1,580 additions and 93 deletions.
6 changes: 3 additions & 3 deletions arb-gateway/src/ArbProofService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable prettier/prettier */
import { EVMProofHelper, type IProofService } from '@ensdomains/evm-gateway';
import { EVMProofHelper, convertIntoMerkleTrieProof, type IProofService } from '@ensdomains/evm-gateway';
import { AbiCoder, Contract, EventLog, ethers, toBeHex, type AddressLike, toNumber } from 'ethers';
import rollupAbi from "./abi/rollupABI.js";
import type { IBlockCache } from './blockCache/IBlockCache.js';
Expand Down Expand Up @@ -63,7 +63,7 @@ export class ArbProofService implements IProofService<ArbProvableBlock> {
return AbiCoder.defaultAbiCoder().encode(
[
'tuple(bytes32 version, bytes32 sendRoot, uint64 nodeIndex,bytes rlpEncodedBlock)',
'tuple(bytes[] stateTrieWitness, bytes[][] storageProofs)',
'tuple(bytes stateTrieWitness, bytes[] storageProofs)',
],
[
{
Expand All @@ -73,7 +73,7 @@ export class ArbProofService implements IProofService<ArbProvableBlock> {
nodeIndex: block.nodeIndex,
rlpEncodedBlock: block.rlpEncodedBlock
},
proof,
convertIntoMerkleTrieProof(proof)
]
);
}
Expand Down
2 changes: 1 addition & 1 deletion arb-gateway/src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ async function fetch(request: CFWRequest, env: Env) {
await tracker.trackEvent(request, 'request', { props }, true);
return app
.handle(request)
.then(tracker.logResult.bind(null, propsDecoder, request));
.then(tracker.logResult.bind(tracker, propsDecoder, request));
}

export default {
Expand Down
11 changes: 3 additions & 8 deletions arb-verifier/contracts/ArbVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {StateProof, EVMProofHelper} from '@ensdomains/evm-verifier/contracts/EVM
import {IEVMVerifier} from '@ensdomains/evm-verifier/contracts/IEVMVerifier.sol';
import {Node, IRollupCore} from '@arbitrum/nitro-contracts/src/rollup/IRollupCore.sol';
import {RLPReader} from '@eth-optimism/contracts-bedrock/src/libraries/rlp/RLPReader.sol';
import {MerkleTrieProofHelper} from '@ensdomains/evm-verifier/contracts/MerkleTrieProofHelper.sol';

struct ArbWitnessData {
bytes32 version;
Expand Down Expand Up @@ -63,14 +64,8 @@ contract ArbVerifier is IEVMVerifier {

//Now that we know that the block is valid, we can get the state root from the block.
bytes32 stateRoot = getStateRootFromBlock(arbData.rlpEncodedBlock);

values = EVMProofHelper.getStorageValues(
target,
commands,
constants,
stateRoot,
stateProof
);
bytes32 storageRoot = MerkleTrieProofHelper.getStorageRoot(stateRoot, target, stateProof.stateTrieWitness);
return EVMProofHelper.getStorageValues(target, MerkleTrieProofHelper.getTrieProof, commands, constants, storageRoot, stateProof.storageProofs);
}

/*
Expand Down
51 changes: 51 additions & 0 deletions arb-verifier/test/testArbVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { HardhatEthersProvider } from '@nomicfoundation/hardhat-ethers/internal/
import type { HardhatEthersHelpers } from '@nomicfoundation/hardhat-ethers/types';
import { expect } from 'chai';
import {
AbiCoder,
concat,
Contract,
FetchRequest,
Provider,
Expand All @@ -28,6 +30,23 @@ declare module 'hardhat/types/runtime' {
ethers: ethersObj;
}
}
const estimateCCIPReadCallbackGas = async (provider, cb) => {
try{
await cb()
}catch(e){
const [sender, urls, data, callbackFunction, extraData ] = e.revert.args
const url = `http://localhost:8080/${sender}/${data}.json`
const responseData:any = await (await fetch(url)).json()
const encoder = new AbiCoder()
const encoded = encoder.encode([ "bytes", "bytes" ], [responseData.data, extraData]);
const newdata = concat([ callbackFunction, encoded ])
const result2 = await provider.estimateGas({
to: sender,
data:newdata
});
console.log(`Gas estimate ${result2}`)
}
}

describe('ArbVerifier', () => {
let provider: Provider;
Expand Down Expand Up @@ -87,54 +106,86 @@ describe('ArbVerifier', () => {
it('simple proofs for fixed values', async () => {
const result = await target.getLatest({ enableCcipRead: true });
expect(Number(result)).to.equal(42);
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getLatest({ enableCcipRead: false });
})
});

it('simple proofs for dynamic values', async () => {
const result = await target.getName({ enableCcipRead: true });
expect(result).to.equal('Satoshi');
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getName({ enableCcipRead: false });
})
});

it('nested proofs for dynamic values', async () => {
const result = await target.getHighscorer(42, { enableCcipRead: true });
expect(result).to.equal('Hal Finney');
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getHighscorer(42, { enableCcipRead: false });
})
});

it('nested proofs for long dynamic values', async () => {
const result = await target.getHighscorer(1, { enableCcipRead: true });
expect(result).to.equal(
'Hubert Blaine Wolfeschlegelsteinhausenbergerdorff Sr.'
);
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getHighscorer(1, { enableCcipRead: false });
})
});

it('nested proofs with lookbehind', async () => {
const result = await target.getLatestHighscore({ enableCcipRead: true });
expect(Number(result)).to.equal(12345);
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getLatestHighscore({ enableCcipRead: false });
})
});

it('nested proofs with lookbehind for dynamic values', async () => {
const result = await target.getLatestHighscorer({ enableCcipRead: true });
expect(result).to.equal('Hal Finney');
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getLatestHighscorer({ enableCcipRead: false });
})
});

it('mappings with variable-length keys', async () => {
const result = await target.getNickname('Money Skeleton', {
enableCcipRead: true,
});
expect(result).to.equal('Vitalik Buterin');
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getNickname('Money Skeleton', {
enableCcipRead: false,
});
})
});

it('nested proofs of mappings with variable-length keys', async () => {
const result = await target.getPrimaryNickname({ enableCcipRead: true });
expect(result).to.equal('Hal Finney');
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getPrimaryNickname({ enableCcipRead: false });
})
});

it('treats uninitialized storage elements as zeroes', async () => {
const result = await target.getZero({ enableCcipRead: true });
expect(Number(result)).to.equal(0);
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getZero({ enableCcipRead: false });
})
});

it('treats uninitialized dynamic values as empty strings', async () => {
const result = await target.getNickname('Santa', { enableCcipRead: true });
expect(result).to.equal("");
await estimateCCIPReadCallbackGas(provider, ()=>{
return target.getNickname('Santa', { enableCcipRead: false });
})
})
});
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion evm-gateway/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@
"type": "module",
"types": "./_types/index.d.ts",
"typings": "./_types/index.d.ts"
}
}
8 changes: 4 additions & 4 deletions evm-gateway/src/EVMProofHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ import { toBeHex, type AddressLike, type JsonRpcProvider } from 'ethers';
* Response of the eth_getProof RPC method.
*/
interface EthGetProofResponse {
accountProof: string[];
accountProof: string;
balance: string;
codeHash: string;
nonce: string;
storageHash: string;
storageProof: {
key: string;
value: string;
proof: string[];
proof: string;
}[];
}

export interface StateProof {
stateTrieWitness: string[];
storageProofs: string[][];
stateTrieWitness: string;
storageProofs: string[];
stateRoot: string;
}

Expand Down
6 changes: 5 additions & 1 deletion evm-gateway/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export { EVMGateway, StorageLayout } from './EVMGateway.js';
export { EVMProofHelper, type StateProof } from './EVMProofHelper.js';
export type { IProofService, ProvableBlock } from './IProofService.js';
export { propsDecoder, type Router } from './utils.js';
export {
propsDecoder,
convertIntoMerkleTrieProof,
type Router,
} from './utils.js';
13 changes: 13 additions & 0 deletions evm-gateway/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { type Request as CFWRequest } from '@cloudflare/workers-types';
import { type PropsDecoder } from '@ensdomains/server-analytics';
import { AbiCoder } from 'ethers';
import { type StateProof } from './EVMProofHelper.js';
export interface Router {
handle: (request: CFWRequest) => Promise<Response>;
}
Expand All @@ -22,3 +24,14 @@ export const propsDecoder: PropsDecoder<CFWRequest> = (
return {};
}
};

const flatten = (data: string) => {
return AbiCoder.defaultAbiCoder().encode(['bytes[]'], [data]);
};

export const convertIntoMerkleTrieProof = (proof: StateProof) => {
return {
stateTrieWitness: flatten(proof.stateTrieWitness),
storageProofs: proof.storageProofs.map(flatten),
};
};
78 changes: 36 additions & 42 deletions evm-verifier/contracts/EVMProofHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {Bytes} from "@eth-optimism/contracts-bedrock/src/libraries/Bytes.sol";
import {SecureMerkleTrie} from "./SecureMerkleTrie.sol";

struct StateProof {
bytes[] stateTrieWitness; // Witness proving the `storageRoot` against a state root.
bytes[][] storageProofs; // An array of proofs of individual storage elements
bytes stateTrieWitness; // Witness proving the `storageRoot` against a state root.
bytes[] storageProofs; // An array of proofs of individual storage elements
}

uint8 constant OP_CONSTANT = 0x00;
Expand All @@ -17,52 +17,39 @@ uint8 constant FLAG_DYNAMIC = 0x01;
library EVMProofHelper {
using Bytes for bytes;

error AccountNotFound(address);
error UnknownOpcode(uint8);
error InvalidSlotSize(uint256 size);

/**
* @notice Get the storage root for the provided merkle proof
* @param stateRoot The state root the witness was generated against
* @param target The address we are fetching a storage root for
* @param witness A witness proving the value of the storage root for `target`.
* @return The storage root retrieved from the provided state root
*/
function getStorageRoot(bytes32 stateRoot, address target, bytes[] memory witness) private pure returns (bytes32) {
(bool exists, bytes memory encodedResolverAccount) = SecureMerkleTrie.get(
abi.encodePacked(target),
witness,
stateRoot
);
if(!exists) {
revert AccountNotFound(target);
}
RLPReader.RLPItem[] memory accountState = RLPReader.readList(encodedResolverAccount);
return bytes32(RLPReader.readBytes(accountState[2]));
}

/**
* @notice Prove whether the provided storage slot is part of the storageRoot
* @param target address to verify against
* @param getter function to verify the storage proof
* @param storageRoot the storage root for the account that contains the storage slot
* @param slot The storage key we are fetching the value of
* @param witness the StorageProof struct containing the necessary proof data
* @return The retrieved storage proof value or 0x if the storage slot is empty
*/
function getSingleStorageProof(bytes32 storageRoot, uint256 slot, bytes[] memory witness) private pure returns (bytes memory) {
(bool exists, bytes memory retrievedValue) = SecureMerkleTrie.get(
abi.encodePacked(slot),
function getSingleStorageProof(
address target,
function(address,uint256,bytes memory, bytes32) internal view returns(bytes memory) getter,
bytes32 storageRoot,
uint256 slot,
bytes memory witness
) private view returns (bytes memory) {
return getter(
target,
slot,
witness,
storageRoot
);
if(!exists) {
// Nonexistent values are treated as zero.
return "";
}
return RLPReader.readBytes(retrievedValue);
}

function getFixedValue(bytes32 storageRoot, uint256 slot, bytes[] memory witness) private pure returns(bytes32) {
bytes memory value = getSingleStorageProof(storageRoot, slot, witness);
function getFixedValue(
address target,
function(address,uint256,bytes memory, bytes32) internal view returns(bytes memory) getter,
bytes32 storageRoot, uint256 slot, bytes memory witness
) private view returns(bytes32) {
bytes memory value = getSingleStorageProof(target, getter, storageRoot, slot, witness);
// RLP encoded storage slots are stored without leading 0 bytes.
// Casting to bytes32 appends trailing 0 bytes, so we have to bit shift to get the
// original fixed-length representation back.
Expand All @@ -82,7 +69,7 @@ library EVMProofHelper {
}
}

function computeFirstSlot(bytes32 command, bytes[] memory constants, bytes[] memory values) private pure returns(bool isDynamic, uint256 slot) {
function computeFirstSlot(bytes32 command, bytes[] memory constants, bytes[] memory values) internal pure returns(bool isDynamic, uint256 slot) {
uint8 flags = uint8(command[0]);
isDynamic = (flags & FLAG_DYNAMIC) != 0;

Expand All @@ -96,8 +83,12 @@ library EVMProofHelper {
}
}

function getDynamicValue(bytes32 storageRoot, uint256 slot, StateProof memory proof, uint256 proofIdx) private pure returns(bytes memory value, uint256 newProofIdx) {
uint256 firstValue = uint256(getFixedValue(storageRoot, slot, proof.storageProofs[proofIdx++]));
function getDynamicValue(
address target,
function(address,uint256,bytes memory, bytes32) internal view returns(bytes memory) getter,
bytes32 storageRoot, uint256 slot, bytes[] memory proof, uint256 proofIdx) private view returns(bytes memory value, uint256 newProofIdx
) {
uint256 firstValue = uint256(getFixedValue(target, getter,storageRoot, slot, proof[proofIdx++]));
if(firstValue & 0x01 == 0x01) {
// Long value: first slot is `length * 2 + 1`, following slots are data.
uint256 length = (firstValue - 1) / 2;
Expand All @@ -107,10 +98,10 @@ library EVMProofHelper {
// all at once, but we're trying to avoid writing new library code.
while(length > 0) {
if(length < 32) {
value = bytes.concat(value, getSingleStorageProof(storageRoot, slot++, proof.storageProofs[proofIdx++]).slice(0, length));
value = bytes.concat(value, getSingleStorageProof(target, getter, storageRoot, slot++, proof[proofIdx++]).slice(0, length));
length = 0;
} else {
value = bytes.concat(value, getSingleStorageProof(storageRoot, slot++, proof.storageProofs[proofIdx++]));
value = bytes.concat(value, getSingleStorageProof(target, getter, storageRoot, slot++, proof[proofIdx++]));
length -= 32;
}
}
Expand All @@ -122,20 +113,23 @@ library EVMProofHelper {
}
}

function getStorageValues(address target, bytes32[] memory commands, bytes[] memory constants, bytes32 stateRoot, StateProof memory proof) internal pure returns(bytes[] memory values) {
bytes32 storageRoot = getStorageRoot(stateRoot, target, proof.stateTrieWitness);
function getStorageValues(
address target,
function(address,uint256,bytes memory, bytes32) internal view returns(bytes memory) getter,
bytes32[] memory commands, bytes[] memory constants, bytes32 storageRoot, bytes[] memory proof) internal view returns(bytes[] memory values
) {
uint256 proofIdx = 0;
values = new bytes[](commands.length);
for(uint256 i = 0; i < commands.length; i++) {
bytes32 command = commands[i];
(bool isDynamic, uint256 slot) = computeFirstSlot(command, constants, values);
if(!isDynamic) {
values[i] = abi.encode(getFixedValue(storageRoot, slot, proof.storageProofs[proofIdx++]));
values[i] = abi.encode(getFixedValue(target, getter, storageRoot, slot, proof[proofIdx++]));
if(values[i].length > 32) {
revert InvalidSlotSize(values[i].length);
}
} else {
(values[i], proofIdx) = getDynamicValue(storageRoot, slot, proof, proofIdx);
(values[i], proofIdx) = getDynamicValue(target, getter, storageRoot, slot, proof, proofIdx);
}
}
}
Expand Down
Loading

0 comments on commit 14ebd3f

Please sign in to comment.