Skip to content

Commit

Permalink
Merge branch 'main' of github.com:risc0/risc0-ethereum into victor/mmr
Browse files Browse the repository at this point in the history
  • Loading branch information
nategraf committed Jan 10, 2025
2 parents 8af3229 + 917180d commit 94065e9
Show file tree
Hide file tree
Showing 28 changed files with 625 additions and 218 deletions.
13 changes: 6 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-
risc0-binfmt = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false }

# Alloy guest dependencies
alloy-consensus = { version = "0.8" }
alloy-consensus = { version = "0.9" }
alloy-rlp = { version = "0.3.8" }
alloy-primitives = { version = "0.8.8" }
alloy-sol-types = { version = "0.8.8" }
alloy-primitives = { version = "0.8.16" }
alloy-sol-types = { version = "0.8.16" }

# OP Steel
op-alloy-network = { version = "0.8" }
op-alloy-network = { version = "0.9" }

# Alloy host dependencies
alloy = { version = "0.8" }
# Note: semver breaking change in 0.7.7, be careful if switching to lower patch version
alloy = { version = "0.9" }
alloy-trie = { version = "0.7.7" }

# Beacon chain support
Expand All @@ -45,7 +44,7 @@ anyhow = { version = "1.0" }
bincode = { version = "1.3" }
clap = { version = "4.5", features = ["derive", "env"] }
log = "0.4"
revm = { version = "18.0", default-features = false, features = ["std"] }
revm = { version = "19.2", default-features = false, features = ["std"] }
reqwest = "0.12"
serde = "1.0"
serde_json = "1.0"
Expand Down
5 changes: 2 additions & 3 deletions build/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 RISC Zero, Inc.
// Copyright 2025 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.
Expand All @@ -21,7 +21,6 @@ use std::{

use anyhow::{anyhow, bail, Context, Result};
use risc0_build::GuestListEntry;
use risc0_zkp::core::digest::Digest;

const SOL_HEADER: &str = r#"// Copyright 2024 RISC Zero, Inc.
//
Expand Down Expand Up @@ -109,7 +108,7 @@ pub fn generate_image_id_sol(guests: &[GuestListEntry]) -> Result<Vec<u8>> {
.iter()
.map(|guest| {
let name = guest.name.to_uppercase().replace('-', "_");
let image_id = hex::encode(Digest::from(guest.image_id));
let image_id = hex::encode(guest.image_id);
format!("bytes32 public constant {name}_ID = bytes32(0x{image_id});")
})
.collect();
Expand Down
2 changes: 1 addition & 1 deletion examples/erc20-counter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ risc0-build = { git = "https://github.com/risc0/risc0", branch = "main", feature
risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false }
risc0-zkp = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false }

alloy = { version = "0.8", features = ["full"] }
alloy = { version = "0.9", features = ["full"] }
alloy-primitives = { version = "0.8", features = ["rlp", "serde", "std"] }
alloy-sol-types = { version = "0.8" }
anyhow = { version = "1.0.75" }
Expand Down
1 change: 0 additions & 1 deletion examples/erc20-counter/apps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version = { workspace = true }
edition = { workspace = true }

[dependencies]
alloy = { workspace = true }
alloy-primitives = { workspace = true }
anyhow = { workspace = true }
clap = { workspace = true, features = ["derive", "env"] }
Expand Down
19 changes: 10 additions & 9 deletions examples/erc20-counter/apps/src/bin/publisher.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 RISC Zero, Inc.
// Copyright 2025 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.
Expand All @@ -16,17 +16,18 @@
// to the Bonsai proving service and publish the received proofs directly
// to your deployed app contract.

use alloy::{
network::EthereumWallet,
providers::ProviderBuilder,
signers::local::PrivateKeySigner,
sol_types::{SolCall, SolValue},
};
use alloy_primitives::{Address, U256};
use anyhow::{ensure, Context, Result};
use clap::Parser;
use erc20_counter_methods::{BALANCE_OF_ELF, BALANCE_OF_ID};
use risc0_ethereum_contracts::encode_seal;
use risc0_steel::alloy::{
network::EthereumWallet,
providers::ProviderBuilder,
signers::local::PrivateKeySigner,
sol,
sol_types::{SolCall, SolValue},
};
use risc0_steel::{
ethereum::{EthEvmEnv, ETH_SEPOLIA_CHAIN_SPEC},
host::BlockNumberOrTag,
Expand All @@ -37,7 +38,7 @@ use tokio::task;
use tracing_subscriber::EnvFilter;
use url::Url;

alloy::sol! {
sol! {
/// Interface to be called by the guest.
interface IERC20 {
function balanceOf(address account) external view returns (uint);
Expand All @@ -50,7 +51,7 @@ alloy::sol! {
}
}

alloy::sol!(
sol!(
#[sol(rpc, all_derives)]
"../contracts/src/ICounter.sol"
);
Expand Down
2 changes: 1 addition & 1 deletion examples/governance/apps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = { workspace = true }
edition = { workspace = true }

[dependencies]
alloy = { version = "0.8", features = ["full"] }
alloy = { version = "0.9", features = ["full"] }
alloy-primitives = { workspace = true }
alloy-sol-types = { workspace = true }
anyhow = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion examples/op/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ risc0-op-steel = { path = "../../op-steel" }
risc0-steel = { path = "../../steel" }
risc0-ethereum-contracts = { path = "../../contracts" }
examples-common = { path = "common" }
alloy = { version = "0.8" }
alloy = "0.9"
3 changes: 1 addition & 2 deletions examples/token-stats/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = ["core", "host", "methods"]

[workspace.dependencies]
# Intra-workspace dependencies
risc0-steel = { path = "../../steel" }
risc0-steel = { path = "../../steel", features = ["unstable-verifier"] }

# risc0 monorepo dependencies.
risc0-build = { git = "https://github.com/risc0/risc0", branch = "main" }
Expand All @@ -21,7 +21,6 @@ log = "0.4"
token-stats-core = { path = "core" }
token-stats-methods = { path = "methods" }
once_cell = "1.19"
rlp = "0.5.2"
serde = "1.0"
thiserror = "2.0"
tokio = { version = "1.35", features = ["full"] }
Expand Down
71 changes: 62 additions & 9 deletions examples/token-stats/host/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 RISC Zero, Inc.
// Copyright 2025 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.
Expand All @@ -16,22 +16,26 @@ use alloy_sol_types::{SolCall, SolValue};
use anyhow::{Context, Result};
use clap::Parser;
use risc0_steel::{
alloy::providers::{Provider, ProviderBuilder},
ethereum::{EthEvmEnv, ETH_MAINNET_CHAIN_SPEC},
Contract,
Contract, SteelVerifier,
};
use risc0_zkvm::{default_executor, ExecutorEnv};
use token_stats_core::{APRCommitment, CometMainInterface, CONTRACT};
use token_stats_methods::TOKEN_STATS_ELF;
use tracing_subscriber::EnvFilter;
use url::Url;

// Simple program to show the use of Ethereum contract data inside the guest.
#[derive(Parser, Debug)]
#[command(about, long_about = None)]
struct Args {
/// URL of the RPC endpoint
#[arg(short, long, env = "RPC_URL")]
#[arg(long, env)]
rpc_url: Url,

/// Beacon API endpoint URL
#[clap(long, env)]
beacon_api_url: Url,
}

#[tokio::main]
Expand All @@ -43,8 +47,17 @@ async fn main() -> Result<()> {
// Parse the command line arguments.
let args = Args::parse();

// Create an EVM environment from an RPC endpoint defaulting to the latest block.
let mut env = EthEvmEnv::builder().rpc(args.rpc_url).build().await?;
// Query the latest block number.
let provider = ProviderBuilder::new().on_http(args.rpc_url);
let latest = provider.get_block_number().await?;

// Create an EVM environment for that provider and about 12h (3600 blocks) ago.
let mut env = EthEvmEnv::builder()
.provider(provider.clone())
.block_number(latest - 3600)
.beacon_api(args.beacon_api_url)
.build()
.await?;
// The `with_chain_spec` method is used to specify the chain configuration.
env = env.with_chain_spec(&ETH_MAINNET_CHAIN_SPEC);

Expand Down Expand Up @@ -74,13 +87,53 @@ async fn main() -> Result<()> {
rate
);

// Finally, construct the input from the environment.
let input = env.into_input().await?;
// Construct the commitment and input from the environment representing the state 12h ago.
let commitment_input1 = env.commitment();
let input1 = env.into_input().await?;

// Create another EVM environment for that provider defaulting to the latest block.
let mut env = EthEvmEnv::builder().provider(provider).build().await?;
env = env.with_chain_spec(&ETH_MAINNET_CHAIN_SPEC);

// Preflight the verification of the commitment of the previous input.
SteelVerifier::preflight(&mut env)
.verify(&commitment_input1)
.await?;

// Preflight the actual contract calls.
let mut contract = Contract::preflight(CONTRACT, &mut env);
let utilization = contract
.call_builder(&CometMainInterface::getUtilizationCall {})
.call()
.await?
._0;
println!(
"Call {} Function on {:#} returns: {}",
CometMainInterface::getUtilizationCall::SIGNATURE,
CONTRACT,
utilization
);
let rate = contract
.call_builder(&CometMainInterface::getSupplyRateCall { utilization })
.call()
.await?
._0;
println!(
"Call {} Function on {:#} returns: {}",
CometMainInterface::getSupplyRateCall::SIGNATURE,
CONTRACT,
rate
);

// Finally, construct the second input from the environment representing the latest state.
let input2 = env.into_input().await?;

println!("Running the guest with the constructed input:");
let session_info = {
let env = ExecutorEnv::builder()
.write(&input)
.write(&input1)
.unwrap()
.write(&input2)
.unwrap()
.build()
.context("failed to build executor env")?;
Expand Down
2 changes: 1 addition & 1 deletion examples/token-stats/methods/guest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2021"

[dependencies]
alloy-sol-types = { version = "0.8" }
risc0-steel = { path = "../../../../steel" }
risc0-steel = { path = "../../../../steel", features = ["unstable-verifier"] }
risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false, features = ["std"] }
token-stats-core = { path = "../../core" }

Expand Down
44 changes: 30 additions & 14 deletions examples/token-stats/methods/guest/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 RISC Zero, Inc.
// Copyright 2025 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.
Expand All @@ -15,29 +15,46 @@
use alloy_sol_types::SolValue;
use risc0_steel::{
ethereum::{EthEvmInput, ETH_MAINNET_CHAIN_SPEC},
Contract,
Contract, SteelVerifier,
};
use risc0_zkvm::guest::env;
use token_stats_core::{APRCommitment, CometMainInterface, CONTRACT};

const SECONDS_PER_YEAR: u64 = 60 * 60 * 24 * 365;

fn main() {
// Read the input from the guest environment.
// Read the first input from the guest environment. It corresponds to the older EVM state.
let input: EthEvmInput = env::read();

// Converts the input into a `EvmEnv` for execution. The `with_chain_spec` method is used
// to specify the chain configuration. It checks that the state matches the state root in the
// header provided in the input.
let env = input.into_env().with_chain_spec(&ETH_MAINNET_CHAIN_SPEC);
// Converts the input into a `EvmEnv` for execution.
let env_prev = input.into_env().with_chain_spec(&ETH_MAINNET_CHAIN_SPEC);

// Execute the view calls; it returns the result in the type generated by the `sol!` macro.
let contract = Contract::new(CONTRACT, &env);
// Execute the view calls on the older EVM state.
let contract = Contract::new(CONTRACT, &env_prev);
let utilization = contract
.call_builder(&CometMainInterface::getUtilizationCall {})
.call()
._0;
let supply_rate = contract
let supply_rate_prev = contract
.call_builder(&CometMainInterface::getSupplyRateCall { utilization })
.call()
._0;

// Prepare the second `EvmEnv` for execution. It corresponds to the recent EVM state.
let input: EthEvmInput = env::read();
let env_cur = input.into_env().with_chain_spec(&ETH_MAINNET_CHAIN_SPEC);

// Verify that the older EVM state is valid wrt the recent EVM state.
// We initialize the SteelVerifier with the recent state, to check the previous commitment.
SteelVerifier::new(&env_cur).verify(env_prev.commitment());

// Execute the view calls also on the recent EVM state.
let contract = Contract::new(CONTRACT, &env_cur);
let utilization = contract
.call_builder(&CometMainInterface::getUtilizationCall {})
.call()
._0;
let supply_rate_cur = contract
.call_builder(&CometMainInterface::getSupplyRateCall { utilization })
.call()
._0;
Expand All @@ -48,13 +65,12 @@ fn main() {
// Supply Rate = getSupplyRate(Utilization)
// Supply APR = Supply Rate / (10 ^ 18) * Seconds Per Year * 100
//
// And this is calculating: Supply Rate * Seconds Per Year, to avoid float calculations for
// precision.
let annual_supply_rate = supply_rate * SECONDS_PER_YEAR;
// Compute the average APR, by computing the average over both states.
let annual_supply_rate = (supply_rate_prev + supply_rate_cur) * SECONDS_PER_YEAR / 2;

// This commits the APR at current utilization rate for this given block.
let journal = APRCommitment {
commitment: env.into_commitment(),
commitment: env_cur.into_commitment(),
annualSupplyRate: annual_supply_rate,
};
env::commit_slice(&journal.abi_encode());
Expand Down
4 changes: 2 additions & 2 deletions op-steel/src/optimism/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 RISC Zero, Inc.
// Copyright 2025 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.
Expand Down Expand Up @@ -112,7 +112,7 @@ impl EvmBlockHeader for OpBlockHeader {
// technically, this is only valid after EIP-4399 but revm makes sure it is not used before
blk_env.prevrandao = Some(header.mix_hash);
if let Some(excess_blob_gas) = header.excess_blob_gas {
blk_env.set_blob_excess_gas_and_price(excess_blob_gas)
blk_env.set_blob_excess_gas_and_price(excess_blob_gas, false)
};
}
}
Expand Down
4 changes: 4 additions & 0 deletions steel/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### ⚡️ Features

- Introduce the `SteelVerifier`, which acts as a built-in Steel `Contract` to verify Steel commitments. It is used like any other `Contract`, during the preflight step and in the guest. This functionality is currently marked unstable and must be enabled using the `unstable-verifier` feature.

## [1.2.0](https://github.com/risc0/risc0-ethereum/releases/tag/v1.2.0)

### ⚡️ Features
Expand Down
3 changes: 2 additions & 1 deletion steel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
alloy = { workspace = true, optional = true, features = ["eips", "network", "provider-http", "rpc-types"] }
alloy = { workspace = true, optional = true, features = ["full"] }
alloy-consensus = { workspace = true }
alloy-primitives = { workspace = true, features = ["rlp", "serde"] }
alloy-rlp = { workspace = true }
Expand Down Expand Up @@ -51,3 +51,4 @@ host = [
"dep:url",
]
unstable-history = []
unstable-verifier = []
Loading

0 comments on commit 94065e9

Please sign in to comment.