Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Implement transient get/set bytes32 hostios #185

Closed
wants to merge 6 commits into from
Closed
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
74 changes: 50 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -122,30 +122,38 @@ get_stylus_test_rust = $(wildcard $(stylus_test_dir)/$(1)/*.toml $(stylus_test_d
get_stylus_test_c = $(wildcard $(c_sdk)/examples/$(1)/*.c $(c_sdk)/examples/$(1)/*.h) $(stylus_lang_c)
stylus_test_bfs = $(wildcard $(stylus_test_dir)/bf/*.b)

stylus_test_keccak_wasm = $(call get_stylus_test_wasm,keccak)
stylus_test_keccak_src = $(call get_stylus_test_rust,keccak)
stylus_test_keccak-100_wasm = $(call get_stylus_test_wasm,keccak-100)
stylus_test_keccak-100_src = $(call get_stylus_test_rust,keccak-100)
stylus_test_fallible_wasm = $(call get_stylus_test_wasm,fallible)
stylus_test_fallible_src = $(call get_stylus_test_rust,fallible)
stylus_test_storage_wasm = $(call get_stylus_test_wasm,storage)
stylus_test_storage_src = $(call get_stylus_test_rust,storage)
stylus_test_multicall_wasm = $(call get_stylus_test_wasm,multicall)
stylus_test_multicall_src = $(call get_stylus_test_rust,multicall)
stylus_test_log_wasm = $(call get_stylus_test_wasm,log)
stylus_test_log_src = $(call get_stylus_test_rust,log)
stylus_test_create_wasm = $(call get_stylus_test_wasm,create)
stylus_test_create_src = $(call get_stylus_test_rust,create)
stylus_test_evm-data_wasm = $(call get_stylus_test_wasm,evm-data)
stylus_test_evm-data_src = $(call get_stylus_test_rust,evm-data)
stylus_test_sdk-storage_wasm = $(call get_stylus_test_wasm,sdk-storage)
stylus_test_sdk-storage_src = $(call get_stylus_test_rust,sdk-storage)
stylus_test_erc20_wasm = $(call get_stylus_test_wasm,erc20)
stylus_test_erc20_src = $(call get_stylus_test_rust,erc20)
stylus_test_read-return-data_wasm = $(call get_stylus_test_wasm,read-return-data)
stylus_test_read-return-data_src = $(call get_stylus_test_rust,read-return-data)

stylus_test_wasms = $(stylus_test_keccak_wasm) $(stylus_test_keccak-100_wasm) $(stylus_test_fallible_wasm) $(stylus_test_storage_wasm) $(stylus_test_multicall_wasm) $(stylus_test_log_wasm) $(stylus_test_create_wasm) $(stylus_test_sdk-storage_wasm) $(stylus_test_erc20_wasm) $(stylus_test_read-return-data_wasm) $(stylus_test_evm-data_wasm) $(stylus_test_bfs:.b=.wasm)
stylus_test_keccak_wasm = $(call get_stylus_test_wasm,keccak)
stylus_test_keccak_src = $(call get_stylus_test_rust,keccak)
stylus_test_keccak-100_wasm = $(call get_stylus_test_wasm,keccak-100)
stylus_test_keccak-100_src = $(call get_stylus_test_rust,keccak-100)
stylus_test_fallible_wasm = $(call get_stylus_test_wasm,fallible)
stylus_test_fallible_src = $(call get_stylus_test_rust,fallible)
stylus_test_storage_wasm = $(call get_stylus_test_wasm,storage)
stylus_test_storage_src = $(call get_stylus_test_rust,storage)
stylus_test_multicall_wasm = $(call get_stylus_test_wasm,multicall)
stylus_test_multicall_src = $(call get_stylus_test_rust,multicall)
stylus_test_log_wasm = $(call get_stylus_test_wasm,log)
stylus_test_log_src = $(call get_stylus_test_rust,log)
stylus_test_create_wasm = $(call get_stylus_test_wasm,create)
stylus_test_create_src = $(call get_stylus_test_rust,create)
stylus_test_evm-data_wasm = $(call get_stylus_test_wasm,evm-data)
stylus_test_evm-data_src = $(call get_stylus_test_rust,evm-data)
stylus_test_sdk-storage_wasm = $(call get_stylus_test_wasm,sdk-storage)
stylus_test_sdk-storage_src = $(call get_stylus_test_rust,sdk-storage)
stylus_test_erc20_wasm = $(call get_stylus_test_wasm,erc20)
stylus_test_erc20_src = $(call get_stylus_test_rust,erc20)
stylus_test_read-return-data_wasm = $(call get_stylus_test_wasm,read-return-data)
stylus_test_read-return-data_src = $(call get_stylus_test_rust,read-return-data)
stylus_test_transient-enter_wasm = $(call get_stylus_test_wasm,transient-enter)
stylus_test_transient-enter_src = $(call get_stylus_test_rust,transient-enter)
stylus_test_transient-reenter_wasm = $(call get_stylus_test_wasm,transient-reenter)
stylus_test_transient-reenter_src = $(call get_stylus_test_rust,transient-reenter)
stylus_test_transient-delegate-enter_wasm = $(call get_stylus_test_wasm,transient-delegate-enter)
stylus_test_transient-delegate-enter_src = $(call get_stylus_test_rust,transient-delegate-enter)
stylus_test_transient-delegate-reenter_wasm = $(call get_stylus_test_wasm,transient-delegate-reenter)
stylus_test_transient-delegate-reenter_src = $(call get_stylus_test_rust,transient-delegate-reenter)

stylus_test_wasms = $(stylus_test_keccak_wasm) $(stylus_test_keccak-100_wasm) $(stylus_test_fallible_wasm) $(stylus_test_storage_wasm) $(stylus_test_multicall_wasm) $(stylus_test_log_wasm) $(stylus_test_create_wasm) $(stylus_test_sdk-storage_wasm) $(stylus_test_erc20_wasm) $(stylus_test_read-return-data_wasm) $(stylus_test_evm-data_wasm) $(stylus_test_bfs:.b=.wasm) $(stylus_test_transient-enter_wasm) $(stylus_test_transient-reenter_wasm) $(stylus_test_transient-delegate-enter_wasm) $(stylus_test_transient-delegate-reenter_wasm)
stylus_benchmarks = $(wildcard $(stylus_dir)/*.toml $(stylus_dir)/src/*.rs) $(stylus_test_wasms)

# user targets
Expand Down Expand Up @@ -233,6 +241,8 @@ clean:
rm -rf $(output_root)
rm -f contracts/test/prover/proofs/*.json contracts/test/prover/spec-proofs/*.json
rm -rf arbitrator/target
rm -f $(forward_dir)/forward.wat
rm -f $(forward_dir)/forward_stub.wat
rm -rf arbitrator/wasm-libraries/target
rm -f arbitrator/wasm-libraries/soft-float/soft-float.wasm
rm -f arbitrator/wasm-libraries/soft-float/*.o
Expand Down Expand Up @@ -418,6 +428,22 @@ $(stylus_test_read-return-data_wasm): $(stylus_test_read-return-data_src)
$(cargo_nightly) --manifest-path $< --release --config $(stylus_cargo)
@touch -c $@ # cargo might decide to not rebuild the binary

$(stylus_test_transient-enter_wasm): $(stylus_test_transient-enter_src)
$(cargo_nightly) --manifest-path $< --release --config $(stylus_cargo)
@touch -c $@ # cargo might decide to not rebuild the binary

$(stylus_test_transient-reenter_wasm): $(stylus_test_transient-reenter_src)
$(cargo_nightly) --manifest-path $< --release --config $(stylus_cargo)
@touch -c $@ # cargo might decide to not rebuild the binary

$(stylus_test_transient-delegate-enter_wasm): $(stylus_test_transient-delegate-enter_src)
$(cargo_nightly) --manifest-path $< --release --config $(stylus_cargo)
@touch -c $@ # cargo might decide to not rebuild the binary

$(stylus_test_transient-delegate-reenter_wasm): $(stylus_test_transient-delegate-reenter_src)
$(cargo_nightly) --manifest-path $< --release --config $(stylus_cargo)
@touch -c $@ # cargo might decide to not rebuild the binary

$(stylus_test_sdk-storage_wasm): $(stylus_test_sdk-storage_src)
$(cargo_nightly) --manifest-path $< --release --config $(stylus_cargo)
@touch -c $@ # cargo might decide to not rebuild the binary
Expand Down
11 changes: 11 additions & 0 deletions arbitrator/arbutil/src/evm/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ impl From<u8> for EvmApiStatus {
pub enum EvmApiMethod {
GetBytes32,
SetBytes32,
TransientGetBytes32,
TransientSetBytes32,
ContractCall,
DelegateCall,
StaticCall,
Expand All @@ -57,6 +59,15 @@ pub trait EvmApi: Send + 'static {
/// Analogous to `vm.SSTORE`.
fn set_bytes32(&mut self, key: Bytes32, value: Bytes32) -> Result<u64>;

/// Reads the 32-byte value in the EVM transient storage at offset `key`.
/// Returns the value.
/// Analogous to `vm.TLOAD`.
fn transient_get_bytes32(&mut self, key: Bytes32) -> Bytes32;

/// Stores the given value at the given key in the EVM transient storage.
/// Analogous to `vm.TSTORE`.
fn transient_set_bytes32(&mut self, key: Bytes32, value: Bytes32) -> Result<()>;

/// Calls the contract at the given address.
/// Returns the EVM return data's length, the gas cost, and whether the call succeeded.
/// Analogous to `vm.CALL`.
Expand Down
14 changes: 14 additions & 0 deletions arbitrator/arbutil/src/evm/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,20 @@ impl<T: JsCallIntoGo> EvmApi for JsEvmApi<T> {
}
}

fn transient_get_bytes32(&mut self, key: Bytes32) -> Bytes32 {
let [value] = call!(self, 1, TransientGetBytes32, key);
value.assert_bytes32()
}

fn transient_set_bytes32(&mut self, key: Bytes32, value: Bytes32) -> Result<()> {
let [out] = call!(self, 1, TransientSetBytes32, key, value);
match out {
ApiValueKind::Nil => Ok(()),
ApiValueKind::String(err) => bail!(err),
_ => unreachable!(),
}
}

fn contract_call(
&mut self,
contract: Bytes20,
Expand Down
3 changes: 3 additions & 0 deletions arbitrator/arbutil/src/evm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ pub mod user;
// params.SstoreSentryGasEIP2200
pub const SSTORE_SENTRY_GAS: u64 = 2300;

// params.WarmStorageReadCostEIP2929
pub const TRANSIENT_OP_GAS: u64 = 100;

// params.LogGas and params.LogDataGas
pub const LOG_TOPIC_GAS: u64 = 375;
pub const LOG_DATA_GAS: u64 = 8;
Expand Down
2 changes: 1 addition & 1 deletion arbitrator/langs/c
Submodule c updated 2 files
+20 −0 include/hostio.h
+1 −1 include/storage.h
21 changes: 21 additions & 0 deletions arbitrator/stylus/src/evm_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ pub struct GoEvmApi {
gas_cost: *mut u64,
error: *mut RustBytes,
) -> EvmApiStatus,
pub transient_get_bytes32: unsafe extern "C" fn(id: usize, key: Bytes32) -> Bytes32, // value
pub transient_set_bytes32: unsafe extern "C" fn(
id: usize,
key: Bytes32,
value: Bytes32,
error: *mut RustBytes,
) -> EvmApiStatus,
pub contract_call: unsafe extern "C" fn(
id: usize,
contract: Bytes20,
Expand Down Expand Up @@ -117,6 +124,20 @@ impl EvmApi for GoEvmApi {
}
}

fn transient_get_bytes32(&mut self, key: Bytes32) -> Bytes32 {
call!(self, transient_get_bytes32, key)
}

fn transient_set_bytes32(&mut self, key: Bytes32, value: Bytes32) -> Result<()> {
let mut error = RustBytes::new(vec![]);
let api_status = call!(self, transient_set_bytes32, key, value, ptr!(error));
let error = into_vec!(error); // done here to always drop
match api_status {
EvmApiStatus::Success => Ok(()),
EvmApiStatus::Failure => Err(error!(error)),
}
}

fn contract_call(
&mut self,
contract: Bytes20,
Expand Down
16 changes: 16 additions & 0 deletions arbitrator/stylus/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,22 @@ pub(crate) fn storage_store_bytes32<E: EvmApi>(
hostio!(env, storage_store_bytes32(key, value))
}

pub(crate) fn transient_load_bytes32<E: EvmApi>(
mut env: WasmEnvMut<E>,
key: u32,
dest: u32,
) -> MaybeEscape {
hostio!(env, transient_load_bytes32(key, dest))
}

pub(crate) fn transient_store_bytes32<E: EvmApi>(
mut env: WasmEnvMut<E>,
key: u32,
value: u32,
) -> MaybeEscape {
hostio!(env, transient_store_bytes32(key, value))
}

pub(crate) fn call_contract<E: EvmApi>(
mut env: WasmEnvMut<E>,
contract: u32,
Expand Down
4 changes: 4 additions & 0 deletions arbitrator/stylus/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ impl<E: EvmApi> NativeInstance<E> {
"write_result" => func!(host::write_result),
"storage_load_bytes32" => func!(host::storage_load_bytes32),
"storage_store_bytes32" => func!(host::storage_store_bytes32),
"transient_load_bytes32" => func!(host::transient_load_bytes32),
"transient_store_bytes32" => func!(host::transient_store_bytes32),
"call_contract" => func!(host::call_contract),
"delegate_call_contract" => func!(host::delegate_call_contract),
"static_call_contract" => func!(host::static_call_contract),
Expand Down Expand Up @@ -332,6 +334,8 @@ pub fn module(wasm: &[u8], compile: CompileConfig) -> Result<Vec<u8>> {
"write_result" => stub!(|_: u32, _: u32|),
"storage_load_bytes32" => stub!(|_: u32, _: u32|),
"storage_store_bytes32" => stub!(|_: u32, _: u32|),
"transient_load_bytes32" => stub!(|_: u32, _: u32|),
"transient_store_bytes32" => stub!(|_: u32, _: u32|),
"call_contract" => stub!(u8 <- |_: u32, _: u32, _: u32, _: u32, _: u64, _: u32|),
"delegate_call_contract" => stub!(u8 <- |_: u32, _: u32, _: u32, _: u64, _: u32|),
"static_call_contract" => stub!(u8 <- |_: u32, _: u32, _: u32, _: u64, _: u32|),
Expand Down
8 changes: 8 additions & 0 deletions arbitrator/stylus/src/test/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ impl EvmApi for TestEvmApi {
Ok(22100) // pretend worst case
}

fn transient_get_bytes32(&mut self, key: Bytes32) -> Bytes32 {
unimplemented!()
}

fn transient_set_bytes32(&mut self, key: Bytes32, value: Bytes32) -> Result<()> {
unimplemented!()
}

/// Simulates a contract call.
/// Note: this call function is for testing purposes only and deviates from onchain behavior.
fn contract_call(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
target = "wasm32-unknown-unknown"
Loading
Loading