From 1c863c545933b4c3920a70707daa518ab29ab8b9 Mon Sep 17 00:00:00 2001 From: Roman Khlopkov <roman.khlopkov@demlabs.net> Date: Wed, 30 Mar 2022 23:19:56 +0300 Subject: [PATCH] [+] API for bridge emissions --- dap-sdk/crypto/src/dap_uuid.c | 13 ++ modules/common/dap_chain_datum_token.c | 57 +++++--- .../common/include/dap_chain_datum_token.h | 28 ++-- modules/mempool/dap_chain_mempool.c | 36 +++-- modules/mempool/include/dap_chain_mempool.h | 6 +- modules/net/dap_chain_node_cli_cmd.c | 137 ++++++++++-------- 6 files changed, 173 insertions(+), 104 deletions(-) diff --git a/dap-sdk/crypto/src/dap_uuid.c b/dap-sdk/crypto/src/dap_uuid.c index ac4a130496..9afa343389 100644 --- a/dap-sdk/crypto/src/dap_uuid.c +++ b/dap-sdk/crypto/src/dap_uuid.c @@ -73,3 +73,16 @@ uint64_t dap_uuid_generate_uint64() // l_input[0],l_input[1],l_input[2],l_input[3]); return l_output; } + +void dap_uuid_generate_nonce(void *a_nonce, size_t a_nonce_size) +{ + if (!a_nonce || !a_none_size) + return; + uint32_t l_input[4] ={ + [0] = random_uint32_t(UINT32_MAX), + [1] = time(NULL), + [2] = atomic_fetch_add(&s_global_counter, 1), + [3] = random_uint32_t(UINT32_MAX) + }; + SHAKE128((unsigned char *)a_nonce, a_nonce_size, (unsigned char *)l_input, sizeof(l_input)); +} diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 5dc8b7d004..a1069379ba 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -261,6 +261,18 @@ err: } +dap_chain_datum_token_emission_t *dap_chain_datum_emission_create(uint256_t a_value, const char *a_ticker, dap_chain_addr_t *a_addr) +{ + dap_chain_datum_token_emission_t *l_emission = DAP_NEW_Z(dap_chain_datum_token_emission_t); + l_emission->hdr.version = 2; + l_emission->hdr.value_256 = a_value; + strncpy(l_emission->hdr.ticker, a_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 1); + l_emission->hdr.ticker[DAP_CHAIN_TICKER_SIZE_MAX - 1] = '\0'; + l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; + memcpy(&l_emission->hdr.address, a_addr, sizeof(l_emission->hdr.address)); + dap_uuid_generate_nonce(&l_emission->hdr.nonce, DAP_CHAIN_DATUM_NONCE_SIZE); +} + size_t dap_chain_datum_emission_get_size(uint8_t *a_emission_serial) { size_t l_ret = 0; @@ -270,24 +282,11 @@ size_t dap_chain_datum_emission_get_size(uint8_t *a_emission_serial) } else { l_ret = sizeof(l_emission->hdr); } - switch (l_emission->hdr.type) { - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH: { - uint64_t l_size = *(uint64_t *)(a_emission_serial + l_ret); - l_ret += l_size; - } break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO: - l_ret += sizeof(l_emission->data.type_algo); - break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER: - l_ret += sizeof(l_emission->data.type_atom_owner); - break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT: - l_ret += sizeof(l_emission->data.type_presale); - break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED: - default: - break; + if (l_emission->hdr.type == DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH) { + uint64_t l_size = *(uint64_t *)(a_emission_serial + l_ret); + l_ret += l_size; } + l_ret += sizeof(l_emission->data); return l_ret; } @@ -319,18 +318,34 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emissi return l_emission; } -dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_sign(dap_chain_datum_token_emission_t *a_emission, dap_enc_key_t *a_sign_key) +dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_tsd(dap_chain_datum_token_emission_t *a_emission, int a_type, size_t a_size, void *a_data) { + if (!a_emission || a_emission->hdr.type != DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH) + return NULL; + dap_tsd_t *l_tsd = dap_tsd_create(a_type, a_data, a_size); + size_t l_tsd_size = sizeof(dap_tsd_t) + a_size; + size_t l_emission_size = dap_chain_datum_emission_get_size((uint8_t *)a_emission); + dap_chain_datum_token_emission_t *l_emission = DAP_REALLOC(a_emission, l_emission_size + l_tsd_size); + memcpy(l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size, l_tsd, l_tsd_size); + DAP_DELETE(l_tsd); + l_emission->data.type_auth.tsd_total_size += l_tsd_size; + return l_emission; +} + +dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_sign(dap_enc_key_t *a_sign_key, dap_chain_datum_token_emission_t *a_emission) +{ + if (!a_emission) + return NULL; size_t l_emission_size = dap_chain_datum_emission_get_size((uint8_t *)a_emission); - dap_chain_datum_token_emission_t *l_ret = dap_chain_datum_emission_read((uint8_t *)a_emission, &l_emission_size); - dap_sign_t *l_sign = dap_sign_create(a_sign_key, l_ret, l_emission_size, 0); + dap_sign_t *l_sign = dap_sign_create(a_sign_key, l_ret, sizeof(l_ret->hdr), 0); if (!l_sign) return NULL; l_ret = DAP_REALLOC(l_ret, l_emission_size + dap_sign_get_size(l_sign)); size_t l_sign_size = dap_sign_get_size(l_sign); - memcpy((byte_t *)&l_ret->data + l_ret->data.type_auth.size, l_sign, l_sign_size); + memcpy(l_ret->tsd_n_signs + l_ret->data.type_auth.size, l_sign, l_sign_size); DAP_DELETE(l_sign); l_ret->data.type_auth.size += l_sign_size; + l_ret->data.type_auth.signs_count++; return l_ret; } diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index 3f5de21111..db02764436 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -386,11 +386,13 @@ typedef struct dap_chain_datum_token_emission{ char codename[32]; } DAP_ALIGN_PACKED type_algo; struct { - uint16_t signs_count; uint64_t size; - byte_t signs[]; + uint64_t tsd_total_size; + uint16_t signs_count; } DAP_ALIGN_PACKED type_auth;// Signs if exists + byte_t free_space[128]; // For future changes } data; + byte_t tsd_n_signs[]; } DAP_ALIGN_PACKED dap_chain_datum_token_emission_t; // Different emissions type @@ -399,12 +401,17 @@ typedef struct dap_chain_datum_token_emission{ #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO 0x02 #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER 0x03 #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT 0x04 -// 256 -// #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_UNDEFINED 0x05 -// #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_AUTH 0x06 -// #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_ALGO 0x07 -// #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_ATOM_OWNER 0x08 -// #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_256_SMART_CONTRACT 0x09 + +// TSD sections with emission additional params for AUTH type +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_UNKNOWN 0x0000 +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TIMESTAMP 0x0001 +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_ADDRESS 0x0002 +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_VALUE 0x0003 +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_CONTRACT 0x0004 +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_NET_ID 0x0005 +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BLOCK_NUM 0x0006 +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TOKEN_SYM 0x0007 + extern const char *c_dap_chain_datum_token_emission_type_str[]; /// TDS op funcs @@ -413,8 +420,11 @@ void dap_chain_datum_token_flags_dump(dap_string_t * a_str_out, uint16_t a_flags void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_n_tsd, size_t a_certs_size); dap_sign_t ** dap_chain_datum_token_simple_signs_parse(dap_chain_datum_token_t * a_datum_token, size_t a_datum_token_size, size_t *a_signs_count, size_t * a_signs_valid); dap_chain_datum_token_t *dap_chain_datum_token_read(byte_t *a_token_serial, size_t *a_token_size); + +dap_chain_datum_token_emission_t *dap_chain_datum_emission_create(uint256_t a_value, const char *a_ticker, dap_chain_addr_t *a_addr); +dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_tsd(dap_chain_datum_token_emission_t *a_emission, int a_type, size_t a_size, void *a_data); dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emission_serial, size_t *a_emission_size); size_t dap_chain_datum_emission_get_size(uint8_t *a_emission_serial); -dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_sign(dap_chain_datum_token_emission_t *a_emission, dap_enc_key_t *a_sign_key); +dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_sign(dap_enc_key_t *a_sign_key, dap_chain_datum_token_emission_t *a_emission); // 256 TYPE bool dap_chain_datum_token_is_old(uint8_t a_type); diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index c392357992..bb13a77c4d 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -93,8 +93,8 @@ char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t if (dap_chain_global_db_gr_set(l_key_str, a_datum, dap_chain_datum_size(a_datum), l_gdb_group)) { log_it(L_NOTICE, "Datum with data's hash %s was placed in mempool", l_key_str); } else { - log_it(L_WARNING, "Can't place data's hash %s was placed in mempool", l_key_str); - DAP_DELETE(l_key_str); + log_it(L_WARNING, "Can't place data's hash %s in mempool", l_key_str); + DAP_DEL_Z(l_key_str); } DAP_DELETE(l_gdb_group); @@ -588,8 +588,8 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond(dap_chain_net_t * a_net, } dap_chain_hash_fast_t *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_emission_hash, - dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, - dap_chain_addr_t *a_addr_to, dap_cert_t *a_certs, size_t a_certs_count) + dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, const char *a_ticker, + dap_chain_addr_t *a_addr_to, dap_cert_t **a_certs, size_t a_certs_count) { char *l_gdb_group_mempool_base_tx = dap_chain_net_get_gdb_group_mempool(a_chain); // create first transaction (with tx_token) @@ -598,7 +598,7 @@ dap_chain_hash_fast_t *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, da dap_chain_hash_fast_t l_tx_prev_hash = { 0 }; // create items - dap_chain_tx_token_t *l_tx_token = dap_chain_datum_tx_item_token_create(a_emission_chain_id, a_emission_hash, l_ticker); + dap_chain_tx_token_t *l_tx_token = dap_chain_datum_tx_item_token_create(a_emission_chain_id, a_emission_hash, a_ticker); dap_chain_tx_in_t *l_in = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, 0); dap_chain_tx_out_t *l_out = dap_chain_datum_tx_item_out_create(a_addr_to, a_emission_value); @@ -607,13 +607,11 @@ dap_chain_hash_fast_t *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, da dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_in); dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_out); - if (a_certs){ + if (a_certs) { // Sign all that we have with certs for(size_t i = 0; i < a_certs_count; i++) { if(dap_chain_datum_tx_add_sign_item(&l_tx, a_certs[i]->enc_key) < 0) { - dap_chain_node_cli_set_reply_text(a_str_reply, "No private key for certificate=%s", - a_certs[i]->name); - DAP_DELETE(l_addr); + log_it(L_WARNING, "No private key for certificate '%s'", a_certs[i]->name); return NULL; } } @@ -644,6 +642,26 @@ dap_chain_hash_fast_t *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, da return l_datum_tx_hash; } +dap_chain_datum_token_emission_t *dap_chain_mempool_emission_get(dap_chain_t *a_chain, const char *a_emission_hash_str) +{ + size_t l_emission_size; + char *l_gdb_group = dap_chain_net_get_gdb_group_mempool(a_chain); + dap_chain_datum_t *l_emission = (dap_chain_datum_t *)dap_chain_global_db_gr_get( + l_emission_hash_str, &l_emission_size, l_gdb_group); + if (!l_emission) { + char *l_emission_hash_str_from_base58 = dap_enc_base58_to_hex_str_from_str(a_emission_hash_str); + l_emission = (dap_chain_datum_t *)dap_chain_global_db_gr_get( + l_emission_hash_str_from_base58, &l_emission_size, l_gdb_group); + DAP_DELETE(l_emission_hash_str_from_base58); + } + DAP_DELETE(l_gdb_group); + if (!l_emission) + return NULL; + dap_chain_datum_token_emission_t *l_ret = dap_chain_datum_emission_read(l_emission->data, &l_emission_size); + DAP_DELETE(l_emission); + return l_ret; +} + uint8_t* dap_datum_mempool_serialize(dap_datum_mempool_t *datum_mempool, size_t *size) { size_t a_request_size = 2 * sizeof(uint16_t), shift_size = 0; diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h index c9db3876ff..a89a68be4b 100644 --- a/modules/mempool/include/dap_chain_mempool.h +++ b/modules/mempool/include/dap_chain_mempool.h @@ -68,5 +68,7 @@ int dap_chain_mempool_tx_create_massive(dap_chain_t * a_chain, dap_enc_key_t *a_ uint256_t a_value, uint256_t a_value_fee, size_t a_tx_num); dap_chain_hash_fast_t *dap_chain_mempool_base_tx_create(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_emission_hash, - dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, - dap_chain_addr_t *a_addr_to, dap_cert_t *a_certs, size_t a_certs_count); + dap_chain_id_t a_emission_chain_id, uint256_t a_emission_value, const char *a_ticker, + dap_chain_addr_t *a_addr_to, dap_cert_t **a_certs, size_t a_certs_count); +dap_chain_datum_token_emission_t *dap_chain_mempool_emission_get(dap_chain_t *a_chain, const char *a_emission_hash_str); + diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 1cd965b421..0234781cec 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -3238,7 +3238,7 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) const char * l_addr_str = NULL; const char * l_emission_hash_str = NULL; - dap_chain_hash_fast_t l_emission_hash; + dap_chain_hash_fast_t l_emission_hash, l_datum_emission_hash; dap_chain_datum_token_emission_t *l_emission = NULL; size_t l_emission_size; @@ -3337,15 +3337,8 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) } } else { if (l_emission_hash_str) { - char *l_emission_hash_str_from_base58 = dap_enc_base58_to_hex_str_from_str(l_emission_hash_str); - DL_FOREACH(l_net->pub.chains, l_chain_emission) { - - l_emission = (dap_chain_datum_token_emission_t *)dap_chain_global_db_gr_get( - l_emission_hash_str, &l_emission_size, dap_chain_net_get_gdb_group_mempool(l_chain_emission)); - if (l_emission) - break; - l_emission = (dap_chain_datum_token_emission_t *)dap_chain_global_db_gr_get( - l_emission_hash_str_from_base58, &l_emission_size, dap_chain_net_get_gdb_group_mempool(l_chain_emission)); + DL_FOREACH(a_net->pub.chains, l_chain_emission) { + l_emission = dap_chain_mempool_emission_get(l_chain_emission, l_emission_hash_str); if (l_emission) break; } @@ -3369,54 +3362,42 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) DAP_DELETE(l_addr); return -47; } + if(!l_ticker) { + dap_chain_node_cli_set_reply_text(a_str_reply, "token_emit requires parameter '-token'"); + return -3; + } } + //dap_chain_mempool_emission_create(l_emission, DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH, l_ticker, l_emission_value); if (!l_add_sign) { - // Create emission datum - if (!l_chain_emission) { + if (!l_chain_emission) l_chain_emission = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_EMISSION); - } - l_emission = DAP_NEW_Z(dap_chain_datum_token_emission_t); - l_emission->hdr.version = 2; - l_emission->hdr.value_256 = l_emission_value; - strncpy(l_emission->hdr.ticker, l_ticker, sizeof(l_emission->hdr.ticker) - 1); - l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; - memcpy(&l_emission->hdr.address, l_addr, sizeof(l_emission->hdr.address)); - time_t l_time = time(NULL); - memcpy(&l_emission->hdr.nonce, &l_time, sizeof(time_t)); - l_emission_size = sizeof(l_emission->hdr) + sizeof(l_emission->data.type_auth); + // Create emission datum + l_emission = dap_chain_datum_emission_create(l_emission_value, l_ticker, l_addr); } l_emission->data.type_auth.signs_count += l_certs_size; // Then add signs - for(size_t i = 0; i < l_certs_size; i++) { - dap_sign_t *l_sign = dap_cert_sign(l_certs[i], &l_emission->hdr, - sizeof(l_emission->hdr), 0); - size_t l_sign_size = dap_sign_get_size(l_sign); - l_emission_size += l_sign_size; - l_emission->data.type_auth.size += l_sign_size; - l_emission = DAP_REALLOC(l_emission, l_emission_size); - memcpy(l_emission->data.type_auth.signs + l_emission->data.type_auth.size, l_sign, l_sign_size); - DAP_DELETE(l_sign); - } - + for(size_t i = 0; i < l_certs_size; i++) + l_emission = dap_chain_datum_emission_add_sign(l_certs[i]->enc_key, l_emission); + // Calc emission's hash + l_emission_size = dap_chain_datum_emission_get_size(l_emission); + dap_hash_fast(l_emission, l_emission_size, &l_emission_hash); // Produce datum dap_chain_datum_t *l_datum_emission = dap_chain_datum_create(DAP_CHAIN_DATUM_TOKEN_EMISSION, l_emission, l_emission_size); + // Delete token emission + DAP_DEL_Z(l_emission); size_t l_datum_emission_size = sizeof(l_datum_emission->header) + l_datum_emission->header.data_size; // Calc datum emission's hash - dap_hash_fast(l_datum_emission, l_datum_emission_size, &l_emission_hash); - // Calc token's hash - dap_hash_fast(l_emission, l_emission_size, &l_token_emission_hash); - + dap_hash_fast(l_datum_emission, l_datum_emission_size, &l_datum_emission_hash); bool l_hex_format = dap_strcmp(l_hash_out_type, "hex"); - l_emission_hash_str = l_hex_format ? dap_chain_hash_fast_to_str_new(&l_emission_hash) - : dap_enc_base58_encode_hash_to_str(&l_emission_hash); - // Delete token emission - DAP_DEL_Z(l_emission); + l_emission_hash_str = l_hex_format ? dap_chain_hash_fast_to_str_new(&l_datum_emission_hash) + : dap_enc_base58_encode_hash_to_str(&l_datum_emission_hash); // Add token emission datum to mempool - bool l_placed = dap_chain_global_db_gr_set(dap_strdup(l_emission_hash_str), + char *l_gdb_group_mempool_emission = dap_chain_net_get_gdb_group_mempool(l_chain_emission); + bool l_placed = dap_chain_global_db_gr_set(l_emission_hash_str, (uint8_t *)l_datum_emission, l_datum_emission_size, l_gdb_group_mempool_emission); @@ -3431,7 +3412,7 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) if(l_chain_base_tx) { dap_chain_hash_fast_t *l_datum_tx_hash = dap_chain_mempool_base_tx_create(l_chain_base_tx, &l_emission_hash, - l_chain_emission->id, l_emission_value, + l_chain_emission->id, l_emission_value, l_ticker, l_addr, l_certs, l_certs_size); char *l_tx_hash_str = l_hex_format ? dap_chain_hash_fast_to_str_new(l_datum_tx_hash) : dap_enc_base58_encode_hash_to_str(l_datum_tx_hash); @@ -3826,8 +3807,12 @@ int com_tx_create(int argc, char ** argv, char **str_reply) const char * l_token_ticker = NULL; const char * l_net_name = NULL; const char * l_chain_name = NULL; + const char * l_emission_chain_name = NULL; const char * l_tx_num_str = NULL; const char *l_emission_hash_str = NULL; + const char *l_certs_str = NULL; + dap_cert_t **l_certs = NULL; + size_t l_certs_count = 0; dap_chain_hash_fast_t l_emission_hash = {}; size_t l_tx_num = 0; @@ -3835,11 +3820,13 @@ int com_tx_create(int argc, char ** argv, char **str_reply) uint256_t l_value_fee = {}; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-from_wallet", &l_from_wallet_name); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-from_emission", &l_emission_hash_str); + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-emission_chain", &l_emission_chain_name); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-to_addr", &addr_base58_to); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-token", &l_token_ticker); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-net", &l_net_name); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-chain", &l_chain_name); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-tx_num", &l_tx_num_str); + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-certs", &l_certs_str); if(l_tx_num_str) l_tx_num = strtoul(l_tx_num_str, NULL, 10); @@ -3860,17 +3847,45 @@ int com_tx_create(int argc, char ** argv, char **str_reply) dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-to_addr'"); return -2; } + + if(!l_net_name) { + dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-net'"); + return -6; + } + dap_chain_net_t * l_net = dap_chain_net_by_name(l_net_name); + dap_ledger_t *l_ledger = l_net ? l_net->pub.ledger : NULL; + if(l_net == NULL || (l_ledger = dap_chain_ledger_by_net_name(l_net_name)) == NULL) { + dap_chain_node_cli_set_reply_text(str_reply, "not found net by name '%s'", l_net_name); + return -7; + } + + dap_chain_t *l_emission_chain; if (l_emission_hash_str) { if (dap_chain_hash_fast_from_str(l_emission_hash_str, &l_emission_hash)) { dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-emission_hash' " "to be valid string containing hash in hex or base58 format"); return -3; } - } else { - if(IS_ZERO_256(l_value)) { - dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-value' to be valid uint256 value"); + if (!l_emission_chain_name || + (l_emission_chain = dap_chain_net_get_chain_by_name(l_net, l_emission_chain_name)) == NULL) { + dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-emission_chain' " + "to be a valid chain name"); + return -9; + } + if(!l_certs_str) { + dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-certs'"); return -4; } + dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count); + if(!l_certs_count) { + dap_chain_node_cli_set_reply_text(str_reply, + "tx_create requires at least one valid certificate to sign the basic transaction of emission"); + return -5; + } + } + if(IS_ZERO_256(l_value)) { + dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-value' to be valid uint256 value"); + return -4; } if(addr_base58_fee && IS_ZERO_256(l_value_fee)) { dap_chain_node_cli_set_reply_text(str_reply, @@ -3878,17 +3893,6 @@ int com_tx_create(int argc, char ** argv, char **str_reply) return -5; } - if(!l_net_name) { - dap_chain_node_cli_set_reply_text(str_reply, "tx_create requires parameter '-net'"); - return -6; - } - dap_chain_net_t * l_net = dap_chain_net_by_name(l_net_name); - dap_ledger_t *l_ledger = l_net ? l_net->pub.ledger : NULL; - if(l_net == NULL || (l_ledger = dap_chain_ledger_by_net_name(l_net_name)) == NULL) { - dap_chain_node_cli_set_reply_text(str_reply, "not found net by name '%s'", l_net_name); - return -7; - } - dap_chain_t * l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_name); if(!l_chain) { l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_TX); @@ -3908,7 +3912,8 @@ int com_tx_create(int argc, char ** argv, char **str_reply) dap_string_t *string_ret = dap_string_new(NULL); int res = 0; if (l_emission_hash_str) { - dap_hash_fast_t *l_tx_hash = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_addr_to); + dap_hash_fast_t *l_tx_hash = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_emission_chain->id, + l_value, l_token_ticker, l_addr_to, l_certs, l_certs_count); if (l_tx_hash){ char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(l_tx_hash,l_tx_hash_str,sizeof (l_tx_hash_str)-1); @@ -4013,20 +4018,26 @@ int com_tx_verify(int a_argc, char **a_argv, char **a_str_reply) *a_str_reply = NULL; } dap_hash_fast_t l_tx_hash; - if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash)) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Invalid tx hash format, need hex or base58"); - return -3; + char *l_hex_str_from58 = NULL; + if (dap_chain_hash_fast_from_hex_str(l_tx_hash_str, &l_tx_hash)) { + l_hex_str_from58 = dap_enc_base58_to_hex_str_from_str(l_tx_hash_str); + if (dap_chain_hash_fast_from_hex_str(l_hex_str_from58, &l_tx_hash)) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Invalid tx hash format, need hex or base58"); + return -3; + } } size_t l_tx_size = 0; char *l_gdb_group = dap_chain_net_get_gdb_group_mempool(l_chain); dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) dap_chain_global_db_gr_get(l_hex_str_from58 ? l_hex_str_from58 : l_tx_hash_str, &l_tx_size, l_gdb_group); + DAP_DEL_Z(l_hex_str_from58); if (!l_tx) { dap_chain_node_cli_set_reply_text(a_str_reply, "Specified tx not found"); return -3; } - if (dap_chain_ledger_tx_add_check(l_net->pub.ledger, l_tx)) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Specified tx verify fail!"); + int l_ret = dap_chain_ledger_tx_add_check(l_net->pub.ledger, l_tx); + if (l_ret) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Specified tx verify fail with return code=%d", l_ret); return -4; } dap_chain_node_cli_set_reply_text(a_str_reply, "Specified tx verified successfully"); -- GitLab