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

Conversation

joshuacolvin0
Copy link
Member

@joshuacolvin0 joshuacolvin0 commented Dec 7, 2023

@cla-bot cla-bot bot added the s label Dec 7, 2023
@joshuacolvin0 joshuacolvin0 marked this pull request as ready for review December 11, 2023 19:48
@joshuacolvin0 joshuacolvin0 marked this pull request as draft December 11, 2023 20:26
@joshuacolvin0 joshuacolvin0 marked this pull request as ready for review December 12, 2023 02:16
Copy link

codecov bot commented Dec 12, 2023

Codecov Report

Merging #185 (e7a6287) into stylus (87f358c) will decrease coverage by 0.27%.
Report is 1 commits behind head on stylus.
The diff coverage is 35.25%.

Additional details and impacted files
@@            Coverage Diff             @@
##           stylus     #185      +/-   ##
==========================================
- Coverage   58.13%   57.87%   -0.27%     
==========================================
  Files         282      282              
  Lines       43331    43443     +112     
==========================================
- Hits        25190    25141      -49     
- Misses      15694    15832     +138     
- Partials     2447     2470      +23     

dest: u32,
) -> MaybeEscape {
let mut env = WasmEnv::start(&mut env, 2 * PTR_INK + EVM_API_INK)?;
env.buy_gas(TRANSIENT_BYTES32_GAS)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be nice to map errors here to be more informative. To know if it failed at buying gas, at reading, or at transient get

Copy link
Member Author

Choose a reason for hiding this comment

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

the error messages bubbled up are already informative enough

let gas_cost = api.set_bytes32(key, value).unwrap();
program.buy_gas(gas_cost).unwrap();
}

#[no_mangle]
pub unsafe extern "C" fn user_host__storage_transient_load_bytes32(key: usize, dest: usize) {
let program = Program::start(2 * PTR_INK + EVM_API_INK);
Copy link
Contributor

Choose a reason for hiding this comment

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

Where does the magic number 2 come from?

Copy link
Member Author

Choose a reason for hiding this comment

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

reading two ptr inputs (key, dest)

let value = wavm::read_bytes32(value);

let api = &mut program.evm_api;
api.transient_set_bytes32(key, value).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we move wavm::read_bytes32(key) and value into the api.transient_set_bytes32(key, value).unwrap(); to avoid declaring two variables?

Copy link
Member Author

Choose a reason for hiding this comment

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

This code has been replaced by macro. In general, better to keep things explicit so that the amount of gas used is as clear as possible

Base automatically changed from rename-memory-grow to stylus December 14, 2023 03:18
change names and update Makefile to cleanup generated files
Copy link
Contributor

@rachel-bousfield rachel-bousfield left a comment

Choose a reason for hiding this comment

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

Nice work! Some minor suggests as I continue reviewing

Comment on lines 128 to 129
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.

👍

@@ -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.

👍

Comment on lines 13 to 14
// 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.

👍

Comment on lines 52 to 71
#[no_mangle]
pub unsafe extern "C" fn vm_hooks__transient_storage_load_bytes32(key: u32, dest: u32) {
let mut program = Program::start(2 * PTR_INK + EVM_API_INK);
let key = wavm::read_bytes32(key);

let value = TRANSIENT_KEYS.lock().get(&key).cloned().unwrap_or_default();
program.buy_gas(evm::TRANSIENT_BYTES32_GAS).unwrap();
wavm::write_bytes32(dest, value);
}

#[no_mangle]
pub unsafe extern "C" fn vm_hooks__transient_storage_store_bytes32(key: u32, value: u32) {
let mut program = Program::start(2 * PTR_INK + EVM_API_INK);
program.buy_gas(evm::TRANSIENT_BYTES32_GAS).unwrap(); // pretend the worst case

let key = wavm::read_bytes32(key);
let value = wavm::read_bytes32(value);
TRANSIENT_KEYS.lock().insert(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 these since they're unused

Copy link
Member Author

Choose a reason for hiding this comment

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

👍

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.

👍

@joshuacolvin0
Copy link
Member Author

implemented in different PR

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants