Skip to content

Commit

Permalink
Add code_address field
Browse files Browse the repository at this point in the history
Move code_address to the end of evmc_message for better compatibility. Fix language bindigs.

Small fixes

still fixing tools/vmtester/tests.cpp

Fix rust bindings
  • Loading branch information
yperbasis committed Jul 16, 2021
1 parent 6711434 commit 3dbc193
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 12 deletions.
1 change: 1 addition & 0 deletions bindings/go/evmc/evmc.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static struct evmc_result execute_wrapper(struct evmc_vm* vm,
input_size,
*value,
{{0}}, // create2_salt: not required for execution
{{0}}, // code_address: not required for execution
};
struct evmc_host_context* context = (struct evmc_host_context*)context_index;
Expand Down
5 changes: 3 additions & 2 deletions bindings/go/evmc/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ type HostContext interface {
EmitLog(addr Address, topics []Hash, data []byte)
Call(kind CallKind,
destination Address, sender Address, value Hash, input []byte, gas int64, depth int,
static bool, salt Hash) (output []byte, gasLeft int64, createAddr Address, err error)
static bool, salt Hash, codeAddress Address) (output []byte, gasLeft int64, createAddr Address, err error)
AccessAccount(addr Address) AccessStatus
AccessStorage(addr Address, key Hash) AccessStatus
}
Expand Down Expand Up @@ -208,7 +208,8 @@ func call(pCtx unsafe.Pointer, msg *C.struct_evmc_message) C.struct_evmc_result

kind := CallKind(msg.kind)
output, gasLeft, createAddr, err := ctx.Call(kind, goAddress(msg.destination), goAddress(msg.sender), goHash(msg.value),
goByteSlice(msg.input_data, msg.input_size), int64(msg.gas), int(msg.depth), msg.flags != 0, goHash(msg.create2_salt))
goByteSlice(msg.input_data, msg.input_size), int64(msg.gas), int(msg.depth), msg.flags != 0, goHash(msg.create2_salt),
goAddress(msg.code_address))

