Skip to content
This repository was archived by the owner on Nov 17, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions bindings/java/c/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,19 @@ static evmc_bytes32 get_code_hash_fn(struct evmc_host_context* context, const ev
return result;
}

static inline size_t min(size_t a, size_t b)
{
return (a > b) ? b : a;
}

static size_t copy_code_fn(struct evmc_host_context* context,
const evmc_address* address,
size_t code_offset,
uint8_t* buffer_data,
size_t buffer_size)
{
(void)buffer_size; // FIXME: buffer_size suspiciously unused.
const char java_method_name[] = "copy_code";
const char java_method_signature[] = "(I[BI)Ljava/nio/ByteBuffer;";
const char java_method_signature[] = "(I[B)Ljava/nio/ByteBuffer;";

assert(context != NULL);
JNIEnv* jenv = attach();
Expand All @@ -253,23 +257,27 @@ static size_t copy_code_fn(struct evmc_host_context* context,

// set java method params
jbyteArray jaddress = CopyDataToJava(jenv, address, sizeof(struct evmc_address));
jint jcode_offset = (jint)code_offset;

// call java method
jobject jresult = (*jenv)->CallStaticObjectMethod(jenv, host_class, method, context->index,
jaddress, jcode_offset);
jobject jresult =
(*jenv)->CallStaticObjectMethod(jenv, host_class, method, context->index, jaddress);
assert(jresult != NULL);

// copy jresult back to buffer_data
buffer_data = (uint8_t*)(*jenv)->GetDirectBufferAddress(jenv, jresult);
(void)buffer_data;
assert(buffer_data != NULL);
size_t code_size;
uint8_t* code = GetDirectBuffer(jenv, jresult, &code_size);

size_t result = get_code_size_fn(context, address) - code_offset;
size_t length = 0;
if (code_offset < code_size)
{
length = min(buffer_size, code_size - code_offset);
if (length > 0)
memcpy(buffer_data, code + code_offset, length);
}

(*jenv)->ReleaseByteArrayElements(jenv, jaddress, (jbyte*)address, 0);

return result;
return length;
}

static void selfdestruct_fn(struct evmc_host_context* context,
Expand Down
30 changes: 15 additions & 15 deletions bindings/java/java/src/main/java/org/ethereum/evmc/Host.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
* <p>The set of all callback functions expected by VM instances.
*/
final class Host {
static private ByteBuffer ensureDirectBuffer(ByteBuffer input) {
// Reallocate if needed.
if (!input.isDirect())
Copy link
Member

Choose a reason for hiding this comment

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

No idea what it does. Is this even tested?

Copy link
Member Author

@axic axic Oct 14, 2020

Choose a reason for hiding this comment

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

Not all of them are, but get/set_storage is. This helper enforces that the ByteBuffer is in a format ("direct buffer") which can be queried from JNI (e.g. the GetDirectBuffer helper in C won't assert). The tests always use "direct buffer" though so we never seen an assert.

return ByteBuffer.allocateDirect(input.remaining()).put(input);
return input;
}

/** Check account existence callback function. */
static boolean account_exists(int context_index, byte[] address) {
HostContext context =
Expand All @@ -31,7 +38,7 @@ static ByteBuffer get_storage(int context_index, byte[] address, byte[] key) {
requireNonNull(
getContext(context_index),
"HostContext does not exist for context_index: " + context_index);
return context.getStorage(address, key);
return ensureDirectBuffer(context.getStorage(address, key));
}

/** Set storage callback function. */
Expand All @@ -48,7 +55,7 @@ static ByteBuffer get_balance(int context_index, byte[] address) {
requireNonNull(
getContext(context_index),
"HostContext does not exist for context_index: " + context_index);
return context.getBalance(address);
return ensureDirectBuffer(context.getBalance(address));
}

/** Get code size callback function. */
Expand All @@ -66,23 +73,16 @@ static ByteBuffer get_code_hash(int context_index, byte[] address) {
requireNonNull(
getContext(context_index),
"HostContext does not exist for context_index: " + context_index);
return context.getCodeHash(address);
return ensureDirectBuffer(context.getCodeHash(address));
}

/** Copy code callback function. */
static ByteBuffer copy_code(int context_index, byte[] address, int code_offset) {
static ByteBuffer copy_code(int context_index, byte[] address) {
HostContext context =
requireNonNull(
getContext(context_index),
"HostContext does not exist for context_index: " + context_index);
byte[] code = context.getCode(address).array();

if (code != null && code_offset > 0 && code_offset < code.length) {
int length = code.length - code_offset;
return ByteBuffer.allocateDirect(length).put(code, code_offset, length);
}

return ByteBuffer.allocateDirect(0);
return ensureDirectBuffer(context.getCode(address));
}

/** Selfdestruct callback function. */
Expand All @@ -100,7 +100,7 @@ static ByteBuffer call(int context_index, ByteBuffer msg) {
requireNonNull(
getContext(context_index),
"HostContext does not exist for context_index: " + context_index);
return context.call(msg);
return ensureDirectBuffer(context.call(msg));
}

/** Get transaction context callback function. */
Expand All @@ -109,7 +109,7 @@ static ByteBuffer get_tx_context(int context_index) {
requireNonNull(
getContext(context_index),
"HostContext does not exist for context_index: " + context_index);
return context.getTxContext();
return ensureDirectBuffer(context.getTxContext());
}

/** Get block hash callback function. */
Expand All @@ -118,7 +118,7 @@ static ByteBuffer get_block_hash_fn(int context_index, long number) {
requireNonNull(
getContext(context_index),
"HostContext does not exist for context_index: " + context_index);
return context.getBlockHash(number);
return ensureDirectBuffer(context.getBlockHash(number));
}

/** Emit log callback function. */
Expand Down