diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index fa6c46c570e2e1f93335dfbf0a6c3433b856ec7f..07855c803dca5e3feb5345b61a0c015ff83268f6 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -222,6 +222,162 @@ void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_tok } } +void s_datum_token_dump_tsd_to_json(json_object * json_obj_out, dap_chain_datum_token_t *a_token, size_t a_token_size, const char *a_hash_out_type) +{ + dap_tsd_t *l_tsd = dap_chain_datum_token_tsd_get(a_token, a_token_size); + if (l_tsd == NULL) { + json_object_object_add(json_obj_out, "status", json_object_new_string("<CORRUPTED TSD SECTION>")); + return; + } + size_t l_tsd_total_size = 0; + switch (a_token->type) { + case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: + switch (a_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: + l_tsd_total_size = a_token->header_private_decl.tsd_total_size; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: + l_tsd_total_size = a_token->header_native_decl.tsd_total_size; break; + default: break; + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: + switch (a_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: + l_tsd_total_size = a_token->header_private_update.tsd_total_size; break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: + l_tsd_total_size = a_token->header_native_update.tsd_total_size; break; + default: break; + } break; + default: break; + } + size_t l_tsd_size = 0; + for (size_t l_offset = 0; l_offset < l_tsd_total_size; l_offset += l_tsd_size) { + l_tsd = (dap_tsd_t *) (((byte_t*)l_tsd) + l_tsd_size); + l_tsd_size = l_tsd ? dap_tsd_size(l_tsd) : 0; + if (l_tsd_size == 0) { + log_it(L_ERROR,"Wrong zero TSD size, exiting s_datum_token_dump_tsd()"); + return; + } else if (l_tsd_size+l_offset > l_tsd_total_size) { + log_it(L_WARNING, "<CORRUPTED TSD> too big size %u when left maximum %zu", + l_tsd->size, l_tsd_total_size - l_offset); + return; + } + switch(l_tsd->type) { + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: { + uint16_t l_t = 0; + dap_chain_datum_token_flags_dump_to_json(json_obj_out,_dap_tsd_get_scalar(l_tsd, &l_t)); + json_object_object_add(json_obj_out, "flags_set", json_object_new_string("empty")); + continue; + } + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS: { + uint16_t l_t = 0; + dap_chain_datum_token_flags_dump_to_json(json_obj_out,_dap_tsd_get_scalar(l_tsd, &l_t)); + json_object_object_add(json_obj_out, "flags_unset", json_object_new_string("empty")); + continue; + } + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256 + uint256_t l_t = uint256_0; + char *l_balance = dap_chain_balance_print(_dap_tsd_get_scalar(l_tsd, &l_t)); + json_object_object_add(json_obj_out, "total_supply", json_object_new_string(l_balance)); + DAP_DELETE(l_balance); + continue; + } + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD: { // 128 + uint128_t l_t = uint128_0; + char *l_balance = dap_chain_balance_print(GET_256_FROM_128(_dap_tsd_get_scalar(l_tsd, &l_t))); + json_object_object_add(json_obj_out, "total_supply", json_object_new_string(l_balance)); + DAP_DELETE(l_balance); + continue; + } + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: { + uint16_t l_t = 0; + json_object_object_add(json_obj_out, "total_signs_valid", json_object_new_int(_dap_tsd_get_scalar(l_tsd, &l_t))); + continue; + } + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: + if(l_tsd->size >= sizeof(dap_pkey_t)) { + char *l_hash_str; + dap_pkey_t *l_pkey = (dap_pkey_t*)l_tsd->data; + dap_hash_fast_t l_hf = { }; + if (!dap_pkey_get_hash(l_pkey, &l_hf)) { + json_object_object_add(json_obj_out, "total_pkeys_add", json_object_new_string("<WRONG CALCULATION FINGERPRINT>")); + } else { + if (!dap_strcmp(a_hash_out_type, "hex") || !dap_strcmp(a_hash_out_type, "content_hash")) + l_hash_str = dap_chain_hash_fast_to_str_new(&l_hf); + else + l_hash_str = dap_enc_base58_encode_hash_to_str(&l_hf); + json_object_object_add(json_obj_out, "total_pkeys_add", json_object_new_string(l_hash_str)); + DAP_DELETE(l_hash_str); + } + } else + json_object_object_add(json_obj_out, "total_pkeys_add_with_wrong_size", json_object_new_int(l_tsd->size)); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: + if(l_tsd->size == sizeof(dap_chain_hash_fast_t) ){ + char *l_hash_str = (!dap_strcmp(a_hash_out_type,"hex")|| !dap_strcmp(a_hash_out_type, "content_hash")) + ? dap_chain_hash_fast_to_str_new((dap_chain_hash_fast_t*) l_tsd->data) + : dap_enc_base58_encode_hash_to_str((dap_chain_hash_fast_t*) l_tsd->data); + json_object_object_add(json_obj_out, "total_pkeys_remove", json_object_new_string(l_hash_str)); + DAP_DELETE( l_hash_str ); + } else + json_object_object_add(json_obj_out, "total_pkeys_remove_with_wrong_size", json_object_new_int(l_tsd->size)); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: { + char *balance = NULL; + dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); + balance = dap_chain_balance_to_coins(l_tsd_section->emission_rate); + json_object_object_add(json_obj_out, "ticker_token_from", json_object_new_string(l_tsd_section->ticker_token_from)); + json_object_object_add(json_obj_out, "emission_rate", json_object_new_string(balance)); + DAP_DEL_Z(balance); + }continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD : + json_object_object_add(json_obj_out, "datum_type_allowed_add", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_REMOVE : + json_object_object_add(json_obj_out, "datum_type_allowed_remove", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_ADD : + json_object_object_add(json_obj_out, "datum_type_blocked_add", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_REMOVE: + json_object_object_add(json_obj_out, "datum_type_blocked_remove", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD: + json_object_object_add(json_obj_out, "tx_sender_allowed_add", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE: + json_object_object_add(json_obj_out, "tx_sender_allowed_remove", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD: + json_object_object_add(json_obj_out, "tx_sender_blocked_add", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE: + json_object_object_add(json_obj_out, "tx_sender_blocked_remove", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD: + json_object_object_add(json_obj_out, "tx_receiver_allowed_add", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE: + json_object_object_add(json_obj_out, "tx_receiver_allowed", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD: + json_object_object_add(json_obj_out, "tx_receiver_blocked_add", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE: + json_object_object_add(json_obj_out, "tx_receiver_blocked_remove", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + case DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION: + json_object_object_add(json_obj_out, "description", json_object_new_string(dap_tsd_get_string_const(l_tsd))); + continue; + default: { + char l_tsd_type_char[50] = {}; + dap_string_append_printf(l_tsd_type_char, "<0x%04hX>", l_tsd->type, l_tsd->size); + json_object_object_add(json_obj_out, "tsd_type", json_object_new_string(l_tsd_type_char)); + json_object_object_add(json_obj_out, "tsd_size", json_object_new_int(l_tsd->size)); + } + } + } +} + /** * @brief _dap_chain_datum_tx_out_data * diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 07118fbc49bf6453f03deb45853990b6c51e645e..ea631e9f33865dfbd683b6b033135861fdd19297 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -219,6 +219,31 @@ void dap_chain_datum_token_flags_dump(dap_string_t * a_str_out, uint16_t a_flags } } +/** + * @brief dap_chain_datum_token_flags_dump_to_json + * @param json_obj_out + * @param a_flags + */ +void dap_chain_datum_token_flags_dump_to_json(json_object * json_obj_out, uint16_t a_flags) +{ + if(!a_flags){ + json_object_object_add(json_obj_out, "flags:", json_object_new_string(c_dap_chain_datum_token_flag_str[DAP_CHAIN_DATUM_TOKEN_FLAG_NONE])); + + return; + } + bool is_first = true; + for ( uint16_t i = 0; BIT(i) <= DAP_CHAIN_DATUM_TOKEN_FLAG_MAX; i++){ + if( a_flags & (1 << i) ){ + if(is_first) + is_first = false; + + json_object_object_add(json_obj_out, "flags:", json_object_new_string(c_dap_chain_datum_token_flag_str[BIT(i)])); + + } + } +} + + /** * @brief dap_chain_datum_token_certs_dump @@ -267,6 +292,58 @@ void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_ } } +/** + * @brief dap_chain_datum_token_certs_dump_to_json + * @param a_json_obj_out + * @param a_data_n_tsd + * @param a_certs_size + */ +void dap_chain_datum_token_certs_dump_to_json(json_object *a_json_obj_out, byte_t * a_data_n_tsd, size_t a_certs_size, const char *a_hash_out_type) +{ + json_object_object_add(a_json_obj_out, "Signatures", json_object_new_string("")); + if (!a_certs_size) { + json_object_object_add(a_json_obj_out, "status", json_object_new_string("<NONE>")); + return; + } + + size_t l_offset = 0; + json_object * json_arr_seg = json_object_new_array(); + for (int i = 1; l_offset < (a_certs_size); i++) { + json_object * l_json_obj_out = json_object_new_object(); + dap_sign_t *l_sign = (dap_sign_t *) (a_data_n_tsd + l_offset); + l_offset += dap_sign_get_size(l_sign); + if (l_sign->header.sign_size == 0) { + json_object_object_add(l_json_obj_out, "status", json_object_new_string("<CORRUPTED - 0 size signature>")); + break; + } + + if (l_sign->header.sign_size > a_certs_size) + { + json_object_object_add(l_json_obj_out, "status", json_object_new_string("<CORRUPTED - signature size is greater than a_certs_size>")); + continue; + } + + dap_chain_hash_fast_t l_pkey_hash = {0}; + if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) { + json_object_object_add(l_json_obj_out, "status", json_object_new_string("<CORRUPTED - can't calc hash>")); + continue; + } + + char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str(&l_pkey_hash) + : dap_chain_hash_fast_to_str_new(&l_pkey_hash); + + json_object_object_add(l_json_obj_out, "line", json_object_new_int(i)); + json_object_object_add(l_json_obj_out, "hash", json_object_new_string(l_hash_str)); + json_object_object_add(l_json_obj_out, "sign_type", json_object_new_string(dap_sign_type_to_str(l_sign->header.type))); + json_object_object_add(l_json_obj_out, "bytes", json_object_new_int(l_sign->header.sign_size)); + json_object_array_add(json_arr_seg, l_json_obj_out); + DAP_DEL_Z(l_hash_str); + } + json_object_object_add(a_json_obj_out, "status", json_arr_seg); +} + + dap_sign_t ** dap_chain_datum_token_signs_parse(dap_chain_datum_token_t * a_datum_token, size_t a_datum_token_size, size_t *a_signs_total, size_t * a_signs_valid) { assert(a_datum_token_size); diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index eac32ebaede40a9170b2f788ea84a16ba7666174..4fb52984e1bc6c68a1e32c84da0434cdd57fa4d9 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -30,6 +30,7 @@ #include "dap_string.h" #include "dap_tsd.h" #include "dap_strfuncs.h" +#include "json_object.h" // Token declaration @@ -504,7 +505,9 @@ extern const char *c_dap_chain_datum_token_emission_type_str[]; /// TDS op funcs dap_tsd_t* dap_chain_datum_token_tsd_get(dap_chain_datum_token_t * a_token, size_t a_token_size); void dap_chain_datum_token_flags_dump(dap_string_t * a_str_out, uint16_t a_flags); +void dap_chain_datum_token_flags_dump_to_json(json_object * json_obj_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, const char *a_hash_out_type); +void dap_chain_datum_token_certs_dump_to_json(json_object *a_json_obj_out, byte_t * a_data_n_tsd, size_t a_certs_size, const char *a_hash_out_type); dap_sign_t ** dap_chain_datum_token_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(const byte_t *a_token_serial, size_t *a_token_size); diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h index 33d37f51425d481dc73bd713c704941cc6390eb8..cba9ffe2e64400d9def5ff00e245709cb4e90a16 100644 --- a/modules/common/include/dap_chain_datum_tx.h +++ b/modules/common/include/dap_chain_datum_tx.h @@ -153,6 +153,6 @@ dap_sign_t *dap_chain_datum_tx_get_sign(dap_chain_datum_tx_t *a_tx, int a_sign_n */ int dap_chain_datum_tx_verify_sign(dap_chain_datum_tx_t *a_tx); -json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx); +//json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx); int dap_chain_datum_tx_get_fee_value (dap_chain_datum_tx_t *a_tx, uint256_t *a_value); diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum.c b/modules/json_rpc/common/dap_json_rpc_chain_datum.c index c55f9d93999a547009b8138d917af098074950e4..155980ec218ee9c3602090f461c91505edcd2481 100644 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum.c +++ b/modules/json_rpc/common/dap_json_rpc_chain_datum.c @@ -698,7 +698,7 @@ json_object * dap_chain_datum_data_to_json(dap_chain_datum_t *a_datum) { json_object *l_obj_data; switch (a_datum->header.type_id) { case DAP_CHAIN_DATUM_TX: - l_obj_data = dap_chain_datum_tx_to_json((dap_chain_datum_tx_t*)a_datum->data); + l_obj_data = dap_chain_datum_tx_to_json((dap_chain_datum_tx_t*)a_datum->data,NULL); if (!l_obj_data) { dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TX_TO_JSON, "Can't convert DAP_CHAIN_DATUM_TX to JSON"); diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c index 043b57b2519d415eb37d79a995c7f3adeead627c..b6377c825eaf4566d31a5d4d17008acd68712b0e 100644 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c +++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c @@ -14,7 +14,7 @@ -json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx){ +json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx,dap_chain_net_id_t *a_net_id){ json_object *l_obj_items = json_object_new_array(); if (!l_obj_items) { dap_json_rpc_allocation_error; diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h index 71a89ae9da616614fea742cc774611e9f1ced68c..ef472df5f6e70ab8d560df2d15746eb30d6383f3 100644 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h +++ b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h @@ -28,4 +28,4 @@ #include "dap_chain_datum_tx.h" #include "dap_json_rpc_errors.h" -json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx); +json_object * dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx, dap_chain_net_id_t *a_net_id); diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index bc549582557f87509b80b4e74fcf1188a543bc3a..e74a42ad35e0c33ae6dfe7043bd85f4fdb74ceab 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -813,10 +813,10 @@ dap_chain_datum_token_t *dap_ledger_token_ticker_check(dap_ledger_t *a_ledger, c * @param a_tx * @param a_tx_hash * @param a_hash_out_type - * @return a_str_out + * @return a_json_out */ -static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_datum_tx_t *a_tx, +static void s_tx_header_print(json_object *a_json_out, dap_chain_datum_tx_t *a_tx, const char *a_hash_out_type, dap_chain_hash_fast_t *a_tx_hash) { char l_time_str[DAP_TIME_STR_SIZE] = "unknown"; @@ -825,11 +825,12 @@ static void s_tx_header_print(dap_string_t *a_str_out, dap_chain_datum_tx_t *a_t char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str(a_tx_hash) : dap_chain_hash_fast_to_str_new(a_tx_hash); - dap_string_append_printf(a_str_out, "TX hash %s \n\t%s",l_tx_hash_str, l_time_str); + json_object_object_add(a_json_out, "TX hash ", json_object_new_string(l_tx_hash_str)); + json_object_object_add(a_json_out, "time ", json_object_new_string(l_time_str)); DAP_DELETE(l_tx_hash_str); } -static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspent, dap_ledger_t *a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, dap_string_t *a_str_out) { +static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspent, dap_ledger_t *a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, json_object *json_arr_out) { if (a_unspent && a_item->cache_data.ts_spent) { // With 'unspent' flag spent ones are ignored return; @@ -924,8 +925,9 @@ static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspen if (l_src_addr && l_dst_addr && !memcmp(l_dst_addr, l_src_addr, sizeof(dap_chain_addr_t))) continue; // send to self if (l_src_addr && !memcmp(l_src_addr, a_addr, sizeof(dap_chain_addr_t))) { + json_object * l_json_obj_datum = json_object_new_object(); if (!l_header_printed) { - s_tx_header_print(a_str_out, l_tx, a_hash_out_type, l_tx_hash); + s_tx_header_print(l_json_obj_datum, l_tx, a_hash_out_type, l_tx_hash); l_header_printed = true; } //const char *l_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, &l_tx_hash); @@ -933,17 +935,18 @@ static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspen : dap_chain_tx_out_cond_subtype_to_str( ((dap_chain_tx_out_cond_t *)l_list_out->data)->header.subtype); char *l_value_str = dap_chain_balance_print(l_value); - dap_string_append_printf(a_str_out, "\tsend %s %s to %s\n", - l_value_str, - l_src_token ? l_src_token : "UNKNOWN", - l_dst_addr_str); + json_object_object_add(l_json_obj_datum, "send", json_object_new_string(l_value_str)); + json_object_object_add(l_json_obj_datum, "to addr", json_object_new_string(l_dst_addr_str)); + json_object_object_add(l_json_obj_datum, "token", l_src_token ? json_object_new_string(l_src_token) : json_object_new_string("UNKNOWN")); + json_object_array_add(json_arr_out, l_json_obj_datum); if (l_dst_addr) DAP_DELETE(l_dst_addr_str); DAP_DELETE(l_value_str); } if (l_dst_addr && !memcmp(l_dst_addr, a_addr, sizeof(dap_chain_addr_t))) { + json_object * l_json_obj_datum = json_object_new_object(); if (!l_header_printed) { - s_tx_header_print(a_str_out, l_tx, a_hash_out_type, l_tx_hash); + s_tx_header_print(l_json_obj_datum, l_tx, a_hash_out_type, l_tx_hash); l_header_printed = true; } const char *l_dst_token = (l_type == TX_ITEM_TYPE_OUT_EXT) ? @@ -953,11 +956,11 @@ static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspen : dap_chain_tx_out_cond_subtype_to_str( l_src_subtype)); char *l_value_str = dap_chain_balance_print(l_value); - dap_string_append_printf(a_str_out, "\trecv %s %s from %s\n", - l_value_str, - l_dst_token ? l_dst_token : - (l_src_token ? l_src_token : "UNKNOWN"), - l_src_addr_str); + json_object_object_add(l_json_obj_datum, "recv ", json_object_new_string(l_value_str)); + json_object_object_add(l_json_obj_datum, "token ", l_dst_token ? json_object_new_string(l_dst_token) : + (l_src_token ? json_object_new_string(l_src_token) : json_object_new_string("UNKNOWN"))); + json_object_object_add(l_json_obj_datum, "from ", json_object_new_string(l_src_addr_str)); + json_object_array_add(json_arr_out, l_json_obj_datum); if (l_src_addr) DAP_DELETE(l_src_addr_str); DAP_DELETE(l_value_str); @@ -966,10 +969,10 @@ static void s_dump_datum_tx_for_addr(dap_ledger_tx_item_t *a_item, bool a_unspen dap_list_free(l_list_out_items); } -char *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only) +json_object *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only) { - dap_string_t *l_str_out = dap_string_new(NULL); - if (!l_str_out) { + json_object * json_arr_out = json_object_new_array(); + if (!json_arr_out) { log_it(L_CRITICAL, "Memory allocation error"); return NULL; } @@ -981,15 +984,18 @@ char *dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); //unsigned test = dap_ledger_count(a_ledger); HASH_ITER(hh, l_ledger_pvt->ledger_items, l_tx_item, l_tx_tmp) { - s_dump_datum_tx_for_addr(l_tx_item, a_unspent_only, a_ledger, a_addr, a_hash_out_type, l_str_out); + s_dump_datum_tx_for_addr(l_tx_item, a_unspent_only, a_ledger, a_addr, a_hash_out_type, json_arr_out); } pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); // if no history - if(!l_str_out->len) - dap_string_append(l_str_out, "\tempty"); - char *l_ret_str = l_str_out ? dap_string_free(l_str_out, false) : NULL; - return l_ret_str; + if(!json_arr_out) + { + json_object * json_obj_addr = json_object_new_object(); + json_object_object_add(json_obj_addr, "status:", json_object_new_string("empty")); + json_object_array_add(json_arr_out, json_obj_addr); + } + return json_arr_out; } /** @@ -1819,69 +1825,77 @@ int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_toke return dap_ledger_token_add(a_ledger, l_token, a_token_size); } -dap_string_t *dap_ledger_threshold_info(dap_ledger_t *a_ledger) +json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; - dap_string_t *l_str_ret = dap_string_new(""); + json_object* json_arr_out = json_object_new_array(); uint32_t l_counter = 0; pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){ + json_object* json_obj_tx = json_object_new_object(); + if (!json_obj_tx) { + return NULL; + } char l_tx_prev_hash_str[70]={0}; char l_time[1024] = {0}; - char l_item_size[70] = {0}; dap_chain_hash_fast_to_str(&l_tx_item->tx_hash_fast,l_tx_prev_hash_str,sizeof(l_tx_prev_hash_str)); dap_time_to_str_rfc822(l_time, sizeof(l_time), l_tx_item->tx->header.ts_created); //log_it(L_DEBUG,"Ledger thresholded tx_hash_fast %s, time_created: %s, tx_item_size: %d", l_tx_prev_hash_str, l_time, l_tx_item->tx->header.tx_items_size); - dap_string_append(l_str_ret, "Ledger thresholded tx_hash_fast"); - dap_string_append(l_str_ret, l_tx_prev_hash_str); - dap_string_append(l_str_ret, ", time_created:"); - dap_string_append(l_str_ret, l_time); - dap_string_append(l_str_ret, ""); - sprintf(l_item_size, ", tx_item_size: %d\n", l_tx_item->tx->header.tx_items_size); - dap_string_append(l_str_ret, l_item_size); + json_object_object_add(json_obj_tx, "Ledger thresholded tx_hash_fast", json_object_new_string(l_tx_prev_hash_str)); + json_object_object_add(json_obj_tx, "time_created", json_object_new_string(l_time)); + json_object_object_add(json_obj_tx, "tx_item_size", json_object_new_int(l_tx_item->tx->header.tx_items_size)); + json_object_array_add(json_arr_out, json_obj_tx); l_counter +=1; } - if (!l_counter) - dap_string_append(l_str_ret, "0 items in ledger tx threshold\n"); + if (!l_counter){ + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "status", json_object_new_string("0 items in ledger tx threshold")); + json_object_array_add(json_arr_out, json_obj_tx); + } pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); pthread_rwlock_rdlock(&l_ledger_pvt->threshold_emissions_rwlock); l_counter = 0; dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; HASH_ITER(hh, l_ledger_pvt->threshold_emissions, l_emission_item, l_emission_tmp){ + json_object* json_obj_tx = json_object_new_object(); char l_emission_hash_str[70]={0}; - char l_item_size[70] = {0}; dap_chain_hash_fast_to_str(&l_emission_item->datum_token_emission_hash,l_emission_hash_str,sizeof(l_emission_hash_str)); //log_it(L_DEBUG,"Ledger thresholded datum_token_emission_hash %s, emission_item_size: %lld", l_emission_hash_str, l_emission_item->datum_token_emission_size); - dap_string_append(l_str_ret, "Ledger thresholded datum_token_emission_hash: "); - dap_string_append(l_str_ret, l_emission_hash_str); - sprintf(l_item_size, ", tx_item_size: %zu\n", l_emission_item->datum_token_emission_size); - dap_string_append(l_str_ret, l_item_size); + json_object_object_add(json_obj_tx, "Ledger thresholded datum_token_emission_hash", json_object_new_string(l_emission_hash_str)); + json_object_object_add(json_obj_tx, "tx_item_size", json_object_new_int(l_tx_item->tx->header.tx_items_size)); + json_object_array_add(json_arr_out, json_obj_tx); l_counter +=1; } - if (!l_counter) - dap_string_append(l_str_ret, "0 items in ledger emission threshold\n"); + if (!l_counter){ + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "status", json_object_new_string("0 items in ledger emission threshold")); + json_object_array_add(json_arr_out, json_obj_tx); + } pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock); - return l_str_ret; + return json_arr_out; } -dap_string_t *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_threshold_hash) +json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_threshold_hash) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); dap_ledger_tx_item_t *l_tx_item, *l_tx_tmp; - dap_string_t *l_str_ret = dap_string_new(""); + json_object * json_arr_out = json_object_new_array(); + json_object* json_obj_tx = json_object_new_object(); + if (!json_obj_tx) { + return NULL; + } pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){ if (!memcmp(l_threshold_hash, &l_tx_item->tx_hash_fast, sizeof(dap_chain_hash_fast_t))){ char l_tx_hash_str[70]={0}; dap_chain_hash_fast_to_str(l_threshold_hash,l_tx_hash_str,sizeof(l_tx_hash_str)); - dap_string_append(l_str_ret, "Hash was found in ledger tx threshold:"); - dap_string_append(l_str_ret, l_tx_hash_str); - dap_string_append(l_str_ret, "\n"); + json_object_object_add(json_obj_tx, "Hash was found in ledger tx threshold", json_object_new_string(l_tx_hash_str)); + json_object_array_add(json_arr_out, json_obj_tx); pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); - return l_str_ret; + return json_arr_out; } } pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); @@ -1892,43 +1906,44 @@ dap_string_t *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_h if (!memcmp(&l_emission_item->datum_token_emission_hash,l_threshold_hash, sizeof(dap_chain_hash_fast_t))){ char l_emission_hash_str[70]={0}; dap_chain_hash_fast_to_str(l_threshold_hash,l_emission_hash_str,sizeof(l_emission_hash_str)); - dap_string_append(l_str_ret, "Hash was found in ledger emission threshold: "); - dap_string_append(l_str_ret, l_emission_hash_str); - dap_string_append(l_str_ret, "\n"); + json_object_object_add(json_obj_tx, "Hash was found in ledger emission threshold", json_object_new_string(l_emission_hash_str)); + json_object_array_add(json_arr_out, json_obj_tx); pthread_rwlock_unlock(&l_ledger_pvt->threshold_txs_rwlock); - return l_str_ret; + return json_arr_out; } } pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock); - dap_string_append(l_str_ret, "Hash wasn't found in ledger\n"); - return l_str_ret; + json_object_object_add(json_obj_tx, "Hash wasn't found in ledger", json_object_new_string("empty")); + json_object_array_add(json_arr_out, json_obj_tx); + return json_arr_out; } -dap_string_t *dap_ledger_balance_info(dap_ledger_t *a_ledger) +json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger) { dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); - dap_string_t *l_str_ret = dap_string_new(""); + json_object * json_arr_out = json_object_new_array(); pthread_rwlock_rdlock(&l_ledger_pvt->balance_accounts_rwlock); uint32_t l_counter = 0; dap_ledger_wallet_balance_t *l_balance_item, *l_balance_tmp; HASH_ITER(hh, l_ledger_pvt->balance_accounts, l_balance_item, l_balance_tmp) { + json_object* json_obj_tx = json_object_new_object(); //log_it(L_DEBUG,"Ledger balance key %s, token_ticker: %s, balance: %s", l_balance_key, l_balance_item->token_ticker, // dap_chain_balance_print(l_balance_item->balance)); - dap_string_append(l_str_ret, "Ledger balance key: "); - dap_string_append(l_str_ret, l_balance_item->key); - dap_string_append(l_str_ret, ", token_ticker:"); - dap_string_append(l_str_ret, l_balance_item->token_ticker); - dap_string_append(l_str_ret, ", balance:"); + json_object_object_add(json_obj_tx, "Ledger balance key", json_object_new_string(l_balance_item->key)); + json_object_object_add(json_obj_tx, "token_ticker", json_object_new_string(l_balance_item->token_ticker)); char *l_balance = dap_chain_balance_print(l_balance_item->balance); - dap_string_append(l_str_ret, l_balance); + json_object_object_add(json_obj_tx, "balance", json_object_new_string(l_balance)); DAP_DELETE(l_balance); - dap_string_append(l_str_ret, "\n"); + json_object_array_add(json_arr_out, json_obj_tx); l_counter +=1; } - if (!l_counter) - dap_string_append(l_str_ret, "0 items in ledger balance_accounts\n"); + if (!l_counter){ + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "0 items in ledger balance_accounts", json_object_new_string("empty")); + json_object_array_add(json_arr_out, json_obj_tx); + } pthread_rwlock_unlock(&l_ledger_pvt->balance_accounts_rwlock); - return l_str_ret; + return json_arr_out; } /** @@ -2002,14 +2017,14 @@ dap_list_t * dap_ledger_token_auth_pkeys_hashes(dap_ledger_t *a_ledger, const ch * @param a_ledger * @return */ -dap_list_t *dap_ledger_token_info(dap_ledger_t *a_ledger) +json_object *dap_ledger_token_info(dap_ledger_t *a_ledger) { - dap_list_t *l_ret_list = NULL; - dap_string_t *l_str_tmp;// = dap_string_new(""); + json_object * json_obj_datum; + json_object * json_arr_out = json_object_new_array(); dap_ledger_token_item_t *l_token_item, *l_tmp_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { - l_str_tmp = dap_string_new(""); + json_obj_datum = json_object_new_object(); const char *l_type_str; const char *l_flags_str = s_flag_str_from_code(l_token_item->datum_token->header_private_decl.flags); switch (l_token_item->type) { @@ -2040,56 +2055,52 @@ dap_list_t *dap_ledger_token_info(dap_ledger_t *a_ledger) default: l_type_str = "UNKNOWN"; break; } - char *l_item_str = NULL; - if ((l_token_item->subtype != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE) || (l_token_item->type != DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC)) { char *l_balance_cur = dap_chain_balance_print(l_token_item->current_supply); char *l_balance_total = dap_chain_balance_print(l_token_item->total_supply); - dap_chain_datum_token_dump_tsd(l_str_tmp, l_token_item->datum_token, l_token_item->datum_token_size, "hex"); + json_object_object_add(json_obj_datum, "-->Token name", json_object_new_string(l_token_item->ticker)); + json_object_object_add(json_obj_datum, "type", json_object_new_string(l_type_str)); + json_object_object_add(json_obj_datum, "flags", json_object_new_string(s_flag_str_from_code(l_token_item->datum_token->header_native_decl.flags))); + json_object_object_add(json_obj_datum, "description", l_token_item->description_token_size != 0 ? + json_object_new_string(l_token_item->description_token) : + json_object_new_string("The token description is not set")); + json_object_object_add(json_obj_datum, "Supply current", json_object_new_string(l_balance_cur)); + json_object_object_add(json_obj_datum, "Supply total", json_object_new_string(l_balance_total)); + json_object_object_add(json_obj_datum, "Decimals", json_object_new_string("18")); + json_object_object_add(json_obj_datum, "Auth signs valid", json_object_new_int(l_token_item->auth_signs_valid)); + json_object_object_add(json_obj_datum, "Auth signs total", json_object_new_int(l_token_item->auth_signs_total)); + json_object_object_add(json_obj_datum, "TSD and Signs", json_object_new_string("")); + s_datum_token_dump_tsd_to_json(json_obj_datum, l_token_item->datum_token, l_token_item->datum_token_size, "hex"); size_t l_certs_field_size = l_token_item->datum_token_size - sizeof(*l_token_item->datum_token) - l_token_item->datum_token->header_native_decl.tsd_total_size; - dap_chain_datum_token_certs_dump(l_str_tmp, l_token_item->datum_token->data_n_tsd + l_token_item->datum_token->header_native_decl.tsd_total_size, - l_certs_field_size, "hex"); - l_item_str = dap_strdup_printf("-->Token name '%s', type %s, flags: %s, description: '%s'\n" - "\tSupply (current/total) %s/%s\n" - "\tDecimals: 18\n" - "\tAuth signs (valid/total) %zu/%zu\n" - "TSD and Signs:\n" - "%s" - "\tTotal emissions %u\n___\n", - l_token_item->ticker, l_type_str, s_flag_str_from_code(l_token_item->datum_token->header_native_decl.flags), - l_token_item->description_token_size != 0 ? l_token_item->description_token : "The token description is not set", - l_balance_cur, l_balance_total, - l_token_item->auth_signs_valid, l_token_item->auth_signs_total, - l_str_tmp->str, - HASH_COUNT(l_token_item->token_emissions)); + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token_item->datum_token->data_n_tsd + l_token_item->datum_token->header_native_decl.tsd_total_size, + l_certs_field_size, "hex"); + json_object_object_add(json_obj_datum, "and TSD and Signs", json_object_new_string("")); + json_object_object_add(json_obj_datum, "Total emissions", json_object_new_int(HASH_COUNT(l_token_item->token_emissions))); + json_object_array_add(json_arr_out, json_obj_datum); DAP_DEL_Z(l_balance_cur); DAP_DEL_Z(l_balance_total); } else { char *l_balance_cur = dap_chain_balance_print(l_token_item->current_supply); char *l_balance_total = dap_chain_balance_print(l_token_item->total_supply); + json_object_object_add(json_obj_datum, "-->Token name", json_object_new_string(l_token_item->ticker)); + json_object_object_add(json_obj_datum, "Supply current", json_object_new_string(l_balance_cur)); + json_object_object_add(json_obj_datum, "Supply total", json_object_new_string(l_balance_total)); + json_object_object_add(json_obj_datum, "Decimals", json_object_new_string("18")); + json_object_object_add(json_obj_datum, "Auth signs valid", json_object_new_int(l_token_item->auth_signs_valid)); + json_object_object_add(json_obj_datum, "Auth signs total", json_object_new_int(l_token_item->auth_signs_total)); + json_object_object_add(json_obj_datum, "Signs", json_object_new_string("")); size_t l_certs_field_size = l_token_item->datum_token_size - sizeof(*l_token_item->datum_token); - dap_chain_datum_token_certs_dump(l_str_tmp, l_token_item->datum_token->data_n_tsd, - l_certs_field_size, "hex"); - l_item_str = dap_strdup_printf("-->Token name '%s', type %s, flags: %s\n" - "\tSupply (current/total) %s/%s\n" - "\tDecimals: 18\n" - "\tAuth signs (valid/total) %zu/%zu\n" - "%s" - "\tTotal emissions %u\n___\n", - l_token_item->ticker, l_type_str, "SIMPLE token has no flags", - l_balance_cur, l_balance_total, - l_token_item->auth_signs_valid, l_token_item->auth_signs_total, - l_str_tmp->str, - HASH_COUNT(l_token_item->token_emissions)); + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token_item->datum_token->data_n_tsd, + l_certs_field_size, "hex"); + json_object_object_add(json_obj_datum, "Total emissions", json_object_new_int(HASH_COUNT(l_token_item->token_emissions))); + json_object_array_add(json_arr_out, json_obj_datum); DAP_DEL_Z(l_balance_cur); DAP_DEL_Z(l_balance_total); } - l_ret_list = dap_list_append(l_ret_list, l_item_str); - dap_string_free(l_str_tmp, true); } pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); - return l_ret_list; + return json_arr_out; } /** diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 077af7ad71f2dd7ff8c1b9a4e3811895156b2fec..687321a91a56413c1b7e56ca3344d0df8310cb2a 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -94,19 +94,28 @@ void s_dap_chain_tx_hash_processed_ht_free(dap_chain_tx_hash_processed_ht_t **l_ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_ledger_t *a_ledger, - dap_string_t *a_str_out, + json_object * json_obj_out, const char *a_hash_out_type, dap_chain_hash_fast_t *a_tx_hash) { + dap_time_t l_ts_create = (dap_time_t)a_datum->header.ts_created; + char l_tx_hash_str[70]={0}; + char l_tmp_buf[DAP_TIME_STR_SIZE]; const char *l_ticker = a_ledger ? dap_ledger_tx_get_token_ticker_by_hash(a_ledger, a_tx_hash) : NULL; if (!l_ticker) return false; - dap_chain_datum_dump_tx(a_datum, l_ticker, a_str_out, a_hash_out_type, a_tx_hash, a_ledger->net->pub.id); + dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_create); + dap_chain_hash_fast_to_str(a_tx_hash,l_tx_hash_str,sizeof(l_tx_hash_str)); + json_object_object_add(json_obj_out, "Datum_tx_hash", json_object_new_string(l_tx_hash_str)); + json_object_object_add(json_obj_out, "TS_Created", json_object_new_string(l_tmp_buf)); + json_object_object_add(json_obj_out, "Token_ticker", json_object_new_string(l_ticker)); + json_object* datum_tx = dap_chain_datum_tx_to_json(a_datum,&a_ledger->net->pub.id); + json_object_object_add(json_obj_out, "Datum_tx", datum_tx); dap_list_t *l_out_items = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_OUT_ALL, NULL); int l_out_idx = 0; - dap_string_append_printf(a_str_out, "Spent OUTs:\r\n"); + json_object* json_arr_items = json_object_new_array(); bool l_spent = false; for (dap_list_t *l_item = l_out_items; l_item; l_item = l_item->next, ++l_out_idx) { switch (*(dap_chain_tx_item_type_t*)l_item->data) { @@ -118,9 +127,10 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, if (dap_ledger_tx_hash_is_used_out_item(a_ledger, a_tx_hash, l_out_idx, &l_spender)) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; dap_hash_fast_to_str(&l_spender, l_hash_str, sizeof(l_hash_str)); - dap_string_append_printf(a_str_out, - "\tOUT %d is spent by tx %s\r\n", - l_out_idx, l_hash_str); + json_object * l_json_obj_datum = json_object_new_object(); + json_object_object_add(l_json_obj_datum, "OUT - ", json_object_new_int(l_out_idx)); + json_object_object_add(l_json_obj_datum, "is spent by tx", json_object_new_string(l_hash_str)); + json_object_array_add(json_arr_items, l_json_obj_datum); l_spent = true; } break; @@ -129,7 +139,9 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, break; } } - dap_string_append_printf(a_str_out, l_spent ? "\r\n\r\n" : "\tall OUTs yet unspent\r\n\r\n"); + dap_list_free(l_out_items); + json_object_object_add(json_obj_out, "Spent OUTs", json_arr_items); + json_object_object_add(json_obj_out, "all OUTs yet unspent", l_spent ? json_object_new_string("no") : json_object_new_string("yes")); return true; } @@ -184,7 +196,7 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, json_object *l_obj_ts_created = json_object_new_string(l_time_str); json_object_object_add(json_obj_datum, "tx_created", l_obj_ts_created); - json_object* datum_tx = dap_chain_datum_tx_to_json(l_tx); + json_object* datum_tx = dap_chain_datum_tx_to_json(l_tx,&a_chain->net_id); json_object_object_add(json_obj_datum, "items", datum_tx); return json_obj_datum; @@ -561,6 +573,9 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, char *l_coins_str = dap_chain_balance_to_coins(l_corr_value); json_object_object_add(l_corr_object, "recv_coins", json_object_new_string(l_coins_str)); json_object_object_add(l_corr_object, "recv_datoshi", json_object_new_string(l_value_str)); + if (!j_arr_data) { + j_arr_data = json_object_new_array(); + } json_object_array_add(j_arr_data, l_corr_object); DAP_DELETE(l_value_str); DAP_DELETE(l_coins_str); @@ -880,8 +895,9 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger * @param a_str_reply * @return int */ -int com_ledger(int a_argc, char ** a_argv, void **a_str_reply) +int com_ledger(int a_argc, char ** a_argv, void **reply) { + json_object ** json_arr_reply = (json_object **) reply; enum { CMD_NONE, CMD_LIST, CMD_LEDGER_HISTORY, CMD_TX_INFO }; int arg_index = 1; const char *l_addr_base58 = NULL; @@ -895,8 +911,8 @@ int com_ledger(int a_argc, char ** a_argv, void **a_str_reply) if(!l_hash_out_type) l_hash_out_type = "hex"; if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "invalid parameter -H, valid values: -H <hex | base58>"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR; } //switch ledger params list | tx | info @@ -921,18 +937,17 @@ int com_ledger(int a_argc, char ** a_argv, void **a_str_reply) dap_chain_tx_hash_processed_ht_t *l_list_tx_hash_processd = NULL; if(!l_is_all && !l_addr_base58 && !l_wallet_name && !l_tx_hash_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "command 'tx' requires parameter '-all' or '-addr' or '-w' or '-tx'"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "command 'tx' requires parameter '-all' or '-addr' or '-w' or '-tx'"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR; } // Select chain network if(!l_net_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "command requires parameter '-net'"); - return -2; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "command requires parameter '-net'"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR; } else { if((l_net = dap_chain_net_by_name(l_net_str)) == NULL) { // Can't find such network - dap_cli_server_cmd_set_reply_text(a_str_reply, - "command requires parameter '-net' to be valid chain network name"); - return -3; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "command requires parameter '-net' to be valid chain network name"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR; } } @@ -940,8 +955,8 @@ int com_ledger(int a_argc, char ** a_argv, void **a_str_reply) if(l_tx_hash_str) { if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash)) { l_tx_hash_str = NULL; - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx hash not recognized"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_ERR, "tx hash not recognized"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_ERR; } } @@ -962,37 +977,41 @@ int com_ledger(int a_argc, char ** a_argv, void **a_str_reply) l_addr = dap_chain_addr_from_str(l_addr_base58); } if(!l_addr && !l_tx_hash_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "wallet address not recognized"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_WALLET_ADDR_ERR, "wallet address not recognized"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_WALLET_ADDR_ERR; } } - dap_string_t *l_str_ret = dap_string_new(NULL); - + json_object* json_obj_out = json_object_new_object(); char *l_str_out = NULL; dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str); if(l_is_all) { size_t l_tx_count = dap_ledger_count(l_ledger), l_tx_count_spent_count = 0; if (!l_tx_count) { - dap_string_append_printf(l_str_ret, "Network ledger %s contains no transactions.\n", l_ledger->net->pub.name); + json_object_object_add(json_obj_out, "Network ledger", json_object_new_string(l_ledger->net->pub.name)); + json_object_object_add(json_obj_out, "info", json_object_new_string("Contains no transactions.")); } else { - dap_string_append_printf(l_str_ret, "There are %zu transactions in the network ledger %s:\n", - l_tx_count, l_ledger->net->pub.name); + json_object_object_add(json_obj_out, "Network ledger", json_object_new_string(l_ledger->net->pub.name)); + json_object_object_add(json_obj_out, "count tx", json_object_new_int(l_tx_count)); + json_object* json_arr_tx = json_object_new_array(); dap_list_t *l_txs_list = dap_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag); for (dap_list_t *iter = l_txs_list; iter; iter = dap_list_next(iter)) { dap_chain_datum_tx_t *l_tx = iter->data; dap_hash_fast_t l_tx_hash = { }; dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); - s_dap_chain_datum_tx_out_data(l_tx, l_ledger, l_str_ret, l_hash_out_type, &l_tx_hash); + json_object * l_json_obj_datum = json_object_new_object(); + s_dap_chain_datum_tx_out_data(l_tx, l_ledger, l_json_obj_datum, l_hash_out_type, &l_tx_hash); + json_object_array_add(json_arr_tx, l_json_obj_datum); } + json_object_object_add(json_obj_out, "data", json_arr_tx); dap_list_free(l_txs_list); } } else { if(l_addr) { - l_str_out = dap_ledger_token_tx_item_list(l_ledger, l_addr, l_hash_out_type, l_unspent_flag); + json_object* json_obj_array = dap_ledger_token_tx_item_list(l_ledger, l_addr, l_hash_out_type, l_unspent_flag); + json_object_object_add(json_obj_out, "Datum_tx", json_obj_array); char *l_addr_str = dap_chain_addr_to_str(l_addr); - dap_string_append_printf(l_str_ret, "history for addr %s:\n%s\n", l_addr_str, - l_str_out ? l_str_out : " empty"); + json_object_object_add(json_obj_out, "history for addr ", json_object_new_string(l_addr_str)); DAP_DELETE(l_addr_str); } else if(l_tx_hash_str) { dap_chain_datum_tx_t *l_tx = NULL; @@ -1005,19 +1024,22 @@ int com_ledger(int a_argc, char ** a_argv, void **a_str_reply) size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); dap_hash_fast_t l_tx_hash = { }; dap_hash_fast(l_tx, l_tx_size, &l_tx_hash); - s_dap_chain_datum_tx_out_data(l_tx, l_ledger, l_str_ret, l_hash_out_type, &l_tx_hash); - dap_string_append_printf(l_str_ret, "history for tx hash %s:\n%s\n", l_tx_hash_str, - l_str_out ? l_str_out : " empty"); + s_dap_chain_datum_tx_out_data(l_tx, l_ledger, json_obj_out, l_hash_out_type, &l_tx_hash); + json_object_object_add(json_obj_out, "history for tx hash ", json_object_new_string(l_tx_hash_str)); + json_object_object_add(json_obj_out, "ticker ", json_object_new_string(l_tx_hash_str)); } else { - dap_string_append_printf(l_str_ret, "There is not transaction %s in the network ledger\n",l_tx_hash_str); + json_object_object_add(json_obj_out, "status", json_object_new_string("There is not transaction in the network ledger")); + json_object_object_add(json_obj_out, "hash", json_object_new_string(l_tx_hash_str)); } } } DAP_DELETE(l_str_out); DAP_DELETE(l_addr); s_dap_chain_tx_hash_processed_ht_free(&l_list_tx_hash_processd); - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s%s", l_sign_str, l_str_ret->str); - dap_string_free(l_str_ret, true); + if (json_obj_out) { + json_object_array_add(*json_arr_reply, json_obj_out); + } + json_object_object_add(json_obj_out, "sign ", json_object_new_string(l_sign_str)); return 0; } else if(l_cmd == CMD_LIST){ @@ -1036,61 +1058,51 @@ int com_ledger(int a_argc, char ** a_argv, void **a_str_reply) l_sub_cmd = SUB_CMD_LIST_LEDGER_THRESHOLD_WITH_HASH; if (dap_chain_hash_fast_from_str(l_tx_threshold_hash_str, &l_tx_threshold_hash)){ l_tx_hash_str = NULL; - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx threshold hash not recognized"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_TRESHOLD_ERR, "tx threshold hash not recognized"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_TRESHOLD_ERR; } } } if (l_sub_cmd == SUBCMD_NONE) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'list' requires subcommands 'coins' or 'threshold'"); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "Command 'list' requires subcommands 'coins' or 'threshold'"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR; } dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-net", &l_net_str); if (l_net_str == NULL){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'list' requires key -net"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "Command 'list' requires key -net"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR; } dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str); if (l_ledger == NULL){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get ledger for net %s", l_net_str); - return -2; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_LACK_ERR, "Can't get ledger for net %s", l_net_str); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_LACK_ERR; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD){ - dap_string_t *l_str_ret = dap_ledger_threshold_info(l_ledger); - if (l_str_ret){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); - dap_string_free(l_str_ret, true); + json_object* json_obj_out = dap_ledger_threshold_info(l_ledger); + if (json_obj_out){ + json_object_array_add(*json_arr_reply, json_obj_out); } - return 0; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_THRESHOLD_WITH_HASH){ - dap_string_t *l_str_ret = dap_ledger_threshold_hash_info(l_ledger, &l_tx_threshold_hash); - if (l_str_ret){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); - dap_string_free(l_str_ret, true); + json_object *json_obj_out = dap_ledger_threshold_hash_info(l_ledger, &l_tx_threshold_hash); + if (json_obj_out){ + json_object_array_add(*json_arr_reply, json_obj_out); } - return 0; } if (l_sub_cmd == SUB_CMD_LIST_LEDGER_BALANCE){ - dap_string_t *l_str_ret = dap_ledger_balance_info(l_ledger); - if (l_str_ret){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); - dap_string_free(l_str_ret, true); + json_object *json_obj_out = dap_ledger_balance_info(l_ledger); + if (json_obj_out){ + json_object_array_add(*json_arr_reply, json_obj_out); } - return 0; } - dap_string_t *l_str_ret = dap_string_new(""); - dap_list_t *l_token_list = dap_ledger_token_info(l_ledger); - dap_string_append_printf(l_str_ret, "Found %lu tokens in %s ledger\n", dap_list_length(l_token_list), l_net_str); - for (dap_list_t *l_list = l_token_list; l_list; l_list = dap_list_next(l_list)) { - dap_string_append(l_str_ret, (char *)l_list->data); + json_object *json_obj_datum = dap_ledger_token_info(l_ledger); + + if (json_obj_datum) { + json_object_array_add(*json_arr_reply, json_obj_datum); } - dap_list_free_full(l_token_list, NULL); - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_ret->str); - dap_string_free(l_str_ret, true); return 0; } else if (l_cmd == CMD_TX_INFO){ //GET hash @@ -1101,38 +1113,46 @@ int com_ledger(int a_argc, char ** a_argv, void **a_str_reply) bool l_unspent_flag = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL); //check input if (l_tx_hash_str == NULL){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "Subcommand 'info' requires key -hash"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "Subcommand 'info' requires key -hash"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR; } if (l_net_str == NULL){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "Subcommand 'info' requires key -net"); - return -2; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "Subcommand 'info' requires key -net"); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR; } dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); if (!l_net) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find net %s", l_net_str); - return -2; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_FIND_ERR, "Can't find net %s", l_net_str); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_FIND_ERR; } dap_chain_hash_fast_t *l_tx_hash = DAP_NEW(dap_chain_hash_fast_t); if (dap_chain_hash_fast_from_str(l_tx_hash_str, l_tx_hash)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't get hash_fast from %s, check that the hash is correct", l_tx_hash_str); - return -4; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_GET_ERR, "Can't get hash_fast from %s, check that the hash is correct", l_tx_hash_str); + DAP_DEL_Z(l_tx_hash); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_GET_ERR; } dap_chain_datum_tx_t *l_datum_tx = dap_chain_net_get_tx_by_hash(l_net, l_tx_hash, l_unspent_flag ? TX_SEARCH_TYPE_NET_UNSPENT : TX_SEARCH_TYPE_NET); if (l_datum_tx == NULL) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find datum for transaction hash %s in chains", l_tx_hash_str); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_TX_HASH_ERR, "Can't find datum for transaction hash %s in chains", l_tx_hash_str); + DAP_DEL_Z(l_tx_hash); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_TX_HASH_ERR; + } + json_object* json_datum = json_object_new_object(); + if (!s_dap_chain_datum_tx_out_data(l_datum_tx, l_net->pub.ledger, json_datum, l_hash_out_type, l_tx_hash)){ + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_TX_HASH_ERR, "Can't find transaction hash %s in ledger", l_tx_hash_str); + json_object_put(json_datum); + DAP_DEL_Z(l_tx_hash); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_TX_HASH_ERR; } - dap_string_t *l_str = dap_string_new(""); - if (!s_dap_chain_datum_tx_out_data(l_datum_tx, l_net->pub.ledger, l_str, l_hash_out_type, l_tx_hash)) - dap_string_append_printf(l_str, "Can't find transaction hash %s in ledger", l_tx_hash_str); - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str->str); - dap_string_free(l_str, true); + DAP_DEL_Z(l_tx_hash); + if (json_datum){ + json_object_array_add(*json_arr_reply, json_datum); + } } else{ - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'ledger' requires parameter 'list' or 'tx' or 'info'"); - return -6; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "Command 'ledger' requires parameter 'list' or 'tx' or 'info'", l_tx_hash_str); + return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR; } return 0; } diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index a7995926180af9004a4207ee8d3d22484c871510..72e18b96d6ebf677afd2ae56d77da60d1e719c18 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -212,7 +212,7 @@ char* dap_ledger_tx_check_err_str(int a_code); * */ -char * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only); +json_object * dap_ledger_token_tx_item_list(dap_ledger_t * a_ledger, dap_chain_addr_t *a_addr, const char *a_hash_out_type, bool a_unspent_only); /** * Check token ticker existance @@ -230,14 +230,14 @@ int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_toke int dap_ledger_token_load(dap_ledger_t *a_ledger, byte_t *a_token, size_t a_token_size); int dap_ledger_token_decl_add_check(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_token, size_t a_token_size); char *dap_ledger_token_decl_add_err_code_to_str(int a_code); -dap_list_t *dap_ledger_token_info(dap_ledger_t *a_ledger); +json_object *dap_ledger_token_info(dap_ledger_t *a_ledger); // Get all token-declarations dap_list_t* dap_ledger_token_decl_all(dap_ledger_t *a_ledger); -dap_string_t *dap_ledger_threshold_info(dap_ledger_t *a_ledger); -dap_string_t *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash); -dap_string_t *dap_ledger_balance_info(dap_ledger_t *a_ledger); +json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger); +json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *l_tx_treshold_hash); +json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger); size_t dap_ledger_token_auth_signs_valid(dap_ledger_t *a_ledger, const char * a_token_ticker); size_t dap_ledger_token_auth_signs_total(dap_ledger_t *a_ledger, const char * a_token_ticker); diff --git a/modules/net/include/dap_chain_node_cli_cmd_tx.h b/modules/net/include/dap_chain_node_cli_cmd_tx.h index 76a3cd8c912b61599be45f489dc5f8da96cf6333..ed0ef2d1f2e9e3b8b302468b7fba49e174612e7b 100644 --- a/modules/net/include/dap_chain_node_cli_cmd_tx.h +++ b/modules/net/include/dap_chain_node_cli_cmd_tx.h @@ -57,6 +57,24 @@ json_object* dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t* l_net, */ int com_ledger(int a_argc, char ** a_argv, void **a_str_reply); +typedef enum s_com_ledger_err{ + DAP_CHAIN_NODE_CLI_COM_LEDGER_OK = 0, + DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_INCOMPATIBLE_PARAMS_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_WALLET_ADDR_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_TRESHOLD_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_LACK_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_FIND_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_ID_NET_ADDR_DIF_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_GET_ERR, + DAP_CHAIN_NODE_CLI_COM_LEDGER_TX_HASH_ERR, + + /* add custom codes here */ + + DAP_CHAIN_NODE_CLI_COM_LEDGER_UNKNOWN /* MAX */ +} s_com_ledger_err_t; /** * token command *