From a88ae70ceed5a77763cf26fc149b5279244bdcf2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 13 Mar 2019 20:47:55 +0100 Subject: [PATCH] rust: add type aliases for more enums --- CHANGELOG.md | 3 + bindings/rust/evmc-vm/src/lib.rs | 88 ++++++++++++++--------------- bindings/rust/evmc-vm/src/types.rs | 64 +++++++++++++++++++++ examples/example-rust-vm/src/lib.rs | 4 +- 4 files changed, 111 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06bbd9673..118e180de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning]. - Added `MockedHost` C++ class (in form of header-only `evmc::mocked_host` library) which can be used to emulate Host behavior when testing VM implementations. [#456](https://github.com/ethereum/evmc/pull/456) +- In the Rust bindings added more type aliases (`MessageKind`, `MessageFlags`, `StatusCode`, + `StorageStatus`, `Revision`). + [#206](https://github.com/ethereum/evmc/pull/206) ### Changed diff --git a/bindings/rust/evmc-vm/src/lib.rs b/bindings/rust/evmc-vm/src/lib.rs index c0c1afb3f..e002fb445 100644 --- a/bindings/rust/evmc-vm/src/lib.rs +++ b/bindings/rust/evmc-vm/src/lib.rs @@ -22,7 +22,7 @@ pub trait EvmcVm { /// This is called for every incoming message. fn execute<'a>( &self, - revision: ffi::evmc_revision, + revision: Revision, code: &'a [u8], message: &'a ExecutionMessage, context: Option<&'a mut ExecutionContext<'a>>, @@ -32,7 +32,7 @@ pub trait EvmcVm { /// EVMC result structure. #[derive(Debug)] pub struct ExecutionResult { - status_code: ffi::evmc_status_code, + status_code: StatusCode, gas_left: i64, output: Option>, create_address: Option
, @@ -41,7 +41,7 @@ pub struct ExecutionResult { /// EVMC execution message structure. #[derive(Debug)] pub struct ExecutionMessage { - kind: ffi::evmc_call_kind, + kind: MessageKind, flags: u32, depth: i32, gas: i64, @@ -65,11 +65,7 @@ pub struct ExecutionContext<'a> { impl ExecutionResult { /// Manually create a result. - pub fn new( - _status_code: ffi::evmc_status_code, - _gas_left: i64, - _output: Option<&[u8]>, - ) -> Self { + pub fn new(_status_code: StatusCode, _gas_left: i64, _output: Option<&[u8]>) -> Self { ExecutionResult { status_code: _status_code, gas_left: _gas_left, @@ -84,21 +80,21 @@ impl ExecutionResult { /// Create failure result. pub fn failure() -> Self { - ExecutionResult::new(ffi::evmc_status_code::EVMC_FAILURE, 0, None) + ExecutionResult::new(StatusCode::EVMC_FAILURE, 0, None) } /// Create a revert result. pub fn revert(_gas_left: i64, _output: Option<&[u8]>) -> Self { - ExecutionResult::new(ffi::evmc_status_code::EVMC_REVERT, _gas_left, _output) + ExecutionResult::new(StatusCode::EVMC_REVERT, _gas_left, _output) } /// Create a successful result. pub fn success(_gas_left: i64, _output: Option<&[u8]>) -> Self { - ExecutionResult::new(ffi::evmc_status_code::EVMC_SUCCESS, _gas_left, _output) + ExecutionResult::new(StatusCode::EVMC_SUCCESS, _gas_left, _output) } /// Read the status code. - pub fn status_code(&self) -> ffi::evmc_status_code { + pub fn status_code(&self) -> StatusCode { self.status_code } @@ -121,7 +117,7 @@ impl ExecutionResult { impl ExecutionMessage { pub fn new( - kind: ffi::evmc_call_kind, + kind: MessageKind, flags: u32, depth: i32, gas: i64, @@ -149,7 +145,7 @@ impl ExecutionMessage { } /// Read the message kind. - pub fn kind(&self) -> ffi::evmc_call_kind { + pub fn kind(&self) -> MessageKind { self.kind } @@ -239,7 +235,7 @@ impl<'a> ExecutionContext<'a> { address: &Address, key: &Bytes32, value: &Bytes32, - ) -> ffi::evmc_storage_status { + ) -> StorageStatus { unsafe { assert!((*self.host).set_storage.is_some()); (*self.host).set_storage.unwrap()( @@ -501,9 +497,9 @@ mod tests { #[test] fn result_new() { - let r = ExecutionResult::new(ffi::evmc_status_code::EVMC_FAILURE, 420, None); + let r = ExecutionResult::new(StatusCode::EVMC_FAILURE, 420, None); - assert!(r.status_code() == ffi::evmc_status_code::EVMC_FAILURE); + assert!(r.status_code() == StatusCode::EVMC_FAILURE); assert!(r.gas_left() == 420); assert!(r.output().is_none()); assert!(r.create_address().is_none()); @@ -526,7 +522,7 @@ mod tests { #[test] fn result_from_ffi() { let f = ffi::evmc_result { - status_code: ffi::evmc_status_code::EVMC_SUCCESS, + status_code: StatusCode::EVMC_SUCCESS, gas_left: 1337, output_data: Box::into_raw(Box::new([0xde, 0xad, 0xbe, 0xef])) as *const u8, output_size: 4, @@ -537,7 +533,7 @@ mod tests { let r: ExecutionResult = f.into(); - assert!(r.status_code() == ffi::evmc_status_code::EVMC_SUCCESS); + assert!(r.status_code() == StatusCode::EVMC_SUCCESS); assert!(r.gas_left() == 1337); assert!(r.output().is_some()); assert!(r.output().unwrap().len() == 4); @@ -547,7 +543,7 @@ mod tests { #[test] fn result_into_heap_ffi() { let r = ExecutionResult::new( - ffi::evmc_status_code::EVMC_FAILURE, + StatusCode::EVMC_FAILURE, 420, Some(&[0xc0, 0xff, 0xee, 0x71, 0x75]), ); @@ -555,7 +551,7 @@ mod tests { let f: *const ffi::evmc_result = r.into(); assert!(!f.is_null()); unsafe { - assert!((*f).status_code == ffi::evmc_status_code::EVMC_FAILURE); + assert!((*f).status_code == StatusCode::EVMC_FAILURE); assert!((*f).gas_left == 420); assert!(!(*f).output_data.is_null()); assert!((*f).output_size == 5); @@ -572,12 +568,12 @@ mod tests { #[test] fn result_into_heap_ffi_empty_data() { - let r = ExecutionResult::new(ffi::evmc_status_code::EVMC_FAILURE, 420, None); + let r = ExecutionResult::new(StatusCode::EVMC_FAILURE, 420, None); let f: *const ffi::evmc_result = r.into(); assert!(!f.is_null()); unsafe { - assert!((*f).status_code == ffi::evmc_status_code::EVMC_FAILURE); + assert!((*f).status_code == StatusCode::EVMC_FAILURE); assert!((*f).gas_left == 420); assert!((*f).output_data.is_null()); assert!((*f).output_size == 0); @@ -591,14 +587,14 @@ mod tests { #[test] fn result_into_stack_ffi() { let r = ExecutionResult::new( - ffi::evmc_status_code::EVMC_FAILURE, + StatusCode::EVMC_FAILURE, 420, Some(&[0xc0, 0xff, 0xee, 0x71, 0x75]), ); let f: ffi::evmc_result = r.into(); unsafe { - assert!(f.status_code == ffi::evmc_status_code::EVMC_FAILURE); + assert!(f.status_code == StatusCode::EVMC_FAILURE); assert!(f.gas_left == 420); assert!(!f.output_data.is_null()); assert!(f.output_size == 5); @@ -615,11 +611,11 @@ mod tests { #[test] fn result_into_stack_ffi_empty_data() { - let r = ExecutionResult::new(ffi::evmc_status_code::EVMC_FAILURE, 420, None); + let r = ExecutionResult::new(StatusCode::EVMC_FAILURE, 420, None); let f: ffi::evmc_result = r.into(); unsafe { - assert!(f.status_code == ffi::evmc_status_code::EVMC_FAILURE); + assert!(f.status_code == StatusCode::EVMC_FAILURE); assert!(f.gas_left == 420); assert!(f.output_data.is_null()); assert!(f.output_size == 0); @@ -639,7 +635,7 @@ mod tests { let create2_salt = Bytes32 { bytes: [255u8; 32] }; let ret = ExecutionMessage::new( - ffi::evmc_call_kind::EVMC_CALL, + MessageKind::EVMC_CALL, 44, 66, 4466, @@ -650,7 +646,7 @@ mod tests { create2_salt, ); - assert_eq!(ret.kind(), ffi::evmc_call_kind::EVMC_CALL); + assert_eq!(ret.kind(), MessageKind::EVMC_CALL); assert_eq!(ret.flags(), 44); assert_eq!(ret.depth(), 66); assert_eq!(ret.gas(), 4466); @@ -670,7 +666,7 @@ mod tests { let create2_salt = Bytes32 { bytes: [255u8; 32] }; let msg = ffi::evmc_message { - kind: ffi::evmc_call_kind::EVMC_CALL, + kind: MessageKind::EVMC_CALL, flags: 44, depth: 66, gas: 4466, @@ -704,7 +700,7 @@ mod tests { let create2_salt = Bytes32 { bytes: [255u8; 32] }; let msg = ffi::evmc_message { - kind: ffi::evmc_call_kind::EVMC_CALL, + kind: MessageKind::EVMC_CALL, flags: 44, depth: 66, gas: 4466, @@ -768,16 +764,16 @@ mod tests { ffi::evmc_result { status_code: if success { - ffi::evmc_status_code::EVMC_SUCCESS + StatusCode::EVMC_SUCCESS } else { - ffi::evmc_status_code::EVMC_INTERNAL_ERROR + StatusCode::EVMC_INTERNAL_ERROR }, gas_left: 2, // NOTE: we are passing the input pointer here, but for testing the lifetime is ok output_data: msg.input_data, output_size: msg.input_size, release: None, - create_address: ffi::evmc_address::default(), + create_address: Address::default(), padding: [0u8; 4], } } @@ -832,36 +828,36 @@ mod tests { #[test] fn test_call_empty_data() { // This address is useless. Just a dummy parameter for the interface function. - let test_addr = ffi::evmc_address { bytes: [0u8; 20] }; + let test_addr = Address::default(); let host = get_dummy_host_interface(); let host_context = std::ptr::null_mut(); let mut exe_context = ExecutionContext::new(&host, host_context); let message = ExecutionMessage::new( - ffi::evmc_call_kind::EVMC_CALL, + MessageKind::EVMC_CALL, 0, 0, 6566, test_addr, test_addr, None, - ffi::evmc_uint256be::default(), - ffi::evmc_bytes32::default(), + Uint256::default(), + Bytes32::default(), ); let b = exe_context.call(&message); - assert_eq!(b.status_code(), ffi::evmc_status_code::EVMC_SUCCESS); + assert_eq!(b.status_code(), StatusCode::EVMC_SUCCESS); assert_eq!(b.gas_left(), 2); assert!(b.output().is_none()); assert!(b.create_address().is_some()); - assert_eq!(b.create_address().unwrap(), &ffi::evmc_address::default()); + assert_eq!(b.create_address().unwrap(), &Address::default()); } #[test] fn test_call_with_data() { // This address is useless. Just a dummy parameter for the interface function. - let test_addr = ffi::evmc_address { bytes: [0u8; 20] }; + let test_addr = Address::default(); let host = get_dummy_host_interface(); let host_context = std::ptr::null_mut(); let mut exe_context = ExecutionContext::new(&host, host_context); @@ -869,24 +865,24 @@ mod tests { let data = vec![0xc0, 0xff, 0xfe]; let message = ExecutionMessage::new( - ffi::evmc_call_kind::EVMC_CALL, + MessageKind::EVMC_CALL, 0, 0, 6566, test_addr, test_addr, Some(&data), - ffi::evmc_uint256be::default(), - ffi::evmc_bytes32::default(), + Uint256::default(), + Bytes32::default(), ); let b = exe_context.call(&message); - assert_eq!(b.status_code(), ffi::evmc_status_code::EVMC_SUCCESS); + assert_eq!(b.status_code(), StatusCode::EVMC_SUCCESS); assert_eq!(b.gas_left(), 2); assert!(b.output().is_some()); assert_eq!(b.output().unwrap(), &data); assert!(b.create_address().is_some()); - assert_eq!(b.create_address().unwrap(), &ffi::evmc_address::default()); + assert_eq!(b.create_address().unwrap(), &Address::default()); } } diff --git a/bindings/rust/evmc-vm/src/types.rs b/bindings/rust/evmc-vm/src/types.rs index 4a2712d4a..3b7ba601d 100644 --- a/bindings/rust/evmc-vm/src/types.rs +++ b/bindings/rust/evmc-vm/src/types.rs @@ -9,6 +9,21 @@ pub type Bytes32 = ffi::evmc_bytes32; /// EVMC big-endian 256-bit integer pub type Uint256 = ffi::evmc_uint256be; +/// EVMC call kind. +pub type MessageKind = ffi::evmc_call_kind; + +/// EVMC message (call) flags. +pub type MessageFlags = ffi::evmc_flags; + +/// EVMC status code. +pub type StatusCode = ffi::evmc_status_code; + +/// EVMC storage status. +pub type StorageStatus = ffi::evmc_storage_status; + +/// EVMC VM revision. +pub type Revision = ffi::evmc_revision; + #[cfg(test)] mod tests { use super::*; @@ -34,4 +49,53 @@ mod tests { let b = Uint256::default(); assert_eq!(a.clone(), b.clone()); } + + #[test] + fn message_kind() { + assert_eq!(MessageKind::EVMC_CALL, ffi::evmc_call_kind::EVMC_CALL); + assert_eq!( + MessageKind::EVMC_CALLCODE, + ffi::evmc_call_kind::EVMC_CALLCODE + ); + assert_eq!( + MessageKind::EVMC_DELEGATECALL, + ffi::evmc_call_kind::EVMC_DELEGATECALL + ); + assert_eq!(MessageKind::EVMC_CREATE, ffi::evmc_call_kind::EVMC_CREATE); + } + + #[test] + fn message_flags() { + assert_eq!(MessageFlags::EVMC_STATIC, ffi::evmc_flags::EVMC_STATIC); + } + + #[test] + fn status_code() { + assert_eq!( + StatusCode::EVMC_SUCCESS, + ffi::evmc_status_code::EVMC_SUCCESS + ); + assert_eq!( + StatusCode::EVMC_FAILURE, + ffi::evmc_status_code::EVMC_FAILURE + ); + } + + #[test] + fn storage_status() { + assert_eq!( + StorageStatus::EVMC_STORAGE_UNCHANGED, + ffi::evmc_storage_status::EVMC_STORAGE_UNCHANGED + ); + assert_eq!( + StorageStatus::EVMC_STORAGE_MODIFIED, + ffi::evmc_storage_status::EVMC_STORAGE_MODIFIED + ); + } + + #[test] + fn revision() { + assert_eq!(Revision::EVMC_FRONTIER, ffi::evmc_revision::EVMC_FRONTIER); + assert_eq!(Revision::EVMC_ISTANBUL, ffi::evmc_revision::EVMC_ISTANBUL); + } } diff --git a/examples/example-rust-vm/src/lib.rs b/examples/example-rust-vm/src/lib.rs index 09464808a..153cdb02a 100644 --- a/examples/example-rust-vm/src/lib.rs +++ b/examples/example-rust-vm/src/lib.rs @@ -16,7 +16,7 @@ impl EvmcVm for ExampleRustVM { fn execute<'a>( &self, - _revision: evmc_sys::evmc_revision, + _revision: Revision, _code: &'a [u8], message: &'a ExecutionMessage, _context: Option<&'a mut ExecutionContext<'a>>, @@ -26,7 +26,7 @@ impl EvmcVm for ExampleRustVM { } let _context = _context.unwrap(); - if message.kind() != evmc_sys::evmc_call_kind::EVMC_CALL { + if message.kind() != MessageKind::EVMC_CALL { return ExecutionResult::failure(); }