Skip to content

Commit

Permalink
change from transparent-proxy to immutable with external trie hooks a…
Browse files Browse the repository at this point in the history
…nd machine, add OP_LENGTH, OP_STACK_SIZE, add chain SHAPE, change all gateway proofs to tuples
  • Loading branch information
adraffy committed Oct 1, 2024
1 parent 1b63a38 commit 8edec00
Show file tree
Hide file tree
Showing 69 changed files with 2,693 additions and 2,006 deletions.
Binary file modified bun.lockb
Binary file not shown.
49 changes: 0 additions & 49 deletions contracts/AbstractSelfVerifier.sol

This file was deleted.

54 changes: 18 additions & 36 deletions contracts/AbstractVerifier.sol
Original file line number Diff line number Diff line change
@@ -1,58 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IGatewayProofVerifier} from "./IGatewayProofVerifier.sol";
import {IGatewayVerifier} from "./IGatewayVerifier.sol";
import {IProverHooks} from "./IProverHooks.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {StorageSlot} from "@openzeppelin/contracts/utils/StorageSlot.sol";

abstract contract AbstractVerifier is IGatewayProofVerifier {

event GatewayChanged();
abstract contract AbstractVerifier is IGatewayVerifier, Ownable {

bytes32 constant SLOT_urls = keccak256("unruggable.gateway.urls");
bytes32 constant SLOT_window = keccak256("unruggable.gateway.window");
event GatewayURLsChanged();

modifier onlyOwner() {
require(msg.sender == _owner(), "not admin owner");
_;
}
string[] _urls;
uint256 immutable _window;
IProverHooks immutable _hooks;

function _owner() internal view returns (address) {
return Ownable(ERC1967Utils.getAdmin()).owner();
}

function owner() external view returns (address) {
return _owner();
constructor(string[] memory urls, uint256 window, IProverHooks hooks) Ownable(msg.sender) {
_urls = urls;
_window = window;
_hooks = hooks;
}

function setGatewayURLs(string[] calldata urls) external onlyOwner {
StorageSlot.getBytesSlot(SLOT_urls).value = abi.encode(urls);
emit GatewayChanged();
function setGatewayURLs(string[] memory urls) external onlyOwner {
_urls = urls;
emit GatewayURLsChanged();
}

function gatewayURLs() external view returns (string[] memory) {
bytes memory storedValue = StorageSlot.getBytesSlot(SLOT_urls).value;
// Check if the stored value is empty or not set
if (storedValue.length == 0) {
return new string[](0);
}
return abi.decode(storedValue, (string[]));
}

function setWindow(uint256 window) external onlyOwner {
StorageSlot.getUint256Slot(SLOT_window).value = window;
emit GatewayChanged();
return _urls;
}

function getWindow() external view returns (uint256) {
return StorageSlot.getUint256Slot(SLOT_window).value;
return _window;
}

function _checkWindow(uint256 latest, uint256 got) internal view {
uint256 window = StorageSlot.getUint256Slot(SLOT_window).value;
if (got + window < latest) revert("too old");
if (got + _window < latest) revert("too old");
if (got > latest) revert("too new");
}

}
}
96 changes: 64 additions & 32 deletions contracts/GatewayFetchTarget.sol
Original file line number Diff line number Diff line change
@@ -1,42 +1,74 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GatewayRequest} from "./GatewayProtocol.sol";
import {IGatewayProofVerifier} from "./IGatewayProofVerifier.sol";
import {IGatewayProver} from "./IGatewayProver.sol";
import {IGatewayVerifier} from './IGatewayVerifier.sol';
import {GatewayRequest} from './GatewayRequest.sol';
import {IGatewayProver} from './IGatewayProver.sol';

error OffchainLookup(address from, string[] urls, bytes request, bytes4 callback, bytes carry);
error OffchainLookup(
address from,
string[] urls,
bytes request,
bytes4 callback,
bytes carry
);

abstract contract GatewayFetchTarget {
struct Session {
IGatewayVerifier verifier;
bytes context;
GatewayRequest req;
bytes4 callback;
bytes carry;
}

struct Session {
IGatewayProofVerifier verifier;
bytes context;
GatewayRequest req;
bytes4 callback;
bytes carry;
}
function fetch(
IGatewayVerifier verifier,
GatewayRequest memory req,
bytes4 callback
) internal view {
fetch(verifier, req, callback, '', new string[](0));
}

function fetch(IGatewayProofVerifier verifier, GatewayRequest memory req, bytes4 callback, bytes memory carry) internal view {
bytes memory context = verifier.getLatestContext();
revert OffchainLookup(
address(this),
verifier.gatewayURLs(),
abi.encodeCall(IGatewayProver.proveRequest, (context, req)),
this.fetchCallback.selector,
abi.encode(Session(verifier, context, req, callback, carry))
);
}

function fetchCallback(bytes calldata response, bytes calldata carry) external view {
Session memory ses = abi.decode(carry, (Session));
(bytes[] memory values, uint8 exitCode) = ses.verifier.getStorageValues(ses.context, ses.req, response);
(bool ok, bytes memory ret) = address(this).staticcall(abi.encodeWithSelector(ses.callback, values, exitCode, ses.carry));
if (ok) {
assembly { return(add(ret, 32), mload(ret)) }
} else {
assembly { revert(add(ret, 32), mload(ret)) }
}
}
function fetch(
IGatewayVerifier verifier,
GatewayRequest memory req,
bytes4 callback,
bytes memory carry,
string[] memory urls
) internal view {
bytes memory context = verifier.getLatestContext();
if (urls.length == 0) urls = verifier.gatewayURLs();
revert OffchainLookup(
address(this),
urls,
abi.encodeCall(IGatewayProver.proveRequest, (context, req)),
this.fetchCallback.selector,
abi.encode(Session(verifier, context, req, callback, carry))
);
}

function fetchCallback(
bytes calldata response,
bytes calldata carry
) external view {
Session memory ses = abi.decode(carry, (Session));
(bytes[] memory values, uint8 exitCode) = ses.verifier.getStorageValues(
ses.context,
ses.req,
response
);
(bool ok, bytes memory ret) = address(this).staticcall(
abi.encodeWithSelector(ses.callback, values, exitCode, ses.carry)
);
if (ok) {
assembly {
return(add(ret, 32), mload(ret))
}
} else {
assembly {
revert(add(ret, 32), mload(ret))
}
}
}
}
20 changes: 9 additions & 11 deletions contracts/GatewayFetcher.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./GatewayProtocol.sol";
import "./GatewayRequest.sol";

library GatewayFetcher {

Expand Down Expand Up @@ -54,7 +54,8 @@ library GatewayFetcher {
}
return r;
}
function addInput(GatewayRequest memory r, bytes memory v) internal pure returns (uint256 i) {

function defineInput(GatewayRequest memory r, bytes memory v) internal pure returns (uint256 i) {
bytes[] memory m = r.inputs;
uint256 n = m.length;
if (n >= MAX_INPUTS) revert RequestOverflow();
Expand Down Expand Up @@ -104,13 +105,16 @@ library GatewayFetcher {
return r;
}
function push(GatewayRequest memory r, bytes memory v) internal pure returns (GatewayRequest memory) {
return v.length <= 32 ? r.addByte(OP_PUSH_BYTES).addSmallBytes(v) : r.push(r.addInput(v)).addByte(OP_PUSH_INPUT);
return v.length <= 32 ? r.addByte(OP_PUSH_BYTES).addSmallBytes(v) : r.push(r.defineInput(v)).addByte(OP_PUSH_INPUT);
}

function pushTarget(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_PUSH_TARGET); }
function pushSlot(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_PUSH_SLOT); }
function pushStackSize(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_PUSH_STACK_SIZE); }

