Skip to content

Commit

Permalink
Remove nested array from StateProof.storageProofs
Browse files Browse the repository at this point in the history
  • Loading branch information
makoto committed May 8, 2024
1 parent cf18c96 commit 5f7a8ef
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 57 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
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
2 changes: 1 addition & 1 deletion evm-gateway/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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';
17 changes: 17 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,18 @@ export const propsDecoder: PropsDecoder<CFWRequest> = (
return {};
}
};

export const convertIntoMerkleTrieProof = (
proof: StateProof
) => {
const storageProofs:any = []
const stateTrieWitness = AbiCoder.defaultAbiCoder().encode(["bytes[]"], [proof.stateTrieWitness])
for (let index = 0; index < proof.storageProofs.length; index++) {
const storageProof = AbiCoder.defaultAbiCoder().encode(["bytes[]"], [proof.storageProofs[index]])
storageProofs[index] = storageProof
}
return({
stateTrieWitness,
storageProofs
})
}
20 changes: 10 additions & 10 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 @@ -31,10 +31,10 @@ library EVMProofHelper {
*/
function getSingleStorageProof(
address target,
function(address,uint256,bytes[] memory, bytes32) internal view returns(bytes memory) getter,
function(address,uint256,bytes memory, bytes32) internal view returns(bytes memory) getter,
bytes32 storageRoot,
uint256 slot,
bytes[] memory witness
bytes memory witness
) private view returns (bytes memory) {
return getter(
target,
Expand All @@ -46,8 +46,8 @@ library EVMProofHelper {

function getFixedValue(
address target,
function(address,uint256,bytes[] memory, bytes32) internal view returns(bytes memory) getter,
bytes32 storageRoot, uint256 slot, bytes[] memory witness
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.
Expand Down Expand Up @@ -85,8 +85,8 @@ library EVMProofHelper {

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
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) {
Expand Down Expand Up @@ -115,8 +115,8 @@ library EVMProofHelper {

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
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);
Expand Down
13 changes: 7 additions & 6 deletions evm-verifier/contracts/MerkleTrieProofHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ library MerkleTrieProofHelper {
* @return The storage value
*/

// function getTrieProof(address, uint256 slot, bytes[] memory witness, bytes32 root) internal pure returns(bytes memory){
function getTrieProof(address, uint256 slot, bytes[] memory witness, bytes32 root) internal pure returns(bytes memory){
function getTrieProof(address, uint256 slot, bytes memory witness, bytes32 root) internal pure returns(bytes memory){
(bytes[] memory _witness) = abi.decode(witness, (bytes[]));

(bool exists, bytes memory retrievedValue) = SecureMerkleTrie.get(
abi.encodePacked(slot),
witness,
_witness,
root
);
if(!exists) {
Expand All @@ -47,10 +47,11 @@ library MerkleTrieProofHelper {
* @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) internal view returns (bytes32) {
function getStorageRoot(bytes32 stateRoot, address target, bytes memory witness) internal view returns (bytes32) {
(bytes[] memory _witness) = abi.decode(witness, (bytes[]));
(bool exists, bytes memory encodedResolverAccount) = SecureMerkleTrie.get(
abi.encodePacked(target),
witness,
_witness,
stateRoot
);
if(!exists) {
Expand Down
6 changes: 3 additions & 3 deletions l1-gateway/src/L1ProofService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
type JsonRpcProvider,
} from 'ethers';

import { EVMProofHelper, type IProofService } from '@ensdomains/evm-gateway';
import { EVMProofHelper, convertIntoMerkleTrieProof, type IProofService } from '@ensdomains/evm-gateway';
import { Block, type JsonRpcBlock } from '@ethereumjs/block';

type RlpObject = Uint8Array | Array<RlpObject>;
Expand Down Expand Up @@ -74,9 +74,9 @@ export class L1ProofService implements IProofService<L1ProvableBlock> {
return AbiCoder.defaultAbiCoder().encode(
[
'tuple(uint256 blockNo, bytes blockHeader)',
'tuple(bytes[] stateTrieWitness, bytes[][] storageProofs)',
'tuple(bytes stateTrieWitness, bytes[] storageProofs)',
],
[{ blockNo, blockHeader }, proof]
[{ blockNo, blockHeader }, convertIntoMerkleTrieProof(proof)]
);
}
}
4 changes: 3 additions & 1 deletion l1-verifier/contracts/L1Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.17;
import { IEVMVerifier } from "@ensdomains/evm-verifier/contracts/IEVMVerifier.sol";
import { RLPReader } from "@eth-optimism/contracts-bedrock/src/libraries/rlp/RLPReader.sol";
import { StateProof, EVMProofHelper } from "@ensdomains/evm-verifier/contracts/EVMProofHelper.sol";
import {MerkleTrieProofHelper} from '@ensdomains/evm-verifier/contracts/MerkleTrieProofHelper.sol';

struct L1WitnessData {
uint256 blockNo;
Expand All @@ -30,6 +31,7 @@ contract L1Verifier is IEVMVerifier {
}
RLPReader.RLPItem[] memory headerFields = RLPReader.readList(l1Data.blockHeader);
bytes32 stateRoot = bytes32(RLPReader.readBytes(headerFields[3]));
return 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);
}
}
6 changes: 3 additions & 3 deletions op-gateway/src/OPProofService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EVMProofHelper, type IProofService } from '@ensdomains/evm-gateway';
import { EVMProofHelper, convertIntoMerkleTrieProof, type IProofService } from '@ensdomains/evm-gateway';
import { type JsonRpcBlock } from '@ethereumjs/block';
import { AbiCoder, Contract, JsonRpcProvider, type AddressLike } from 'ethers';

Expand Down Expand Up @@ -109,7 +109,7 @@ export class OPProofService implements IProofService<OPProvableBlock> {
return AbiCoder.defaultAbiCoder().encode(
[
'tuple(uint256 l2OutputIndex, tuple(bytes32 version, bytes32 stateRoot, bytes32 messagePasserStorageRoot, bytes32 latestBlockhash) outputRootProof)',
'tuple(bytes[] stateTrieWitness, bytes[][] storageProofs)',
'tuple(bytes stateTrieWitness, bytes[] storageProofs)',
],
[
{
Expand All @@ -123,7 +123,7 @@ export class OPProofService implements IProofService<OPProvableBlock> {
latestBlockhash: rpcBlock.hash,
},
},
proof,
convertIntoMerkleTrieProof(proof),
]
);
}
Expand Down
12 changes: 4 additions & 8 deletions scroll-gateway/src/ScrollProofService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,10 @@ export class ScrollProofService implements IProofService<ScrollProvableBlock> {
const batchIndex = obj.batch_index
const proof = await this.helper.getProofs(Number(block.number), address, slots)
const compressedProofs:any = []
const accountProof: Array<string> = proof.stateTrieWitness;
const accountProof: string = proof.stateTrieWitness;
for (let index = 0; index < proof.storageProofs.length; index++) {
const storageProof: Array<string> = proof.storageProofs[index];
compressedProofs[index] = []
compressedProofs[index][0] = concat([
const storageProof: string = proof.storageProofs[index];
compressedProofs[index] = concat([
`0x${accountProof.length.toString(16).padStart(2, "0")}`,
...accountProof,
`0x${storageProof.length.toString(16).padStart(2, "0")}`,
Expand All @@ -77,16 +76,13 @@ export class ScrollProofService implements IProofService<ScrollProvableBlock> {
const res:any = AbiCoder.defaultAbiCoder().encode(
[
'tuple(uint256 batchIndex)',
'tuple(bytes[] stateTrieWitness, bytes[][] storageProofs)',
// Refactoring TODO
// 'tuple(bytes stateTrieWitness, bytes[] storageProofs)',
'tuple(bytes[] storageProofs)',
],
[
{
batchIndex
},
{
stateTrieWitness:[],
storageProofs:compressedProofs
},
]
Expand Down
25 changes: 7 additions & 18 deletions scroll-verifier/contracts/ScrollVerifier.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import {StateProof, EVMProofHelper} from '@ensdomains/evm-verifier/contracts/EVMProofHelper.sol';
import {EVMProofHelper} from '@ensdomains/evm-verifier/contracts/EVMProofHelper.sol';
import {IEVMVerifier} from '@ensdomains/evm-verifier/contracts/IEVMVerifier.sol';
import {RLPReader} from "@eth-optimism/contracts-bedrock/src/libraries/rlp/RLPReader.sol";

Expand Down Expand Up @@ -32,6 +32,10 @@ struct ScrollWitnessData {
uint256 batchIndex;
}

struct StateProof {
bytes[] storageProofs; // An array of proofs of individual storage elements
}

contract ScrollVerifier is IEVMVerifier {
error InvalidSlotSize(uint256 size);
IScrollChainCommitmentVerifier public immutable verifier;
Expand All @@ -50,24 +54,9 @@ contract ScrollVerifier is IEVMVerifier {
return _gatewayURLs;
}

function compressProof(
bytes[] memory stateTrieWitness,
bytes[][] memory storageProofs,
uint256 storageIndex
) public pure returns (bytes memory output) {
output = abi.encodePacked(uint8(stateTrieWitness.length));
for (uint256 i = 0; i < stateTrieWitness.length; i++) {
output = abi.encodePacked(output, stateTrieWitness[i]);
}
output = abi.encodePacked(output, uint8(storageProofs[storageIndex].length));
for (uint256 i = 0; i < storageProofs[storageIndex].length; i++) {
output = abi.encodePacked(output, storageProofs[storageIndex][i]);
}
return output;
}

function getTrieProof(address target, uint256 slot, bytes[] memory compressedProof, bytes32 root) internal view returns(bytes memory){
(bytes32 stateRoot, bytes32 storageValue) = verifier.verifyZkTrieProof(target, bytes32(slot), compressedProof[0]);
function getTrieProof(address target, uint256 slot, bytes memory compressedProof, bytes32 root) internal view returns(bytes memory){
(bytes32 stateRoot, bytes32 storageValue) = verifier.verifyZkTrieProof(target, bytes32(slot), compressedProof);
require(stateRoot == root, "stateRoot not matched");
return abi.encodePacked(storageValue);
}
Expand Down

0 comments on commit 5f7a8ef

Please sign in to comment.