diff --git a/examples/properties.rs b/examples/properties.rs index ceedfb1b5..70776bca7 100644 --- a/examples/properties.rs +++ b/examples/properties.rs @@ -60,6 +60,11 @@ pub fn timestamp() -> u64 { properties::timestamp() } +#[zink::external] +pub fn gasleft() -> Bytes32 { + properties::gasleft() +} + #[cfg(not(target_arch = "wasm32"))] fn main() {} @@ -193,4 +198,27 @@ mod tests { assert_eq!(info.ret, 26u64.to_bytes32(), "{info:?}"); Ok(()) } + + #[test] + fn test_gas_left() -> anyhow::Result<()> { + let contract = Contract::search("properties")?.compile()?; + + let mut evm1 = EVM::default().tx_gas_limit(50000).commit(true); + let info1 = evm1.deploy(&contract.bytecode()?)?; + let info1 = evm1 + .calldata(&contract.encode(["gasleft()".as_bytes()])?) + .call(info1.address)?; + let gasleft1 = u64::from_be_bytes(info1.ret[24..].try_into().unwrap()); + let gas1 = 50000 - gasleft1; + + let mut evm2 = EVM::default().tx_gas_limit(70000).commit(true); + let info2 = evm2.deploy(&contract.bytecode()?)?; + let info2 = evm2 + .calldata(&contract.encode(["gasleft()".as_bytes()])?) + .call(info2.address)?; + let gasleft2 = u64::from_be_bytes(info2.ret[24..].try_into().unwrap()); + let gas2 = 70000 - gasleft2; + assert_eq!(gas1, gas2); + Ok(()) + } } diff --git a/zink/src/ffi/evm.rs b/zink/src/ffi/evm.rs index 1a3ea1a8c..60d9954be 100644 --- a/zink/src/ffi/evm.rs +++ b/zink/src/ffi/evm.rs @@ -183,7 +183,7 @@ extern "C" { pub fn gaslimit() -> Bytes32; /// Get the amount of available gas. - pub fn gas() -> u64; + pub fn gas() -> Bytes32; /// Get the block’s timestamp. pub fn timestamp() -> u64; diff --git a/zink/src/primitives/properties.rs b/zink/src/primitives/properties.rs index 962551118..8aee8976f 100644 --- a/zink/src/primitives/properties.rs +++ b/zink/src/primitives/properties.rs @@ -47,7 +47,7 @@ pub fn gaslimit() -> Bytes32 { } /// Get the amount of available gas. -pub fn gas() -> u64 { +pub fn gasleft() -> Bytes32 { unsafe { ffi::evm::gas() } } diff --git a/zink/zint/src/evm.rs b/zink/zint/src/evm.rs index 2a9841c1b..14d91fdf0 100644 --- a/zink/zint/src/evm.rs +++ b/zink/zint/src/evm.rs @@ -27,6 +27,8 @@ pub struct EVM<'e> { pub caller: [u8; 20], /// Blob hashes pub blob_hashes: Option>, + /// The gas limit of the transaction + pub tx_gas_limit: u64, /// If commit changes commit: bool, } @@ -41,6 +43,7 @@ impl<'e> Default for EVM<'e> { inner: evm, caller: [0; 20], blob_hashes: None, + tx_gas_limit: GAS_LIMIT, commit: false, } } @@ -148,10 +151,16 @@ impl EVM<'_> { self } + /// Set tx’s gaslimit + pub fn tx_gas_limit(mut self, gaslimit: u64) -> Self { + self.tx_gas_limit = gaslimit; + self + } + /// Send transaction to the provided address. pub fn call(&mut self, to: [u8; 20]) -> Result { let to = TransactTo::Call(to.into()); - self.inner.tx_mut().gas_limit = GAS_LIMIT; + self.inner.tx_mut().gas_limit = self.tx_gas_limit; self.inner.tx_mut().transact_to = to; self.inner.tx_mut().caller = self.caller.into(); if let Some(hashes) = &self.blob_hashes {