forked from ensdomains/evmgateway
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
30 changed files
with
2,152 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,5 @@ | |
# (uses first one: infura > alchemy > public) | ||
INFURA_KEY= | ||
ALCHEMY_KEY= | ||
ANKR_KEY= | ||
PORT=8000 |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.23; | ||
|
||
import {EVMRequest, EVMProver, ProofSequence} from "../EVMProver.sol"; | ||
import {LineaTrieCallbacks} from "./LineaTrieCallbacks.sol"; | ||
|
||
contract LineaSelfVerifier { | ||
|
||
function verify(EVMRequest memory req, bytes32 stateRoot, bytes[] memory proofs, bytes memory order) external view returns (bytes[] memory outputs, uint8 exitCode) { | ||
return EVMProver.evalRequest(req, ProofSequence(0, | ||
stateRoot, | ||
proofs, order, | ||
LineaTrieCallbacks.proveAccountState, | ||
LineaTrieCallbacks.proveStorageValue | ||
)); | ||
} | ||
|
||
function verify_proveAccountState(bytes32 stateRoot, address target, bytes memory encodedProof) internal pure returns (bytes32) { | ||
return LineaTrieCallbacks.proveAccountState(stateRoot, target, encodedProof); | ||
} | ||
|
||
function verify_proveStorageValue(bytes32 storageRoot, address target, uint256 slot, bytes memory encodedProof) internal pure returns (uint256) { | ||
return uint256(LineaTrieCallbacks.proveStorageValue(storageRoot, target, slot, encodedProof)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.23; | ||
|
||
import {SparseMerkleProof} from "./SparseMerkleProof.sol"; | ||
import {NOT_A_CONTRACT, NULL_CODE_HASH} from "../ProofUtils.sol"; | ||
|
||
import "forge-std/console2.sol"; | ||
|
||
error InvalidProof(); | ||
|
||
library LineaTrieCallbacks { | ||
|
||
uint256 constant LAST_LEAF_INDEX = 41; | ||
|
||
struct Proof { | ||
uint256 leafIndex; | ||
bytes value; | ||
bytes[] nodes; | ||
} | ||
|
||
function proveAccountState(bytes32 stateRoot, address target, bytes memory encodedProof) internal pure returns (bytes32) { | ||
Proof[] memory proofs = abi.decode(encodedProof, (Proof[])); | ||
if (proofs.length == 1) { | ||
Proof memory proof = proofs[0]; | ||
if (!SparseMerkleProof.verifyProof(proof.nodes, proof.leafIndex, stateRoot)) revert InvalidProof(); | ||
bytes32 targetHash = SparseMerkleProof.mimcHash(abi.encode(target)); | ||
SparseMerkleProof.Leaf memory leaf = SparseMerkleProof.getLeaf(proof.nodes[LAST_LEAF_INDEX]); | ||
if (targetHash != leaf.hKey) revert InvalidProof(); | ||
bytes32 valueHash = SparseMerkleProof.hashAccountValue(proof.value); | ||
if (valueHash != leaf.hValue) revert InvalidProof(); | ||
SparseMerkleProof.Account memory account = SparseMerkleProof.getAccount(proof.value); | ||
return account.keccakCodeHash == NULL_CODE_HASH ? NOT_A_CONTRACT : account.storageRoot; | ||
} else { | ||
proveDoesNotExist(proofs[0], proofs[1]); | ||
return NOT_A_CONTRACT; | ||
} | ||
} | ||
|
||
function proveDoesNotExist(Proof memory left, Proof memory right) internal pure { | ||
|
||
} | ||
|
||
function proveStorageValue(bytes32 storageRoot, address, uint256 slot, bytes memory encodedProof) internal pure returns (uint256) { | ||
Proof[] memory proofs = abi.decode(encodedProof, (Proof[])); | ||
if (proofs.length == 1) { | ||
Proof memory proof = proofs[0]; | ||
if (!SparseMerkleProof.verifyProof(proof.nodes, proof.leafIndex, storageRoot)) revert InvalidProof(); | ||
SparseMerkleProof.Leaf memory leaf = SparseMerkleProof.getLeaf(proof.nodes[LAST_LEAF_INDEX]); | ||
if (SparseMerkleProof.hashStorageValue(bytes32(slot)) != leaf.hKey) revert InvalidProof(); | ||
bytes32 value = bytes32(proof.value); | ||
if (SparseMerkleProof.hashStorageValue(value) != leaf.hValue) revert InvalidProof(); | ||
return uint256(value); | ||
} else { | ||
proveDoesNotExist(proofs[0], proofs[1]); | ||
return 0; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.23; | ||
|
||
import "../OwnedVerifier.sol"; | ||
import {EVMProver, ProofSequence} from "../EVMProver.sol"; | ||
import {LineaTrieCallbacks} from "./LineaTrieCallbacks.sol"; | ||
|
||
import "forge-std/console2.sol"; | ||
|
||
interface IRollup { | ||
function currentL2BlockNumber() external view returns (uint256); | ||
function stateRootHashes(uint256 l2BlockNumber) external view returns (bytes32); | ||
} | ||
|
||
contract LineaVerifier is OwnedVerifier { | ||
|
||
IRollup immutable _rollup; | ||
|
||
constructor(string[] memory urls, uint256 window, IRollup rollup) OwnedVerifier(urls, window) { | ||
_rollup = rollup; | ||
} | ||
|
||
function getLatestContext() external view returns (bytes memory) { | ||
return abi.encode(_rollup.currentL2BlockNumber()); | ||
} | ||
|
||
function getStorageValues(bytes memory context, EVMRequest memory req, bytes memory proof) external view returns (bytes[] memory, uint8 exitCode) { | ||
uint256 latestL2BlockNumber = abi.decode(context, (uint256)); | ||
( | ||
uint256 l2BlockNumber, | ||
bytes[] memory proofs, | ||
bytes memory order | ||
) = abi.decode(proof, (uint256, bytes[], bytes)); | ||
_checkWindow(latestL2BlockNumber, l2BlockNumber); | ||
bytes32 stateRoot = _rollup.stateRootHashes(l2BlockNumber); | ||
require(stateRoot != bytes32(0), "Linea: not finalized"); | ||
return EVMProver.evalRequest(req, ProofSequence(0, | ||
stateRoot, | ||
proofs, order, | ||
LineaTrieCallbacks.proveAccountState, | ||
LineaTrieCallbacks.proveStorageValue | ||
)); | ||
} | ||
|
||
} | ||
|
Oops, something went wrong.