From c8d818880182b0737bdb7534bba89bbbff0681ff Mon Sep 17 00:00:00 2001 From: Flouse Date: Tue, 27 Jul 2021 07:13:50 +0000 Subject: [PATCH 1/4] Remove polyjuice-tests/fuzz/mock_generator_utils.h - deprecate polyjuice-tests/fuzz/mock_generator_utils.h and follow the newest version of deps/godwoken-scripts/c/generator_utils.h - mock_mint_sudt for new account --- polyjuice-tests/fuzz/README.md | 1 - polyjuice-tests/fuzz/ckb_syscalls.h | 24 +- polyjuice-tests/fuzz/mock_generator_utils.h | 558 -------------------- polyjuice-tests/fuzz/mock_godwoken.hpp | 53 +- 4 files changed, 45 insertions(+), 591 deletions(-) delete mode 100644 polyjuice-tests/fuzz/mock_generator_utils.h diff --git a/polyjuice-tests/fuzz/README.md b/polyjuice-tests/fuzz/README.md index 22862333..b283ba8f 100644 --- a/polyjuice-tests/fuzz/README.md +++ b/polyjuice-tests/fuzz/README.md @@ -4,7 +4,6 @@ These three file were created to simulate `gw_syscalls`: - polyjuice-tests/fuzz/ckb_syscalls.h -- polyjuice-tests/fuzz/mock_generator_utils.h _(will be deprecated and follow the newest update in `godwoken-scripts`)_ - polyjuice-tests/fuzz/mock_godwoken.hpp ## Polyjuice Generator Fuzzer diff --git a/polyjuice-tests/fuzz/ckb_syscalls.h b/polyjuice-tests/fuzz/ckb_syscalls.h index 6b1d1ac8..e5daf71d 100644 --- a/polyjuice-tests/fuzz/ckb_syscalls.h +++ b/polyjuice-tests/fuzz/ckb_syscalls.h @@ -46,10 +46,12 @@ void dbg_print_hex(const uint8_t* ptr, size_t size) { #define dbg_print_hex(p) do {} while (0) #endif +#define MOCK_SUCCESS 0 + int ckb_exit(int8_t code) { printf("ckb_exit, code=%d\n", code); exit(0); - return CKB_SUCCESS; + return MOCK_SUCCESS; } // Mock implementation for the SYS_ckb_load_cell_data_as_code syscall in @@ -61,14 +63,15 @@ static int inline __internal_syscall(long n, long _a0, long _a1, long _a2, long _a3, long _a4, long _a5); #ifdef GW_GENERATOR -#include "mock_generator_utils.h" +#include "generator_utils.h" +#include "mock_godwoken.hpp" #endif static int inline __internal_syscall(long n, long _a0, long _a1, long _a2, long _a3, long _a4, long _a5) { switch (n) { // mock syscall(GW_SYS_LOAD_TRANSACTION, addr, &inner_len, 0, 0, 0, 0) - case GW_SYS_LOAD_TRANSACTION: + case GW_SYS_LOAD_TRANSACTION: // Load Layer2 Transaction return gw_load_transaction_from_raw_tx((uint8_t *)_a0, (uint64_t *)_a1); // mock syscall(GW_SYS_LOAD, raw_key, value, 0, 0, 0, 0) @@ -90,7 +93,7 @@ static int inline __internal_syscall(long n, long _a0, long _a1, long _a2, fclose(stream); stream = NULL; if (ret != 1) { // ret = The total number of elements successfully read - return MOCK_SECP256K1_ERROR_LOADING_DATA; + return GW_ERROR_NOT_FOUND; } *(uint64_t *)_a1 = CKB_SECP256K1_DATA_SIZE; return MOCK_SUCCESS; @@ -126,19 +129,6 @@ static int inline __internal_syscall(long n, long _a0, long _a1, long _a2, case GW_SYS_LOAD_ACCOUNT_SCRIPT: return gw_sys_load_account_script((uint8_t *)_a0, (uint64_t *)_a1, _a2, _a3); - // mock syscall(GW_SYS_LOAD_SCRIPT_HASH_BY_ACCOUNT_ID, account_id, script_hash, 0, 0, 0, 0) - case GW_SYS_LOAD_SCRIPT_HASH_BY_ACCOUNT_ID: - return gw_sys_load_script_hash_by_account_id(_a0, (uint8_t *)_a1); - - // mock syscall(GW_SYS_LOAD_ACCOUNT_ID_BY_SCRIPT_HASH, script_hash, account_id, 0, 0, 0, 0) - case GW_SYS_LOAD_ACCOUNT_ID_BY_SCRIPT_HASH: - // TODO: test this - return gw_sys_load_account_id_by_script_hash((uint8_t *)_a0, (uint32_t *)_a1); - - // mock syscall(GW_SYS_GET_SCRIPT_HASH_BY_SHORT_ADDRESS, script_hash, prefix, prefix_len, 0, 0, 0) - case GW_SYS_GET_SCRIPT_HASH_BY_SHORT_ADDRESS: - return gw_sys_get_script_hash_by_short_address((uint8_t *)_a0, (uint8_t *)_a1, _a2); - // mock syscall(GW_SYS_LOAD_ROLLUP_CONFIG, addr, &inner_len, 0, 0, 0, 0) case GW_SYS_LOAD_ROLLUP_CONFIG: return gw_sys_load_rollup_config((uint8_t *)_a0, (uint64_t *)_a1); diff --git a/polyjuice-tests/fuzz/mock_generator_utils.h b/polyjuice-tests/fuzz/mock_generator_utils.h deleted file mode 100644 index da8791e6..00000000 --- a/polyjuice-tests/fuzz/mock_generator_utils.h +++ /dev/null @@ -1,558 +0,0 @@ -#ifndef GW_GENERATOR_H_ -#define GW_GENERATOR_H_ -/* Layer2 contract generator - * - * The generator supposed to be run off-chain. - * generator dynamic linking with the layer2 contract code, - * and provides layer2 syscalls. - * - * A program should be able to generate a post state after run the generator, - * and should be able to use the states to construct a transaction that satifies - * the validator. - */ - -/* https://stackoverflow.com/a/1545079 */ -#pragma push_macro("errno") -#undef errno -#include "ckb_syscalls.h" -#pragma pop_macro("errno") -#include "gw_def.h" - -/* syscalls */ -/* Syscall account store / load / create */ -#define GW_SYS_CREATE 3100 -#define GW_SYS_STORE 3101 -#define GW_SYS_LOAD 3102 -#define GW_SYS_LOAD_SCRIPT_HASH_BY_ACCOUNT_ID 3103 -#define GW_SYS_LOAD_ACCOUNT_ID_BY_SCRIPT_HASH 3104 -#define GW_SYS_LOAD_ACCOUNT_SCRIPT 3105 -#define GW_SYS_GET_SCRIPT_HASH_BY_SHORT_ADDRESS 3106 -/* Syscall call / return */ -#define GW_SYS_SET_RETURN_DATA 3201 -/* Syscall data store / load */ -#define GW_SYS_STORE_DATA 3301 -#define GW_SYS_LOAD_DATA 3302 -/* Syscall load metadata structures */ -#define GW_SYS_LOAD_ROLLUP_CONFIG 3401 -#define GW_SYS_LOAD_TRANSACTION 3402 -#define GW_SYS_LOAD_BLOCKINFO 3403 -#define GW_SYS_GET_BLOCK_HASH 3404 -/* Syscall builtins */ -#define GW_SYS_PAY_FEE 3501 -#define GW_SYS_LOG 3502 -#define GW_SYS_RECOVER_ACCOUNT 3503 - -#define MOCK_SUCCESS 0 -#define MOCK_SECP256K1_ERROR_LOADING_DATA -101 - -typedef struct gw_context_t { - /* verification context */ - gw_transaction_context_t transaction_context; - gw_block_info_t block_info; - uint8_t rollup_config[GW_MAX_ROLLUP_CONFIG_SIZE]; - uint64_t rollup_config_size; - /* original sender nonce */ - uint32_t original_sender_nonce; - /* layer2 syscalls */ - gw_load_fn sys_load; - gw_get_account_nonce_fn sys_get_account_nonce; - gw_store_fn sys_store; - gw_set_program_return_data_fn sys_set_program_return_data; - gw_create_fn sys_create; - gw_get_account_id_by_script_hash_fn sys_get_account_id_by_script_hash; - gw_get_script_hash_by_account_id_fn sys_get_script_hash_by_account_id; - gw_get_account_script_fn sys_get_account_script; - gw_load_data_fn sys_load_data; - gw_store_data_fn sys_store_data; - gw_get_block_hash_fn sys_get_block_hash; - gw_get_script_hash_by_prefix_fn sys_get_script_hash_by_prefix; - gw_recover_account_fn sys_recover_account; - gw_log_fn sys_log; - gw_pay_fee_fn sys_pay_fee; - _gw_load_raw_fn _internal_load_raw; - _gw_store_raw_fn _internal_store_raw; -} gw_context_t; - -#include "common.h" -#include "mock_godwoken.hpp" - -int _internal_load_raw(gw_context_t *ctx, const uint8_t raw_key[GW_VALUE_BYTES], - uint8_t value[GW_VALUE_BYTES]) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - - int ret = syscall(GW_SYS_LOAD, raw_key, value, 0, 0, 0, 0); - if (ret != 0) { - printf("failed internal_load_raw"); - /* Even we load via syscall, the data structure in the bottom is a SMT */ - return GW_FATAL_SMT_FETCH; - } - return 0; -} - -int _internal_store_raw(gw_context_t *ctx, const uint8_t raw_key[GW_KEY_BYTES], - const uint8_t value[GW_VALUE_BYTES]) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - - int ret = syscall(GW_SYS_STORE, raw_key, value, 0, 0, 0, 0); - if (ret != 0) { - printf("failed internal_store_raw"); - /* Even we load via syscall, the data structure in the bottom is a SMT */ - return GW_FATAL_SMT_STORE; - } - return 0; -} - -// int _ensure_account_exists(gw_context_t *ctx, uint32_t account_id) { -// uint8_t script_hash[32]; -// int ret = ctx->sys_get_script_hash_by_account_id(ctx, account_id, script_hash); -// if (ret != 0) { -// return ret; -// } -// for (int i = 0; i < 32; i++) { -// /* if account not exists script_hash will be zero */ -// if (script_hash[i] != 0) { -// return 0; -// } -// } -// return GW_FATAL_ACCOUNT_NOT_FOUND; -// } - -int sys_load(gw_context_t *ctx, uint32_t account_id, const uint8_t *key, - const uint64_t key_len, uint8_t value[GW_VALUE_BYTES]) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - int ret = _ensure_account_exists(ctx, account_id); - if (ret != 0) { - return ret; - } - - // TODO: get mock balance from gw_mock_host.accounts - if (1 == *(uint32_t*)key) { // SUDT_KEY_FLAG_BALANCE = 1 - dbg_print("mock ID(%d) balance = 40000", account_id); - value[0] = 64; - value[1] = 156; - return MOCK_SUCCESS; - } - - uint8_t raw_key[GW_KEY_BYTES] = {0}; - gw_build_account_key(account_id, key, key_len, raw_key); - dbg_print("[sys_load] load value by account_key"); - return _internal_load_raw(ctx, raw_key, value); -} -int sys_store(gw_context_t *ctx, uint32_t account_id, const uint8_t *key, - const uint64_t key_len, const uint8_t value[GW_VALUE_BYTES]) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - int ret = _ensure_account_exists(ctx, account_id); - if (ret != 0) { - return ret; - } - - uint8_t raw_key[GW_KEY_BYTES]; - gw_build_account_key(account_id, key, key_len, raw_key); - return _internal_store_raw(ctx, raw_key, value); -} - -int sys_get_account_nonce(gw_context_t *ctx, uint32_t account_id, - uint32_t *nonce) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - int ret = _ensure_account_exists(ctx, account_id); - if (ret != 0) { - return ret; - } - - uint8_t key[32] = {0}; - gw_build_account_field_key(account_id, GW_ACCOUNT_NONCE, key); - uint8_t value[32] = {0}; - dbg_print("[sys_get_account_nonce] load value by account_field_key"); - ret = _internal_load_raw(ctx, key, value); - if (ret != 0) { - return ret; - } - memcpy(nonce, value, sizeof(uint32_t)); - return 0; -} - -/* set call return data */ -int sys_set_program_return_data(gw_context_t *ctx, uint8_t *data, - uint64_t len) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - if (len > GW_MAX_DATA_SIZE) { - printf("Exceeded max return data size"); - return GW_FATAL_BUFFER_OVERFLOW; - } - return syscall(GW_SYS_SET_RETURN_DATA, data, len, 0, 0, 0, 0); -} - -/* Get account id by account script_hash */ -int sys_get_account_id_by_script_hash(gw_context_t *ctx, - uint8_t script_hash[32], - uint32_t *account_id) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - uint8_t raw_key[32] = {0}; - uint8_t value[32] = {0}; - gw_build_script_hash_to_account_id_key(script_hash, raw_key); - dbg_print("[sys_get_account_id_by_script_hash] load value by account_id_key"); - int ret = _internal_load_raw(ctx, raw_key, value); - if (ret != 0) { - return ret; - } - *account_id = *((uint32_t *)value); - - /* if account_id is greater than 0, it is exist */ - if (*account_id > 0) { - return 0; - } - - ret = _ensure_account_exists(ctx, *account_id); - if (ret != 0) { - return ret; - } - - return 0; -} - -/* Get account script_hash by account id */ -int sys_get_script_hash_by_account_id(gw_context_t *ctx, uint32_t account_id, - uint8_t script_hash[32]) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - - int ret = _ensure_account_exists(ctx, account_id); - if (ret != 0) { - return ret; - } - - uint8_t raw_key[32] = {0}; - gw_build_account_field_key(account_id, GW_ACCOUNT_SCRIPT_HASH, raw_key); - dbg_print("[sys_get_script_hash_by_account_id] load script_hash by account_field_key"); - return _internal_load_raw(ctx, raw_key, script_hash); -} - -/* Get account script by account id */ -int sys_get_account_script(gw_context_t *ctx, uint32_t account_id, - uint64_t *len, uint64_t offset, uint8_t *script) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - - /* get account script hash */ - int ret; - uint8_t script_hash[32] = {0}; - ret = sys_get_script_hash_by_account_id(ctx, account_id, script_hash); - if (ret != 0) { - return ret; - } - - if (_is_zero_hash(script_hash)) { - printf("account script_hash is zero, which means account isn't exist"); - return GW_ERROR_NOT_FOUND; - } - - volatile uint64_t inner_len = *len; - ret = syscall(GW_SYS_LOAD_ACCOUNT_SCRIPT, script, &inner_len, offset, - account_id, 0, 0); - *len = inner_len; - return ret; -} -/* Store data by data hash */ -int sys_store_data(gw_context_t *ctx, uint64_t data_len, uint8_t *data) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - if (data_len > GW_MAX_DATA_SIZE) { - printf("Exceeded max store data size"); - return GW_FATAL_INVALID_DATA; - } - return syscall(GW_SYS_STORE_DATA, data_len, data, 0, 0, 0, 0); -} -/* Load data by data hash */ -int sys_load_data(gw_context_t *ctx, uint8_t data_hash[32], uint64_t *len, - uint64_t offset, uint8_t *data) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - - /* Check data_hash_key */ - int data_exists = 0; - int ret = _check_data_hash_exist(ctx, data_hash, &data_exists); - if (ret != 0) { - return ret; - } - - if (!data_exists) { - printf("data hash not exist"); - /* return not found if data isn't exist in the state tree */ - return GW_ERROR_NOT_FOUND; - } - - volatile uint64_t inner_len = *len; - ret = syscall(GW_SYS_LOAD_DATA, data, &inner_len, offset, data_hash, 0, 0); - *len = inner_len; - return ret; -} - -// Load Layer2 Transaction -int _sys_load_l2transaction(void *addr, uint64_t *len) { - volatile uint64_t inner_len = *len; - int ret = syscall(GW_SYS_LOAD_TRANSACTION, addr, &inner_len, 0, 0, 0, 0); - *len = inner_len; - return ret; -} - -int _sys_load_block_info(void *addr, uint64_t *len) { - volatile uint64_t inner_len = *len; - int ret = syscall(GW_SYS_LOAD_BLOCKINFO, addr, &inner_len, 0, 0, 0, 0); - *len = inner_len; - return ret; -} - -int sys_get_block_hash(gw_context_t *ctx, uint64_t number, - uint8_t block_hash[32]) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - return syscall(GW_SYS_GET_BLOCK_HASH, block_hash, number, 0, 0, 0, 0); -} - -int sys_get_script_hash_by_prefix(gw_context_t *ctx, uint8_t *prefix, - uint64_t prefix_len, - uint8_t script_hash[32]) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - - if (prefix_len == 0 || prefix_len > 32) { - return GW_FATAL_INVALID_DATA; - } - - return _load_script_hash_by_short_script_hash(ctx, prefix, prefix_len, - script_hash); - // return syscall(GW_SYS_GET_SCRIPT_HASH_BY_SHORT_ADDRESS, script_hash, prefix, prefix_len, 0, 0, 0); -} - -int sys_create(gw_context_t *ctx, uint8_t *script, uint64_t script_len, - uint32_t *account_id) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - - /* calculate script_hash */ - uint8_t script_hash[32] = {0}; - blake2b_state blake2b_ctx; - blake2b_init(&blake2b_ctx, 32); - blake2b_update(&blake2b_ctx, script, script_len); - blake2b_final(&blake2b_ctx, script_hash, 32); - - /* check existance */ - int account_exist = 0; - int ret = - _check_account_exists_by_script_hash(ctx, script_hash, &account_exist); - if (ret != 0) { - return ret; - } - if (account_exist) { - return GW_ERROR_DUPLICATED_SCRIPT_HASH; - } - - return syscall(GW_SYS_CREATE, script, script_len, account_id, 0, 0, 0); -} - -int sys_recover_account(struct gw_context_t *ctx, uint8_t message[32], - uint8_t *signature, uint64_t signature_len, - uint8_t code_hash[32], uint8_t *script, - uint64_t *script_len) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - volatile uint64_t inner_script_len = 0; - int ret = syscall(GW_SYS_RECOVER_ACCOUNT, script, &inner_script_len, message, - signature, signature_len, code_hash); - *script_len = inner_script_len; - return ret; -} - -int sys_log(gw_context_t *ctx, uint32_t account_id, uint8_t service_flag, - uint64_t data_length, const uint8_t *data) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - int ret = _ensure_account_exists(ctx, account_id); - if (ret != 0) { - return ret; - } - - return syscall(GW_SYS_LOG, account_id, service_flag, data_length, data, 0, 0); -} - -int sys_pay_fee(gw_context_t *ctx, const uint8_t *payer_addr, - const uint64_t short_addr_len, uint32_t sudt_id, - uint128_t amount) { - if (ctx == NULL) { - return GW_FATAL_INVALID_CONTEXT; - } - int ret = _ensure_account_exists(ctx, sudt_id); - if (ret != 0) { - return ret; - } - - return syscall(GW_SYS_PAY_FEE, payer_addr, short_addr_len, sudt_id, &amount, - 0, 0); -} - -int _sys_load_rollup_config(uint8_t *addr, uint64_t *len) { - volatile uint64_t inner_len = *len; - int ret = syscall(GW_SYS_LOAD_ROLLUP_CONFIG, addr, &inner_len, 0, 0, 0, 0); - *len = inner_len; - - if (*len > GW_MAX_ROLLUP_CONFIG_SIZE) { - ckb_debug("[_sys_load_rollup_config] length too long"); - return GW_FATAL_INVALID_DATA; - } - mol_seg_t config_seg; - config_seg.ptr = addr; - config_seg.size = *len; - if (MolReader_RollupConfig_verify(&config_seg, false) != MOL_OK) { - ckb_debug("[_sys_load_rollup_config] rollup config cell data is not RollupConfig format"); - return GW_FATAL_INVALID_DATA; - } - - return ret; -} - -int gw_context_init(gw_context_t *ctx) { - /* setup syscalls */ - ctx->sys_load = sys_load; - ctx->sys_store = sys_store; - ctx->sys_set_program_return_data = sys_set_program_return_data; - ctx->sys_create = sys_create; - ctx->sys_get_account_id_by_script_hash = sys_get_account_id_by_script_hash; - ctx->sys_get_script_hash_by_account_id = sys_get_script_hash_by_account_id; - ctx->sys_get_account_nonce = sys_get_account_nonce; - ctx->sys_get_account_script = sys_get_account_script; - ctx->sys_store_data = sys_store_data; - ctx->sys_load_data = sys_load_data; - ctx->sys_get_block_hash = sys_get_block_hash; - ctx->sys_get_script_hash_by_prefix = sys_get_script_hash_by_prefix; - ctx->sys_recover_account = sys_recover_account; - ctx->sys_pay_fee = sys_pay_fee; - ctx->sys_log = sys_log; - ctx->_internal_load_raw = _internal_load_raw; - ctx->_internal_store_raw = _internal_store_raw; - - /* initialize context */ - uint8_t tx_buf[GW_MAX_L2TX_SIZE] = {0}; - uint64_t len = GW_MAX_L2TX_SIZE; - int ret = _sys_load_l2transaction(tx_buf, &len); - if (ret != 0) { - return ret; - } - // dbg_print("[gw_context_init] l2tx size: %d", len); - if (len > GW_MAX_L2TX_SIZE) { - return GW_FATAL_INVALID_DATA; - } - - mol_seg_t l2transaction_seg; - l2transaction_seg.ptr = tx_buf; - l2transaction_seg.size = len; - ret = gw_parse_transaction_context(&ctx->transaction_context, - &l2transaction_seg); - // dbg_print("[gw_context_init] ret of gw_parse_transaction_context: %d", ret); - if (ret != 0) { - return ret; - } - - uint8_t block_info_buf[sizeof(MolDefault_BlockInfo)] = {0}; - len = sizeof(block_info_buf); - ret = _sys_load_block_info(block_info_buf, &len); - // dbg_print("[gw_context_init] ret of _sys_load_block_info: %d", ret); - if (ret != 0) { - return ret; - } - - mol_seg_t block_info_seg; - block_info_seg.ptr = block_info_buf; - block_info_seg.size = len; - ret = gw_parse_block_info(&ctx->block_info, &block_info_seg); - // dbg_print("[gw_context_init] ret of gw_parse_block_info: %d", ret); - if (ret != 0) { - return ret; - } - - ctx->rollup_config_size = GW_MAX_ROLLUP_CONFIG_SIZE; - ret = _sys_load_rollup_config(ctx->rollup_config, &ctx->rollup_config_size); - // dbg_print("[gw_context_init] ret of _sys_load_rollup_config: %d", ret); - if (ret != 0) { - return ret; - } - - /* init original sender nonce */ - ret = _load_sender_nonce(ctx, &ctx->original_sender_nonce); - if (ret != 0) { - printf("failed to init original sender nonce"); - return ret; - } - - return 0; -} - -int gw_finalize(gw_context_t *ctx) { - /* update sender nonce */ - int ret = _increase_sender_nonce(ctx); - if (ret != 0) { - printf("failed to update original sender nonce"); - return ret; - } - - return 0; -} - -int gw_verify_sudt_account(gw_context_t *ctx, uint32_t sudt_id) { - uint8_t script_buffer[GW_MAX_SCRIPT_SIZE]; - uint64_t script_len = GW_MAX_SCRIPT_SIZE; - int ret = sys_get_account_script(ctx, sudt_id, &script_len, 0, script_buffer); - if (ret != 0) { - return ret; - } - if (script_len > GW_MAX_SCRIPT_SIZE) { - return GW_FATAL_INVALID_SUDT_SCRIPT; - } - mol_seg_t script_seg; - script_seg.ptr = script_buffer; - script_seg.size = script_len; - if (MolReader_Script_verify(&script_seg, false) != MOL_OK) { - ckb_debug("[gw_verify_sudt_account] load account script: invalid script"); - return GW_FATAL_INVALID_SUDT_SCRIPT; - } - mol_seg_t code_hash_seg = MolReader_Script_get_code_hash(&script_seg); - mol_seg_t hash_type_seg = MolReader_Script_get_hash_type(&script_seg); - - mol_seg_t rollup_config_seg; - rollup_config_seg.ptr = ctx->rollup_config; - rollup_config_seg.size = ctx->rollup_config_size; - mol_seg_t l2_sudt_validator_script_type_hash = - MolReader_RollupConfig_get_l2_sudt_validator_script_type_hash( - &rollup_config_seg); - if (memcmp(l2_sudt_validator_script_type_hash.ptr, code_hash_seg.ptr, 32) != - 0) { - return GW_FATAL_INVALID_SUDT_SCRIPT; - } - if (*hash_type_seg.ptr != 1) { - return GW_FATAL_INVALID_SUDT_SCRIPT; - } - return 0; -} -#endif diff --git a/polyjuice-tests/fuzz/mock_godwoken.hpp b/polyjuice-tests/fuzz/mock_godwoken.hpp index ce02829d..3e7b5f64 100644 --- a/polyjuice-tests/fuzz/mock_godwoken.hpp +++ b/polyjuice-tests/fuzz/mock_godwoken.hpp @@ -182,19 +182,19 @@ extern "C" int gw_sys_load_script_hash_by_account_id(const uint32_t account_id, // {125, 181, 86, 185, 69, 172, 188, 175, 36, 25, 118, 119, 114, 72, 199, 183, 204, 25, 147, 120, 109, 220, 192, 171, 10, 235, 47, 230, 42, 210, 169, 223}}; } -extern "C" int gw_sys_get_script_hash_by_short_address(uint8_t *script_hash_addr, - uint8_t *prefix_addr, - uint64_t prefix_len) { - for (auto pair : gw_host->code_store) { - if (0 == memcmp(pair.first.bytes, prefix_addr, prefix_len)) { - memcpy(script_hash_addr, pair.first.bytes, sizeof(pair.first.bytes)); - return 0; - } - } +// extern "C" int gw_sys_get_script_hash_by_short_address(uint8_t *script_hash_addr, +// uint8_t *prefix_addr, +// uint64_t prefix_len) { +// for (auto pair : gw_host->code_store) { +// if (0 == memcmp(pair.first.bytes, prefix_addr, prefix_len)) { +// memcpy(script_hash_addr, pair.first.bytes, sizeof(pair.first.bytes)); +// return 0; +// } +// } - dbg_print("gw_sys_get_script_hash_by_short_address failed"); - return GW_ERROR_NOT_FOUND; -} +// dbg_print("gw_sys_get_script_hash_by_short_address failed"); +// return GW_ERROR_NOT_FOUND; +// } extern "C" int gw_sys_load_account_id_by_script_hash(uint8_t *script_hash, uint32_t *account_id_ptr) { @@ -226,6 +226,30 @@ extern "C" int gw_sys_load_rollup_config(uint8_t *addr, return 0; } +void _sudt_build_key(uint32_t key_flag, const uint8_t *short_addr, + uint32_t short_addr_len, uint8_t *key); +/// mock_mint_sudt on layer2 +void mock_mint_sudt(uint32_t sudt_id, uint32_t account_id, uint128_t balance) +{ + uint8_t script_hash[GW_KEY_BYTES] = {0}; + gw_sys_load_script_hash_by_account_id(account_id, script_hash); + + uint8_t key[GW_KEY_BYTES + 8] = {0}; + uint64_t key_len = POLYJUICE_SHORT_ADDR_LEN + 8; + _sudt_build_key(1, // SUDT_KEY_FLAG_BALANCE = 1 + script_hash, + POLYJUICE_SHORT_ADDR_LEN, + key); + + uint8_t value[32] = {0}; + *(uint128_t *)value = balance; + + // sys_store balance + uint8_t raw_key[GW_KEY_BYTES]; + gw_build_account_key(sudt_id, key, key_len, raw_key); + gw_update_raw(raw_key, value); +} + extern "C" int gw_sys_create(uint8_t *script, uint64_t script_len, uint32_t *account_id_ptr) { int ret = 0; @@ -445,12 +469,11 @@ int init() { new_id = create_account_from_script((uint8_t *)build_eth_l2_script.data(), build_eth_l2_script.size()); + mock_mint_sudt(1, new_id, 40000); - - // init destructed key + // TODO: init destructed key const uint8_t zero_nonce[32] = {0}; const uint8_t poly_destructed_key[32] = {5, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - // FIXME: gw_update_raw(poly_destructed_key, zero_nonce); print_state(); From 90625614a72ecc8aea2ee4b6f23eb61dd333767c Mon Sep 17 00:00:00 2001 From: Flouse Date: Wed, 28 Jul 2021 09:28:31 +0000 Subject: [PATCH 2/4] test(fuzz): fix undefined reference to `_sudt_build_key(unsigned int, unsigned char const*, unsigned int, unsigned char*)' --- polyjuice-tests/fuzz/mock_godwoken.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/polyjuice-tests/fuzz/mock_godwoken.hpp b/polyjuice-tests/fuzz/mock_godwoken.hpp index 3e7b5f64..7756ba5d 100644 --- a/polyjuice-tests/fuzz/mock_godwoken.hpp +++ b/polyjuice-tests/fuzz/mock_godwoken.hpp @@ -226,27 +226,27 @@ extern "C" int gw_sys_load_rollup_config(uint8_t *addr, return 0; } -void _sudt_build_key(uint32_t key_flag, const uint8_t *short_addr, - uint32_t short_addr_len, uint8_t *key); /// mock_mint_sudt on layer2 void mock_mint_sudt(uint32_t sudt_id, uint32_t account_id, uint128_t balance) { uint8_t script_hash[GW_KEY_BYTES] = {0}; gw_sys_load_script_hash_by_account_id(account_id, script_hash); + // _sudt_build_key uint8_t key[GW_KEY_BYTES + 8] = {0}; uint64_t key_len = POLYJUICE_SHORT_ADDR_LEN + 8; - _sudt_build_key(1, // SUDT_KEY_FLAG_BALANCE = 1 - script_hash, - POLYJUICE_SHORT_ADDR_LEN, - key); + const uint32_t SUDT_KEY_FLAG_BALANCE = 1; + const uint32_t short_addr_len = POLYJUICE_SHORT_ADDR_LEN; + memcpy(key, (uint8_t *)(&SUDT_KEY_FLAG_BALANCE), sizeof(uint32_t)); + memcpy(key + 4, (uint8_t *)(&short_addr_len), sizeof(uint32_t)); + memcpy(key + 8, script_hash, short_addr_len); + uint8_t raw_key[GW_KEY_BYTES]; + gw_build_account_key(sudt_id, key, key_len, raw_key); uint8_t value[32] = {0}; *(uint128_t *)value = balance; // sys_store balance - uint8_t raw_key[GW_KEY_BYTES]; - gw_build_account_key(sudt_id, key, key_len, raw_key); gw_update_raw(raw_key, value); } From 1b037301ed850eef99336da076f85a14da3c1b81 Mon Sep 17 00:00:00 2001 From: Flouse Date: Thu, 29 Jul 2021 05:16:44 +0000 Subject: [PATCH 3/4] test: fuzzing 30 minutes in CI --- .github/workflows/fuzz.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index b61a867f..5d820b07 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -41,9 +41,9 @@ jobs: working-directory: ./polyjuice-tests/fuzz run: make build/test_contracts && ./build/test_contracts - - name: Fuzzing Polyjuice Generator 360 seconds + - name: Fuzzing Polyjuice Generator 30 minutes working-directory: polyjuice-tests/fuzz - run: make build/polyjuice_generator_fuzzer && ./build/polyjuice_generator_fuzzer corpus -max_total_time=360 -timeout=2 + run: make build/polyjuice_generator_fuzzer && ./build/polyjuice_generator_fuzzer corpus -max_total_time=1800 -timeout=60 - name: Archive inputs that triggered crashes or sanitizer failures uses: actions/upload-artifact@v2 From b70e88bcfff7037bc3744d2f4fec2c7fe013e31a Mon Sep 17 00:00:00 2001 From: Flouse Date: Thu, 29 Jul 2021 05:40:47 +0000 Subject: [PATCH 4/4] test: limit maxinum length of fuzz inputs --- .github/workflows/fuzz.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 5d820b07..ec94e1ef 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -43,7 +43,10 @@ jobs: - name: Fuzzing Polyjuice Generator 30 minutes working-directory: polyjuice-tests/fuzz - run: make build/polyjuice_generator_fuzzer && ./build/polyjuice_generator_fuzzer corpus -max_total_time=1800 -timeout=60 + run: | + make build/polyjuice_generator_fuzzer && \ + ./build/polyjuice_generator_fuzzer corpus -max_len=25000 -max_total_time=1800 -timeout=120 + # Max data buffer size: 24KB < 25000 bytes - name: Archive inputs that triggered crashes or sanitizer failures uses: actions/upload-artifact@v2