statusCode := C.enum_evmc_status_code(0)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion bindings/go/evmc/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (host *testHostContext) EmitLog(addr Address, topics []Hash, data []byte) {

func (host *testHostContext) Call(kind CallKind,
destination Address, sender Address, value Hash, input []byte, gas int64, depth int,
static bool, salt Hash) (output []byte, gasLeft int64, createAddr Address, err error) {
static bool, salt Hash, codeAddress Address) (output []byte, gasLeft int64, createAddr Address, err error) {
output = []byte("output from testHostContext.Call()")
return output, gas, Address{}, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class TestMessage {
long inputSize;
char[] value;
byte[] createSalt;
byte[] codeAddress;

public TestMessage(
int kind,
Expand All @@ -38,6 +39,7 @@ public TestMessage(
this.inputSize = (long) inputData.length;
this.value = value;
this.createSalt = new byte[32];
this.codeAddress = new byte[20];
}

public TestMessage(ByteBuffer msg) {
Expand All @@ -56,11 +58,12 @@ public TestMessage(ByteBuffer msg) {
tmpbuf = msg.get(new byte[32]);
this.value = StandardCharsets.ISO_8859_1.decode(tmpbuf).array();
this.createSalt = msg.get(new byte[32]).array();
this.codeAddress = msg.get(new byte[20]).array();
}

public ByteBuffer toByteBuffer() {

return ByteBuffer.allocateDirect(152)
return ByteBuffer.allocateDirect(172)
.order(ByteOrder.nativeOrder())
.putInt(kind) // 4
.putInt(flags) // 4
Expand All @@ -72,6 +75,7 @@ public ByteBuffer toByteBuffer() {
.put(StandardCharsets.ISO_8859_1.encode(CharBuffer.wrap(inputData))) // 8
.putLong(inputSize) // 8
.put(StandardCharsets.ISO_8859_1.encode(CharBuffer.wrap(value))) // 32
.put(createSalt); // 32
.put(createSalt) // 32
.put(codeAddress); // 20
}
}
1 change: 1 addition & 0 deletions bindings/rust/evmc-vm/src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ mod tests {
input_size: 0,
value: ::evmc_sys::evmc_uint256be::default(),
create2_salt: ::evmc_sys::evmc_bytes32::default(),
code_address: ::evmc_sys::evmc_address::default(),
};
let message: ExecutionMessage = (&message).into();

Expand Down
21 changes: 21 additions & 0 deletions bindings/rust/evmc-vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub struct ExecutionMessage {
input: Option<Vec<u8>>,
value: Uint256,
create2_salt: Bytes32,
code_address: Address,
}

/// EVMC transaction context structure.
Expand Down Expand Up @@ -126,6 +127,7 @@ impl ExecutionMessage {
input: Option<&[u8]>,
value: Uint256,
create2_salt: Bytes32,
code_address: Address,
) -> Self {
ExecutionMessage {
kind,
Expand All @@ -141,6 +143,7 @@ impl ExecutionMessage {
},
value,
create2_salt,
code_address,
}
}

Expand Down Expand Up @@ -188,6 +191,11 @@ impl ExecutionMessage {
pub fn create2_salt(&self) -> &Bytes32 {
&self.create2_salt
}

/// Read the code address of the message.
pub fn code_address(&self) -> &Address {
&self.code_address
}
}

impl<'a> ExecutionContext<'a> {
Expand Down Expand Up @@ -326,6 +334,7 @@ impl<'a> ExecutionContext<'a> {
input_size: input_size,
value: *message.value(),
create2_salt: *message.create2_salt(),
code_address: *message.code_address(),
};
unsafe {
assert!((*self.host).call.is_some());
Expand Down Expand Up @@ -495,6 +504,7 @@ impl From<&ffi::evmc_message> for ExecutionMessage {
},
value: message.value,
create2_salt: message.create2_salt,
code_address: message.code_address,
}
}
}
Expand Down Expand Up @@ -653,6 +663,7 @@ mod tests {
let sender = Address { bytes: [128u8; 20] };
let value = Uint256 { bytes: [0u8; 32] };
let create2_salt = Bytes32 { bytes: [255u8; 32] };
let code_address = Address { bytes: [64u8; 20] };

let ret = ExecutionMessage::new(
MessageKind::EVMC_CALL,
Expand All @@ -664,6 +675,7 @@ mod tests {
Some(&input),
value,
create2_salt,
code_address,
);

assert_eq!(ret.kind(), MessageKind::EVMC_CALL);
Expand All @@ -676,6 +688,7 @@ mod tests {
assert_eq!(*ret.input().unwrap(), input);
assert_eq!(*ret.value(), value);
assert_eq!(*ret.create2_salt(), create2_salt);
assert_eq!(*ret.code_address(), code_address);
}

#[test]
Expand All @@ -684,6 +697,7 @@ mod tests {
let sender = Address { bytes: [128u8; 20] };
let value = Uint256 { bytes: [0u8; 32] };
let create2_salt = Bytes32 { bytes: [255u8; 32] };
let code_address = Address { bytes: [64u8; 20] };

let msg = ffi::evmc_message {
kind: MessageKind::EVMC_CALL,
Expand All @@ -696,6 +710,7 @@ mod tests {
input_size: 0,
value: value,
create2_salt: create2_salt,
code_address: code_address,
};

let ret: ExecutionMessage = (&msg).into();
Expand All @@ -709,6 +724,7 @@ mod tests {
assert!(ret.input().is_none());
assert_eq!(*ret.value(), msg.value);
assert_eq!(*ret.create2_salt(), msg.create2_salt);
assert_eq!(*ret.code_address(), msg.code_address);
}

#[test]
Expand All @@ -718,6 +734,7 @@ mod tests {
let sender = Address { bytes: [128u8; 20] };
let value = Uint256 { bytes: [0u8; 32] };
let create2_salt = Bytes32 { bytes: [255u8; 32] };
let code_address = Address { bytes: [64u8; 20] };

let msg = ffi::evmc_message {
kind: MessageKind::EVMC_CALL,
Expand All @@ -730,6 +747,7 @@ mod tests {
input_size: input.len(),
value: value,
create2_salt: create2_salt,
code_address: code_address,
};

let ret: ExecutionMessage = (&msg).into();
Expand All @@ -744,6 +762,7 @@ mod tests {
assert_eq!(*ret.input().unwrap(), input);
assert_eq!(*ret.value(), msg.value);
assert_eq!(*ret.create2_salt(), msg.create2_salt);
assert_eq!(*ret.code_address(), msg.code_address);
}

unsafe extern "C" fn get_dummy_tx_context(
Expand Down Expand Up @@ -866,6 +885,7 @@ mod tests {
None,
Uint256::default(),
Bytes32::default(),
test_addr,
);

let b = exe_context.call(&message);
Expand Down Expand Up @@ -897,6 +917,7 @@ mod tests {
Some(&data),
Uint256::default(),
Bytes32::default(),
test_addr,
);

let b = exe_context.call(&message);
Expand Down
12 changes: 11 additions & 1 deletion include/evmc/evmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ struct evmc_message
/** The amount of gas for message execution. */
int64_t gas;

/** The destination of the message. */
/** The destination (recipient) of the message. */
evmc_address destination;

/** The sender of the message. */
Expand Down Expand Up @@ -141,6 +141,16 @@ struct evmc_message
* Ignored in evmc_execute_fn().
*/
evmc_bytes32 create2_salt;

/**
* The address of the code to be executed.
* May be different from the destination (recipient) in case of CALLCODE & DELEGATECALL.
* See Section 8 "Message Call" of the Yellow Paper for detail.
*
* Not required when invoking evmc_execute_fn, only when invoking evmc_call_fn.
* Ignored if kind is EVMC_CREATE or EVMC_CREATE2.
*/
evmc_address code_address;
};


Expand Down
28 changes: 22 additions & 6 deletions tools/vmtester/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,17 @@ TEST_F(evmc_vm_test, execute_call)
TEST_F(evmc_vm_test, execute_create)
{
evmc::MockedHost mockedHost;
evmc_message msg{
EVMC_CREATE, 0, 0, 65536, evmc_address{}, evmc_address{}, nullptr, 0, evmc_uint256be{},
evmc_bytes32{}};
evmc_message msg{EVMC_CREATE,
0,
0,
65536,
evmc_address{},
evmc_address{},
nullptr,
0,
evmc_uint256be{},
evmc_bytes32{},
evmc_address{}};
std::array<uint8_t, 2> code = {{0xfe, 0x00}};

evmc_result result =
Expand Down Expand Up @@ -170,9 +178,17 @@ TEST_F(evmc_vm_test, precompile_test)
destination.bytes[18] = static_cast<uint8_t>(i >> 8);
destination.bytes[19] = static_cast<uint8_t>(i & 0xff);

evmc_message msg{
EVMC_CALL, 0, 0, 65536, destination, evmc_address{}, nullptr, 0, evmc_uint256be{},
evmc_bytes32{}};
evmc_message msg{EVMC_CALL,
0,
0,
65536,
destination,
evmc_address{},
nullptr,
0,
evmc_uint256be{},
evmc_bytes32{},
evmc_address{}};

evmc_result result = vm->execute(vm, nullptr, nullptr, EVMC_MAX_REVISION, &msg, nullptr, 0);

Expand Down

0 comments on commit 3dbc193

Please sign in to comment.