Skip to content
This repository was archived by the owner on Nov 26, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 2 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
13 changes: 13 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,17 @@ 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 state trie at offset `key`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe

Reads the 32-byte value from transient storage at offset key.

And drop the next line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

/// Storage is discarded after every transaction
/// 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 state trie.
/// Storage is discarded after every transaction
/// 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_BYTES32_GAS: u64 = 100;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call it TRANSIENT_OP_GAS or similar

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


// 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
+22 −2 include/hostio.h
+22 −1 include/storage.h
22 changes: 22 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,21 @@ impl EvmApi for GoEvmApi {
}
}

fn transient_get_bytes32(&mut self, key: Bytes32) -> Bytes32 {
let value = call!(self, transient_get_bytes32, key);
value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's drop the let value =

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}

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
18 changes: 18 additions & 0 deletions arbitrator/stylus/src/test/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use super::TestInstance;
pub(crate) struct TestEvmApi {
contracts: Arc<Mutex<HashMap<Bytes20, Vec<u8>>>>,
storage: Arc<Mutex<HashMap<Bytes20, HashMap<Bytes32, Bytes32>>>>,
transient_storage: Arc<Mutex<HashMap<Bytes20, HashMap<Bytes32, Bytes32>>>>,
program: Bytes20,
write_result: Arc<Mutex<Vec<u8>>>,
compile: CompileConfig,
Expand All @@ -33,9 +34,12 @@ impl TestEvmApi {
let mut storage = HashMap::new();
storage.insert(program, HashMap::new());

let mut transient_storage = HashMap::new();

let api = TestEvmApi {
contracts: Arc::new(Mutex::new(HashMap::new())),
storage: Arc::new(Mutex::new(storage)),
transient_storage: Arc::new(Mutex::new(transient_storage)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's drop this and related funcs until we have a test framework with a notion of transactions (all tests are currently just isolated calls, so there's no meaningful distinction between normal and transient storage)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

program,
write_result: Arc::new(Mutex::new(vec![])),
compile,
Expand Down Expand Up @@ -77,6 +81,20 @@ impl EvmApi for TestEvmApi {
Ok(22100) // pretend worst case
}

fn transient_get_bytes32(&mut self, key: Bytes32) -> Bytes32 {
let transient_storage = &mut self.transient_storage.lock();
let transient_storage = transient_storage.get_mut(&self.program).unwrap();
let value = transient_storage.get(&key).cloned().unwrap_or_default();
value
}

fn transient_set_bytes32(&mut self, key: Bytes32, value: Bytes32) -> Result<()> {
let transient_storage = &mut self.transient_storage.lock();
let transient_storage = transient_storage.get_mut(&self.program).unwrap();
transient_storage.insert(key, value);
Ok(())
}

/// 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