-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WEB3-171: OP Steel #267
base: main
Are you sure you want to change the base?
WEB3-171: OP Steel #267
Changes from all commits
90c8b6d
3b3e10c
0114452
905e836
4c04ce6
f8dbe60
62d9631
8692fd2
d78b501
0a16a58
9149c51
c280ce1
7cd5fc0
8f125e9
6f6766a
dc13905
729284a
4a95ac8
983c5b4
080d328
9afa7c4
c92c479
164724a
1c52764
10d3c83
153abd4
8e7c544
6e3638f
e942ccc
dc82d73
5d96a92
e4bf626
5c6b4d0
975d3d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/bin/bash | ||
set -e | ||
|
||
run_verify(){ | ||
while read path; do | ||
printf "Project: %s\n" "$path" | ||
cargo run -F verify --manifest-path "$path" | ||
done | ||
} | ||
|
||
grep -rlz --include "Cargo.toml" 'verify\s*=\s*\[[^\[]*\]' | sort -u | run_verify |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Copyright 2024 RISC Zero, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
pragma solidity ^0.8.9; | ||
|
||
import {Encoding, Steel} from "./Steel.sol"; | ||
|
||
abstract contract OpCommitmentValidator { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, to be clear, this is the contract deployed on L1 to validate queries against OP L2 data, ya? It's always hard to keep these things straight (versus verifying on L2 querying L1). Adding a docstring contract itself to state this inline might be helpful. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am really unsure what the best Solidity design would be: Alternatively, Or have this an ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why make this an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the idea of encouraging people to inherit the |
||
/// @notice Address of the OptimismPortal2 contract. | ||
IOptimismPortal2 public immutable optimismPortal; | ||
|
||
constructor(address _optimismPortal) { | ||
optimismPortal = IOptimismPortal2(_optimismPortal); | ||
} | ||
|
||
/// @notice Validates a Steel commitment. | ||
/// @param commitment The commitment to validate. | ||
/// @return True if the commitment is valid, false otherwise. | ||
function validateCommitment(Steel.Commitment memory commitment) internal view returns (bool) { | ||
nategraf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
(uint240 blockID, uint16 version) = Encoding.decodeVersionedID(commitment.id); | ||
if (version == 0x100) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What can be do to reduce the chance of version number collisions causing issues as we expand support? Should we perhaps do something more like having a registry, or perhaps making is a "selector" that is resistant to accidental collisions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, I like this idea. We could use
|
||
return validateDisputeGameCommitment(blockID, commitment.digest); | ||
} else { | ||
return Steel.validateCommitment(commitment); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting! So this contract will validate L1 queries as well. This seems surprising to me, and potentially could cause issues if the caller thinks they are verifying a query against the L2. In particular, someone might use L1 state when and produce a proof when they should have used L2 state, and perhaps bypass some kind of authentication as a result. (e.g. maybe the query is to confirm tokens have been bridged from L1 to L2, and the prover chooses not to actually bridge the tokens, but produce a proof using the L1 balance). This raises an interesting point about how we bind the chain we are querying in the interface. My intuition here would be to have a distinct contract deployment for each chain that can be queried, but another way to do this might be to have a function that additionally takes the chain ID of the chain we are expecting to query. Of course, the guest could also bind this, but that doesn't quite seem like the right pattern to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One solution to this would be to check the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree 100%, especially with different chains and configID, we should rethink our Steel Solidity design. Unfortunately one library is not enough anymore and we should discuss what the right solution could be. |
||
} | ||
} | ||
|
||
/// @notice Validates a Dispute Game commitment. | ||
/// @param gameIndex The index of the game in the DisputeGameFactory. | ||
/// @param rootClaim The root claim of the dispute game. | ||
/// @return True if the commitment is valid, false otherwise. | ||
function validateDisputeGameCommitment(uint256 gameIndex, bytes32 rootClaim) internal view returns (bool) { | ||
IDisputeGameFactory factory = optimismPortal.disputeGameFactory(); | ||
|
||
// Retrieve game information from the factory. | ||
(uint32 gameType, uint64 createdAt, IDisputeGame game) = factory.gameAtIndex(gameIndex); | ||
|
||
// The game type of the dispute game must be the respected game type. | ||
if (gameType != optimismPortal.respectedGameType()) return false; | ||
// The game must have been created after `respectedGameTypeUpdatedAt`. | ||
if (createdAt < optimismPortal.respectedGameTypeUpdatedAt()) return false; | ||
// The game must be resolved in favor of the root claim (the output proposal). | ||
if (game.status() != GameStatus.DEFENDER_WINS) return false; | ||
// The game must have been resolved for at least `proofMaturityDelaySeconds`. | ||
if (block.timestamp - game.resolvedAt() <= optimismPortal.proofMaturityDelaySeconds()) return false; | ||
// The game must not be blacklisted. | ||
if (optimismPortal.disputeGameBlacklist(game)) return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like the OP design here because it makes
I don't see a good fix for this. I guess removing the |
||
|
||
// Finally, verify that the provided root claim matches the game's root claim. | ||
return game.rootClaim() == rootClaim; | ||
} | ||
} | ||
|
||
// https://github.com/ethereum-optimism/optimism/blob/v1.9.3/packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal2.sol | ||
interface IOptimismPortal2 { | ||
function disputeGameBlacklist(IDisputeGame) external view returns (bool); | ||
function disputeGameFactory() external view returns (IDisputeGameFactory); | ||
function proofMaturityDelaySeconds() external view returns (uint256); | ||
function respectedGameType() external view returns (uint32); | ||
function respectedGameTypeUpdatedAt() external view returns (uint64); | ||
function version() external pure returns (string memory); | ||
} | ||
|
||
// https://github.com/ethereum-optimism/optimism/blob/v1.9.3/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGameFactory.sol | ||
interface IDisputeGameFactory { | ||
function gameCount() external view returns (uint256); | ||
function gameAtIndex(uint256 index) external view returns (uint32 gameType, uint64 createdAt, IDisputeGame game); | ||
} | ||
|
||
// https://github.com/ethereum-optimism/optimism/blob/v1.9.3/packages/contracts-bedrock/src/dispute/interfaces/IDisputeGame.sol | ||
interface IDisputeGame { | ||
function status() external view returns (GameStatus); | ||
function resolvedAt() external view returns (uint64); | ||
function rootClaim() external pure returns (bytes32); | ||
} | ||
|
||
// https://github.com/ethereum-optimism/optimism/blob/v1.9.3/packages/contracts-bedrock/src/dispute/lib/Types.sol | ||
enum GameStatus { | ||
IN_PROGRESS, | ||
CHALLENGER_WINS, | ||
DEFENDER_WINS | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[package] | ||
name = "risc0-op-steel" | ||
description = "Optimism abstraction for Steel." | ||
version = "0.1.0-alpha.1" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is a good versioning for op-steel? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think marking it as it's own |
||
rust-version = "1.81" | ||
edition = { workspace = true } | ||
license = { workspace = true } | ||
homepage = { workspace = true } | ||
repository = { workspace = true } | ||
|
||
[package.metadata.docs.rs] | ||
all-features = true | ||
rustdoc-args = ["--cfg", "docsrs"] | ||
|
||
[dependencies] | ||
alloy = { workspace = true, optional = true, features = ["contract", "providers"] } | ||
alloy-primitives = { workspace = true, features = ["rlp", "serde"] } | ||
alloy-sol-types = { workspace = true } | ||
anyhow = { workspace = true } | ||
log = { workspace = true } | ||
op-alloy-network = { workspace = true } | ||
revm = { workspace = true, features = ["std", "optimism"] } | ||
risc0-steel = { workspace = true } | ||
serde = { workspace = true } | ||
test-log = { workspace = true } | ||
thiserror = { workspace = true } | ||
tokio = { workspace = true, optional = true } | ||
url = { workspace = true, optional = true } | ||
|
||
[dev-dependencies] | ||
risc0-op-steel = { workspace = true, features = ["host"] } | ||
|
||
[features] | ||
default = [] | ||
host = ["dep:alloy", "dep:tokio", "dep:url", "risc0-steel/host", "alloy-primitives/rand"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we run the CI against the actual live network, an alternative would be be to spin up a local docker devnet containing at least an L1, L2, and Beacon node