Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Golang
uses: actions/setup-go@v5
with:
Expand Down
51 changes: 41 additions & 10 deletions rvgo/bindings/riscv.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 25 additions & 14 deletions rvsol/src/RISCV.sol
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
pragma solidity 0.8.15;

import { IPreimageOracle } from "@optimism/src/cannon/interfaces/IPreimageOracle.sol";

contract RISCV {
import { IBigStepper } from "@optimism/src/dispute/interfaces/IBigStepper.sol";

/// @title RISCV
/// @notice The RISCV contract emulates a single RISCV hart cycle statelessly, using memory proofs to verify the
/// instruction and optional memory access' inclusion in the memory merkle root provided in the trusted
/// prestate witness.
/// @dev https://github.com/ethereum-optimism/asterisc
contract RISCV is IBigStepper {
/// @notice The preimage oracle contract.
IPreimageOracle public oracle;

/// @notice The version of the contract.
/// @custom:semver 1.1.0-rc.1
string public constant version = "1.1.0-rc.1";

/// @param _oracle The preimage oracle contract.
constructor(IPreimageOracle _oracle) {
oracle = _oracle;
}

// Executes a single RISC-V instruction, starting from
function step(bytes calldata stateData, bytes calldata proof, bytes32 localContext) public returns (bytes32) {
/// @inheritdoc IBigStepper
function step(bytes calldata _stateData, bytes calldata _proof, bytes32 _localContext) public returns (bytes32) {
assembly {
function revertWithCode(code) {
mstore(0, code)
Expand Down Expand Up @@ -310,11 +322,11 @@ contract RISCV {
// expected memory check: no allocated memory (start after scratch + free-mem-ptr + zero slot = 0x80)
revert(0, 0)
}
if iszero(eq(stateData.offset, 132)) {
if iszero(eq(_stateData.offset, 132)) {
// 32*4+4 = 132 expected state data offset
revert(0, 0)
}
if iszero(eq(calldataload(sub(stateData.offset, 32)), stateSize())) {
if iszero(eq(calldataload(sub(_stateData.offset, 32)), stateSize())) {
// user-provided state size must match expected state size
revert(0, 0)
}
Expand All @@ -323,7 +335,7 @@ contract RISCV {
let padding := mod(sub(32, mod(v, 32)), 32)
out := add(v, padding)
}
if iszero(eq(proof.offset, add(add(stateData.offset, paddedLen(stateSize())), 32))) {
if iszero(eq(_proof.offset, add(add(_stateData.offset, paddedLen(stateSize())), 32))) {
// 132+stateSize+padding+32 = expected proof offset
revert(0, 0)
}
Expand All @@ -332,7 +344,7 @@ contract RISCV {
// 132+362+(32-362%32)+32=548
out := 548
}
if iszero(eq(proof.offset, proofContentOffset())) { revert(0, 0) }
if iszero(eq(_proof.offset, proofContentOffset())) { revert(0, 0) }

//
// State loading
Expand All @@ -342,7 +354,7 @@ contract RISCV {
}
// copy the state calldata into memory, so we can mutate it
mstore(0x40, add(memStateOffset(), stateSize())) // alloc, update free mem pointer
calldatacopy(memStateOffset(), stateData.offset, stateSize()) // same format in memory as in calldata
calldatacopy(memStateOffset(), _stateData.offset, stateSize()) // same format in memory as in calldata

//
// State access
Expand Down Expand Up @@ -764,8 +776,7 @@ contract RISCV {
// as prefix
mstore(add(memPtr, 0x04), key)
mstore(add(memPtr, 0x24), offset)
let cgas := 100000 // TODO change call gas
let res := call(cgas, addr, 0, memPtr, 0x44, 0x00, 0x40) // output into scratch space
let res := call(gas(), addr, 0, memPtr, 0x44, 0x00, 0x40) // output into scratch space
if res {
// 1 on success
dat := mload(0x00)
Expand All @@ -775,7 +786,7 @@ contract RISCV {
revertWithCode(0xbadf00d0)
}

// Original implementation is at @optimism/src/cannon/PreimageKeyLib.sol
// Original implementation is at src/cannon/PreimageKeyLib.sol
// but it cannot be used because this is inside assembly block
function localize(preImageKey, localContext_) -> localizedKey {
// Grab the current free memory pointer to restore later.
Expand Down Expand Up @@ -1499,7 +1510,7 @@ contract RISCV {
// I-type, top 12 bits
case 0 {
// imm12 = 000000000000 ECALL
sysCall(localContext)
sysCall(_localContext)
setPC(add64(_pc, toU64(4)))
}
default {
Expand Down