mirror of
https://github.com/status-im/evmc.git
synced 2025-02-24 00:48:09 +00:00
Merge pull request #324 from ethereum/rust-message
rust: introduce ExecutionMessage wrapper
This commit is contained in:
commit
88f2a1dae7
@ -21,10 +21,23 @@ pub struct ExecutionResult {
|
||||
create_address: Option<ffi::evmc_address>,
|
||||
}
|
||||
|
||||
/// EVMC execution message structure.
|
||||
pub struct ExecutionMessage {
|
||||
kind: ffi::evmc_call_kind,
|
||||
flags: u32,
|
||||
depth: i32,
|
||||
gas: i64,
|
||||
destination: ffi::evmc_address,
|
||||
sender: ffi::evmc_address,
|
||||
input: Option<Vec<u8>>,
|
||||
value: ffi::evmc_uint256be,
|
||||
create2_salt: ffi::evmc_bytes32,
|
||||
}
|
||||
|
||||
/// EVMC context structure. Exposes the EVMC host functions, message data, and transaction context
|
||||
/// to the executing VM.
|
||||
pub struct ExecutionContext<'a> {
|
||||
message: &'a ffi::evmc_message,
|
||||
message: ExecutionMessage,
|
||||
context: &'a mut ffi::evmc_context,
|
||||
tx_context: ffi::evmc_tx_context,
|
||||
}
|
||||
@ -68,6 +81,44 @@ impl ExecutionResult {
|
||||
}
|
||||
}
|
||||
|
||||
impl ExecutionMessage {
|
||||
pub fn kind(&self) -> ffi::evmc_call_kind {
|
||||
self.kind
|
||||
}
|
||||
|
||||
pub fn flags(&self) -> u32 {
|
||||
self.flags
|
||||
}
|
||||
|
||||
pub fn depth(&self) -> i32 {
|
||||
self.depth
|
||||
}
|
||||
|
||||
pub fn gas(&self) -> i64 {
|
||||
self.gas
|
||||
}
|
||||
|
||||
pub fn destination(&self) -> &ffi::evmc_address {
|
||||
&self.destination
|
||||
}
|
||||
|
||||
pub fn sender(&self) -> &ffi::evmc_address {
|
||||
&self.sender
|
||||
}
|
||||
|
||||
pub fn input(&self) -> Option<&Vec<u8>> {
|
||||
self.input.as_ref()
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &ffi::evmc_uint256be {
|
||||
&self.value
|
||||
}
|
||||
|
||||
pub fn create2_salt(&self) -> &ffi::evmc_bytes32 {
|
||||
&self.create2_salt
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExecutionContext<'a> {
|
||||
pub fn new(_message: &'a ffi::evmc_message, _context: &'a mut ffi::evmc_context) -> Self {
|
||||
let _tx_context = unsafe {
|
||||
@ -76,13 +127,13 @@ impl<'a> ExecutionContext<'a> {
|
||||
};
|
||||
|
||||
ExecutionContext {
|
||||
message: _message,
|
||||
message: _message.into(),
|
||||
context: _context,
|
||||
tx_context: _tx_context,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_message(&self) -> &ffi::evmc_message {
|
||||
pub fn get_message(&self) -> &ExecutionMessage {
|
||||
&self.message
|
||||
}
|
||||
|
||||
@ -339,6 +390,39 @@ extern "C" fn release_stack_result(result: *const ffi::evmc_result) {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&ffi::evmc_message> for ExecutionMessage {
|
||||
fn from(message: &ffi::evmc_message) -> Self {
|
||||
ExecutionMessage {
|
||||
kind: message.kind,
|
||||
flags: message.flags,
|
||||
depth: message.depth,
|
||||
gas: message.gas,
|
||||
destination: message.destination,
|
||||
sender: message.sender,
|
||||
input: if message.input_data.is_null() {
|
||||
assert!(message.input_size == 0);
|
||||
None
|
||||
} else {
|
||||
// TODO: what to do if input_size is 0?
|
||||
|
||||
// Pre-allocate a vector.
|
||||
let mut buf: Vec<u8> = Vec::with_capacity(message.input_size);
|
||||
|
||||
unsafe {
|
||||
// Set the len of the vec manually.
|
||||
buf.set_len(message.input_size);
|
||||
// Copy from the C struct's buffer to the vec's buffer.
|
||||
std::ptr::copy(message.input_data, buf.as_mut_ptr(), message.input_size);
|
||||
}
|
||||
|
||||
Some(buf)
|
||||
},
|
||||
value: message.value,
|
||||
create2_salt: message.create2_salt,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -562,8 +646,12 @@ mod tests {
|
||||
assert_eq!(c.flags, d.flags);
|
||||
assert_eq!(c.depth, d.depth);
|
||||
assert_eq!(c.gas, d.gas);
|
||||
assert_eq!(c.input_data, d.input_data);
|
||||
assert_eq!(c.input_size, d.input_size);
|
||||
if d.input_data.is_null() {
|
||||
assert!(c.input().is_none());
|
||||
} else {
|
||||
assert!(c.input().is_some());
|
||||
assert_eq!(c.input().unwrap().len(), d.input_size);
|
||||
}
|
||||
|
||||
dummy_context_dispose(context_raw);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ impl EvmcVm for ExampleRustVM {
|
||||
}
|
||||
|
||||
fn execute(&self, _code: &[u8], context: &ExecutionContext) -> ExecutionResult {
|
||||
let is_create = context.get_message().kind == evmc_sys::evmc_call_kind::EVMC_CREATE;
|
||||
let is_create = context.get_message().kind() == evmc_sys::evmc_call_kind::EVMC_CREATE;
|
||||
|
||||
if is_create {
|
||||
ExecutionResult::failure()
|
||||
|
Loading…
x
Reference in New Issue
Block a user