function target(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_TARGET); }
function setTarget(GatewayRequest memory r, address a) internal pure returns (GatewayRequest memory) { return r.push(a).target(); }
function requireContract(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_REQ_CONTRACT); }
function pushTarget(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_PUSH_TARGET); }

function follow(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_SLOT_FOLLOW); }
//function follow(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.pushSlot().concat().keccak().slot(); }
Expand All @@ -120,7 +124,6 @@ library GatewayFetcher {
function slot(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_SLOT); }
function setSlot(GatewayRequest memory r, uint256 x) internal pure returns (GatewayRequest memory) { return r.push(x).slot(); }
function offset(GatewayRequest memory r, uint256 dx) internal pure returns (GatewayRequest memory) { return r.push(dx).addSlot(); }
function pushSlot(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_PUSH_SLOT); }
//function zeroSlot(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_SLOT_ZERO); } // 20240922: deprecated
//function zeroSlot(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.push(uint256(0)).slot(); } // alternative

Expand All @@ -142,16 +145,11 @@ library GatewayFetcher {
function pushInput(GatewayRequest memory r, uint8 i) internal pure returns (GatewayRequest memory) { return r.push(i).addByte(OP_PUSH_INPUT); }
function pushOutput(GatewayRequest memory r, uint8 i) internal pure returns (GatewayRequest memory) { return r.push(i).addByte(OP_PUSH_OUTPUT); }

// function follow(GatewayRequest memory r, uint256 x) internal pure returns (GatewayRequest memory) { return r.push(x).follow(); }
// function follow(GatewayRequest memory r, bytes32 x) internal pure returns (GatewayRequest memory) { return r.push(x).follow(); }
// function follow(GatewayRequest memory r, address x) internal pure returns (GatewayRequest memory) { return r.push(x).follow(); }
// function follow(GatewayRequest memory r, string memory s) internal pure returns (GatewayRequest memory) { return r.push(s).follow(); }
// function follow(GatewayRequest memory r, bytes memory v) internal pure returns (GatewayRequest memory) { return r.push(v).follow(); }

function concat(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_CONCAT); }
function keccak(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_KECCAK); }
function slice(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_SLICE); }
function slice(GatewayRequest memory r, uint256 pos, uint256 len) internal pure returns (GatewayRequest memory) { return r.push(pos).push(len).slice(); }
function length(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_LENGTH); }

function plus(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_PLUS); }
function times(GatewayRequest memory r) internal pure returns (GatewayRequest memory) { return r.addByte(OP_TIMES); }
Expand Down
Loading

0 comments on commit 8edec00

Please sign in to comment.