Skip to content

Commit

Permalink
Ref #88: Implement wrapper for get_code_hash
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanielhourt authored and dimas1185 committed Jun 8, 2023
1 parent a0db8c9 commit 0081b38
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
10 changes: 10 additions & 0 deletions libraries/eosiolib/capi/eosio/action.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ uint64_t publication_time( void );
__attribute__((eosio_wasm_import))
capi_name current_receiver( void );

/**
* Get the hash of the code currently published on the given account
* @param account Name of the account to hash the code of
* @param struct_version Version specifying the desired format of the returned struct
* @param result_buffer Buffer wherein the result should be written
* @param buffer_size Size in bytes of result_buffer
*/
__attribute__((eosio_wasm_import))
uint32_t get_code_hash( uint64_t account, uint32_t struct_version, char* result_buffer, size_t buffer_size );

/**
* Set the action return value which will be included in the action_receipt
* @brief Set the action return value
Expand Down
39 changes: 39 additions & 0 deletions libraries/eosiolib/contracts/eosio/action.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "../../core/eosio/serialize.hpp"
#include "../../core/eosio/datastream.hpp"
#include "../../core/eosio/name.hpp"
#include "../../core/eosio/fixed_bytes.hpp"
#include "../../core/eosio/ignore.hpp"
#include "../../core/eosio/time.hpp"

Expand Down Expand Up @@ -48,9 +49,23 @@ namespace eosio {

__attribute__((eosio_wasm_import))
uint64_t current_receiver();

__attribute__((eosio_wasm_import))
uint32_t get_code_hash( uint64_t account, uint32_t struct_version, char* result_buffer, size_t buffer_size );
}
};

struct code_hash_result {
unsigned_int struct_version;
uint64_t code_sequence;
checksum256 code_hash;
uint8_t vm_type;
uint8_t vm_version;

CDT_REFLECT(struct_version, code_sequence, code_hash, vm_type, vm_version);
EOSLIB_SERIALIZE(code_hash_result, (struct_version)(code_sequence)(code_hash)(vm_type)(vm_version));
};

/**
* @defgroup action Action
* @ingroup contracts
Expand Down Expand Up @@ -146,6 +161,30 @@ namespace eosio {
return name{internal_use_do_not_use::current_receiver()};
}

/**
* Get the hash of the code currently published on the given account
* @param account Name of the account to hash the code of
* @param full_result Optional: If a full result struct is desired, a pointer to the struct to populate
* @return The SHA256 hash of the specified account's code
*/
inline checksum256 get_code_hash( name account, code_hash_result* full_result = nullptr ) {
if (full_result == nullptr)
full_result = (code_hash_result*)alloca(sizeof(code_hash_result));

// Packed size is dynamic, so we don't know what it'll be. Try to have plenty of space.
auto struct_buffer_size = sizeof(code_hash_result)*2;
char* struct_buffer = (char*)alloca(struct_buffer_size);

using VersionType = decltype(code_hash_result::struct_version);
const VersionType STRUCT_VERSION = 0;
internal_use_do_not_use::get_code_hash(account.value, STRUCT_VERSION, struct_buffer, struct_buffer_size);
check(unpack<VersionType>(struct_buffer, struct_buffer_size) == STRUCT_VERSION,
"Hypervisor returned unexpected code hash struct version");
unpack(*full_result, struct_buffer, struct_buffer_size);

return full_result->code_hash;
}

/**
* Copy up to length bytes of current action data to the specified location
*
Expand Down
1 change: 1 addition & 0 deletions tests/unit/test_contracts/capi/action.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ void test_action( void ) {
send_context_free_inline(NULL, 0);
publication_time();
current_receiver();
get_code_hash(0, 0, NULL, 0);
set_action_return_value(NULL, 0);
}

0 comments on commit 0081b38

Please sign in to comment.