Skip to content

Commit

Permalink
Merge branch 'master' into minimum-gapto-parentassertion
Browse files Browse the repository at this point in the history
  • Loading branch information
tsahee authored Dec 27, 2024
2 parents 3ada786 + 2409196 commit ad9ed98
Show file tree
Hide file tree
Showing 57 changed files with 3,815 additions and 249 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ arbitrator/tools/wasmer/target/
arbitrator/tools/wasm-tools/
arbitrator/tools/pricers/
arbitrator/tools/module_roots/
arbitrator/tools/stylus_benchmark
arbitrator/langs/rust/target/
arbitrator/langs/bf/target/

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/arbitrator-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ jobs:
- name: Rustfmt - langs/rust
run: cargo fmt --all --manifest-path arbitrator/langs/rust/Cargo.toml -- --check

- name: Rustfmt - tools/stylus_benchmark
run: cargo fmt --all --manifest-path arbitrator/tools/stylus_benchmark/Cargo.toml -- --check

- name: Make proofs from test cases
run: make -j test-gen-proofs

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/submodule-pin-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ jobs:
run: |
status_state="pending"
declare -Ar exceptions=(
[contracts]=origin/develop
[contracts]=origin/pre-bold
[nitro-testnode]=origin/master
#TODO Rachel to check these are the intended branches.
[arbitrator/langs/c]=origin/vm-storage-cache
[arbitrator/tools/wasmer]=origin/adopt-v4.2.8
Expand All @@ -38,7 +38,7 @@ jobs:
if [[ -v exceptions[$mod] ]]; then
branch=${exceptions[$mod]}
fi
if ! git -C $mod merge-base --is-ancestor HEAD $branch; then
echo $mod diverges from $branch
divergent=1
Expand Down
1 change: 1 addition & 0 deletions arbitrator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ members = [
exclude = [
"stylus/tests/",
"tools/wasmer/",
"tools/stylus_benchmark",
]
resolver = "2"

Expand Down
14 changes: 14 additions & 0 deletions arbitrator/arbutil/src/benchmark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2024, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE

use crate::evm::api::Ink;
use std::time::{Duration, Instant};

// Benchmark is used to track the performance of blocks of code in stylus
#[derive(Clone, Copy, Debug, Default)]
pub struct Benchmark {
pub timer: Option<Instant>,
pub elapsed_total: Duration,
pub ink_start: Option<Ink>,
pub ink_total: Ink,
}
1 change: 1 addition & 0 deletions arbitrator/arbutil/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2022-2024, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE

pub mod benchmark;
/// cbindgen:ignore
pub mod color;
pub mod crypto;
Expand Down
51 changes: 51 additions & 0 deletions arbitrator/jit/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2021-2024, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE

use std::path::PathBuf;
use structopt::StructOpt;

mod arbcompress;
mod caller_env;
pub mod machine;
mod prepare;
pub mod program;
mod socket;
pub mod stylus_backend;
mod test;
mod wasip1_stub;
mod wavmio;

#[derive(StructOpt)]
#[structopt(name = "jit-prover")]
pub struct Opts {
#[structopt(short, long)]
binary: PathBuf,
#[structopt(long, default_value = "0")]
inbox_position: u64,
#[structopt(long, default_value = "0")]
delayed_inbox_position: u64,
#[structopt(long, default_value = "0")]
position_within_message: u64,
#[structopt(long)]
last_block_hash: Option<String>,
#[structopt(long)]
last_send_root: Option<String>,
#[structopt(long)]
inbox: Vec<PathBuf>,
#[structopt(long)]
delayed_inbox: Vec<PathBuf>,
#[structopt(long)]
preimages: Option<PathBuf>,
#[structopt(long)]
cranelift: bool,
#[structopt(long)]
forks: bool,
#[structopt(long)]
pub debug: bool,
#[structopt(long)]
pub require_success: bool,
// JSON inputs supercede any of the command-line inputs which could
// be specified in the JSON file.
#[structopt(long)]
json_inputs: Option<PathBuf>,
}
51 changes: 3 additions & 48 deletions arbitrator/jit/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,13 @@
// Copyright 2022-2024, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE

use crate::machine::{Escape, WasmEnv};
use arbutil::{color, Color};
use eyre::Result;
use std::path::PathBuf;
use jit::machine;
use jit::machine::{Escape, WasmEnv};
use jit::Opts;
use structopt::StructOpt;

mod arbcompress;
mod caller_env;
mod machine;
mod prepare;
mod program;
mod socket;
mod stylus_backend;
mod test;
mod wasip1_stub;
mod wavmio;

#[derive(StructOpt)]
#[structopt(name = "jit-prover")]
pub struct Opts {
#[structopt(short, long)]
binary: PathBuf,
#[structopt(long, default_value = "0")]
inbox_position: u64,
#[structopt(long, default_value = "0")]
delayed_inbox_position: u64,
#[structopt(long, default_value = "0")]
position_within_message: u64,
#[structopt(long)]
last_block_hash: Option<String>,
#[structopt(long)]
last_send_root: Option<String>,
#[structopt(long)]
inbox: Vec<PathBuf>,
#[structopt(long)]
delayed_inbox: Vec<PathBuf>,
#[structopt(long)]
preimages: Option<PathBuf>,
#[structopt(long)]
cranelift: bool,
#[structopt(long)]
forks: bool,
#[structopt(long)]
debug: bool,
#[structopt(long)]
require_success: bool,
// JSON inputs supercede any of the command-line inputs which could
// be specified in the JSON file.
#[structopt(long)]
json_inputs: Option<PathBuf>,
}

fn main() -> Result<()> {
let opts = Opts::from_args();
let env = match WasmEnv::cli(&opts) {
Expand Down
2 changes: 1 addition & 1 deletion arbitrator/jit/src/prepare.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2022-2024, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE

use crate::WasmEnv;
use crate::machine::WasmEnv;
use arbutil::{Bytes32, PreimageType};
use eyre::Ok;
use prover::parse_input::FileData;
Expand Down
63 changes: 46 additions & 17 deletions arbitrator/jit/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#![allow(clippy::too_many_arguments)]

use crate::caller_env::JitEnv;
use crate::machine::{Escape, MaybeEscape, WasmEnvMut};
use crate::stylus_backend::exec_wasm;
use crate::machine::{Escape, MaybeEscape, WasmEnv, WasmEnvMut};
use crate::stylus_backend::{exec_wasm, MessageFromCothread};
use arbutil::evm::api::Gas;
use arbutil::Bytes32;
use arbutil::{evm::EvmData, format::DebugBytes, heapify};
Expand All @@ -16,6 +16,7 @@ use prover::{
machine::Module,
programs::{config::PricingParams, prelude::*},
};
use std::sync::Arc;

const DEFAULT_STYLUS_ARBOS_VERSION: u64 = 31;

Expand Down Expand Up @@ -130,10 +131,6 @@ pub fn new_program(
let evm_data: EvmData = unsafe { *Box::from_raw(evm_data_handler as *mut EvmData) };
let config: JitConfig = unsafe { *Box::from_raw(stylus_config_handler as *mut JitConfig) };

// buy ink
let pricing = config.stylus.pricing;
let ink = pricing.gas_to_ink(Gas(gas));

let Some(module) = exec.module_asms.get(&compiled_hash).cloned() else {
return Err(Escape::Failure(format!(
"module hash {:?} not found in {:?}",
Expand All @@ -142,6 +139,21 @@ pub fn new_program(
)));
};

exec_program(exec, module, calldata, config, evm_data, gas)
}

pub fn exec_program(
exec: &mut WasmEnv,
module: Arc<[u8]>,
calldata: Vec<u8>,
config: JitConfig,
evm_data: EvmData,
gas: u64,
) -> Result<u32, Escape> {
// buy ink
let pricing = config.stylus.pricing;
let ink = pricing.gas_to_ink(Gas(gas));

let cothread = exec_wasm(
module,
calldata,
Expand All @@ -162,7 +174,10 @@ pub fn new_program(
/// returns request_id for the first request from the program
pub fn start_program(mut env: WasmEnvMut, module: u32) -> Result<u32, Escape> {
let (_, exec) = env.jit_env();
start_program_with_wasm_env(exec, module)
}

pub fn start_program_with_wasm_env(exec: &mut WasmEnv, module: u32) -> Result<u32, Escape> {
if exec.threads.len() as u32 != module || module == 0 {
return Escape::hostio(format!(
"got request for thread {module} but len is {}",
Expand All @@ -179,26 +194,27 @@ pub fn start_program(mut env: WasmEnvMut, module: u32) -> Result<u32, Escape> {
/// request_id MUST be last request id returned from start_program or send_response
pub fn get_request(mut env: WasmEnvMut, id: u32, len_ptr: GuestPtr) -> Result<u32, Escape> {
let (mut mem, exec) = env.jit_env();
let msg = get_last_msg(exec, id)?;
mem.write_u32(len_ptr, msg.req_data.len() as u32);
Ok(msg.req_type)
}

pub fn get_last_msg(exec: &mut WasmEnv, id: u32) -> Result<MessageFromCothread, Escape> {
let thread = exec.threads.last_mut().unwrap();
let msg = thread.last_message()?;
if msg.1 != id {
return Escape::hostio("get_request id doesn't match");
};
mem.write_u32(len_ptr, msg.0.req_data.len() as u32);
Ok(msg.0.req_type)
Ok(msg.0)
}

// gets data associated with last request.
// request_id MUST be last request receieved
// data_ptr MUST point to a buffer of at least the length returned by get_request
pub fn get_request_data(mut env: WasmEnvMut, id: u32, data_ptr: GuestPtr) -> MaybeEscape {
let (mut mem, exec) = env.jit_env();
let thread = exec.threads.last_mut().unwrap();
let msg = thread.last_message()?;
if msg.1 != id {
return Escape::hostio("get_request id doesn't match");
};
mem.write_slice(data_ptr, &msg.0.req_data);
let msg = get_last_msg(exec, id)?;
mem.write_slice(data_ptr, &msg.req_data);
Ok(())
}

Expand All @@ -217,11 +233,21 @@ pub fn set_response(
let result = mem.read_slice(result_ptr, result_len as usize);
let raw_data = mem.read_slice(raw_data_ptr, raw_data_len as usize);

set_response_with_wasm_env(exec, id, gas, result, raw_data)
}

pub fn set_response_with_wasm_env(
exec: &mut WasmEnv,
id: u32,
gas: u64,
result: Vec<u8>,
raw_data: Vec<u8>,
) -> MaybeEscape {
let thread = exec.threads.last_mut().unwrap();
thread.set_response(id, result, raw_data, Gas(gas))
}

/// sends previos response
/// sends previous response
/// MUST be called right after set_response to the same id
/// returns request_id for the next request
pub fn send_response(mut env: WasmEnvMut, req_id: u32) -> Result<u32, Escape> {
Expand All @@ -239,16 +265,19 @@ pub fn send_response(mut env: WasmEnvMut, req_id: u32) -> Result<u32, Escape> {
/// removes the last created program
pub fn pop(mut env: WasmEnvMut) -> MaybeEscape {
let (_, exec) = env.jit_env();
pop_with_wasm_env(exec)
}

pub fn pop_with_wasm_env(exec: &mut WasmEnv) -> MaybeEscape {
match exec.threads.pop() {
None => Err(Escape::Child(eyre!("no child"))),
Some(mut thread) => thread.wait_done(),
}
}

pub struct JitConfig {
stylus: StylusConfig,
compile: CompileConfig,
pub stylus: StylusConfig,
pub compile: CompileConfig,
}

/// Creates a `StylusConfig` from its component parts.
Expand Down
4 changes: 4 additions & 0 deletions arbitrator/jit/src/stylus_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#![allow(clippy::too_many_arguments)]

use crate::machine::{Escape, MaybeEscape};
use arbutil::benchmark::Benchmark;
use arbutil::evm::api::{Gas, Ink, VecReader};
use arbutil::evm::{
api::{EvmApiMethod, EVM_API_METHOD_REQ_OFFSET},
Expand Down Expand Up @@ -35,6 +36,7 @@ struct MessageToCothread {
pub struct MessageFromCothread {
pub req_type: u32,
pub req_data: Vec<u8>,
pub benchmark: Benchmark,
}

struct CothreadRequestor {
Expand All @@ -51,6 +53,7 @@ impl RequestHandler<VecReader> for CothreadRequestor {
let msg = MessageFromCothread {
req_type: req_type as u32 + EVM_API_METHOD_REQ_OFFSET,
req_data: req_data.as_ref().to_vec(),
benchmark: Benchmark::default(),
};

if let Err(error) = self.tx.send(msg) {
Expand Down Expand Up @@ -169,6 +172,7 @@ pub fn exec_wasm(
let msg = MessageFromCothread {
req_data: output,
req_type: out_kind as u32,
benchmark: instance.env().benchmark,
};
instance
.env_mut()
Expand Down
4 changes: 4 additions & 0 deletions arbitrator/stylus/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// For license information, see https://github.com/nitro/blob/master/LICENSE

use arbutil::{
benchmark::Benchmark,
evm::{
api::{DataReader, EvmApi, Ink},
EvmData,
Expand Down Expand Up @@ -48,6 +49,8 @@ pub struct WasmEnv<D: DataReader, E: EvmApi<D>> {
pub compile: CompileConfig,
/// The runtime config
pub config: Option<StylusConfig>,
// Used to benchmark execution blocks of code
pub benchmark: Benchmark,
// Using the unused generic parameter D in a PhantomData field
_data_reader_marker: PhantomData<D>,
}
Expand All @@ -68,6 +71,7 @@ impl<D: DataReader, E: EvmApi<D>> WasmEnv<D, E> {
outs: vec![],
memory: None,
meter: None,
benchmark: Benchmark::default(),
_data_reader_marker: PhantomData,
}
}
Expand Down
Loading

0 comments on commit ad9ed98

Please sign in to comment.