From 08a22ad97dff3be072efb92978bcba9bfc1bec23 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Sun, 12 Jan 2025 12:55:20 +0300 Subject: [PATCH 01/18] [+] Created function int dap_chain_net_tx_create_by_json [+] Created function dap_chain_tx_tx_to_json --- dap-sdk | 2 +- modules/net/dap_chain_net_tx.c | 1045 ++++++++++++++++++ modules/net/dap_chain_node_cli_cmd.c | 855 +------------- modules/net/include/dap_chain_net_tx.h | 30 +- modules/net/include/dap_chain_node_cli_cmd.h | 13 +- 5 files changed, 1107 insertions(+), 838 deletions(-) diff --git a/dap-sdk b/dap-sdk index d6b6934683..5931f83c88 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit d6b6934683168160e7d25647ceef59d9439de2c3 +Subproject commit 5931f83c8894be1f78e4888ef39873fc87aa4df2 diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index 7dd4b97464..5dd03126af 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -30,6 +30,12 @@ #include "dap_chain_datum_tx_in_cond.h" #include "dap_chain_tx.h" #include "dap_list.h" +#include "dap_chain_datum_tx_receipt.h" +#include "dap_chain_wallet.h" +#include "dap_chain_datum_tx_voting.h" +#include "json.h" +#include "dap_chain_net_srv.h" +#include "dap_enc_base64.h" #define LOG_TAG "dap_chain_net_tx" @@ -538,3 +544,1042 @@ bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, da return true; } + +static const char* s_json_get_text(struct json_object *a_json, const char *a_key) +{ + if(!a_json || !a_key) + return NULL; + struct json_object *l_json = json_object_object_get(a_json, a_key); + if(l_json && json_object_is_type(l_json, json_type_string)) { + // Read text + return json_object_get_string(l_json); + } + return NULL; +} + +static bool s_json_get_int64(struct json_object *a_json, const char *a_key, int64_t *a_out) +{ + if(!a_json || !a_key || !a_out) + return false; + struct json_object *l_json = json_object_object_get(a_json, a_key); + if(l_json) { + if(json_object_is_type(l_json, json_type_int)) { + // Read number + *a_out = json_object_get_int64(l_json); + return true; + } + } + return false; +} + +static bool s_json_get_unit(struct json_object *a_json, const char *a_key, dap_chain_net_srv_price_unit_uid_t *a_out) +{ + const char *l_unit_str = s_json_get_text(a_json, a_key); + if(!l_unit_str || !a_out) + return false; + dap_chain_net_srv_price_unit_uid_t l_unit = dap_chain_net_srv_price_unit_uid_from_str(l_unit_str); + if(l_unit.enm == SERV_UNIT_UNDEFINED) + return false; + a_out->enm = l_unit.enm; + return true; +} + +static bool s_json_get_uint256(struct json_object *a_json, const char *a_key, uint256_t *a_out) +{ + const char *l_uint256_str = s_json_get_text(a_json, a_key); + if(!a_out || !l_uint256_str) + return false; + uint256_t l_value = dap_chain_balance_scan(l_uint256_str); + if(!IS_ZERO_256(l_value)) { + memcpy(a_out, &l_value, sizeof(uint256_t)); + return true; + } + return false; +} + +// service names: srv_stake, srv_vpn, srv_xchange +static bool s_json_get_srv_uid(struct json_object *a_json, const char *a_key_service_id, const char *a_key_service, uint64_t *a_out) +{ + uint64_t l_srv_id; + if(!a_out) + return false; + // Read service id + if(s_json_get_int64(a_json, a_key_service_id, (int64_t*) &l_srv_id)) { + *a_out = l_srv_id; + return true; + } + else { + // Read service as name + const char *l_service = s_json_get_text(a_json, a_key_service); + if(l_service) { + dap_chain_net_srv_t *l_srv = dap_chain_net_srv_get_by_name(l_service); + if(!l_srv) + return false; + *a_out = l_srv->uid.uint64; + return true; + } + } + return false; +} + +static dap_chain_wallet_t* s_json_get_wallet(struct json_object *a_json, const char *a_key) +{ + return dap_chain_wallet_open(s_json_get_text(a_json, a_key), dap_chain_wallet_get_path(g_config), NULL); +} + +static const dap_cert_t* s_json_get_cert(struct json_object *a_json, const char *a_key) +{ + return dap_cert_find_by_name(s_json_get_text(a_json, a_key)); +} + +// Read pkey from wallet or cert +static dap_pkey_t* s_json_get_pkey(struct json_object *a_json) +{ + dap_pkey_t *l_pub_key = NULL; + // From wallet + dap_chain_wallet_t *l_wallet = s_json_get_wallet(a_json, "wallet"); + if(l_wallet) { + l_pub_key = dap_chain_wallet_get_pkey(l_wallet, 0); + dap_chain_wallet_close(l_wallet); + if(l_pub_key) { + return l_pub_key; + } + } + // From cert + const dap_cert_t *l_cert = s_json_get_cert(a_json, "cert"); + if(l_cert) { + l_pub_key = dap_pkey_from_enc_key(l_cert->enc_key); + } + return l_pub_key; +} + +int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_net, json_object *a_json_obj_error, + dap_chain_datum_tx_t** a_out_tx, size_t* a_items_count, size_t *a_items_ready, void **a_json_arr_reply) +{ + + json_object *l_json = a_tx_json; + json_object *l_jobj_errors = a_json_obj_error ? a_json_obj_error : NULL; + + if (!a_tx_json) + return log_it(L_ERROR, "Empty json"), DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE; + + if(!a_out_tx){ + log_it(L_ERROR, "a_out_tx is NULL"); + return DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_ARGUMENTS; + } + + const char *l_native_token = a_net ? a_net->pub.native_ticker : NULL; + const char *l_main_token = NULL; + bool l_multichanel = false; + + + // Read items from json file + struct json_object *l_json_items = json_object_object_get(l_json, "items"); + size_t l_items_count; + if(!l_json_items || !json_object_is_type(l_json_items, json_type_array) || !(l_items_count = json_object_array_length(l_json_items))) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS, + "Wrong json format: not found array 'items' or array is empty"); + json_object_put(l_json); + return DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS; + } + + log_it(L_ERROR, "Json TX: found %lu items", l_items_count); + // Create transaction + dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); + if(!l_tx) { + json_object_put(l_json); + dap_json_rpc_allocation_error(*a_json_arr_reply); + return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; + } + + struct json_object *l_json_timestamp = json_object_object_get(l_json, "ts_created"); + if (l_json_timestamp) + l_tx->header.ts_created = json_object_get_int64(l_json_timestamp); + else + l_tx->header.ts_created = time(NULL); + + size_t l_items_ready = 0; + dap_list_t *l_in_list = NULL;// list 'in' items + dap_list_t *l_sign_list = NULL;// list 'sign' items + uint256_t l_value_need = { };// how many tokens are needed in the 'out' item + uint256_t l_value_need_fee = {}; + + if(a_net){ // if composition is not offline + // First iteration in input file. Check the tx will be multichannel or not + for(size_t i = 0; i < l_items_count; ++i) { + struct json_object *l_json_item_obj = json_object_array_get_idx(l_json_items, i); + if(!l_json_item_obj || !json_object_is_type(l_json_item_obj, json_type_object)) { + continue; + } + struct json_object *l_json_item_type = json_object_object_get(l_json_item_obj, "type"); + if(!l_json_item_type && json_object_is_type(l_json_item_type, json_type_string)) { + log_it(L_WARNING, "Item %zu without type", i); + continue; + } + const char *l_item_type_str = json_object_get_string(l_json_item_type); + dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_str_to_type(l_item_type_str); + if(l_item_type == TX_ITEM_TYPE_UNKNOWN) { + log_it(L_WARNING, "Item %zu has invalid type '%s'", i, l_item_type_str); + continue; + } + + switch (l_item_type) { + case TX_ITEM_TYPE_IN: { + const char *l_json_item_token = s_json_get_text(l_json_item_obj, "token"); + if (l_json_item_token && dap_strcmp(l_json_item_token, l_native_token)){ + l_multichanel = true; + l_main_token = l_json_item_token; + } + }break; + default: continue; + } + if(l_multichanel) + break; + } + } + + // Creating and adding items to the transaction + for(size_t i = 0; i < l_items_count; ++i) { + struct json_object *l_json_item_obj = json_object_array_get_idx(l_json_items, i); + if(!l_json_item_obj || !json_object_is_type(l_json_item_obj, json_type_object)) { + continue; + } + struct json_object *l_json_item_type = json_object_object_get(l_json_item_obj, "type"); + if(!l_json_item_type && json_object_is_type(l_json_item_type, json_type_string)) { + log_it(L_WARNING, "Item %zu without type", i); + continue; + } + const char *l_item_type_str = json_object_get_string(l_json_item_type); + dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_str_to_type(l_item_type_str); + if(l_item_type == TX_ITEM_TYPE_UNKNOWN) { + log_it(L_WARNING, "Item %zu has invalid type '%s'", i, l_item_type_str); + continue; + } + + log_it(L_DEBUG, "Json TX: process item %s", json_object_get_string(l_json_item_type)); + // Create an item depending on its type + const uint8_t *l_item = NULL; + switch (l_item_type) { + case TX_ITEM_TYPE_IN: { + // Save item obj for in + // Read prev_hash and out_prev_idx + const char *l_prev_hash_str = s_json_get_text(l_json_item_obj, "prev_hash"); + int64_t l_out_prev_idx; + bool l_is_out_prev_idx = s_json_get_int64(l_json_item_obj, "out_prev_idx", &l_out_prev_idx); + // If prev_hash and out_prev_idx were read + if(l_prev_hash_str && l_is_out_prev_idx) { + dap_chain_hash_fast_t l_tx_prev_hash; + if(!dap_chain_hash_fast_from_str(l_prev_hash_str, &l_tx_prev_hash)) { + // Create IN item + dap_chain_tx_in_t *l_in_item = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, (uint32_t) l_out_prev_idx); + if (!l_in_item) { + json_object *l_jobj_err = json_object_new_string("Unable to create in for transaction."); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + l_item = (const uint8_t*) l_in_item; + } else { + log_it(L_WARNING, "Invalid 'in' item, bad prev_hash %s", l_prev_hash_str); + char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, " + "bad prev_hash %s", l_prev_hash_str); + json_object *l_jobj_err = json_object_new_string(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + } + // Read addr_from + else { + l_in_list = dap_list_append(l_in_list, l_json_item_obj); + } + } + break; + + case TX_ITEM_TYPE_OUT: + case TX_ITEM_TYPE_OUT_EXT: { + // Read address and value + uint256_t l_value = { }; + const char *l_json_item_addr_str = s_json_get_text(l_json_item_obj, "addr"); + bool l_is_value = s_json_get_uint256(l_json_item_obj, "value", &l_value); + const char *l_token = s_json_get_text(l_json_item_obj, "token"); + if(l_is_value && l_json_item_addr_str) { + dap_chain_addr_t *l_addr = dap_chain_addr_from_str(l_json_item_addr_str); + if(l_addr && !IS_ZERO_256(l_value)) { + if(l_item_type == TX_ITEM_TYPE_OUT) { + // Create OUT item + const uint8_t *l_out_item = NULL; + if (a_net) {// if composition is not offline + if(l_multichanel) + l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token ? l_token : (l_main_token ? l_main_token : l_native_token)); + else + l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_create(l_addr, l_value); + if (!l_out_item) { + json_object *l_jobj_err = json_object_new_string("Failed to create transaction out. " + "There may not be enough funds in the wallet."); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + if (l_out_item){ + if (l_multichanel && !dap_strcmp(((dap_chain_tx_out_ext_t*)l_out_item)->token, l_native_token)) + SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee); + else + SUM_256_256(l_value_need, l_value, &l_value_need); + } + } else { + l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_create(l_addr, l_value); + if (!l_out_item) { + json_object *l_jobj_err = json_object_new_string("Failed to create transaction out. " + "There may not be enough funds in the wallet."); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + } + l_item = (const uint8_t*) l_out_item; + } else if(l_item_type == TX_ITEM_TYPE_OUT_EXT) { + // Read address and value + if(l_token) { + // Create OUT_EXT item + const uint8_t *l_out_item = NULL; + if (a_net){ // if composition is not offline + if(l_multichanel) + l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token); + else + l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_create(l_addr, l_value); + if (!l_out_item) { + json_object *l_jobj_err = json_object_new_string("Failed to create a out ext" + "for a transaction. There may not be enough funds " + "on the wallet or the wrong ticker token " + "is indicated."); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + if (l_out_item){ + if (l_multichanel && !dap_strcmp(l_token, l_native_token)) + SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee); + else + SUM_256_256(l_value_need, l_value, &l_value_need); + } + } else { + l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token); + if (!l_out_item) { + json_object *l_jobj_err = json_object_new_string("Failed to create a out ext" + "for a transaction. There may not be enough funds " + "on the wallet or the wrong ticker token " + "is indicated."); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + } + l_item = (const uint8_t*) l_out_item; + } + else { + log_it(L_WARNING, "Invalid 'out_ext' item %zu", i); + continue; + } + } + } else { + if(l_item_type == TX_ITEM_TYPE_OUT) { + log_it(L_WARNING, "Invalid 'out' item %zu", i); + } + else if(l_item_type == TX_ITEM_TYPE_OUT_EXT) { + log_it(L_WARNING, "Invalid 'out_ext' item %zu", i); + } + char *l_str_err = dap_strdup_printf("For item %zu of type 'out' or 'out_ext' the " + "string representation of the address could not be converted, " + "or the size of the output sum is 0.", i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + continue; + } + } + } + break; + case TX_ITEM_TYPE_OUT_COND: { + // Read subtype of item + const char *l_subtype_str = s_json_get_text(l_json_item_obj, "subtype"); + dap_chain_tx_out_cond_subtype_t l_subtype = dap_chain_tx_out_cond_subtype_from_str(l_subtype_str); + switch (l_subtype) { + + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:{ + uint256_t l_value = { }; + bool l_is_value = s_json_get_uint256(l_json_item_obj, "value", &l_value); + if(!l_is_value || IS_ZERO_256(l_value)) { + log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_PAY"); + break; + } + uint256_t l_value_max_per_unit = { }; + l_is_value = s_json_get_uint256(l_json_item_obj, "value_max_per_unit", &l_value_max_per_unit); + if(!l_is_value || IS_ZERO_256(l_value_max_per_unit)) { + log_it(L_ERROR, "Json TX: bad value_max_per_unit in OUT_COND_SUBTYPE_SRV_PAY"); + break; + } + dap_chain_net_srv_price_unit_uid_t l_price_unit; + if(!s_json_get_unit(l_json_item_obj, "price_unit", &l_price_unit)) { + log_it(L_ERROR, "Json TX: bad price_unit in OUT_COND_SUBTYPE_SRV_PAY"); + break; + } + dap_chain_net_srv_uid_t l_srv_uid; + if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)){ + // Default service DAP_CHAIN_NET_SRV_VPN_ID + l_srv_uid.uint64 = 0x0000000000000001; + } + + // From "wallet" or "cert" + dap_pkey_t *l_pkey = s_json_get_pkey(l_json_item_obj); + if(!l_pkey) { + log_it(L_ERROR, "Json TX: bad pkey in OUT_COND_SUBTYPE_SRV_PAY"); + break; + } + const char *l_params_str = s_json_get_text(l_json_item_obj, "params"); + size_t l_params_size = dap_strlen(l_params_str); + dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_pay(l_pkey, l_srv_uid, l_value, l_value_max_per_unit, + l_price_unit, l_params_str, l_params_size); + l_item = (const uint8_t*) l_out_cond_item; + // Save value for using in In item + if(l_item) { + SUM_256_256(l_value_need, l_value, &l_value_need); + } else { + char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " + "can of type %s described in item %zu.\n", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + DAP_DELETE(l_pkey); + } + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { + + dap_chain_net_srv_uid_t l_srv_uid; + if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { + // Default service DAP_CHAIN_NET_SRV_XCHANGE_ID + l_srv_uid.uint64 = 0x2; + } + dap_chain_net_t *l_net = dap_chain_net_by_name(s_json_get_text(l_json_item_obj, "net")); + if(!l_net) { + log_it(L_ERROR, "Json TX: bad net in OUT_COND_SUBTYPE_SRV_XCHANGE"); + break; + } + const char *l_token = s_json_get_text(l_json_item_obj, "token"); + if(!l_token) { + log_it(L_ERROR, "Json TX: bad token in OUT_COND_SUBTYPE_SRV_XCHANGE"); + break; + } + uint256_t l_value = { }; + if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) { + log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_XCHANGE"); + break; + } + //const char *l_params_str = s_json_get_text(l_json_item_obj, "params"); + //size_t l_params_size = dap_strlen(l_params_str); + dap_chain_tx_out_cond_t *l_out_cond_item = NULL; //dap_chain_datum_tx_item_out_cond_create_srv_xchange(l_srv_uid, l_net->pub.id, l_token, l_value, l_params_str, l_params_size); + l_item = (const uint8_t*) l_out_cond_item; + // Save value for using in In item + if(l_item) { + SUM_256_256(l_value_need, l_value, &l_value_need); + } else { + char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " + "can of type %s described in item %zu.", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + } + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE:{ + dap_chain_net_srv_uid_t l_srv_uid; + if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { + // Default service DAP_CHAIN_NET_SRV_STAKE_ID + l_srv_uid.uint64 = 0x13; + } + uint256_t l_value = { }; + if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) { + log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); + break; + } + uint256_t l_fee_value = { }; + if(!s_json_get_uint256(l_json_item_obj, "fee", &l_fee_value) || IS_ZERO_256(l_fee_value)) { + break; + } + + const char *l_signing_addr_str = s_json_get_text(l_json_item_obj, "signing_addr"); + dap_chain_addr_t *l_signing_addr = dap_chain_addr_from_str(l_signing_addr_str); + if(!l_signing_addr) { + { + log_it(L_ERROR, "Json TX: bad signing_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); + break; + } + dap_chain_node_addr_t l_signer_node_addr; + const char *l_node_addr_str = s_json_get_text(l_json_item_obj, "node_addr"); + if(!l_node_addr_str || dap_chain_node_addr_from_str(&l_signer_node_addr, l_node_addr_str)) { + log_it(L_ERROR, "Json TX: bad node_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); + break; + } + dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_srv_uid, l_value, l_signing_addr, + &l_signer_node_addr, NULL, uint256_0); + l_item = (const uint8_t*) l_out_cond_item; + // Save value for using in In item + if(l_item) { + SUM_256_256(l_value_need, l_value, &l_value_need); + } else { + char *l_err_str = dap_strdup_printf("Unable to create conditional out for transaction " + "can of type %s described in item %zu.", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_err_str); + DAP_DELETE(l_err_str); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + } + } + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: { + uint256_t l_value = { }; + s_json_get_uint256(l_json_item_obj, "value", &l_value); + if(!IS_ZERO_256(l_value)) { + dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_fee(l_value); + l_item = (const uint8_t*) l_out_cond_item; + // Save value for using in In item + if(l_item) { + SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee); + } else { + char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " + "can of type %s described in item %zu.", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + DAP_DELETE(l_str_err); + } + } + else + log_it(L_ERROR, "Json TX: zero value in OUT_COND_SUBTYPE_FEE"); + } + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED: + log_it(L_WARNING, "Undefined subtype: '%s' of 'out_cond' item %zu ", l_subtype_str, i); + char *l_str_err = dap_strdup_printf("Specified unknown sub type %s of conditional out on item %zu.", + l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + break; + } + } + break; + case TX_ITEM_TYPE_SIG:{ + const char *l_sign_type_str = s_json_get_text(l_json_item_obj, "sig_type"); + if (l_sign_type_str) { + dap_sign_type_t l_sign_type = dap_sign_type_from_str(l_sign_type_str); + if (l_sign_type.type == SIG_TYPE_NULL) { + json_object *l_jobj_err = json_object_new_string("Can't define sign type"); + json_object_array_add(l_jobj_errors, l_jobj_err); + log_it(L_ERROR, "Json TX: Can't define sign type \"%s\"", l_sign_type_str); + break; + } + int64_t l_pkey_size, l_sig_size, l_hash_type = 0; + + s_json_get_int64(l_json_item_obj, "hash_type", &l_hash_type); + s_json_get_int64(l_json_item_obj, "pub_key_size", &l_pkey_size); + s_json_get_int64(l_json_item_obj, "sig_size", &l_sig_size); + debug_if(!l_pkey_size || !l_sig_size, L_WARNING, + "\"pub_key_size\" or \"sig_size\" not provided! Will be calculated automatically"); + + json_object *l_jobj_pub_key = json_object_object_get(l_json_item_obj, "pub_key_b64"), + *l_jobj_sign = json_object_object_get(l_json_item_obj, "sig_b64"); + if (!l_jobj_pub_key || !l_jobj_sign) { + json_object *l_jobj_err = json_object_new_string("Can't get base64-encoded sign or pkey!"); + json_object_array_add(l_jobj_errors, l_jobj_err); + log_it(L_ERROR, "Json TX: Can't get base64-encoded sign or pkey!"); + break; + } + const char *l_pub_key_str = json_object_get_string(l_jobj_pub_key), + *l_sign_str = json_object_get_string(l_jobj_sign); + int64_t l_pkey_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(strlen(l_pub_key_str)), + l_sign_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(strlen(l_sign_str)); + + dap_sign_t *l_sign = DAP_NEW_SIZE(dap_sign_t, sizeof(dap_sign_t) + l_pkey_decoded_size + l_sign_decoded_size); + *l_sign = (dap_sign_t) { + .header.type = l_sign_type, + .header.hash_type = (uint8_t)l_hash_type, + }; + l_pkey_decoded_size = dap_enc_base64_decode(l_pub_key_str, strlen(l_pub_key_str), + l_sign->pkey_n_sign, DAP_ENC_DATA_TYPE_B64_URLSAFE); + debug_if(l_pkey_size != l_pkey_decoded_size, L_ERROR, "Json TX: pkey size mismatch, %zu != %zu", + l_pkey_size, l_pkey_decoded_size); + + l_sign_decoded_size = dap_enc_base64_decode(l_sign_str, strlen(l_sign_str), + l_sign->pkey_n_sign + l_pkey_decoded_size, DAP_ENC_DATA_TYPE_B64_URLSAFE); + debug_if(l_sig_size != l_sign_decoded_size, L_ERROR, "Json TX: sign size mismatch, %zu != %zu", + l_sig_size, l_sign_decoded_size); + + l_sign->header.sign_size = l_sign_decoded_size; + l_sign->header.sign_pkey_size = l_pkey_decoded_size; + size_t l_sign_full_size = dap_sign_get_size(l_sign); + + dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t, sizeof(dap_chain_tx_sig_t) + l_sign_full_size); + l_tx_sig->header.type = TX_ITEM_TYPE_SIG; + l_tx_sig->header.version = 1; + l_tx_sig->header.sig_size = (uint32_t)l_sign_full_size; + memcpy(l_tx_sig->sig, l_sign, l_sign_full_size); + l_item = (const uint8_t*)l_tx_sig; + DAP_DELETE(l_sign); + break; + } else + l_sign_list = dap_list_append(l_sign_list,l_json_item_obj); + } + break; + case TX_ITEM_TYPE_RECEIPT: { + dap_chain_net_srv_uid_t l_srv_uid; + if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { + log_it(L_ERROR, "Json TX: bad service_id in TYPE_RECEIPT"); + break; + } + dap_chain_net_srv_price_unit_uid_t l_price_unit; + if(!s_json_get_unit(l_json_item_obj, "price_unit", &l_price_unit)) { + log_it(L_ERROR, "Json TX: bad price_unit in TYPE_RECEIPT"); + break; + } + int64_t l_units; + if(!s_json_get_int64(l_json_item_obj, "units", &l_units)) { + log_it(L_ERROR, "Json TX: bad units in TYPE_RECEIPT"); + break; + } + uint256_t l_value = { }; + if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) { + log_it(L_ERROR, "Json TX: bad value in TYPE_RECEIPT"); + break; + } + const char *l_params_str = s_json_get_text(l_json_item_obj, "params"); + size_t l_params_size = dap_strlen(l_params_str); + dap_chain_datum_tx_receipt_t *l_receipt = dap_chain_datum_tx_receipt_create(l_srv_uid, l_price_unit, l_units, l_value, l_params_str, l_params_size); + l_item = (const uint8_t*) l_receipt; + if (!l_item) { + char *l_str_err = dap_strdup_printf("Unable to create receipt out for transaction " + "described by item %zu.", i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + } + break; + case TX_ITEM_TYPE_TSD: { + int64_t l_tsd_type; + if(!s_json_get_int64(l_json_item_obj, "type_tsd", &l_tsd_type)) { + log_it(L_ERROR, "Json TX: bad type_tsd in TYPE_TSD"); + break; + } + const char *l_tsd_data = s_json_get_text(l_json_item_obj, "data"); + if (!l_tsd_data) { + log_it(L_ERROR, "Json TX: bad data in TYPE_TSD"); + break; + } + size_t l_data_size = dap_strlen(l_tsd_data); + dap_chain_tx_tsd_t *l_tsd = dap_chain_datum_tx_item_tsd_create((void*)l_tsd_data, (int)l_tsd_type, l_data_size); + l_item = (const uint8_t*) l_tsd; + // l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + } + break; + //case TX_ITEM_TYPE_PKEY: + //break; + //case TX_ITEM_TYPE_IN_EMS: + //break; + //case TX_ITEM_TYPE_IN_EMS_EXT: + //break; + } + // Add item to transaction + if(l_item) { + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_item); + l_items_ready++; + DAP_DELETE(l_item); + } + } + + dap_list_t *l_list; + // Add In items + if(a_net){ + l_list = l_in_list; + while(l_list) { + struct json_object *l_json_item_obj = (struct json_object*) l_list->data; + + const char *l_json_item_addr_str = s_json_get_text(l_json_item_obj, "addr_from"); + const char *l_json_item_token = s_json_get_text(l_json_item_obj, "token"); + l_main_token = l_json_item_token; + dap_chain_addr_t *l_addr_from = NULL; + if(l_json_item_addr_str) { + l_addr_from = dap_chain_addr_from_str(l_json_item_addr_str); + if (!l_addr_from) { + log_it(L_WARNING, "Invalid element 'in', unable to convert string representation of addr_from: '%s' " + "to binary.", l_json_item_addr_str); + char *l_str_err = dap_strdup_printf("Invalid element 'to', unable to convert string representation " + "of addr_from: '%s' to binary.", l_json_item_addr_str); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + // Go to the next item + l_list = dap_list_next(l_list); + continue; + } + } + else { + log_it(L_WARNING, "Invalid 'in' item, incorrect addr_from: '%s'", l_json_item_addr_str ? l_json_item_addr_str : "[null]"); + char *l_str_err = dap_strdup_printf("Invalid 'in' item, incorrect addr_from: '%s'", + l_json_item_addr_str ? l_json_item_addr_str : "[null]"); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + // Go to the next item + l_list = dap_list_next(l_list); + continue; + } + if(!l_json_item_token) { + log_it(L_WARNING, "Invalid 'in' item, not found token name"); + json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found token name"); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + // Go to the next item + l_list = dap_list_next(l_list); + continue; + } + if(IS_ZERO_256(l_value_need)) { + log_it(L_WARNING, "Invalid 'in' item, not found value in out items"); + json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found value in out items"); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + // Go to the next item + l_list = dap_list_next(l_list); + continue; + } + + if(l_addr_from){ + // find the transactions from which to take away coins + dap_list_t *l_list_used_out = NULL; + dap_list_t *l_list_used_out_fee = NULL; + uint256_t l_value_transfer = { }; // how many coins to transfer + uint256_t l_value_transfer_fee = { }; // how many coins to transfer + //SUM_256_256(a_value, a_value_fee, &l_value_need); + uint256_t l_value_need_check = {}; + if (!dap_strcmp(l_native_token, l_main_token)) { + SUM_256_256(l_value_need_check, l_value_need, &l_value_need_check); + SUM_256_256(l_value_need_check, l_value_need_fee, &l_value_need_check); + l_list_used_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_json_item_token, + l_addr_from, l_value_need_check, &l_value_transfer); + if(!l_list_used_out) { + log_it(L_WARNING, "Not enough funds in previous tx to transfer"); + json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds in previous tx " + "to transfer"); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + // Go to the next item + l_list = dap_list_next(l_list); + continue; + } + } else { + //CHECK value need + l_list_used_out = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_json_item_token, + l_addr_from, l_value_need, &l_value_transfer); + if(!l_list_used_out) { + log_it(L_WARNING, "Not enough funds in previous tx to transfer"); + json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds " + "in previous tx to transfer"); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + // Go to the next item + l_list = dap_list_next(l_list); + continue; + } + //CHECK value fee + l_list_used_out_fee = dap_ledger_get_list_tx_outs_with_val(a_net->pub.ledger, l_native_token, + l_addr_from, l_value_need_fee, &l_value_transfer_fee); + if(!l_list_used_out_fee) { + log_it(L_WARNING, "Not enough funds in previous tx to transfer"); + json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds " + "in previous tx to transfer"); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + // Go to the next item + l_list = dap_list_next(l_list); + continue; + } + } + // add 'in' items + uint256_t l_value_got = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out); + assert(EQUAL_256(l_value_got, l_value_transfer)); + if (l_list_used_out_fee) { + uint256_t l_value_got_fee = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out_fee); + assert(EQUAL_256(l_value_got_fee, l_value_transfer_fee)); + dap_list_free_full(l_list_used_out_fee, free); + // add 'out' item for coin fee back + uint256_t l_value_back; + SUBTRACT_256_256(l_value_got_fee, l_value_need_fee, &l_value_back); + if (!IS_ZERO_256(l_value_back)) { + dap_chain_datum_tx_add_out_ext_item(&l_tx, l_addr_from, l_value_back, l_native_token); + l_items_ready++; + } + } else { + SUM_256_256(l_value_need, l_value_need_fee, &l_value_need); + } + dap_list_free_full(l_list_used_out, free); + if(!IS_ZERO_256(l_value_got)) { + // add 'out' item for coin back + uint256_t l_value_back; + SUBTRACT_256_256(l_value_got, l_value_need, &l_value_back); + if(!IS_ZERO_256(l_value_back)) { + if (l_multichanel) + dap_chain_datum_tx_add_out_ext_item(&l_tx, l_addr_from, l_value_back, l_main_token); + else + dap_chain_datum_tx_add_out_item(&l_tx, l_addr_from, l_value_back); + l_items_ready++; + } + } + } + // Go to the next 'in' item + l_list = dap_list_next(l_list); + } + } + dap_list_free(l_in_list); + + // Add signs + l_list = l_sign_list; + while(l_list) { + struct json_object *l_json_item_obj = (struct json_object*) l_list->data; + dap_enc_key_t * l_enc_key = NULL; + + //get wallet or cert + dap_chain_wallet_t *l_wallet = s_json_get_wallet(l_json_item_obj, "wallet"); + const dap_cert_t *l_cert = s_json_get_cert(l_json_item_obj, "cert"); + + int64_t l_pkey_size; + int64_t l_sig_size; + uint8_t *l_pkey = NULL; + int64_t l_hash_type = 0; + dap_sign_t *l_sign = NULL; + + + //wallet goes first + if (l_wallet) { + l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); + } else if (l_cert && l_cert->enc_key) { + l_enc_key = l_cert->enc_key; + } else { + json_object *l_jobj_err = json_object_new_string("Can't create sign for transactions."); + json_object_array_add(l_jobj_errors, l_jobj_err); + log_it(L_ERROR, "Json TX: Item sign has no wallet or cert of they are invalid "); + l_list = dap_list_next(l_list); + continue; + } + + if (l_sign) { + size_t l_chain_sign_size = dap_sign_get_size(l_sign); // sign data + + dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t, + sizeof(dap_chain_tx_sig_t) + l_chain_sign_size); + l_tx_sig->header.type = TX_ITEM_TYPE_SIG; + l_tx_sig->header.sig_size =(uint32_t) l_chain_sign_size; + memcpy(l_tx_sig->sig, l_sign, l_chain_sign_size); + dap_chain_datum_tx_add_item(&l_tx, l_tx_sig); + DAP_DELETE(l_sign); + } + + if(l_enc_key && dap_chain_datum_tx_add_sign_item(&l_tx, l_enc_key) > 0) { + l_items_ready++; + } else { + log_it(L_ERROR, "Json TX: Item sign has invalid enc_key."); + l_list = dap_list_next(l_list); + continue; + } + + if (l_wallet) { + dap_chain_wallet_close(l_wallet); + dap_enc_key_delete(l_enc_key); + } + l_list = dap_list_next(l_list); + } + + dap_list_free(l_sign_list); + json_object_put(l_json); + + *a_out_tx = l_tx; + + if(a_items_count) + *a_items_count = l_items_count; + + if(a_items_ready) + *a_items_ready = l_items_ready; + + return DAP_CHAIN_NET_TX_CREATE_JSON_OK; +} + +int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json) +{ + if(!a_tx || !a_out_json) + return log_it(L_ERROR, "Empty transaction"), DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_ARGUMENTS; + + json_object* json_obj_out = a_out_json; + json_object* l_json_arr_reply = NULL; + dap_hash_fast_t l_hash_tmp = { }; + byte_t *item; size_t l_size; + char *l_hash_str = NULL; + char l_tmp_buf[DAP_TIME_STR_SIZE]; + json_object* json_arr_items = json_object_new_array(); + + char *l_tx_hash_str = dap_hash_fast_str_new(a_tx, dap_chain_datum_tx_get_size(a_tx)); + + json_object_object_add(json_obj_out, "datum_hash", json_object_new_string(l_tx_hash_str)); + json_object_object_add(json_obj_out, "ts_created", json_object_new_int64(a_tx->header.ts_created)); + json_object_object_add(json_obj_out, "datum_type", json_object_new_string("tx")); + + TX_ITEM_ITER_TX(item, l_size, a_tx) { + json_object* json_obj_item = json_object_new_object(); + switch (*item) { + case TX_ITEM_TYPE_IN: + l_hash_tmp = ((dap_chain_tx_in_t*)item)->header.tx_prev_hash; + l_hash_str = dap_hash_fast_to_str_static(&l_hash_tmp); + json_object_object_add(json_obj_item,"type", json_object_new_string("in")); + json_object_object_add(json_obj_item,"prev_hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_item,"out_prev_idx", json_object_new_uint64(((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx)); + break; + case TX_ITEM_TYPE_OUT: { // 256 + const char *l_coins_str, + *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_t*)item)->header.value, &l_coins_str), + *l_addr_str = dap_chain_addr_to_str_static(&((dap_chain_tx_out_t*)item)->addr); + json_object_object_add(json_obj_item,"type", json_object_new_string("out")); + json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str)); + json_object_object_add(json_obj_item,"addr", json_object_new_string(l_addr_str)); + } break; + case TX_ITEM_TYPE_SIG: { + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*)item); + json_object_object_add(json_obj_item,"type", json_object_new_string("sign")); + dap_chain_hash_fast_t l_hash_pkey; + json_object_object_add(json_obj_item,"sig_type",json_object_new_string(dap_sign_type_to_str(l_sign->header.type))); + json_object_object_add(json_obj_item,"pub_key_size",json_object_new_uint64(l_sign->header.sign_pkey_size)); + json_object_object_add(json_obj_item,"sig_size",json_object_new_uint64(l_sign->header.sign_size)); + json_object_object_add(json_obj_item,"hash_type",json_object_new_uint64(l_sign->header.hash_type)); + + char l_pkey_base64[DAP_ENC_BASE64_ENCODE_SIZE(l_sign->header.sign_pkey_size) + 1]; + size_t l_pkey_base64_size = dap_enc_base64_encode(l_sign->pkey_n_sign, l_sign->header.sign_pkey_size, l_pkey_base64, DAP_ENC_DATA_TYPE_B64_URLSAFE); + l_pkey_base64[l_pkey_base64_size] = '\0'; + json_object_object_add(json_obj_item,"pub_key_b64", json_object_new_string(l_pkey_base64)); + + char l_sign_base64[DAP_ENC_BASE64_ENCODE_SIZE(l_sign->header.sign_size) + 1]; + size_t l_sign_base64_size = dap_enc_base64_encode(l_sign->pkey_n_sign + l_sign->header.sign_pkey_size, l_sign->header.sign_size, l_sign_base64, DAP_ENC_DATA_TYPE_B64_URLSAFE); + l_sign_base64[l_sign_base64_size] = '\0'; + json_object_object_add(json_obj_item,"sig_b64", json_object_new_string(l_sign_base64)); + + } break; + case TX_ITEM_TYPE_TSD: { + json_object_object_add(json_obj_item,"type", json_object_new_string("data")); + json_object_object_add(json_obj_item,"type", json_object_new_uint64(((dap_chain_tx_tsd_t*)item)->header.type)); + json_object_object_add(json_obj_item,"size", json_object_new_uint64(((dap_chain_tx_tsd_t*)item)->header.size)); + } break; + case TX_ITEM_TYPE_IN_COND: + json_object_object_add(json_obj_item,"type", json_object_new_string("in_cond")); + l_hash_tmp = ((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash; + l_hash_str = dap_hash_fast_to_str_static(&l_hash_tmp); + json_object_object_add(json_obj_item,"receipt_idx", json_object_new_int(((dap_chain_tx_in_cond_t*)item)->header.receipt_idx)); + json_object_object_add(json_obj_item,"out_prev_idx", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_item,"prev_hash", json_object_new_uint64(((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx)); + break; + case TX_ITEM_TYPE_OUT_COND: { + char l_tmp_buff[70]={0}; + json_object_object_add(json_obj_item,"type", json_object_new_string("out_cond")); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_coins_str); + dap_time_t l_ts_exp = ((dap_chain_tx_out_cond_t*)item)->header.ts_expires; + dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_exp); + json_object_object_add(json_obj_item,"ts_expires", l_ts_exp ? json_object_new_string(l_tmp_buf) : json_object_new_string("never")); + json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str)); + sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64); + json_object_object_add(json_obj_item,"service_id", json_object_new_string(l_tmp_buff)); + switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) { + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: + json_object_object_add(json_obj_item,"subtype", json_object_new_string("fee")); + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: { + const char *l_coins_str, *l_value_str = + dap_uint256_to_char( ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str ); + l_hash_tmp = ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash; + l_hash_str = dap_hash_fast_to_str_static(&l_hash_tmp); + sprintf(l_tmp_buff,"0x%08x",((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32); + json_object_object_add(json_obj_item,"price_unit", json_object_new_string(l_tmp_buff)); + json_object_object_add(json_obj_item,"pkey", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_item,"value_max_per_unit", json_object_new_string(l_value_str)); + json_object_object_add(json_obj_item,"subtype", json_object_new_string("srv_pay")); + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: { + dap_chain_node_addr_t *l_signer_node_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signer_node_addr; + dap_chain_addr_t *l_signing_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signing_addr; + l_hash_tmp = l_signing_addr->data.hash_fast; + l_hash_str = dap_hash_fast_to_str_static(&l_hash_tmp); + json_object_object_add(json_obj_item,"signing_addr", json_object_new_string(dap_chain_addr_to_str_static(l_signing_addr))); + sprintf(l_tmp_buff,""NODE_ADDR_FP_STR"",NODE_ADDR_FP_ARGS(l_signer_node_addr)); + json_object_object_add(json_obj_item,"signer_node_addr", json_object_new_string(l_tmp_buff)); + json_object_object_add(json_obj_item,"subtype", json_object_new_string("srv_stake_pos_delegate")); + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { + const char *l_rate_str, *l_tmp_str = + dap_uint256_to_char( (((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.rate), &l_rate_str ); + sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_net_id.uint64); + json_object_object_add(json_obj_item,"net_id", json_object_new_string(l_tmp_buff)); + json_object_object_add(json_obj_item,"token", json_object_new_string(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_token)); + json_object_object_add(json_obj_item,"rate", json_object_new_string(l_rate_str)); + json_object_object_add(json_obj_item,"subtype", json_object_new_string("srv_xchange")); + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: { + dap_time_t l_ts_unlock = ((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_lock.time_unlock; + dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_unlock); + json_object_object_add(json_obj_item,"time_unlock", json_object_new_string(l_tmp_buf)); + json_object_object_add(json_obj_item,"subtype", json_object_new_string("srv_stake_lock")); + } break; + default: break; + } + } break; + case TX_ITEM_TYPE_OUT_EXT: { + const char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_ext_t*)item)->header.value, &l_coins_str ); + json_object_object_add(json_obj_item,"type", json_object_new_string("out_ext")); + json_object_object_add(json_obj_item,"addr", json_object_new_string(dap_chain_addr_to_str_static(&((dap_chain_tx_out_ext_t*)item)->addr))); + json_object_object_add(json_obj_item,"token", json_object_new_string(((dap_chain_tx_out_ext_t*)item)->token)); + json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str)); + + } break; + case TX_ITEM_TYPE_VOTING:{ + size_t l_tsd_size = 0; + dap_chain_tx_tsd_t *l_item = (dap_chain_tx_tsd_t *)dap_chain_datum_tx_item_get(a_tx, NULL, (byte_t*)item + l_size, TX_ITEM_TYPE_TSD, &l_tsd_size); + if (!l_item || !l_tsd_size) + break; + dap_chain_datum_tx_voting_params_t *l_voting_params = dap_chain_voting_parse_tsd(a_tx); + json_object_object_add(json_obj_item,"type", json_object_new_string("voting")); + json_object_object_add(json_obj_item,"voting_question", json_object_new_string(l_voting_params->voting_question)); + json_object_object_add(json_obj_item,"answer_options", json_object_new_string("")); + + dap_list_t *l_temp = l_voting_params->answers_list; + uint8_t l_index = 0; + while (l_temp) { + json_object_object_add(json_obj_item, dap_itoa(l_index), json_object_new_string((char *)l_temp->data)); + l_index++; + l_temp = l_temp->next; + } + if (l_voting_params->voting_expire) { + dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_voting_params->voting_expire); + json_object_object_add(json_obj_item,"Voting expire", json_object_new_string(l_tmp_buf)); + } + if (l_voting_params->votes_max_count) { + json_object_object_add(json_obj_item, "Votes max count", json_object_new_uint64(l_voting_params->votes_max_count)); + } + json_object_object_add(json_obj_item,"Changing vote is", l_voting_params->vote_changing_allowed ? json_object_new_string("available") : + json_object_new_string("not available")); + l_voting_params->delegate_key_required ? + json_object_object_add(json_obj_item,"Delegated key for participating in voting", json_object_new_string("required")): + json_object_object_add(json_obj_item,"Delegated key for participating in voting", json_object_new_string("not required")); + + dap_list_free_full(l_voting_params->answers_list, NULL); + DAP_DELETE(l_voting_params->voting_question); + DAP_DELETE(l_voting_params); + } break; + case TX_ITEM_TYPE_VOTE:{ + dap_chain_tx_vote_t *l_vote_item = (dap_chain_tx_vote_t *)item; + const char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_vote_item->voting_hash); + json_object_object_add(json_obj_item,"type", json_object_new_string("vote")); + json_object_object_add(json_obj_item,"voting_hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_item,"vote_answer_idx", json_object_new_uint64(l_vote_item->answer_idx)); + + } break; + default: + json_object_object_add(json_obj_item,"type", json_object_new_string("This transaction have unknown item type")); + break; + } + json_object_array_add(json_arr_items, json_obj_item); + } + + json_object_object_add(json_obj_out, "items", json_arr_items); + + if(a_out_json) + a_out_json = json_obj_out; + + + return 0; +} diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 663e6e8211..96d0ef2cdc 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -106,6 +106,8 @@ #include "dap_enc.h" #include "dap_notify_srv.h" +#include "dap_chain_net_tx.h" + #define LOG_TAG "chain_node_cli_cmd" int _cmd_mempool_add_ca(dap_chain_net_t *a_net, dap_chain_t *a_chain, dap_cert_t *a_cert, void **a_str_reply); @@ -5995,116 +5997,6 @@ int com_chain_ca_pub( int a_argc, char ** a_argv, void **a_str_reply) } } - -static const char* s_json_get_text(struct json_object *a_json, const char *a_key) -{ - if(!a_json || !a_key) - return NULL; - struct json_object *l_json = json_object_object_get(a_json, a_key); - if(l_json && json_object_is_type(l_json, json_type_string)) { - // Read text - return json_object_get_string(l_json); - } - return NULL; -} - -static bool s_json_get_int64(struct json_object *a_json, const char *a_key, int64_t *a_out) -{ - if(!a_json || !a_key || !a_out) - return false; - struct json_object *l_json = json_object_object_get(a_json, a_key); - if(l_json) { - if(json_object_is_type(l_json, json_type_int)) { - // Read number - *a_out = json_object_get_int64(l_json); - return true; - } - } - return false; -} - -static bool s_json_get_unit(struct json_object *a_json, const char *a_key, dap_chain_net_srv_price_unit_uid_t *a_out) -{ - const char *l_unit_str = s_json_get_text(a_json, a_key); - if(!l_unit_str || !a_out) - return false; - dap_chain_net_srv_price_unit_uid_t l_unit = dap_chain_net_srv_price_unit_uid_from_str(l_unit_str); - if(l_unit.enm == SERV_UNIT_UNDEFINED) - return false; - a_out->enm = l_unit.enm; - return true; -} - -static bool s_json_get_uint256(struct json_object *a_json, const char *a_key, uint256_t *a_out) -{ - const char *l_uint256_str = s_json_get_text(a_json, a_key); - if(!a_out || !l_uint256_str) - return false; - uint256_t l_value = dap_chain_balance_scan(l_uint256_str); - if(!IS_ZERO_256(l_value)) { - memcpy(a_out, &l_value, sizeof(uint256_t)); - return true; - } - return false; -} - -// service names: srv_stake, srv_vpn, srv_xchange -static bool s_json_get_srv_uid(struct json_object *a_json, const char *a_key_service_id, const char *a_key_service, uint64_t *a_out) -{ - uint64_t l_srv_id; - if(!a_out) - return false; - // Read service id - if(s_json_get_int64(a_json, a_key_service_id, (int64_t*) &l_srv_id)) { - *a_out = l_srv_id; - return true; - } - else { - // Read service as name - const char *l_service = s_json_get_text(a_json, a_key_service); - if(l_service) { - dap_chain_net_srv_t *l_srv = dap_chain_net_srv_get_by_name(l_service); - if(!l_srv) - return false; - *a_out = l_srv->uid.uint64; - return true; - } - } - return false; -} - -static dap_chain_wallet_t* s_json_get_wallet(struct json_object *a_json, const char *a_key) -{ - return dap_chain_wallet_open(s_json_get_text(a_json, a_key), dap_chain_wallet_get_path(g_config), NULL); -} - -static const dap_cert_t* s_json_get_cert(struct json_object *a_json, const char *a_key) -{ - return dap_cert_find_by_name(s_json_get_text(a_json, a_key)); -} - -// Read pkey from wallet or cert -static dap_pkey_t* s_json_get_pkey(struct json_object *a_json) -{ - dap_pkey_t *l_pub_key = NULL; - // From wallet - dap_chain_wallet_t *l_wallet = s_json_get_wallet(a_json, "wallet"); - if(l_wallet) { - l_pub_key = dap_chain_wallet_get_pkey(l_wallet, 0); - dap_chain_wallet_close(l_wallet); - if(l_pub_key) { - return l_pub_key; - } - } - // From cert - const dap_cert_t *l_cert = s_json_get_cert(a_json, "cert"); - if(l_cert) { - l_pub_key = dap_pkey_from_enc_key(l_cert->enc_key); - } - return l_pub_key; -} - - /** * @brief Create transaction from json file * com_tx_create command @@ -6121,9 +6013,6 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) const char *l_chain_name = NULL; // optional parameter const char *l_json_file_path = NULL; const char *l_json_str = NULL; - const char *l_native_token = NULL; - const char *l_main_token = NULL; - bool l_multichanel = false; dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_name); // optional parameter dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-chain", &l_chain_name); // optional parameter @@ -6131,9 +6020,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-json_str", &l_json_str); if(!l_json_file_path && !l_json_str) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON, + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON, "Command requires one of parameters '-json <json file path> or -json_srt <string>'"); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON; + return DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON; } // Open json file @@ -6141,22 +6030,22 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) if (l_json_file_path){ l_json = json_object_from_file(l_json_file_path); if(!l_json) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE, + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE, "Can't open json file: %s", json_util_get_last_err()); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE; + return DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE; } } else if (l_json_str) { l_json = json_tokener_parse(l_json_str); if(!l_json) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE, + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE, "Can't parse input JSON-string", json_util_get_last_err()); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE; + return DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE; } } if(!json_object_is_type(l_json, json_type_object)) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT, "Wrong json format"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_JSON_FORMAT, "Wrong json format"); json_object_put(l_json); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT; + return DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_JSON_FORMAT; } @@ -6167,20 +6056,19 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) l_net_name = json_object_get_string(l_json_net); } if(!l_net_name) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET, + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_NET, "Command requires parameter '-net' or set net in the json file"); json_object_put(l_json); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET; + return DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_NET; } } dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_name); if(!l_net) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME, "Not found net by name '%s'", l_net_name); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME, "Not found net by name '%s'", l_net_name); json_object_put(l_json); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME; + return DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME; } - l_native_token = l_net->pub.native_ticker; - + // Read chain from json file if(!l_chain_name) { struct json_object *l_json_chain = json_object_object_get(l_json, "chain"); @@ -6193,707 +6081,26 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_TX); } if(!l_chain) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME, + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME, "Chain name '%s' not found, try use parameter '-chain' or set chain in the json file", l_chain_name); json_object_put(l_json); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME; - } - - - // Read items from json file - struct json_object *l_json_items = json_object_object_get(l_json, "items"); - size_t l_items_count; - if(!l_json_items || !json_object_is_type(l_json_items, json_type_array) || !(l_items_count = json_object_array_length(l_json_items))) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS, - "Wrong json format: not found array 'items' or array is empty"); - json_object_put(l_json); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS; - } - - log_it(L_ERROR, "Json TX: found %lu items", l_items_count); - // Create transaction - dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); - if(!l_tx) { - json_object_put(l_json); - dap_json_rpc_allocation_error(*a_json_arr_reply); - return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; - } - - struct json_object *l_json_timestamp = json_object_object_get(l_json, "ts_created"); - if (l_json_timestamp) - l_tx->header.ts_created = json_object_get_int64(l_json_timestamp); - else - l_tx->header.ts_created = time(NULL); - - size_t l_items_ready = 0; - dap_list_t *l_sign_list = NULL;// list 'sing' items - dap_list_t *l_in_list = NULL;// list 'in' items - uint256_t l_value_need = { };// how many tokens are needed in the 'out' item - uint256_t l_value_need_fee = {}; - json_object *l_jobj_errors = json_object_new_array(); - // First iteration in input file. Check the tx will be multichannel or not - for(size_t i = 0; i < l_items_count; ++i) { - struct json_object *l_json_item_obj = json_object_array_get_idx(l_json_items, i); - if(!l_json_item_obj || !json_object_is_type(l_json_item_obj, json_type_object)) { - continue; - } - struct json_object *l_json_item_type = json_object_object_get(l_json_item_obj, "type"); - if(!l_json_item_type && json_object_is_type(l_json_item_type, json_type_string)) { - log_it(L_WARNING, "Item %zu without type", i); - continue; - } - const char *l_item_type_str = json_object_get_string(l_json_item_type); - dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_str_to_type(l_item_type_str); - if(l_item_type == TX_ITEM_TYPE_UNKNOWN) { - log_it(L_WARNING, "Item %zu has invalid type '%s'", i, l_item_type_str); - continue; - } - - switch (l_item_type) { - case TX_ITEM_TYPE_IN: { - const char *l_json_item_token = s_json_get_text(l_json_item_obj, "token"); - if (l_json_item_token && dap_strcmp(l_json_item_token, l_native_token)){ - l_multichanel = true; - l_main_token = l_json_item_token; - } - }break; - default: continue; - } - if(l_multichanel) - break; - } - - // Creating and adding items to the transaction - for(size_t i = 0; i < l_items_count; ++i) { - struct json_object *l_json_item_obj = json_object_array_get_idx(l_json_items, i); - if(!l_json_item_obj || !json_object_is_type(l_json_item_obj, json_type_object)) { - continue; - } - struct json_object *l_json_item_type = json_object_object_get(l_json_item_obj, "type"); - if(!l_json_item_type && json_object_is_type(l_json_item_type, json_type_string)) { - log_it(L_WARNING, "Item %zu without type", i); - continue; - } - const char *l_item_type_str = json_object_get_string(l_json_item_type); - dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_str_to_type(l_item_type_str); - if(l_item_type == TX_ITEM_TYPE_UNKNOWN) { - log_it(L_WARNING, "Item %zu has invalid type '%s'", i, l_item_type_str); - continue; - } - - log_it(L_DEBUG, "Json TX: process item %s", json_object_get_string(l_json_item_type)); - // Create an item depending on its type - const uint8_t *l_item = NULL; - switch (l_item_type) { - case TX_ITEM_TYPE_IN: { - // Save item obj for in - // Read prev_hash and out_prev_idx - const char *l_prev_hash_str = s_json_get_text(l_json_item_obj, "prev_hash"); - int64_t l_out_prev_idx; - bool l_is_out_prev_idx = s_json_get_int64(l_json_item_obj, "out_prev_idx", &l_out_prev_idx); - // If prev_hash and out_prev_idx were read - if(l_prev_hash_str && l_is_out_prev_idx) { - dap_chain_hash_fast_t l_tx_prev_hash; - if(!dap_chain_hash_fast_from_str(l_prev_hash_str, &l_tx_prev_hash)) { - // Create IN item - dap_chain_tx_in_t *l_in_item = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, (uint32_t) l_out_prev_idx); - if (!l_in_item) { - json_object *l_jobj_err = json_object_new_string("Unable to create in for transaction."); - json_object_array_add(l_jobj_errors, l_jobj_err); - } - l_item = (const uint8_t*) l_in_item; - } else { - log_it(L_WARNING, "Invalid 'in' item, bad prev_hash %s", l_prev_hash_str); - char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, " - "bad prev_hash %s", l_prev_hash_str); - json_object *l_jobj_err = json_object_new_string(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - } - } - // Read addr_from - else { - l_in_list = dap_list_append(l_in_list, l_json_item_obj); - } - } - break; - - case TX_ITEM_TYPE_OUT: - case TX_ITEM_TYPE_OUT_EXT: { - // Read address and value - uint256_t l_value = { }; - const char *l_json_item_addr_str = s_json_get_text(l_json_item_obj, "addr"); - bool l_is_value = s_json_get_uint256(l_json_item_obj, "value", &l_value); - const char *l_token = s_json_get_text(l_json_item_obj, "token"); - if(l_is_value && l_json_item_addr_str) { - dap_chain_addr_t *l_addr = dap_chain_addr_from_str(l_json_item_addr_str); - if(l_addr && !IS_ZERO_256(l_value)) { - if(l_item_type == TX_ITEM_TYPE_OUT) { - // Create OUT item - const uint8_t *l_out_item = NULL; - if(l_multichanel) - l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token ? l_token : (l_main_token ? l_main_token : l_native_token)); - else - l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_create(l_addr, l_value); - if (!l_out_item) { - json_object *l_jobj_err = json_object_new_string("Failed to create transaction out. " - "There may not be enough funds in the wallet."); - json_object_array_add(l_jobj_errors, l_jobj_err); - } - l_item = (const uint8_t*) l_out_item; - if (l_item){ - if (l_multichanel && !dap_strcmp(((dap_chain_tx_out_ext_t*)l_out_item)->token, l_native_token)) - SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee); - else - SUM_256_256(l_value_need, l_value, &l_value_need); - } - - } else if(l_item_type == TX_ITEM_TYPE_OUT_EXT) { - // Read address and value - if(l_token) { - // Create OUT_EXT item - const uint8_t *l_out_item = NULL; - if(l_multichanel) - l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token); - else - l_out_item = (const uint8_t *)dap_chain_datum_tx_item_out_create(l_addr, l_value); - if (!l_out_item) { - json_object *l_jobj_err = json_object_new_string("Failed to create a out ext" - "for a transaction. There may not be enough funds " - "on the wallet or the wrong ticker token " - "is indicated."); - json_object_array_add(l_jobj_errors, l_jobj_err); - } - l_item = (const uint8_t*) l_out_item; - if (l_item){ - if (l_multichanel && !dap_strcmp(l_token, l_native_token)) - SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee); - else - SUM_256_256(l_value_need, l_value, &l_value_need); - } - } - else { - log_it(L_WARNING, "Invalid 'out_ext' item %zu", i); - continue; - } - } - } else { - if(l_item_type == TX_ITEM_TYPE_OUT) { - log_it(L_WARNING, "Invalid 'out' item %zu", i); - } - else if(l_item_type == TX_ITEM_TYPE_OUT_EXT) { - log_it(L_WARNING, "Invalid 'out_ext' item %zu", i); - } - char *l_str_err = dap_strdup_printf("For item %zu of type 'out' or 'out_ext' the " - "string representation of the address could not be converted, " - "or the size of the output sum is 0.", i); - json_object *l_jobj_err = json_object_new_string(l_str_err); - DAP_DELETE(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - continue; - } - } - } - break; - case TX_ITEM_TYPE_OUT_COND: { - // Read subtype of item - const char *l_subtype_str = s_json_get_text(l_json_item_obj, "subtype"); - dap_chain_tx_out_cond_subtype_t l_subtype = dap_chain_tx_out_cond_subtype_from_str(l_subtype_str); - switch (l_subtype) { - - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY:{ - uint256_t l_value = { }; - bool l_is_value = s_json_get_uint256(l_json_item_obj, "value", &l_value); - if(!l_is_value || IS_ZERO_256(l_value)) { - log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_PAY"); - break; - } - uint256_t l_value_max_per_unit = { }; - l_is_value = s_json_get_uint256(l_json_item_obj, "value_max_per_unit", &l_value_max_per_unit); - if(!l_is_value || IS_ZERO_256(l_value_max_per_unit)) { - log_it(L_ERROR, "Json TX: bad value_max_per_unit in OUT_COND_SUBTYPE_SRV_PAY"); - break; - } - dap_chain_net_srv_price_unit_uid_t l_price_unit; - if(!s_json_get_unit(l_json_item_obj, "price_unit", &l_price_unit)) { - log_it(L_ERROR, "Json TX: bad price_unit in OUT_COND_SUBTYPE_SRV_PAY"); - break; - } - dap_chain_net_srv_uid_t l_srv_uid; - if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)){ - // Default service DAP_CHAIN_NET_SRV_VPN_ID - l_srv_uid.uint64 = 0x0000000000000001; - } - - // From "wallet" or "cert" - dap_pkey_t *l_pkey = s_json_get_pkey(l_json_item_obj); - if(!l_pkey) { - log_it(L_ERROR, "Json TX: bad pkey in OUT_COND_SUBTYPE_SRV_PAY"); - break; - } - const char *l_params_str = s_json_get_text(l_json_item_obj, "params"); - size_t l_params_size = dap_strlen(l_params_str); - dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_pay(l_pkey, l_srv_uid, l_value, l_value_max_per_unit, - l_price_unit, l_params_str, l_params_size); - l_item = (const uint8_t*) l_out_cond_item; - // Save value for using in In item - if(l_item) { - SUM_256_256(l_value_need, l_value, &l_value_need); - } else { - char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " - "can of type %s described in item %zu.\n", l_subtype_str, i); - json_object *l_jobj_err = json_object_new_string(l_str_err); - DAP_DELETE(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - } - DAP_DELETE(l_pkey); - } - break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { - - dap_chain_net_srv_uid_t l_srv_uid; - if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { - // Default service DAP_CHAIN_NET_SRV_XCHANGE_ID - l_srv_uid.uint64 = 0x2; - } - dap_chain_net_t *l_net = dap_chain_net_by_name(s_json_get_text(l_json_item_obj, "net")); - if(!l_net) { - log_it(L_ERROR, "Json TX: bad net in OUT_COND_SUBTYPE_SRV_XCHANGE"); - break; - } - const char *l_token = s_json_get_text(l_json_item_obj, "token"); - if(!l_token) { - log_it(L_ERROR, "Json TX: bad token in OUT_COND_SUBTYPE_SRV_XCHANGE"); - break; - } - uint256_t l_value = { }; - if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) { - log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_XCHANGE"); - break; - } - //const char *l_params_str = s_json_get_text(l_json_item_obj, "params"); - //size_t l_params_size = dap_strlen(l_params_str); - dap_chain_tx_out_cond_t *l_out_cond_item = NULL; //dap_chain_datum_tx_item_out_cond_create_srv_xchange(l_srv_uid, l_net->pub.id, l_token, l_value, l_params_str, l_params_size); - l_item = (const uint8_t*) l_out_cond_item; - // Save value for using in In item - if(l_item) { - SUM_256_256(l_value_need, l_value, &l_value_need); - } else { - char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " - "can of type %s described in item %zu.", l_subtype_str, i); - json_object *l_jobj_err = json_object_new_string(l_str_err); - DAP_DELETE(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - } - } - break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE:{ - dap_chain_net_srv_uid_t l_srv_uid; - if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { - // Default service DAP_CHAIN_NET_SRV_STAKE_ID - l_srv_uid.uint64 = 0x13; - } - uint256_t l_value = { }; - if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) { - log_it(L_ERROR, "Json TX: bad value in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); - break; - } - uint256_t l_fee_value = { }; - if(!s_json_get_uint256(l_json_item_obj, "fee", &l_fee_value) || IS_ZERO_256(l_fee_value)) { - break; - } - - const char *l_signing_addr_str = s_json_get_text(l_json_item_obj, "signing_addr"); - dap_chain_addr_t *l_signing_addr = dap_chain_addr_from_str(l_signing_addr_str); - if(!l_signing_addr) { - { - log_it(L_ERROR, "Json TX: bad signing_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); - break; - } - dap_chain_node_addr_t l_signer_node_addr; - const char *l_node_addr_str = s_json_get_text(l_json_item_obj, "node_addr"); - if(!l_node_addr_str || dap_chain_node_addr_from_str(&l_signer_node_addr, l_node_addr_str)) { - log_it(L_ERROR, "Json TX: bad node_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); - break; - } - dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_srv_uid, l_value, l_signing_addr, - &l_signer_node_addr, NULL, uint256_0); - l_item = (const uint8_t*) l_out_cond_item; - // Save value for using in In item - if(l_item) { - SUM_256_256(l_value_need, l_value, &l_value_need); - } else { - char *l_err_str = dap_strdup_printf("Unable to create conditional out for transaction " - "can of type %s described in item %zu.", l_subtype_str, i); - json_object *l_jobj_err = json_object_new_string(l_err_str); - DAP_DELETE(l_err_str); - json_object_array_add(l_jobj_errors, l_jobj_err); - } - } - } - break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: { - uint256_t l_value = { }; - s_json_get_uint256(l_json_item_obj, "value", &l_value); - if(!IS_ZERO_256(l_value)) { - dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_fee(l_value); - l_item = (const uint8_t*) l_out_cond_item; - // Save value for using in In item - if(l_item) { - SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee); - } else { - char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " - "can of type %s described in item %zu.", l_subtype_str, i); - json_object *l_jobj_err = json_object_new_string(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - DAP_DELETE(l_str_err); - } - } - else - log_it(L_ERROR, "Json TX: zero value in OUT_COND_SUBTYPE_FEE"); - } - break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED: - log_it(L_WARNING, "Undefined subtype: '%s' of 'out_cond' item %zu ", l_subtype_str, i); - char *l_str_err = dap_strdup_printf("Specified unknown sub type %s of conditional out on item %zu.", - l_subtype_str, i); - json_object *l_jobj_err = json_object_new_string(l_str_err); - DAP_DELETE(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - break; - } - } - break; - case TX_ITEM_TYPE_SIG:{ - const char *l_sign_type_str = s_json_get_text(l_json_item_obj, "sig_type"); - if (l_sign_type_str) { - dap_sign_type_t l_sign_type = dap_sign_type_from_str(l_sign_type_str); - if (l_sign_type.type == SIG_TYPE_NULL) { - json_object *l_jobj_err = json_object_new_string("Can't define sign type"); - json_object_array_add(l_jobj_errors, l_jobj_err); - log_it(L_ERROR, "Json TX: Can't define sign type \"%s\"", l_sign_type_str); - break; - } - int64_t l_pkey_size, l_sig_size, l_hash_type = 0; - - s_json_get_int64(l_json_item_obj, "hash_type", &l_hash_type); - s_json_get_int64(l_json_item_obj, "pub_key_size", &l_pkey_size); - s_json_get_int64(l_json_item_obj, "sig_size", &l_sig_size); - debug_if(!l_pkey_size || !l_sig_size, L_WARNING, - "\"pub_key_size\" or \"sig_size\" not provided! Will be calculated automatically"); - - json_object *l_jobj_pub_key = json_object_object_get(l_json_item_obj, "pub_key_b64"), - *l_jobj_sign = json_object_object_get(l_json_item_obj, "sig_b64"); - if (!l_jobj_pub_key || !l_jobj_sign) { - json_object *l_jobj_err = json_object_new_string("Can't get base64-encoded sign or pkey!"); - json_object_array_add(l_jobj_errors, l_jobj_err); - log_it(L_ERROR, "Json TX: Can't get base64-encoded sign or pkey!"); - break; - } - const char *l_pub_key_str = json_object_get_string(l_jobj_pub_key), - *l_sign_str = json_object_get_string(l_jobj_sign); - int64_t l_pkey_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(strlen(l_pub_key_str)), - l_sign_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(strlen(l_sign_str)); - - dap_sign_t *l_sign = DAP_NEW_SIZE(dap_sign_t, sizeof(dap_sign_t) + l_pkey_decoded_size + l_sign_decoded_size); - *l_sign = (dap_sign_t) { - .header.type = l_sign_type, - .header.hash_type = (uint8_t)l_hash_type, - }; - l_pkey_decoded_size = dap_enc_base64_decode(l_pub_key_str, strlen(l_pub_key_str), - l_sign->pkey_n_sign, DAP_ENC_DATA_TYPE_B64_URLSAFE); - debug_if(l_pkey_size != l_pkey_decoded_size, L_ERROR, "Json TX: pkey size mismatch, %zu != %zu", - l_pkey_size, l_pkey_decoded_size); - - l_sign_decoded_size = dap_enc_base64_decode(l_sign_str, strlen(l_sign_str), - l_sign->pkey_n_sign + l_pkey_decoded_size, DAP_ENC_DATA_TYPE_B64_URLSAFE); - debug_if(l_sig_size != l_sign_decoded_size, L_ERROR, "Json TX: sign size mismatch, %zu != %zu", - l_sig_size, l_sign_decoded_size); - - l_sign->header.sign_size = l_sign_decoded_size; - l_sign->header.sign_pkey_size = l_pkey_decoded_size; - size_t l_sign_full_size = dap_sign_get_size(l_sign); - - dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t, sizeof(dap_chain_tx_sig_t) + l_sign_full_size); - l_tx_sig->header.type = TX_ITEM_TYPE_SIG; - l_tx_sig->header.sig_size = (uint32_t)l_sign_full_size; - memcpy(l_tx_sig->sig, l_sign, l_sign_full_size); - l_item = (const uint8_t*)l_tx_sig; - DAP_DELETE(l_sign); - break; - } else - l_sign_list = dap_list_append(l_sign_list,l_json_item_obj); - } - break; - case TX_ITEM_TYPE_RECEIPT: { - dap_chain_net_srv_uid_t l_srv_uid; - if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { - log_it(L_ERROR, "Json TX: bad service_id in TYPE_RECEIPT"); - break; - } - dap_chain_net_srv_price_unit_uid_t l_price_unit; - if(!s_json_get_unit(l_json_item_obj, "price_unit", &l_price_unit)) { - log_it(L_ERROR, "Json TX: bad price_unit in TYPE_RECEIPT"); - break; - } - int64_t l_units; - if(!s_json_get_int64(l_json_item_obj, "units", &l_units)) { - log_it(L_ERROR, "Json TX: bad units in TYPE_RECEIPT"); - break; - } - uint256_t l_value = { }; - if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) { - log_it(L_ERROR, "Json TX: bad value in TYPE_RECEIPT"); - break; - } - const char *l_params_str = s_json_get_text(l_json_item_obj, "params"); - size_t l_params_size = dap_strlen(l_params_str); - dap_chain_datum_tx_receipt_t *l_receipt = dap_chain_datum_tx_receipt_create(l_srv_uid, l_price_unit, l_units, l_value, l_params_str, l_params_size); - l_item = (const uint8_t*) l_receipt; - if (!l_item) { - char *l_str_err = dap_strdup_printf("Unable to create receipt out for transaction " - "described by item %zu.", i); - json_object *l_jobj_err = json_object_new_string(l_str_err); - DAP_DELETE(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - } - } - break; - case TX_ITEM_TYPE_TSD: { - int64_t l_tsd_type; - if(!s_json_get_int64(l_json_item_obj, "type_tsd", &l_tsd_type)) { - log_it(L_ERROR, "Json TX: bad type_tsd in TYPE_TSD"); - break; - } - const char *l_tsd_data = s_json_get_text(l_json_item_obj, "data"); - if (!l_tsd_data) { - log_it(L_ERROR, "Json TX: bad data in TYPE_TSD"); - break; - } - size_t l_data_size = dap_strlen(l_tsd_data); - dap_chain_tx_tsd_t *l_tsd = dap_chain_datum_tx_item_tsd_create((void*)l_tsd_data, (int)l_tsd_type, l_data_size); - l_item = (const uint8_t*) l_tsd; - // l_tsd_list = dap_list_append(l_tsd_list, l_tsd); - } - break; - //case TX_ITEM_TYPE_PKEY: - //break; - //case TX_ITEM_TYPE_IN_EMS: - //break; - //case TX_ITEM_TYPE_IN_EMS_EXT: - //break; - } - // Add item to transaction - if(l_item) { - dap_chain_datum_tx_add_item(&l_tx, (const uint8_t*) l_item); - l_items_ready++; - DAP_DELETE(l_item); - } + return DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME; } - dap_list_t *l_list; - // Add In items - l_list = l_in_list; - while(l_list) { - struct json_object *l_json_item_obj = (struct json_object*) l_list->data; - - const char *l_json_item_addr_str = s_json_get_text(l_json_item_obj, "addr_from"); - const char *l_json_item_token = s_json_get_text(l_json_item_obj, "token"); - l_main_token = l_json_item_token; - dap_chain_addr_t *l_addr_from = NULL; - if(l_json_item_addr_str) { - l_addr_from = dap_chain_addr_from_str(l_json_item_addr_str); - if (!l_addr_from) { - log_it(L_WARNING, "Invalid element 'in', unable to convert string representation of addr_from: '%s' " - "to binary.", l_json_item_addr_str); - char *l_str_err = dap_strdup_printf("Invalid element 'to', unable to convert string representation " - "of addr_from: '%s' to binary.", l_json_item_addr_str); - json_object *l_jobj_err = json_object_new_string(l_str_err); - DAP_DELETE(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - // Go to the next item - l_list = dap_list_next(l_list); - continue; - } - } - else { - log_it(L_WARNING, "Invalid 'in' item, incorrect addr_from: '%s'", l_json_item_addr_str ? l_json_item_addr_str : "[null]"); - char *l_str_err = dap_strdup_printf("Invalid 'in' item, incorrect addr_from: '%s'", - l_json_item_addr_str ? l_json_item_addr_str : "[null]"); - json_object *l_jobj_err = json_object_new_string(l_str_err); - DAP_DELETE(l_str_err); - json_object_array_add(l_jobj_errors, l_jobj_err); - // Go to the next item - l_list = dap_list_next(l_list); - continue; - } - if(!l_json_item_token) { - log_it(L_WARNING, "Invalid 'in' item, not found token name"); - json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found token name"); - json_object_array_add(l_jobj_errors, l_jobj_err); - // Go to the next item - l_list = dap_list_next(l_list); - continue; - } - if(IS_ZERO_256(l_value_need)) { - log_it(L_WARNING, "Invalid 'in' item, not found value in out items"); - json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found value in out items"); - json_object_array_add(l_jobj_errors, l_jobj_err); - // Go to the next item - l_list = dap_list_next(l_list); - continue; - } - if(l_addr_from) - { - // find the transactions from which to take away coins - dap_list_t *l_list_used_out = NULL; - dap_list_t *l_list_used_out_fee = NULL; - uint256_t l_value_transfer = { }; // how many coins to transfer - uint256_t l_value_transfer_fee = { }; // how many coins to transfer - //SUM_256_256(a_value, a_value_fee, &l_value_need); - uint256_t l_value_need_check = {}; - if (!dap_strcmp(l_native_token, l_main_token)) { - SUM_256_256(l_value_need_check, l_value_need, &l_value_need_check); - SUM_256_256(l_value_need_check, l_value_need_fee, &l_value_need_check); - l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token, - l_addr_from, l_value_need_check, &l_value_transfer); - if(!l_list_used_out) { - log_it(L_WARNING, "Not enough funds in previous tx to transfer"); - json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds in previous tx " - "to transfer"); - json_object_array_add(l_jobj_errors, l_jobj_err); - // Go to the next item - l_list = dap_list_next(l_list); - continue; - } - } else { - //CHECK value need - l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_json_item_token, - l_addr_from, l_value_need, &l_value_transfer); - if(!l_list_used_out) { - log_it(L_WARNING, "Not enough funds in previous tx to transfer"); - json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds " - "in previous tx to transfer"); - json_object_array_add(l_jobj_errors, l_jobj_err); - // Go to the next item - l_list = dap_list_next(l_list); - continue; - } - //CHECK value fee - l_list_used_out_fee = dap_ledger_get_list_tx_outs_with_val(l_net->pub.ledger, l_native_token, - l_addr_from, l_value_need_fee, &l_value_transfer_fee); - if(!l_list_used_out_fee) { - log_it(L_WARNING, "Not enough funds in previous tx to transfer"); - json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds " - "in previous tx to transfer"); - json_object_array_add(l_jobj_errors, l_jobj_err); - // Go to the next item - l_list = dap_list_next(l_list); - continue; - } - } - // add 'in' items - uint256_t l_value_got = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out); - assert(EQUAL_256(l_value_got, l_value_transfer)); - if (l_list_used_out_fee) { - uint256_t l_value_got_fee = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out_fee); - assert(EQUAL_256(l_value_got_fee, l_value_transfer_fee)); - dap_list_free_full(l_list_used_out_fee, free); - // add 'out' item for coin fee back - uint256_t l_value_back; - SUBTRACT_256_256(l_value_got_fee, l_value_need_fee, &l_value_back); - if (!IS_ZERO_256(l_value_back)) { - dap_chain_datum_tx_add_out_ext_item(&l_tx, l_addr_from, l_value_back, l_native_token); - l_items_ready++; - } - } else { - SUM_256_256(l_value_need, l_value_need_fee, &l_value_need); - } - dap_list_free_full(l_list_used_out, free); - if(!IS_ZERO_256(l_value_got)) { - // add 'out' item for coin back - uint256_t l_value_back; - SUBTRACT_256_256(l_value_got, l_value_need, &l_value_back); - if(!IS_ZERO_256(l_value_back)) { - if (l_multichanel) - dap_chain_datum_tx_add_out_ext_item(&l_tx, l_addr_from, l_value_back, l_main_token); - else - dap_chain_datum_tx_add_out_item(&l_tx, l_addr_from, l_value_back); - l_items_ready++; - } - } - } - // Go to the next 'in' item - l_list = dap_list_next(l_list); - } - dap_list_free(l_in_list); - - // Add signs - l_list = l_sign_list; - while(l_list) { - - struct json_object *l_json_item_obj = (struct json_object*) l_list->data; - - dap_enc_key_t * l_enc_key = NULL; - - //get wallet or cert - dap_chain_wallet_t *l_wallet = s_json_get_wallet(l_json_item_obj, "wallet"); - const dap_cert_t *l_cert = s_json_get_cert(l_json_item_obj, "cert"); - - int64_t l_pkey_size; - int64_t l_sig_size; - uint8_t *l_pkey = NULL; - int64_t l_hash_type = 0; - dap_sign_t *l_sign = NULL; - - - //wallet goes first - if (l_wallet) { - l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); - } else if (l_cert && l_cert->enc_key) { - l_enc_key = l_cert->enc_key; - } else { - json_object *l_jobj_err = json_object_new_string("Can't create sign for transactions."); - json_object_array_add(l_jobj_errors, l_jobj_err); - log_it(L_ERROR, "Json TX: Item sign has no wallet or cert of they are invalid "); - l_list = dap_list_next(l_list); - continue; - } - - if (l_sign) { - size_t l_chain_sign_size = dap_sign_get_size(l_sign); // sign data - - dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t, - sizeof(dap_chain_tx_sig_t) + l_chain_sign_size); - l_tx_sig->header.type = TX_ITEM_TYPE_SIG; - l_tx_sig->header.sig_size =(uint32_t) l_chain_sign_size; - memcpy(l_tx_sig->sig, l_sign, l_chain_sign_size); - dap_chain_datum_tx_add_item(&l_tx, l_tx_sig); - DAP_DELETE(l_sign); - } - - if(l_enc_key && dap_chain_datum_tx_add_sign_item(&l_tx, l_enc_key) > 0) { - l_items_ready++; - } else { - log_it(L_ERROR, "Json TX: Item sign has invalid enc_key."); - l_list = dap_list_next(l_list); - continue; - } - - if (l_wallet) { - dap_chain_wallet_close(l_wallet); - dap_enc_key_delete(l_enc_key); - } - - - l_list = dap_list_next(l_list); + json_object *l_jobj_errors = json_object_new_array(); + size_t l_items_ready = 0, l_items_count = 0; + dap_chain_datum_tx_t *l_tx = NULL; + int l_ret = 0; + if((l_ret = dap_chain_net_tx_create_by_json(l_json, l_net, l_jobj_errors, &l_tx, &l_items_count, &l_items_ready, a_json_arr_reply)) != DAP_CHAIN_NET_TX_CREATE_JSON_OK) { + dap_json_rpc_error_add(*a_json_arr_reply, l_ret, + "Can't create transaction from json file"); + json_object_put(l_json); + return l_ret; } - dap_list_free(l_sign_list); - json_object_put(l_json); - json_object *l_jobj_ret = json_object_new_object(); - if(l_items_ready<l_items_count) { + if(l_items_ready < l_items_count) { json_object *l_tx_create = json_object_new_boolean(false); json_object *l_jobj_valid_items = json_object_new_uint64(l_items_ready); json_object *l_jobj_total_items = json_object_new_uint64(l_items_count); @@ -6903,7 +6110,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) json_object_object_add(l_jobj_ret, "errors", l_jobj_errors); json_object_array_add(*a_json_arr_reply, l_jobj_ret); DAP_DELETE(l_tx); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS; + return DAP_CHAIN_NET_TX_CREATE_JSON_INVALID_ITEMS; } json_object_put(l_jobj_errors); @@ -6920,9 +6127,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) DAP_DEL_Z(l_datum_tx); DAP_DELETE(l_gdb_group_mempool_base_tx); if(!l_placed) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL, + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL, "Can't add transaction to mempool"); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL; + return DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL; } // Completed successfully json_object *l_jobj_tx_create = json_object_new_boolean(true); @@ -6932,7 +6139,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) json_object_object_add(l_jobj_ret, "hash", l_jobj_hash); json_object_object_add(l_jobj_ret, "total_items", l_jobj_total_items); json_object_array_add(*a_json_arr_reply, l_jobj_ret); - return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK; + return DAP_CHAIN_NET_TX_CREATE_JSON_OK; } /** diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h index b06d35012f..b6e33b42e5 100644 --- a/modules/net/include/dap_chain_net_tx.h +++ b/modules/net/include/dap_chain_net_tx.h @@ -25,7 +25,21 @@ #include "dap_chain_net.h" #include "dap_chain_datum_tx_items.h" - +#include "dap_json_rpc_errors.h" + +typedef enum s_com_tx_create_json_err { + DAP_CHAIN_NET_TX_CREATE_JSON_OK = 0, + DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE, + DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_JSON_FORMAT, + DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_NET, + DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME, + DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME, + DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS, + DAP_CHAIN_NET_TX_CREATE_JSON_INVALID_ITEMS, + DAP_CHAIN_NET_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL, + DAP_CHAIN_NET_TX_CREATE_JSON_WRONG_ARGUMENTS, +}s_com_tx_create_json_err_t; typedef enum dap_chain_net_tx_search_type { /// Search local, in memory, possible load data from drive to memory TX_SEARCH_TYPE_LOCAL, @@ -91,3 +105,17 @@ void dap_chain_datum_tx_spends_items_free(dap_chain_datum_tx_spends_items_t * a_ bool dap_chain_net_tx_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_value, dap_chain_addr_t *a_addr); bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, dap_chain_addr_t a_addr); + +/** + * @brief Compose transaction from json. If a_net is NULL it means offline tx creation and + * tx will be created from json as is without any checks and conversions. + * @param a_tx_json input json + * @param a_net network. If NULL it means offline tx creation + * @param a_out_tx output transaction + * @param a_items_count count of items in transaction + */ +int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_net, json_object *a_json_obj_error, + dap_chain_datum_tx_t** a_out_tx, size_t* a_items_count, size_t *a_items_ready, void **a_json_arr_reply); + + +int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json); \ No newline at end of file diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index 5304912bad..93572f9e91 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -211,18 +211,7 @@ typedef enum s_com_tx_create_err{ DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS }s_com_tx_create_err_t; int com_tx_create(int a_argc, char **a_argv, void **a_str_reply); -typedef enum s_com_tx_create_json_err { - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK = 0, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS, - DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL -}s_com_tx_create_json_err_t; + int com_tx_create_json(int a_argc, char **a_argv, void **reply); typedef enum s_com_tx_cond_create{ DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_OK = 0, -- GitLab From 1707120ce734c1b4dc0c4c4248e1a26516b6aebc Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Sun, 12 Jan 2025 13:39:51 +0300 Subject: [PATCH 02/18] [*] Fix functions docs --- modules/net/dap_chain_net_tx.c | 5 +---- modules/net/dap_chain_node_cli_cmd.c | 2 +- modules/net/include/dap_chain_net_tx.h | 18 ++++++++++++++---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index 5dd03126af..c0ec91461d 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -654,7 +654,7 @@ static dap_pkey_t* s_json_get_pkey(struct json_object *a_json) } int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_net, json_object *a_json_obj_error, - dap_chain_datum_tx_t** a_out_tx, size_t* a_items_count, size_t *a_items_ready, void **a_json_arr_reply) + dap_chain_datum_tx_t** a_out_tx, size_t* a_items_count, size_t *a_items_ready) { json_object *l_json = a_tx_json; @@ -677,8 +677,6 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n struct json_object *l_json_items = json_object_object_get(l_json, "items"); size_t l_items_count; if(!l_json_items || !json_object_is_type(l_json_items, json_type_array) || !(l_items_count = json_object_array_length(l_json_items))) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS, - "Wrong json format: not found array 'items' or array is empty"); json_object_put(l_json); return DAP_CHAIN_NET_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS; } @@ -688,7 +686,6 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); if(!l_tx) { json_object_put(l_json); - dap_json_rpc_allocation_error(*a_json_arr_reply); return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; } diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 96d0ef2cdc..0c2000a7db 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -6091,7 +6091,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) size_t l_items_ready = 0, l_items_count = 0; dap_chain_datum_tx_t *l_tx = NULL; int l_ret = 0; - if((l_ret = dap_chain_net_tx_create_by_json(l_json, l_net, l_jobj_errors, &l_tx, &l_items_count, &l_items_ready, a_json_arr_reply)) != DAP_CHAIN_NET_TX_CREATE_JSON_OK) { + if((l_ret = dap_chain_net_tx_create_by_json(l_json, l_net, l_jobj_errors, &l_tx, &l_items_count, &l_items_ready)) != DAP_CHAIN_NET_TX_CREATE_JSON_OK) { dap_json_rpc_error_add(*a_json_arr_reply, l_ret, "Can't create transaction from json file"); json_object_put(l_json); diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h index b6e33b42e5..67e594d734 100644 --- a/modules/net/include/dap_chain_net_tx.h +++ b/modules/net/include/dap_chain_net_tx.h @@ -111,11 +111,21 @@ bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, da * tx will be created from json as is without any checks and conversions. * @param a_tx_json input json * @param a_net network. If NULL it means offline tx creation - * @param a_out_tx output transaction - * @param a_items_count count of items in transaction + * @param a_json_obj_error json object for tx items errors messages + * @param a_out_tx pointer to output transaction pointer + * @param a_items_count count of total items in input json transaction + * @param a_items_ready count of valid items in output transaction + * + * @return s_com_tx_create_json_err_t status code */ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_net, json_object *a_json_obj_error, - dap_chain_datum_tx_t** a_out_tx, size_t* a_items_count, size_t *a_items_ready, void **a_json_arr_reply); - + dap_chain_datum_tx_t** a_out_tx, size_t* a_items_count, size_t *a_items_ready); +/** + * @brief Convert binary transaction to json + * @param a_tx input transaction + * @param a_out_json pointer to json object created by json_object_new_object() + * + * @return s_com_tx_create_json_err_t status code + */ int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json); \ No newline at end of file -- GitLab From d731aa9529918f91741a272bacb0ce657b132022 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Tue, 14 Jan 2025 13:01:49 +0300 Subject: [PATCH 03/18] [+] srv_stake_lock out_cond added to dap_chain_net_tx_create_by_json --- dap-sdk | 2 +- modules/net/dap_chain_net_tx.c | 78 ++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/dap-sdk b/dap-sdk index 5931f83c88..e0e6309061 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 5931f83c8894be1f78e4888ef39873fc87aa4df2 +Subproject commit e0e63090610a266c933fa4c2e04898e2c398f9ef diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index c0ec91461d..938819b088 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -977,6 +977,84 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n } } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK:{ + dap_chain_net_srv_uid_t l_srv_uid; + if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { + // Default service DAP_CHAIN_NET_SRV_STAKE_ID + l_srv_uid.uint64 = 0x12; + } + uint256_t l_value = { }; + if(!s_json_get_uint256(l_json_item_obj, "value", &l_value) || IS_ZERO_256(l_value)) { + log_it(L_ERROR, "Json TX: bad value in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"); + break; + } + const char* l_time_staking_str = NULL; + if((l_time_staking_str = s_json_get_text(l_json_item_obj, "time_staking")) == NULL || dap_strlen(l_time_staking_str) != 6) { + log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"); + break; + } + + char l_time_staking_month_str[3] = {l_time_staking_str[2], l_time_staking_str[3], 0}; + int l_time_staking_month = atoi(l_time_staking_month_str); + if (l_time_staking_month < 1 || l_time_staking_month > 12){ + log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"); + break; + } + + + char l_time_staking_day_str[3] = {l_time_staking_str[4], l_time_staking_str[5], 0}; + int l_time_staking_day = atoi(l_time_staking_day_str); + if (l_time_staking_day < 1 || l_time_staking_day > 31){ + log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"); + break; + } + + dap_time_t l_time_staking = 0; + l_time_staking = dap_time_from_str_simplified(l_time_staking_str); + if (0 == l_time_staking){ + log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"); + break; + } + dap_time_t l_time_now = dap_time_now(); + if (l_time_staking < l_time_now){ + log_it(L_ERROR, "Json TX: bad time staking in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"); + break; + } + l_time_staking -= l_time_now; + + uint256_t l_reinvest_percent = uint256_0; + const char* l_reinvest_percent_str = NULL; + if((l_reinvest_percent_str = s_json_get_text(l_json_item_obj, "reinvest_percent"))!=NULL) { + l_reinvest_percent = dap_chain_coins_to_balance(l_reinvest_percent_str); + if (compare256(l_reinvest_percent, dap_chain_coins_to_balance("100.0")) == 1){ + log_it(L_ERROR, "Json TX: bad reinvest percent in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"); + break; + } + if (IS_ZERO_256(l_reinvest_percent)) { + int l_reinvest_percent_int = atoi(l_reinvest_percent_str); + if (l_reinvest_percent_int < 0 || l_reinvest_percent_int > 100){ + log_it(L_ERROR, "Json TX: bad reinvest percent in DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"); + break; + } + l_reinvest_percent = dap_chain_uint256_from(l_reinvest_percent_int); + MULT_256_256(l_reinvest_percent, GET_256_FROM_64(1000000000000000000ULL), &l_reinvest_percent); + } + } + + dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_stake_lock(l_srv_uid, l_value, l_time_staking, l_reinvest_percent); + l_item = (const uint8_t*) l_out_cond_item; + // Save value for using in In item + if(l_item) { + SUM_256_256(l_value_need, l_value, &l_value_need); + } else { + char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " + "can of type %s described in item %zu.", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + } + break; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE:{ dap_chain_net_srv_uid_t l_srv_uid; if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { -- GitLab From 2a2341e3c7bf2d1c4d4fb891f4ce2c97457bb2f9 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Wed, 15 Jan 2025 10:02:26 +0300 Subject: [PATCH 04/18] .. --- dap-sdk | 2 +- modules/net/dap_chain_net_tx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dap-sdk b/dap-sdk index d6b6934683..e0e6309061 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit d6b6934683168160e7d25647ceef59d9439de2c3 +Subproject commit e0e63090610a266c933fa4c2e04898e2c398f9ef diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index 7dd4b97464..bf987657e3 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -537,4 +537,4 @@ bool dap_chain_net_tx_set_fee(dap_chain_net_id_t a_net_id, uint256_t a_value, da l_net->pub.fee_addr = a_addr; return true; -} + } -- GitLab From 7861b3105251df04dc51965d9282f07330234856 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Wed, 15 Jan 2025 12:09:28 +0300 Subject: [PATCH 05/18] [+] Added checking inputs with prev hash in tx_create_json --- modules/net/dap_chain_net_tx.c | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index 938819b088..250b5c0ad1 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -726,8 +726,57 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n if (l_json_item_token && dap_strcmp(l_json_item_token, l_native_token)){ l_multichanel = true; l_main_token = l_json_item_token; + break; + } + const char *l_prev_hash_str = s_json_get_text(l_json_item_obj, "prev_hash"); + int64_t l_out_prev_idx; + bool l_is_out_prev_idx = s_json_get_int64(l_json_item_obj, "out_prev_idx", &l_out_prev_idx); + // If prev_hash and out_prev_idx were read + if(l_prev_hash_str && l_is_out_prev_idx){ + dap_chain_hash_fast_t l_tx_prev_hash = {}; + if(!dap_chain_hash_fast_from_str(l_prev_hash_str, &l_tx_prev_hash)) { + //check out token + dap_chain_datum_tx_t *l_prev_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_tx_prev_hash); + byte_t *l_prev_item = l_prev_tx ? dap_chain_datum_tx_item_get_nth(l_prev_tx, TX_ITEM_TYPE_OUT_ALL, l_out_prev_idx) : NULL; + if (l_prev_item){ + const char* l_token = NULL; + if (*l_prev_item == TX_ITEM_TYPE_OUT){ + l_token = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_tx_prev_hash); + } else if(*l_prev_item == TX_ITEM_TYPE_OUT_EXT){ + l_token = ((dap_chain_tx_out_ext_t*)l_prev_item)->token; + } else { + log_it(L_WARNING, "Invalid 'in' item, wrong type of item with index %"DAP_UINT64_FORMAT_U" in previous tx %s", l_out_prev_idx, l_prev_hash_str); + char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, " + "wrong type of item with index %"DAP_UINT64_FORMAT_U" in previous tx %s", l_out_prev_idx, l_prev_hash_str); + json_object *l_jobj_err = json_object_new_string(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + break; + } + if (dap_strcmp(l_token, l_native_token)){ + l_multichanel = true; + l_main_token = l_json_item_token; + break; + } + + } else { + log_it(L_WARNING, "Invalid 'in' item, can't find item with index %"DAP_UINT64_FORMAT_U" in previous tx %s", l_out_prev_idx, l_prev_hash_str); + char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, " + "can't find item with index %"DAP_UINT64_FORMAT_U" in previous tx %s", l_out_prev_idx, l_prev_hash_str); + json_object *l_jobj_err = json_object_new_string(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } + } else { + log_it(L_WARNING, "Invalid 'in' item, bad prev_hash %s", l_prev_hash_str); + char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, " + "bad prev_hash %s", l_prev_hash_str); + json_object *l_jobj_err = json_object_new_string(l_str_err); + if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); + } } }break; + case TX_ITEM_TYPE_IN_COND: + case TX_ITEM_TYPE_IN_EMS: + case TX_ITEM_TYPE_IN_REWARD: default: continue; } if(l_multichanel) -- GitLab From 613dd984cf402fdd83f5eb90f9afeef15e667705 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Thu, 16 Jan 2025 15:45:54 +0300 Subject: [PATCH 06/18] [*] Fix block dump command --- modules/type/blocks/dap_chain_cs_blocks.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 05d3c5dde8..b74bfb74eb 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -733,6 +733,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) case SUBCMD_DUMP:{ const char *l_hash_out_type = NULL; + const char *l_hash_str = NULL; dap_chain_hash_fast_t l_block_hash={0}; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); if(!l_hash_out_type) @@ -740,15 +741,17 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "invalid parameter -H, valid values: -H <hex | base58>"); return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; - } - if (!l_subcmd_str_arg) { + } + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-hash", &l_hash_str); + if (!l_hash_str) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, "Enter block hash "); return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR; } - dap_chain_hash_fast_from_str(l_subcmd_str_arg, &l_block_hash); // Convert argument to hash + + dap_chain_hash_fast_from_str(l_hash_str, &l_block_hash); dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_block_hash); if (!l_block_cache) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR, "Can't find block %s ", l_subcmd_str_arg); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR, "Can't find block %s ", l_hash_str); return DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR; } dap_chain_block_t *l_block = l_block_cache->block; -- GitLab From 59726cdb1b65dfb1199795348b830955a77b71d7 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Thu, 16 Jan 2025 16:47:06 +0300 Subject: [PATCH 07/18] .. --- modules/type/blocks/dap_chain_cs_blocks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index b74bfb74eb..9c85963438 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -201,7 +201,7 @@ int dap_chain_cs_blocks_init() "\t\tComplete the current new round, verify it and if everything is ok - publish new blocks in chain\n\n" "Blockchain explorer:\n" - "block -net <net_name> [-chain <chain_name>] dump <block_hash>\n" + "block -net <net_name> [-chain <chain_name>] dump -hash <block_hash>\n" "\t\tDump block info\n\n" "block -net <net_name> [-chain <chain_name>] list [{signed | first_signed}] [-limit] [-offset] [-head]" -- GitLab From 55aaace60e0ed2e0ec734514422d6a21d0983915 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Thu, 16 Jan 2025 17:30:53 +0300 Subject: [PATCH 08/18] [*] Change json_str to tx_obj [+] Add availability send number as string in tx obj --- modules/net/dap_chain_net_tx.c | 5 +++++ modules/net/dap_chain_node_cli_cmd.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index 250b5c0ad1..f3affeae81 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -567,6 +567,11 @@ static bool s_json_get_int64(struct json_object *a_json, const char *a_key, int6 // Read number *a_out = json_object_get_int64(l_json); return true; + } else if (json_object_is_type(l_json, json_type_string)){ + // Read number + const char* l_value_text = json_object_get_string(l_json); + *a_out = atol(l_value_text); + return true; } } return false; diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 0c2000a7db..45bd7fcf2e 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -6017,11 +6017,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply) dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_name); // optional parameter dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-chain", &l_chain_name); // optional parameter dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-json", &l_json_file_path); - dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-json_str", &l_json_str); + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-tx_obj", &l_json_str); if(!l_json_file_path && !l_json_str) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON, - "Command requires one of parameters '-json <json file path> or -json_srt <string>'"); + "Command requires one of parameters '-json <json file path> or -tx_obj <string>'"); return DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON; } -- GitLab From dcbd33692d673605ac826581e863b8c8e328d4ad Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Thu, 16 Jan 2025 17:33:55 +0300 Subject: [PATCH 09/18] up sub --- dap-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dap-sdk b/dap-sdk index e0e6309061..69f295dd81 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit e0e63090610a266c933fa4c2e04898e2c398f9ef +Subproject commit 69f295dd81601b52bbf222edab814d8df7c3ace9 -- GitLab From 55f4295b198f89d2144e15963b3127848578252d Mon Sep 17 00:00:00 2001 From: denis <denis.sumin> Date: Fri, 17 Jan 2025 10:35:49 +0300 Subject: [PATCH 10/18] [*] up dap-sdk --- dap-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dap-sdk b/dap-sdk index bca10a63f6..da046e00eb 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit bca10a63f6fe82df2808c1741e80592148b85e85 +Subproject commit da046e00ebeb5261ebcd874d5bdeeb05d37c9a0f -- GitLab From 08f40f801e0826d9e3a9112671141fdeec50792f Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Fri, 17 Jan 2025 12:21:17 +0300 Subject: [PATCH 11/18] [+] Add extern "C" into headers --- modules/common/include/dap_chain_datum.h | 8 ++++++++ modules/common/include/dap_chain_datum_anchor.h | 8 ++++++++ modules/common/include/dap_chain_datum_decree.h | 9 +++++++++ .../common/include/dap_chain_datum_hashtree_roots.h | 6 ++++++ modules/common/include/dap_chain_datum_poll.h | 7 +++++++ modules/common/include/dap_chain_datum_token.h | 7 +++++++ modules/common/include/dap_chain_datum_tx.h | 9 +++++++++ modules/common/include/dap_chain_datum_tx_in.h | 9 +++++++++ modules/common/include/dap_chain_datum_tx_in_cond.h | 9 +++++++++ modules/common/include/dap_chain_datum_tx_in_ems.h | 8 ++++++++ modules/common/include/dap_chain_datum_tx_in_reward.h | 7 +++++++ modules/common/include/dap_chain_datum_tx_items.h | 6 ++++++ modules/common/include/dap_chain_datum_tx_out.h | 8 ++++++++ modules/common/include/dap_chain_datum_tx_out_cond.h | 8 ++++++++ modules/common/include/dap_chain_datum_tx_out_ext.h | 7 +++++++ modules/common/include/dap_chain_datum_tx_pkey.h | 9 +++++++++ modules/common/include/dap_chain_datum_tx_receipt.h | 1 + modules/common/include/dap_chain_datum_tx_sig.h | 7 +++++++ modules/common/include/dap_chain_datum_tx_tsd.h | 6 ++++++ modules/common/include/dap_chain_datum_tx_voting.h | 7 +++++++ modules/net/include/dap_chain_ledger.h | 8 ++++++++ modules/net/include/dap_chain_net.h | 7 +++++++ modules/net/include/dap_chain_net_anchor.h | 10 +++++++++- modules/net/include/dap_chain_net_balancer.h | 10 +++++++++- modules/net/include/dap_chain_net_bugreport.h | 8 ++++++++ modules/net/include/dap_chain_net_decree.h | 8 ++++++++ modules/net/include/dap_chain_net_node_list.h | 8 ++++++++ modules/net/include/dap_chain_net_tx.h | 10 +++++++++- modules/net/include/dap_chain_node.h | 8 ++++++++ modules/net/include/dap_chain_node_cli.h | 8 ++++++++ modules/net/include/dap_chain_node_cli_cmd.h | 8 ++++++++ modules/net/include/dap_chain_node_cli_cmd_tx.h | 7 +++++++ modules/net/include/dap_chain_node_client.h | 8 ++++++++ modules/net/include/dap_chain_node_dns_client.h | 7 +++++++ modules/net/include/dap_chain_node_dns_server.h | 7 +++++++ modules/net/include/dap_chain_node_ping.h | 8 ++++++++ modules/wallet/include/dap_chain_coin.h | 9 +++++++++ modules/wallet/include/dap_chain_wallet.h | 10 +++++++++- modules/wallet/include/dap_chain_wallet_cache.h | 10 +++++++++- modules/wallet/include/dap_chain_wallet_internal.h | 6 ++++++ modules/wallet/include/dap_chain_wallet_ops.h | 8 ++++++++ 41 files changed, 314 insertions(+), 5 deletions(-) diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h index 1fad5120e8..7c20ce32be 100644 --- a/modules/common/include/dap_chain_datum.h +++ b/modules/common/include/dap_chain_datum.h @@ -104,6 +104,10 @@ #define DAP_CHAIN_DATUM_ID_SIZE 2 +#ifdef __cplusplus +extern "C" { +#endif + // Datum subchain type id typedef union dap_chain_datum_typeid{ uint8_t data[DAP_CHAIN_DATUM_ID_SIZE]; @@ -168,3 +172,7 @@ bool dap_chain_datum_dump_tx_json(json_object* a_json_arr_reply, dap_chain_net_id_t a_net_id); json_object * dap_chain_datum_to_json(dap_chain_datum_t* a_datum); void dap_chain_datum_dump_json(json_object* a_json_arr_reply,json_object *a_obj_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id, bool a_verbose); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_anchor.h b/modules/common/include/dap_chain_datum_anchor.h index 79a0c48102..41986a06be 100644 --- a/modules/common/include/dap_chain_datum_anchor.h +++ b/modules/common/include/dap_chain_datum_anchor.h @@ -48,8 +48,16 @@ DAP_STATIC_INLINE size_t dap_chain_datum_anchor_get_size(dap_chain_datum_anchor_ return sizeof(*a_datum_anchor) + a_datum_anchor->header.data_size + a_datum_anchor->header.signs_size; } +#ifdef __cplusplus +extern "C" { +#endif + int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor, dap_hash_fast_t * a_out_hash); void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); void dap_chain_datum_anchor_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index 70ef4f65bd..e1292b35b2 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -31,6 +31,10 @@ #define DAP_CHAIN_DATUM_DECREE_VERSION 0 +#ifdef __cplusplus +extern "C" { +#endif + // Governance decree typedef struct dap_chain_datum_decree { uint16_t decree_version; @@ -343,3 +347,8 @@ void dap_chain_datum_decree_certs_dump_json(json_object * a_json_out, byte_t * a */ dap_chain_datum_decree_t* dap_chain_datum_decree_sign_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_decree, size_t a_certs_count, size_t *a_total_sign_count); + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_hashtree_roots.h b/modules/common/include/dap_chain_datum_hashtree_roots.h index 2b8ec9b513..8ff8f79d86 100644 --- a/modules/common/include/dap_chain_datum_hashtree_roots.h +++ b/modules/common/include/dap_chain_datum_hashtree_roots.h @@ -26,6 +26,9 @@ #include "dap_common.h" #include "dap_chain_common.h" +#ifdef __cplusplus +extern "C" { +#endif /** * @struct dap_chain_datum_hashtree_roots_v1 * @brief Hash tree roots for block, version 1 @@ -45,3 +48,6 @@ typedef struct dap_chain_datum_hashtree_roots_v2{ typedef dap_chain_datum_hashtree_roots_v2_t dap_chain_datum_hashtree_roots_t; +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_poll.h b/modules/common/include/dap_chain_datum_poll.h index d023c26b51..30993b3805 100644 --- a/modules/common/include/dap_chain_datum_poll.h +++ b/modules/common/include/dap_chain_datum_poll.h @@ -20,3 +20,10 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. */ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index 8f6d89e63a..c37131dc12 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -34,6 +34,9 @@ #define DAP_CHAIN_DATUM_NONCE_SIZE 64 +#ifdef __cplusplus +extern "C" { +#endif // Token declaration typedef struct dap_chain_datum_token_old { uint16_t type; @@ -437,3 +440,7 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_append_sign(dap_sign_ dap_sign_t *dap_chain_datum_emission_get_signs(dap_chain_datum_token_emission_t *a_emission, size_t *a_signs_count); // 256 TYPE bool dap_chain_datum_token_is_old(uint8_t a_type); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h index 98b8b7bff9..f5ef493eed 100644 --- a/modules/common/include/dap_chain_datum_tx.h +++ b/modules/common/include/dap_chain_datum_tx.h @@ -29,6 +29,11 @@ #include "dap_time.h" #include "dap_pkey.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** * @struct dap_chain_datum_tx * @brief Transaction section, consists from lot of tx_items @@ -182,3 +187,7 @@ DAP_STATIC_INLINE dap_hash_fast_t dap_chain_node_datum_tx_calc_hash(dap_chain_da dap_hash_fast_t l_res; return dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_res), l_res; } + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_in.h b/modules/common/include/dap_chain_datum_tx_in.h index bac85f8809..242ae43ecf 100644 --- a/modules/common/include/dap_chain_datum_tx_in.h +++ b/modules/common/include/dap_chain_datum_tx_in.h @@ -27,6 +27,11 @@ #include "dap_common.h" #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** * @struct dap_chain_tx_item * @brief Sections belongs to heading tx section, with inputs, outputs and others tx relatated items @@ -45,3 +50,7 @@ typedef struct dap_chain_tx_used_out_item { uint32_t num_idx_out; uint256_t value; } dap_chain_tx_used_out_item_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_in_cond.h b/modules/common/include/dap_chain_datum_tx_in_cond.h index 553e7f71ac..f6ffe2fca0 100644 --- a/modules/common/include/dap_chain_datum_tx_in_cond.h +++ b/modules/common/include/dap_chain_datum_tx_in_cond.h @@ -27,6 +27,11 @@ #include "dap_common.h" #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** * @struct dap_chain_tx_item * @brief Sections belongs to heading tx section, with inputs, outputs and others tx relatated items @@ -40,3 +45,7 @@ typedef struct dap_chain_tx_in_cond { uint32_t receipt_idx DAP_ALIGNED(4); } DAP_PACKED header; /// Only header's hash is used for verification } DAP_PACKED dap_chain_tx_in_cond_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_in_ems.h b/modules/common/include/dap_chain_datum_tx_in_ems.h index 04a17f84b7..b745fa727d 100644 --- a/modules/common/include/dap_chain_datum_tx_in_ems.h +++ b/modules/common/include/dap_chain_datum_tx_in_ems.h @@ -27,6 +27,10 @@ #include "dap_common.h" #include "dap_chain_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @struct dap_chain_tx_token * @brief Token item @@ -58,3 +62,7 @@ typedef struct dap_chain_tx_in_ems_ext{ uint16_t ext_tx_out_idx; // Output index } header; /// Only header's hash is used for verification } DAP_ALIGN_PACKED dap_chain_tx_in_ems_ext_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_in_reward.h b/modules/common/include/dap_chain_datum_tx_in_reward.h index 220d10a0d5..6d8fa17a37 100644 --- a/modules/common/include/dap_chain_datum_tx_in_reward.h +++ b/modules/common/include/dap_chain_datum_tx_in_reward.h @@ -24,7 +24,14 @@ along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/ #pragma once #include "dap_chain_common.h" +#ifdef __cplusplus +extern "C" { +#endif typedef struct dap_chain_tx_in_reward { dap_chain_tx_item_type_t type; /// @param type @brief Transaction item type dap_hash_t block_hash; /// @param block_hash @brief Hash of the block signed with current validator } DAP_ALIGN_PACKED dap_chain_tx_in_reward_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index 9c004c1979..d62f1c12a6 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -41,6 +41,9 @@ #include "dap_chain_datum_tx_tsd.h" #include "dap_chain_datum_tx_in_reward.h" +#ifdef __cplusplus +extern "C" { +#endif typedef struct dap_chain_datum_tx_item_groups { dap_list_t *items_in_all; @@ -249,3 +252,6 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a #define dap_chain_datum_tx_out_get_by_out_idx(a_tx, a_out_num) \ dap_chain_datum_tx_item_get_nth(a_tx, TX_ITEM_TYPE_OUT_ALL, a_out_num); +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_out.h b/modules/common/include/dap_chain_datum_tx_out.h index 3b877a4456..084b5bba20 100644 --- a/modules/common/include/dap_chain_datum_tx_out.h +++ b/modules/common/include/dap_chain_datum_tx_out.h @@ -28,6 +28,10 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @struct dap_chain_tx_out * @brief Transaction item outout @@ -48,3 +52,7 @@ typedef struct dap_chain_tx_out { } DAP_PACKED header; /// Only header's hash is used for verification dap_chain_addr_t addr; //// } DAP_PACKED dap_chain_tx_out_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h index c528b329c6..1325127e68 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -29,6 +29,10 @@ #include "dap_time.h" #include "dap_chain_common.h" +#ifdef __cplusplus +extern "C" { +#endif + enum dap_chain_tx_out_cond_subtype { DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED = 0x0, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY = 0x01, @@ -134,3 +138,7 @@ typedef struct dap_chain_tx_out_cond { uint32_t tsd_size; // Condition parameters size uint8_t tsd[]; // condition parameters, pkey, hash or smth like this } DAP_ALIGN_PACKED dap_chain_tx_out_cond_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_out_ext.h b/modules/common/include/dap_chain_datum_tx_out_ext.h index 6c9351f1b5..69aa1e9f5b 100644 --- a/modules/common/include/dap_chain_datum_tx_out_ext.h +++ b/modules/common/include/dap_chain_datum_tx_out_ext.h @@ -29,6 +29,9 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" +#ifdef __cplusplus +extern "C" { +#endif typedef struct dap_chain_tx_out_ext{ struct { dap_chain_tx_item_type_t type; // Transaction item type - should be TX_ITEM_TYPE_OUT_EXT @@ -37,3 +40,7 @@ typedef struct dap_chain_tx_out_ext{ dap_chain_addr_t addr; // Address to transfer to const char token[DAP_CHAIN_TICKER_SIZE_MAX]; // Which token is transferred } DAP_PACKED dap_chain_tx_out_ext_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_pkey.h b/modules/common/include/dap_chain_datum_tx_pkey.h index af5e911358..817f6b2244 100644 --- a/modules/common/include/dap_chain_datum_tx_pkey.h +++ b/modules/common/include/dap_chain_datum_tx_pkey.h @@ -27,6 +27,11 @@ #include "dap_common.h" #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** * @struct dap_chain_tx_pkey * @brief TX item with one of the transaction's public keys @@ -40,3 +45,7 @@ typedef struct dap_chain_tx_pkey{ uint32_t seq_no; /// Sequence number, out of the header so could be changed during reorganization uint8_t pkey[]; /// @param sig @brief raw pkey dat } DAP_PACKED dap_chain_tx_pkey_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_receipt.h b/modules/common/include/dap_chain_datum_tx_receipt.h index 5210c4fff5..ee0bb2845d 100644 --- a/modules/common/include/dap_chain_datum_tx_receipt.h +++ b/modules/common/include/dap_chain_datum_tx_receipt.h @@ -27,6 +27,7 @@ #include <stdint.h> #include "dap_chain_common.h" + typedef struct dap_chain_receipt_info { dap_chain_net_srv_uid_t srv_uid; // Service UID #if DAP_CHAIN_NET_SRV_UID_SIZE == 8 diff --git a/modules/common/include/dap_chain_datum_tx_sig.h b/modules/common/include/dap_chain_datum_tx_sig.h index a44e1a36c8..90bea9846d 100644 --- a/modules/common/include/dap_chain_datum_tx_sig.h +++ b/modules/common/include/dap_chain_datum_tx_sig.h @@ -28,6 +28,9 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" +#ifdef __cplusplus +extern "C" { +#endif /** * @struct dap_chain_tx_sig @@ -41,3 +44,7 @@ typedef struct dap_chain_tx_sig{ } DAP_PACKED header; /// Only header's hash is used for verification uint8_t sig[]; /// @param sig @brief raw signature data } DAP_PACKED dap_chain_tx_sig_t; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_tsd.h b/modules/common/include/dap_chain_datum_tx_tsd.h index fc78dcd320..1b3484b876 100644 --- a/modules/common/include/dap_chain_datum_tx_tsd.h +++ b/modules/common/include/dap_chain_datum_tx_tsd.h @@ -5,6 +5,9 @@ #include "dap_chain_datum_tx.h" #include "dap_tsd.h" +#ifdef __cplusplus +extern "C" { +#endif typedef struct dap_chain_tx_tsd { struct { dap_chain_tx_item_type_t type; @@ -13,3 +16,6 @@ typedef struct dap_chain_tx_tsd { byte_t tsd[]; } DAP_PACKED dap_chain_tx_tsd_t; +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_voting.h b/modules/common/include/dap_chain_datum_tx_voting.h index d9a991a839..91139d1bd9 100644 --- a/modules/common/include/dap_chain_datum_tx_voting.h +++ b/modules/common/include/dap_chain_datum_tx_voting.h @@ -36,6 +36,9 @@ #define DAP_CHAIN_DATUM_TX_VOTING_OPTION_MAX_LENGTH 100 #define DAP_CHAIN_DATUM_TX_VOTING_OPTION_MAX_COUNT 10 +#ifdef __cplusplus +extern "C" { +#endif typedef enum dap_chain_datum_voting_tsd_type { VOTING_TSD_TYPE_QUESTION = 0x01, @@ -90,3 +93,7 @@ json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_ dap_chain_tx_vote_t *dap_chain_datum_tx_item_vote_create(dap_chain_hash_fast_t *a_voting_hash, uint64_t *a_answer_idx); json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote, dap_ledger_t *a_ledger); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index b0b3456a2a..bfbee3ca8d 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -40,6 +40,10 @@ #define DAP_CHAIN_NET_SRV_TRANSFER_ID 0x09 #define DAP_CHAIN_NET_SRV_BLOCK_REWARD_ID 0x08 +#ifdef __cplusplus +extern "C" { +#endif + typedef struct dap_ledger { dap_chain_net_t *net; void *_internal; @@ -465,3 +469,7 @@ bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger); void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback); dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond); void dap_ledger_load_end(dap_ledger_t *a_ledger); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 92989ff89f..9d47cc67b1 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -41,6 +41,9 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #define DAP_CHAIN_NET_MEMPOOL_TTL 4 * 3600 // 4 hours #define DAP_CHAIN_NET_NODES_TTL 14 * 24 * 3600 // 2 weeks +#ifdef __cplusplus +extern "C" { +#endif typedef struct dap_chain_node_client dap_chain_node_client_t; typedef struct dap_ledger dap_ledger_t; @@ -239,3 +242,7 @@ dap_chain_net_decree_t *dap_chain_net_get_net_decree(dap_chain_net_t *a_net); void dap_chain_net_set_net_decree(dap_chain_net_t *a_net, dap_chain_net_decree_t *a_decree); decree_table_t **dap_chain_net_get_decrees(dap_chain_net_t *a_net); anchor_table_t **dap_chain_net_get_anchors(dap_chain_net_t *a_net); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_net_anchor.h b/modules/net/include/dap_chain_net_anchor.h index cb19ca0811..36d33c3d63 100644 --- a/modules/net/include/dap_chain_net_anchor.h +++ b/modules/net/include/dap_chain_net_anchor.h @@ -24,8 +24,16 @@ #include "dap_chain_datum_anchor.h" #include "dap_chain_net.h" +#ifdef __cplusplus +extern "C" { +#endif + int dap_chain_net_anchor_init(); int dap_chain_net_anchor_verify(dap_chain_net_t *a_net, dap_chain_datum_anchor_t * a_anchor, size_t a_data_size); int dap_chain_net_anchor_load(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain, dap_hash_fast_t *a_anchor_hash); -int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain, dap_hash_fast_t *a_anchor_hash); \ No newline at end of file +int dap_chain_net_anchor_unload(dap_chain_datum_anchor_t * a_anchor, dap_chain_t *a_chain, dap_hash_fast_t *a_anchor_hash); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_net_balancer.h b/modules/net/include/dap_chain_net_balancer.h index 4d314dbc7e..e005eea71d 100644 --- a/modules/net/include/dap_chain_net_balancer.h +++ b/modules/net/include/dap_chain_net_balancer.h @@ -30,6 +30,10 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #define DAP_BALANCER_PROTOCOL_VERSION 2 #define DAP_BALANCER_MAX_REPLY_SIZE 2048 +#ifdef __cplusplus +extern "C" { +#endif + typedef struct dap_balancer_request_info dap_balancer_request_info_t; typedef struct dap_chain_net_links { @@ -66,4 +70,8 @@ void dap_chain_net_balancer_http_issue_link(dap_http_simple_t *a_http_simple, vo dap_link_info_t *dap_chain_net_balancer_dns_issue_link(const char *a_net_name); int dap_chain_net_balancer_handshake(dap_chain_node_info_t *a_node_info, dap_chain_net_t * a_net); dap_string_t *dap_chain_net_balancer_get_node_str(dap_chain_net_t *a_net); -void dap_chain_net_balancer_request(void *a_arg); \ No newline at end of file +void dap_chain_net_balancer_request(void *a_arg); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_net_bugreport.h b/modules/net/include/dap_chain_net_bugreport.h index b336ac607f..c8da9094df 100644 --- a/modules/net/include/dap_chain_net_bugreport.h +++ b/modules/net/include/dap_chain_net_bugreport.h @@ -24,4 +24,12 @@ #include "dap_http_server.h" +#ifdef __cplusplus +extern "C" { +#endif + int dap_chain_net_bugreport_init(dap_http_server_t * a_http); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h index 6cf2e6eff0..dcb2bceee1 100644 --- a/modules/net/include/dap_chain_net_decree.h +++ b/modules/net/include/dap_chain_net_decree.h @@ -25,6 +25,10 @@ #include "dap_list.h" #include "dap_chain_net.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct dap_chain_net_decree { dap_list_t *pkeys; uint16_t num_of_owners; @@ -41,3 +45,7 @@ int dap_chain_net_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t int dap_chain_net_decree_load(dap_chain_datum_decree_t * a_decree, dap_chain_t *a_chain, dap_chain_hash_fast_t *a_decree_hash); dap_chain_datum_decree_t *dap_chain_net_decree_get_by_hash(dap_chain_net_t *a_net, dap_hash_fast_t *a_hash, bool *is_applied); int dap_chain_net_decree_reset_applied(dap_chain_net_t *a_net, dap_chain_hash_fast_t *a_decree_hash); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_net_node_list.h b/modules/net/include/dap_chain_net_node_list.h index 8fe6dd6b1b..f61624c9b4 100644 --- a/modules/net/include/dap_chain_net_node_list.h +++ b/modules/net/include/dap_chain_net_node_list.h @@ -29,6 +29,10 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #define DAP_NODE_LIST_URI_HASH "node_list_hash" +#ifdef __cplusplus +extern "C" { +#endif + struct node_link_request { dap_chain_node_info_t *link_info; dap_chain_net_t *net; @@ -55,3 +59,7 @@ DAP_STATIC_INLINE char* dap_chain_net_node_list_get_gdb_group(dap_chain_net_t * void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple, void *a_arg); int dap_chain_net_node_list_request(dap_chain_net_t *a_net, uint16_t a_port, bool a_sync, char a_cmd); int dap_chain_net_node_list_init(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h index 67e594d734..b729a75025 100644 --- a/modules/net/include/dap_chain_net_tx.h +++ b/modules/net/include/dap_chain_net_tx.h @@ -27,6 +27,10 @@ #include "dap_chain_datum_tx_items.h" #include "dap_json_rpc_errors.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef enum s_com_tx_create_json_err { DAP_CHAIN_NET_TX_CREATE_JSON_OK = 0, DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, @@ -128,4 +132,8 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n * * @return s_com_tx_create_json_err_t status code */ -int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json); \ No newline at end of file +int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_node.h b/modules/net/include/dap_chain_node.h index 320748529e..a6d46f8c51 100644 --- a/modules/net/include/dap_chain_node.h +++ b/modules/net/include/dap_chain_node.h @@ -28,6 +28,10 @@ #include "dap_chain.h" #include "dap_client.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct dap_chain_net dap_chain_net_t; typedef struct dap_chain_node_info_old { @@ -91,3 +95,7 @@ bool dap_chain_node_mempool_autoproc_init(); inline static void dap_chain_node_mempool_autoproc_deinit() {} dap_list_t *dap_chain_node_get_states_list_sort(dap_chain_net_t *a_net, dap_chain_node_addr_t *a_ignored, size_t a_ignored_count); dap_string_t *dap_chain_node_states_info_read(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_node_cli.h b/modules/net/include/dap_chain_node_cli.h index 14b52dc90b..2893306b7d 100644 --- a/modules/net/include/dap_chain_node_cli.h +++ b/modules/net/include/dap_chain_node_cli.h @@ -32,6 +32,10 @@ #include "dap_cli_server.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Initialization of the server side of the interaction * with the console kelvin-node-cli @@ -42,3 +46,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config); * Deinitialization of the server side */ void dap_chain_node_cli_delete(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index 93572f9e91..3b8871adf0 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -31,6 +31,10 @@ #include "dap_chain_node_cli.h" #include "json.h" +#ifdef __cplusplus +extern "C" { +#endif + int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(json_object* a_json_arr_reply, int *a_arg_index, int a_argc, char **a_argv, dap_chain_t **a_chain, dap_chain_net_t **a_net, @@ -375,3 +379,7 @@ int cmd_find(int a_argc, char **a_argv, void **a_str_reply); void dap_notify_new_client_send_info(dap_events_socket_t *a_es, void *a_arg); int com_exec_cmd(int argc, char **argv, void **reply); + +#ifdef __cplusplus +} +#endif \ No newline at end of file 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 442f895e7e..def00d9838 100644 --- a/modules/net/include/dap_chain_node_cli_cmd_tx.h +++ b/modules/net/include/dap_chain_node_cli_cmd_tx.h @@ -29,6 +29,10 @@ #include "dap_chain_common.h" #include "dap_chain_net.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct dap_chain_tx_hash_processed_ht{ dap_chain_hash_fast_t hash; UT_hash_handle hh; @@ -115,3 +119,6 @@ typedef enum s_com_token_err{ */ int cmd_decree(int a_argc, char **a_argv, void **a_str_reply); +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_node_client.h b/modules/net/include/dap_chain_node_client.h index d255d2b35c..b696f030bb 100644 --- a/modules/net/include/dap_chain_node_client.h +++ b/modules/net/include/dap_chain_node_client.h @@ -30,6 +30,10 @@ #include "dap_chain_node.h" #include "dap_stream_ch_pkt.h" +#ifdef __cplusplus +extern "C" { +#endif + // connection states typedef enum dap_chain_node_client_state { NODE_CLIENT_STATE_ERROR = -1, @@ -171,3 +175,7 @@ static inline const char * dap_chain_node_client_state_to_str( dap_chain_node_cl } } + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_node_dns_client.h b/modules/net/include/dap_chain_node_dns_client.h index 5ab385243c..0ce425c7a7 100644 --- a/modules/net/include/dap_chain_node_dns_client.h +++ b/modules/net/include/dap_chain_node_dns_client.h @@ -33,6 +33,9 @@ #define DNS_LISTEN_PORT 53 // UDP #define DNS_LISTEN_PORT_STR "53" // UDP +#ifdef __cplusplus +extern "C" { +#endif typedef struct _dap_dns_buf_t { char *data; uint32_t size; @@ -51,3 +54,7 @@ void dap_dns_buf_put_uint64(dap_dns_buf_t *buf, uint64_t val); void dap_dns_buf_put_uint32(dap_dns_buf_t *buf, uint32_t val); void dap_dns_buf_put_uint16(dap_dns_buf_t *buf, uint16_t val); uint16_t dap_dns_buf_get_uint16(dap_dns_buf_t *buf); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_node_dns_server.h b/modules/net/include/dap_chain_node_dns_server.h index aa22b05bd3..56f79e1b26 100644 --- a/modules/net/include/dap_chain_node_dns_server.h +++ b/modules/net/include/dap_chain_node_dns_server.h @@ -38,6 +38,10 @@ #define DNS_MAX_HOSTNAME_LEN 255 #define DNS_MAX_DOMAIN_NAME_LEN 63 +#ifdef __cplusplus +extern "C" { +#endif + typedef enum _dap_dns_query_type_t { DNS_QUERY_TYPE_STANDARD, DNS_QUERY_TYPE_INVERSE, @@ -122,3 +126,6 @@ void dap_dns_server_stop(); int dap_dns_zone_register(char *zone, dap_dns_zone_callback_t callback); int dap_dns_zone_unregister(char *zone); +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/net/include/dap_chain_node_ping.h b/modules/net/include/dap_chain_node_ping.h index b94fa2ad8f..5c4a6eb30c 100644 --- a/modules/net/include/dap_chain_node_ping.h +++ b/modules/net/include/dap_chain_node_ping.h @@ -27,6 +27,10 @@ #endif #include <pthread.h> +#ifdef __cplusplus +extern "C" { +#endif + // start sending ping int start_node_ping(pthread_t *a_thread, struct in_addr a_addr, int a_port, int a_count); @@ -38,3 +42,7 @@ int wait_node_ping(pthread_t l_thread, int timeout_ms); int dap_chain_node_ping_background_start(dap_chain_net_t *a_net, dap_list_t *a_node_list); int dap_chain_node_ping_background_stop(void); int dap_chain_node_ping_background_status(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/wallet/include/dap_chain_coin.h b/modules/wallet/include/dap_chain_coin.h index e7e79f6034..5395e039a5 100644 --- a/modules/wallet/include/dap_chain_coin.h +++ b/modules/wallet/include/dap_chain_coin.h @@ -22,3 +22,12 @@ along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. */ #pragma once + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/wallet/include/dap_chain_wallet.h b/modules/wallet/include/dap_chain_wallet.h index 01c65dc889..ecea35b5f8 100644 --- a/modules/wallet/include/dap_chain_wallet.h +++ b/modules/wallet/include/dap_chain_wallet.h @@ -38,6 +38,10 @@ #define DAP_WALLET$M_FL_PROTECTED (1 << 0) /* Wallet is password protected */ #define DAP_WALLET$M_FL_ACTIVE (1 << 1) /* Has been activated (has been open with password) */ +#ifdef __cplusplus +extern "C" { +#endif + typedef struct dap_chain_wallet{ char name[ DAP_WALLET$SZ_NAME + 1 ]; /* Human readable name of BMF Wallet */ uint64_t flags; /* See DAP_WALLET$M_FL_* constants */ @@ -95,4 +99,8 @@ int dap_chain_wallet_get_pkey_hash(dap_chain_wallet_t *a_wallet, dap_hash_fast_t int dap_chain_wallet_add_wallet_opened_notify(dap_chain_wallet_opened_callback_t a_callback, void *a_arg); int dap_chain_wallet_add_wallet_created_notify(dap_chain_wallet_opened_callback_t a_callback, void *a_arg); -dap_list_t* dap_chain_wallet_get_local_addr(); \ No newline at end of file +dap_list_t* dap_chain_wallet_get_local_addr(); + +#ifdef __cplusplus +extern "C" { +#endif \ No newline at end of file diff --git a/modules/wallet/include/dap_chain_wallet_cache.h b/modules/wallet/include/dap_chain_wallet_cache.h index 2225436069..d277fca4cd 100644 --- a/modules/wallet/include/dap_chain_wallet_cache.h +++ b/modules/wallet/include/dap_chain_wallet_cache.h @@ -27,6 +27,10 @@ #include "dap_chain_common.h" #include "dap_chain_ledger.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef enum dap_chain_wallet_getting_type { DAP_CHAIN_WALLET_CACHE_GET_FIRST = 0, DAP_CHAIN_WALLET_CACHE_GET_LAST, @@ -100,4 +104,8 @@ int dap_chain_wallet_cache_tx_find_outs(dap_chain_net_t *a_net, const char *a_to dap_chain_wallet_cache_iter_t *dap_chain_wallet_cache_iter_create(dap_chain_addr_t a_addr); void dap_chain_wallet_cache_iter_delete(dap_chain_wallet_cache_iter_t *a_iter); -dap_chain_datum_tx_t *dap_chain_wallet_cache_iter_get(dap_chain_wallet_cache_iter_t *a_iter, dap_chain_wallet_getting_type_t a_type); \ No newline at end of file +dap_chain_datum_tx_t *dap_chain_wallet_cache_iter_get(dap_chain_wallet_cache_iter_t *a_iter, dap_chain_wallet_getting_type_t a_type); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/wallet/include/dap_chain_wallet_internal.h b/modules/wallet/include/dap_chain_wallet_internal.h index f11d1bc16c..40de3c46b6 100644 --- a/modules/wallet/include/dap_chain_wallet_internal.h +++ b/modules/wallet/include/dap_chain_wallet_internal.h @@ -31,6 +31,9 @@ #define DAP_CHAIN_WALLETS_FILE_SIGNATURE (uint64_t)0x1a167bef15feea18 +#ifdef __cplusplus +extern "C" { +#endif enum { DAP_WALLET$K_TYPE_PLAIN = 0, /* 0x00 - uncompressed and unencrypted */ @@ -97,3 +100,6 @@ typedef struct dap_chain_wallet_internal #define DAP_CHAIN_WALLET_INTERNAL_LOCAL(a) dap_chain_wallet_internal_t * l_wallet_internal = DAP_CHAIN_WALLET_INTERNAL(a) #define DAP_CHAIN_WALLET_INTERNAL_LOCAL_NEW(a) dap_chain_wallet_internal_t * l_wallet_internal = DAP_NEW_Z(dap_chain_wallet_internal_t); a->_internal = l_wallet_internal +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/modules/wallet/include/dap_chain_wallet_ops.h b/modules/wallet/include/dap_chain_wallet_ops.h index 90f610a1e8..6085befa48 100644 --- a/modules/wallet/include/dap_chain_wallet_ops.h +++ b/modules/wallet/include/dap_chain_wallet_ops.h @@ -3,6 +3,14 @@ #include "dap_chain.h" #include "dap_chain_wallet.h" +#ifdef __cplusplus +extern "C" { +#endif + void dap_chain_wallet_op_tx_request(dap_chain_wallet_t * a_wallet, uint32_t a_wallet_key_idx, /// Sender's wallet and key index in it dap_chain_t * a_chain_source, uint64_t a_value, /// Token source and daptoshi's value dap_chain_t * a_chain_tx_request, dap_chain_addr_t a_destination ); /// TX blockchain where to create new block + +#ifdef __cplusplus +} +#endif \ No newline at end of file -- GitLab From 6a8370c8c46c6155a121496c4518b97fa2c20c24 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Fri, 17 Jan 2025 14:14:30 +0300 Subject: [PATCH 12/18] .. --- modules/common/include/dap_chain_datum.h | 7 +- .../common/include/dap_chain_datum_anchor.h | 10 +- .../common/include/dap_chain_datum_decree.h | 9 +- .../include/dap_chain_datum_hashtree_roots.h | 6 - .../common/include/dap_chain_datum_token.h | 101 +++---- modules/common/include/dap_chain_datum_tx.h | 8 +- .../common/include/dap_chain_datum_tx_in.h | 6 - .../include/dap_chain_datum_tx_in_cond.h | 8 - .../include/dap_chain_datum_tx_in_ems.h | 6 - .../include/dap_chain_datum_tx_in_reward.h | 6 - .../common/include/dap_chain_datum_tx_items.h | 6 +- .../common/include/dap_chain_datum_tx_out.h | 6 - .../include/dap_chain_datum_tx_out_cond.h | 34 +-- .../include/dap_chain_datum_tx_out_ext.h | 7 - .../common/include/dap_chain_datum_tx_pkey.h | 8 - .../common/include/dap_chain_datum_tx_sig.h | 8 - .../common/include/dap_chain_datum_tx_tsd.h | 6 - .../include/dap_chain_datum_tx_voting.h | 8 +- modules/net/include/dap_chain_ledger.h | 154 +++++------ modules/net/include/dap_chain_net.h | 63 ++--- modules/net/include/dap_chain_net_balancer.h | 7 +- modules/net/include/dap_chain_net_decree.h | 7 +- modules/net/include/dap_chain_net_node_list.h | 7 +- modules/net/include/dap_chain_net_tx.h | 9 +- modules/net/include/dap_chain_node.h | 6 +- modules/net/include/dap_chain_node_cli_cmd.h | 251 +++++++++--------- .../net/include/dap_chain_node_cli_cmd_tx.h | 63 ++--- modules/net/include/dap_chain_node_client.h | 8 +- .../net/include/dap_chain_node_dns_client.h | 6 +- .../net/include/dap_chain_node_dns_server.h | 8 +- modules/wallet/include/dap_chain_coin.h | 8 - modules/wallet/include/dap_chain_wallet.h | 8 +- .../wallet/include/dap_chain_wallet_cache.h | 7 +- .../include/dap_chain_wallet_internal.h | 7 - 34 files changed, 403 insertions(+), 466 deletions(-) diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h index 7c20ce32be..e171564335 100644 --- a/modules/common/include/dap_chain_datum.h +++ b/modules/common/include/dap_chain_datum.h @@ -104,9 +104,6 @@ #define DAP_CHAIN_DATUM_ID_SIZE 2 -#ifdef __cplusplus -extern "C" { -#endif // Datum subchain type id typedef union dap_chain_datum_typeid{ @@ -133,6 +130,10 @@ typedef struct dap_chain_datum{ byte_t data[]; /// Stored datum body } DAP_ALIGN_PACKED dap_chain_datum_t; +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief dap_chain_datum_size * @param a_datum diff --git a/modules/common/include/dap_chain_datum_anchor.h b/modules/common/include/dap_chain_datum_anchor.h index 41986a06be..37014cce76 100644 --- a/modules/common/include/dap_chain_datum_anchor.h +++ b/modules/common/include/dap_chain_datum_anchor.h @@ -43,15 +43,17 @@ typedef struct dap_chain_datum_anchor{ // ANCHOR TSD types #define DAP_CHAIN_DATUM_ANCHOR_TSD_TYPE_DECREE_HASH 0x0001 -DAP_STATIC_INLINE size_t dap_chain_datum_anchor_get_size(dap_chain_datum_anchor_t *a_datum_anchor) -{ - return sizeof(*a_datum_anchor) + a_datum_anchor->header.data_size + a_datum_anchor->header.signs_size; -} + #ifdef __cplusplus extern "C" { #endif +DAP_STATIC_INLINE size_t dap_chain_datum_anchor_get_size(dap_chain_datum_anchor_t *a_datum_anchor) +{ + return sizeof(*a_datum_anchor) + a_datum_anchor->header.data_size + a_datum_anchor->header.signs_size; +} + int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor, dap_hash_fast_t * a_out_hash); void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index e1292b35b2..19e956cbbd 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -31,10 +31,6 @@ #define DAP_CHAIN_DATUM_DECREE_VERSION 0 -#ifdef __cplusplus -extern "C" { -#endif - // Governance decree typedef struct dap_chain_datum_decree { uint16_t decree_version; @@ -98,6 +94,11 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION 0x010A #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE 0x010B + +#ifdef __cplusplus +extern "C" { +#endif + DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_decree_subtype) { switch(a_decree_subtype) { diff --git a/modules/common/include/dap_chain_datum_hashtree_roots.h b/modules/common/include/dap_chain_datum_hashtree_roots.h index 8ff8f79d86..2b8ec9b513 100644 --- a/modules/common/include/dap_chain_datum_hashtree_roots.h +++ b/modules/common/include/dap_chain_datum_hashtree_roots.h @@ -26,9 +26,6 @@ #include "dap_common.h" #include "dap_chain_common.h" -#ifdef __cplusplus -extern "C" { -#endif /** * @struct dap_chain_datum_hashtree_roots_v1 * @brief Hash tree roots for block, version 1 @@ -48,6 +45,3 @@ typedef struct dap_chain_datum_hashtree_roots_v2{ typedef dap_chain_datum_hashtree_roots_v2_t dap_chain_datum_hashtree_roots_t; -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index c37131dc12..f596c2e605 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -34,9 +34,6 @@ #define DAP_CHAIN_DATUM_NONCE_SIZE 64 -#ifdef __cplusplus -extern "C" { -#endif // Token declaration typedef struct dap_chain_datum_token_old { uint16_t type; @@ -217,30 +214,6 @@ typedef struct dap_chain_datum_token_tsd_delegate_from_stake_lock { #define DAP_CHAIN_DATUM_TOKEN_FLAG_UNDEFINED 0xffff -DAP_STATIC_INLINE const char *dap_chain_datum_token_flag_to_str(uint32_t a_flag) -{ - switch (a_flag) { - case DAP_CHAIN_DATUM_TOKEN_FLAG_NONE: return "NONE"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED: return "ALL_SENDER_BLOCKED"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED: return "ALL_SENDER_ALLOWED"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_FROZEN: return "ALL_SENDER_FROZEN"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN: return "ALL_SENDER_UNFROZEN"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED: return "ALL_RECEIVER_BLOCKED"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED: return "ALL_RECEIVER_ALLOWED"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN: return "ALL_RECEIVER_FROZEN"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_UNFROZEN: return "ALL_RECEIVER_UNFROZEN"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_ALL: return "STATIC_ALL"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_FLAGS: return "STATIC_FLAGS"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_ALL: return "STATIC_PERMISSIONS_ALL"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_DATUM_TYPE: return "STATIC_PERMISSIONS_DATUM_TYPE"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_SENDER: return "TATIC_PERMISSIONS_TX_SENDER"; - case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_RECEIVER: return "STATIC_PERMISSIONS_TX_RECEIVER"; - default: return "UNKNOWN FLAG OR FLAGS GROUP"; - } -} - -uint32_t dap_chain_datum_token_flag_from_str(const char *a_str); - /// -------- General tsd types ---- // Flags set/unsed #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS 0x0001 @@ -298,29 +271,6 @@ uint32_t dap_chain_datum_token_flag_from_str(const char *a_str); #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE 0x0024 #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR 0x0025 - -// Get delegated ticker -DAP_STATIC_INLINE int dap_chain_datum_token_get_delegated_ticker(char *a_buf, const char *a_ticker) -{ - if (!a_buf || !a_ticker) - return -1; - *a_buf = 'm'; - dap_strncpy(a_buf + 1, a_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 1); - return 0; -} - -DAP_STATIC_INLINE bool dap_chain_datum_token_is_old(uint8_t a_type) -{ - return a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE - || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL - || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE - || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL - || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE - || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC; -} - -/* Token emission section */ - struct DAP_ALIGN_PACKED dap_chain_emission_header_v0 { uint8_t version; uint8_t type; // Emission Type @@ -410,6 +360,57 @@ typedef struct dap_chain_datum_token_emission { #define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_CROSSCHAIN "CROSSCHAIN" #define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_OUT "OUT" + +#ifdef __cplusplus +extern "C" { +#endif + +DAP_STATIC_INLINE const char *dap_chain_datum_token_flag_to_str(uint32_t a_flag) +{ + switch (a_flag) { + case DAP_CHAIN_DATUM_TOKEN_FLAG_NONE: return "NONE"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_BLOCKED: return "ALL_SENDER_BLOCKED"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_ALLOWED: return "ALL_SENDER_ALLOWED"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_FROZEN: return "ALL_SENDER_FROZEN"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN: return "ALL_SENDER_UNFROZEN"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_BLOCKED: return "ALL_RECEIVER_BLOCKED"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_ALLOWED: return "ALL_RECEIVER_ALLOWED"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN: return "ALL_RECEIVER_FROZEN"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_UNFROZEN: return "ALL_RECEIVER_UNFROZEN"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_ALL: return "STATIC_ALL"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_FLAGS: return "STATIC_FLAGS"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_ALL: return "STATIC_PERMISSIONS_ALL"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_DATUM_TYPE: return "STATIC_PERMISSIONS_DATUM_TYPE"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_SENDER: return "TATIC_PERMISSIONS_TX_SENDER"; + case DAP_CHAIN_DATUM_TOKEN_FLAG_STATIC_PERMISSIONS_TX_RECEIVER: return "STATIC_PERMISSIONS_TX_RECEIVER"; + default: return "UNKNOWN FLAG OR FLAGS GROUP"; + } +} + +uint32_t dap_chain_datum_token_flag_from_str(const char *a_str); + +// Get delegated ticker +DAP_STATIC_INLINE int dap_chain_datum_token_get_delegated_ticker(char *a_buf, const char *a_ticker) +{ + if (!a_buf || !a_ticker) + return -1; + *a_buf = 'm'; + dap_strncpy(a_buf + 1, a_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 1); + return 0; +} + +DAP_STATIC_INLINE bool dap_chain_datum_token_is_old(uint8_t a_type) +{ + return a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_SIMPLE + || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_DECL + || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PRIVATE_UPDATE + || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_DECL + || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_NATIVE_UPDATE + || a_type == DAP_CHAIN_DATUM_TOKEN_TYPE_OLD_PUBLIC; +} + +/* Token emission section */ + DAP_STATIC_INLINE const char *dap_chain_datum_emission_type_str(uint8_t a_type) { switch (a_type) { diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h index f5ef493eed..110f2313c5 100644 --- a/modules/common/include/dap_chain_datum_tx.h +++ b/modules/common/include/dap_chain_datum_tx.h @@ -30,10 +30,6 @@ #include "dap_pkey.h" -#ifdef __cplusplus -extern "C" { -#endif - /** * @struct dap_chain_datum_tx * @brief Transaction section, consists from lot of tx_items @@ -61,6 +57,10 @@ typedef struct dap_chain_datum_tx { !!( item = dap_chain_datum_tx_item_get(tx, &item_index, (byte_t*)item + item_size, item_type, &item_size) );\ item_index = 0 ) +#ifdef __cplusplus +extern "C" { +#endif + /** * Create empty transaction * diff --git a/modules/common/include/dap_chain_datum_tx_in.h b/modules/common/include/dap_chain_datum_tx_in.h index 242ae43ecf..5352eca464 100644 --- a/modules/common/include/dap_chain_datum_tx_in.h +++ b/modules/common/include/dap_chain_datum_tx_in.h @@ -28,9 +28,6 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" -#ifdef __cplusplus -extern "C" { -#endif /** * @struct dap_chain_tx_item @@ -51,6 +48,3 @@ typedef struct dap_chain_tx_used_out_item { uint256_t value; } dap_chain_tx_used_out_item_t; -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_in_cond.h b/modules/common/include/dap_chain_datum_tx_in_cond.h index f6ffe2fca0..3991f242ed 100644 --- a/modules/common/include/dap_chain_datum_tx_in_cond.h +++ b/modules/common/include/dap_chain_datum_tx_in_cond.h @@ -28,10 +28,6 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" -#ifdef __cplusplus -extern "C" { -#endif - /** * @struct dap_chain_tx_item * @brief Sections belongs to heading tx section, with inputs, outputs and others tx relatated items @@ -45,7 +41,3 @@ typedef struct dap_chain_tx_in_cond { uint32_t receipt_idx DAP_ALIGNED(4); } DAP_PACKED header; /// Only header's hash is used for verification } DAP_PACKED dap_chain_tx_in_cond_t; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_in_ems.h b/modules/common/include/dap_chain_datum_tx_in_ems.h index b745fa727d..bc9ee838ce 100644 --- a/modules/common/include/dap_chain_datum_tx_in_ems.h +++ b/modules/common/include/dap_chain_datum_tx_in_ems.h @@ -27,9 +27,6 @@ #include "dap_common.h" #include "dap_chain_common.h" -#ifdef __cplusplus -extern "C" { -#endif /** * @struct dap_chain_tx_token @@ -63,6 +60,3 @@ typedef struct dap_chain_tx_in_ems_ext{ } header; /// Only header's hash is used for verification } DAP_ALIGN_PACKED dap_chain_tx_in_ems_ext_t; -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_in_reward.h b/modules/common/include/dap_chain_datum_tx_in_reward.h index 6d8fa17a37..3e05f35218 100644 --- a/modules/common/include/dap_chain_datum_tx_in_reward.h +++ b/modules/common/include/dap_chain_datum_tx_in_reward.h @@ -24,14 +24,8 @@ along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/ #pragma once #include "dap_chain_common.h" -#ifdef __cplusplus -extern "C" { -#endif typedef struct dap_chain_tx_in_reward { dap_chain_tx_item_type_t type; /// @param type @brief Transaction item type dap_hash_t block_hash; /// @param block_hash @brief Hash of the block signed with current validator } DAP_ALIGN_PACKED dap_chain_tx_in_reward_t; -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index d62f1c12a6..4d2c90f790 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -41,9 +41,6 @@ #include "dap_chain_datum_tx_tsd.h" #include "dap_chain_datum_tx_in_reward.h" -#ifdef __cplusplus -extern "C" { -#endif typedef struct dap_chain_datum_tx_item_groups { dap_list_t *items_in_all; @@ -78,6 +75,9 @@ typedef struct dap_chain_datum_tx_item_groups { } dap_chain_datum_tx_item_groups_t; +#ifdef __cplusplus +extern "C" { +#endif /** * Get item name by item type * diff --git a/modules/common/include/dap_chain_datum_tx_out.h b/modules/common/include/dap_chain_datum_tx_out.h index 084b5bba20..f7e48c54a7 100644 --- a/modules/common/include/dap_chain_datum_tx_out.h +++ b/modules/common/include/dap_chain_datum_tx_out.h @@ -28,9 +28,6 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" -#ifdef __cplusplus -extern "C" { -#endif /** * @struct dap_chain_tx_out @@ -53,6 +50,3 @@ typedef struct dap_chain_tx_out { dap_chain_addr_t addr; //// } DAP_PACKED dap_chain_tx_out_t; -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h index 1325127e68..b5988638c9 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -29,10 +29,6 @@ #include "dap_time.h" #include "dap_chain_common.h" -#ifdef __cplusplus -extern "C" { -#endif - enum dap_chain_tx_out_cond_subtype { DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED = 0x0, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY = 0x01, @@ -45,19 +41,6 @@ enum dap_chain_tx_out_cond_subtype { }; typedef byte_t dap_chain_tx_out_cond_subtype_t; -DAP_STATIC_INLINE const char *dap_chain_tx_out_cond_subtype_to_str(dap_chain_tx_out_cond_subtype_t a_subtype){ - switch (a_subtype) { - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY"; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE"; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE"; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE"; - default: {} - } - return "UNDEFINED"; -} - // Stake lock base flags // Lock by time #define DAP_CHAIN_NET_SRV_STAKE_LOCK_FLAG_BY_TIME 0x00000008 @@ -139,6 +122,23 @@ typedef struct dap_chain_tx_out_cond { uint8_t tsd[]; // condition parameters, pkey, hash or smth like this } DAP_ALIGN_PACKED dap_chain_tx_out_cond_t; +#ifdef __cplusplus +extern "C" { +#endif + +DAP_STATIC_INLINE const char *dap_chain_tx_out_cond_subtype_to_str(dap_chain_tx_out_cond_subtype_t a_subtype){ + switch (a_subtype) { + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY"; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE"; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE"; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK"; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE"; + default: {} + } + return "UNDEFINED"; +} + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_out_ext.h b/modules/common/include/dap_chain_datum_tx_out_ext.h index 69aa1e9f5b..6c9351f1b5 100644 --- a/modules/common/include/dap_chain_datum_tx_out_ext.h +++ b/modules/common/include/dap_chain_datum_tx_out_ext.h @@ -29,9 +29,6 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" -#ifdef __cplusplus -extern "C" { -#endif typedef struct dap_chain_tx_out_ext{ struct { dap_chain_tx_item_type_t type; // Transaction item type - should be TX_ITEM_TYPE_OUT_EXT @@ -40,7 +37,3 @@ typedef struct dap_chain_tx_out_ext{ dap_chain_addr_t addr; // Address to transfer to const char token[DAP_CHAIN_TICKER_SIZE_MAX]; // Which token is transferred } DAP_PACKED dap_chain_tx_out_ext_t; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_pkey.h b/modules/common/include/dap_chain_datum_tx_pkey.h index 817f6b2244..117d906c00 100644 --- a/modules/common/include/dap_chain_datum_tx_pkey.h +++ b/modules/common/include/dap_chain_datum_tx_pkey.h @@ -28,10 +28,6 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" -#ifdef __cplusplus -extern "C" { -#endif - /** * @struct dap_chain_tx_pkey * @brief TX item with one of the transaction's public keys @@ -45,7 +41,3 @@ typedef struct dap_chain_tx_pkey{ uint32_t seq_no; /// Sequence number, out of the header so could be changed during reorganization uint8_t pkey[]; /// @param sig @brief raw pkey dat } DAP_PACKED dap_chain_tx_pkey_t; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_sig.h b/modules/common/include/dap_chain_datum_tx_sig.h index 90bea9846d..93b5562b18 100644 --- a/modules/common/include/dap_chain_datum_tx_sig.h +++ b/modules/common/include/dap_chain_datum_tx_sig.h @@ -28,10 +28,6 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" -#ifdef __cplusplus -extern "C" { -#endif - /** * @struct dap_chain_tx_sig * @brief Section with set of transaction signatures @@ -44,7 +40,3 @@ typedef struct dap_chain_tx_sig{ } DAP_PACKED header; /// Only header's hash is used for verification uint8_t sig[]; /// @param sig @brief raw signature data } DAP_PACKED dap_chain_tx_sig_t; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_tsd.h b/modules/common/include/dap_chain_datum_tx_tsd.h index 1b3484b876..fc78dcd320 100644 --- a/modules/common/include/dap_chain_datum_tx_tsd.h +++ b/modules/common/include/dap_chain_datum_tx_tsd.h @@ -5,9 +5,6 @@ #include "dap_chain_datum_tx.h" #include "dap_tsd.h" -#ifdef __cplusplus -extern "C" { -#endif typedef struct dap_chain_tx_tsd { struct { dap_chain_tx_item_type_t type; @@ -16,6 +13,3 @@ typedef struct dap_chain_tx_tsd { byte_t tsd[]; } DAP_PACKED dap_chain_tx_tsd_t; -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/common/include/dap_chain_datum_tx_voting.h b/modules/common/include/dap_chain_datum_tx_voting.h index 91139d1bd9..a87c67824c 100644 --- a/modules/common/include/dap_chain_datum_tx_voting.h +++ b/modules/common/include/dap_chain_datum_tx_voting.h @@ -36,10 +36,6 @@ #define DAP_CHAIN_DATUM_TX_VOTING_OPTION_MAX_LENGTH 100 #define DAP_CHAIN_DATUM_TX_VOTING_OPTION_MAX_COUNT 10 -#ifdef __cplusplus -extern "C" { -#endif - typedef enum dap_chain_datum_voting_tsd_type { VOTING_TSD_TYPE_QUESTION = 0x01, VOTING_TSD_TYPE_ANSWER, @@ -76,6 +72,10 @@ typedef struct dap_chain_datum_tx_voting_params { bool vote_changing_allowed; } dap_chain_datum_tx_voting_params_t; +#ifdef __cplusplus +extern "C" { +#endif + dap_chain_datum_tx_voting_params_t *dap_chain_voting_parse_tsd(dap_chain_datum_tx_t* a_tx); diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index bfbee3ca8d..3f0b2aa997 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -40,10 +40,6 @@ #define DAP_CHAIN_NET_SRV_TRANSFER_ID 0x09 #define DAP_CHAIN_NET_SRV_BLOCK_REWARD_ID 0x08 -#ifdef __cplusplus -extern "C" { -#endif - typedef struct dap_ledger { dap_chain_net_t *net; void *_internal; @@ -109,66 +105,6 @@ typedef enum dap_ledger_check_error { DAP_LEDGER_TX_CHECK_MULTIPLE_OUTS_TO_OTHER_NET, } dap_ledger_check_error_t; -DAP_STATIC_INLINE const char *dap_ledger_check_error_str(dap_ledger_check_error_t a_error) -{ - switch (a_error) { - case DAP_LEDGER_CHECK_OK: return "No error"; - case DAP_LEDGER_CHECK_INVALID_ARGS: return "Invalid arguments"; - case DAP_LEDGER_CHECK_INVALID_SIZE: return "Incorrect size of datum or datum's content"; - case DAP_LEDGER_CHECK_ALREADY_CACHED: return "Datum already cached in ledger"; - case DAP_LEDGER_CHECK_PARSE_ERROR: return "Incorrect datum interrnal structure, can't pasre it"; - case DAP_LEDGER_CHECK_APPLY_ERROR: return "Datum can't be applied"; - case DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY: return "Not enough memory"; - case DAP_LEDGER_CHECK_INTEGER_OVERFLOW: return "Incorrect datum values relationship lead to integer overflow, can't process"; - case DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS: return "No enough valid signatures in datum"; - case DAP_LEDGER_CHECK_TICKER_NOT_FOUND: return "Can't find specified token ticker"; - case DAP_LEDGER_CHECK_ZERO_VALUE: return "Unacceptable zero value"; - case DAP_LEDGER_CHECK_ADDR_FORBIDDEN: return "Specified address is forbidden"; - case DAP_LEDGER_CHECK_WHITELISTED: return "Datum is in hard accept list"; - /* TX check return codes */ - case DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED: return "Double spend attempt for emission"; - case DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED: return "Double spend attempt for stake-lock emission"; - case DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND: return "Specified emission not found in ledger"; - case DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS: return "Transaction has no valid inputs, can't process"; - case DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN: return "Incorrect deledated token specified in stake-lock transaction"; - case DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS: return "Condtional output for stake-lock emission not found"; - case DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS: return "Tokenized output for stake-lock girdled emission not found"; - case DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX: return "Output for basic transaction not found"; - case DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE: return "Incorrect value for stake-lock emission, should be stake * rate"; - case DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED: return "Incorrect token ticker for stake-lock emission"; - case DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED: return "Double spend attempt for transaction output"; - case DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND: return "No previous transaction found"; - case DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND: return "Specified output number not found in previous transaction"; - case DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED: return "Previuos transaction output has unknown type, possible ledger corruption"; - case DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH: return "Trying to spend transaction output from wrongful wallet"; - case DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX: return "Double spend attempt within single transaction"; - case DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET: return "No verificator found for specified conditional ipnput"; - case DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE: return "Verificator check return error"; - case DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS: return "Sum of transaction outputs isn't equal to sum of its inputs"; - case DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED: return "Double spend attempt for reward"; - case DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL: return "Wrongful reward item in transaction"; - case DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER: return "Can't calculate main ticker found for transaction"; - case DAP_LEDGER_TX_CHECK_UNEXPECTED_TOKENIZED_OUT: return "Tokenized out is forbidden for single-channel transactions"; - case DAP_LEDGER_TX_CHECK_NOT_ENOUGH_FEE: return "Not enough network fee for transaction processing"; - case DAP_LEDGER_TX_CHECK_NOT_ENOUGH_TAX: return "Not enough sovereign tax provided with current transaction"; - case DAP_LEDGER_TX_CHECK_FOR_REMOVING_CANT_FIND_TX: return "Can't find tx in ledger for removing."; - case DAP_LEDGER_TX_CHECK_MULTIPLE_OUTS_TO_OTHER_NET: return "The transaction was rejected because it contains multiple outputs to other networks."; - /* Emisssion check return codes */ - case DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY: return "Value of emission execeeds current token supply"; - case DAP_LEDGER_EMISSION_CHECK_LEGACY_FORBIDDEN: return "Legacy type of emissions are present for old chains comliance only"; - /* Token declaration/update return codes */ - case DAP_LEDGER_TOKEN_ADD_CHECK_NOT_ENOUGH_UNIQUE_SIGNS: return "Not all token signs is unique"; - case DAP_LEDGER_TOKEN_ADD_CHECK_LEGACY_FORBIDDEN: return "Legacy type of tokens are present for old chains comliance only"; - case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_SUPPLY: return "Specified supply must be greater than current one"; - case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR: return "Specified address has invalid format"; - case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH: return "Specified address can't be processed cause double (for adding) or absent (for removing)"; - case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH: return "Specified public key or its hash can't be processed cause double (for adding) or absent (for removing)"; - case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN: return "Specified TSD section type is not allowed in datum token of specified type"; - case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED: return "Incorrect token ticker for delegated token"; - default: return "Unknown error"; - } -} - typedef enum dap_chan_ledger_notify_opcodes{ DAP_LEDGER_NOTIFY_OPCODE_ADDED = 'a', // 0x61 DAP_LEDGER_NOTIFY_OPCODE_DELETED = 'd', // 0x64 @@ -210,18 +146,6 @@ typedef struct dap_ledger_datum_iter_data { dap_chain_net_srv_uid_t uid; } dap_ledger_datum_iter_data_t; -typedef int (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); -typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_in_hash, dap_chain_tx_out_cond_t *a_prev_cond); -typedef void (*dap_ledger_delete_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_chain_tx_out_cond_t *a_prev_cond); -typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, dap_chan_ledger_notify_opcodes_t a_opcode); -typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg, dap_chan_ledger_notify_opcodes_t a_opcode); -typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash); -typedef struct dap_chain_net dap_chain_net_t; -typedef int (*dap_chain_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_apply); -typedef bool (*dap_chain_ledger_voting_delete_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx); -typedef bool (*dap_ledger_tag_check_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action); - - //Change this UUID to automatically reload ledger cache on next node startup #define DAP_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc" @@ -256,6 +180,84 @@ typedef bool (*dap_ledger_tag_check_callback_t)(dap_ledger_t *a_ledger, dap_chai #define DAP_LEDGER_SPENT_TXS_STR "spent_txs" #define DAP_LEDGER_BALANCES_STR "balances" +#ifdef __cplusplus +extern "C" { +#endif + +DAP_STATIC_INLINE const char *dap_ledger_check_error_str(dap_ledger_check_error_t a_error) +{ + switch (a_error) { + case DAP_LEDGER_CHECK_OK: return "No error"; + case DAP_LEDGER_CHECK_INVALID_ARGS: return "Invalid arguments"; + case DAP_LEDGER_CHECK_INVALID_SIZE: return "Incorrect size of datum or datum's content"; + case DAP_LEDGER_CHECK_ALREADY_CACHED: return "Datum already cached in ledger"; + case DAP_LEDGER_CHECK_PARSE_ERROR: return "Incorrect datum interrnal structure, can't pasre it"; + case DAP_LEDGER_CHECK_APPLY_ERROR: return "Datum can't be applied"; + case DAP_LEDGER_CHECK_NOT_ENOUGH_MEMORY: return "Not enough memory"; + case DAP_LEDGER_CHECK_INTEGER_OVERFLOW: return "Incorrect datum values relationship lead to integer overflow, can't process"; + case DAP_LEDGER_CHECK_NOT_ENOUGH_VALID_SIGNS: return "No enough valid signatures in datum"; + case DAP_LEDGER_CHECK_TICKER_NOT_FOUND: return "Can't find specified token ticker"; + case DAP_LEDGER_CHECK_ZERO_VALUE: return "Unacceptable zero value"; + case DAP_LEDGER_CHECK_ADDR_FORBIDDEN: return "Specified address is forbidden"; + case DAP_LEDGER_CHECK_WHITELISTED: return "Datum is in hard accept list"; + /* TX check return codes */ + case DAP_LEDGER_TX_CHECK_IN_EMS_ALREADY_USED: return "Double spend attempt for emission"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_IN_EMS_ALREADY_USED: return "Double spend attempt for stake-lock emission"; + case DAP_LEDGER_TX_CHECK_EMISSION_NOT_FOUND: return "Specified emission not found in ledger"; + case DAP_LEDGER_TX_CHECK_TX_NO_VALID_INPUTS: return "Transaction has no valid inputs, can't process"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_INVALID_TOKEN: return "Incorrect deledated token specified in stake-lock transaction"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_NO_OUT_COND_FOR_IN_EMS: return "Condtional output for stake-lock emission not found"; + case DAP_LEDGER_TX_CHECK_NO_OUT_EXT_FOR_GIRDLED_IN_EMS: return "Tokenized output for stake-lock girdled emission not found"; + case DAP_LEDGER_TX_CHECK_NO_OUT_ITEMS_FOR_BASE_TX: return "Output for basic transaction not found"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_UNEXPECTED_VALUE: return "Incorrect value for stake-lock emission, should be stake * rate"; + case DAP_LEDGER_TX_CHECK_STAKE_LOCK_OTHER_TICKER_EXPECTED: return "Incorrect token ticker for stake-lock emission"; + case DAP_LEDGER_TX_CHECK_OUT_ITEM_ALREADY_USED: return "Double spend attempt for transaction output"; + case DAP_LEDGER_TX_CHECK_PREV_TX_NOT_FOUND: return "No previous transaction found"; + case DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_NOT_FOUND: return "Specified output number not found in previous transaction"; + case DAP_LEDGER_TX_CHECK_PREV_OUT_ITEM_MISSTYPED: return "Previuos transaction output has unknown type, possible ledger corruption"; + case DAP_LEDGER_TX_CHECK_PKEY_HASHES_DONT_MATCH: return "Trying to spend transaction output from wrongful wallet"; + case DAP_LEDGER_TX_CHECK_PREV_OUT_ALREADY_USED_IN_CURRENT_TX: return "Double spend attempt within single transaction"; + case DAP_LEDGER_TX_CHECK_NO_VERIFICATOR_SET: return "No verificator found for specified conditional ipnput"; + case DAP_LEDGER_TX_CHECK_VERIFICATOR_CHECK_FAILURE: return "Verificator check return error"; + case DAP_LEDGER_TX_CHECK_SUM_INS_NOT_EQUAL_SUM_OUTS: return "Sum of transaction outputs isn't equal to sum of its inputs"; + case DAP_LEDGER_TX_CHECK_REWARD_ITEM_ALREADY_USED: return "Double spend attempt for reward"; + case DAP_LEDGER_TX_CHECK_REWARD_ITEM_ILLEGAL: return "Wrongful reward item in transaction"; + case DAP_LEDGER_TX_CHECK_NO_MAIN_TICKER: return "Can't calculate main ticker found for transaction"; + case DAP_LEDGER_TX_CHECK_UNEXPECTED_TOKENIZED_OUT: return "Tokenized out is forbidden for single-channel transactions"; + case DAP_LEDGER_TX_CHECK_NOT_ENOUGH_FEE: return "Not enough network fee for transaction processing"; + case DAP_LEDGER_TX_CHECK_NOT_ENOUGH_TAX: return "Not enough sovereign tax provided with current transaction"; + case DAP_LEDGER_TX_CHECK_FOR_REMOVING_CANT_FIND_TX: return "Can't find tx in ledger for removing."; + case DAP_LEDGER_TX_CHECK_MULTIPLE_OUTS_TO_OTHER_NET: return "The transaction was rejected because it contains multiple outputs to other networks."; + /* Emisssion check return codes */ + case DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY: return "Value of emission execeeds current token supply"; + case DAP_LEDGER_EMISSION_CHECK_LEGACY_FORBIDDEN: return "Legacy type of emissions are present for old chains comliance only"; + /* Token declaration/update return codes */ + case DAP_LEDGER_TOKEN_ADD_CHECK_NOT_ENOUGH_UNIQUE_SIGNS: return "Not all token signs is unique"; + case DAP_LEDGER_TOKEN_ADD_CHECK_LEGACY_FORBIDDEN: return "Legacy type of tokens are present for old chains comliance only"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_SUPPLY: return "Specified supply must be greater than current one"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_INVALID_ADDR: return "Specified address has invalid format"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH: return "Specified address can't be processed cause double (for adding) or absent (for removing)"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH: return "Specified public key or its hash can't be processed cause double (for adding) or absent (for removing)"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN: return "Specified TSD section type is not allowed in datum token of specified type"; + case DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED: return "Incorrect token ticker for delegated token"; + default: return "Unknown error"; + } +} + + +typedef int (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_tx_out_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); +typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_hash_fast_t *a_tx_in_hash, dap_chain_tx_out_cond_t *a_prev_cond); +typedef void (*dap_ledger_delete_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx_in, dap_chain_tx_out_cond_t *a_prev_cond); +typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, dap_chan_ledger_notify_opcodes_t a_opcode); +typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg, dap_chan_ledger_notify_opcodes_t a_opcode); +typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash); +typedef struct dap_chain_net dap_chain_net_t; +typedef int (*dap_chain_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_apply); +typedef bool (*dap_chain_ledger_voting_delete_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx); +typedef bool (*dap_ledger_tag_check_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action); + + + int dap_ledger_init(); void dap_ledger_deinit(); diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index 9d47cc67b1..2d15a72444 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -41,10 +41,6 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #define DAP_CHAIN_NET_MEMPOOL_TTL 4 * 3600 // 4 hours #define DAP_CHAIN_NET_NODES_TTL 14 * 24 * 3600 // 2 weeks -#ifdef __cplusplus -extern "C" { -#endif - typedef struct dap_chain_node_client dap_chain_node_client_t; typedef struct dap_ledger dap_ledger_t; typedef struct dap_chain_net_decree dap_chain_net_decree_t; @@ -81,6 +77,38 @@ typedef struct dap_chain_net { uint8_t pvt[]; } dap_chain_net_t; +enum dap_chain_net_json_rpc_error_list{ + DAP_CHAIN_NET_JSON_RPC_OK, + DAP_CHAIN_NET_JSON_RPC_INVALID_PARAMETER_HASH = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NET_JSON_RPC_CAN_NOT_PARAMETER_NET_REQUIRE, + DAP_CHAIN_NET_JSON_RPC_WRONG_NET, + DAP_CHAIN_NET_JSON_RPC_MANY_ARGUMENT_FOR_COMMAND_NET_LIST, + DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_STATS, + DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_GO, + DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_ADDR_COMMAND_INFO, + DAP_CHAIN_NET_JSON_RPC_CANT_CALCULATE_HASH_FOR_ADDR, + DAP_CHAIN_NET_JSON_RPC_CAN_NOT_GET_CLUSTER, + DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_COMMAND_LINK, + DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_COMMAND_SYNC, + DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_CA_ADD, + DAP_CHAIN_NET_JSON_RPC_CAN_NOT_FIND_CERT_CA_ADD, + DAP_CHAIN_NET_JSON_RPC_CAN_NOT_KEY_IN_CERT_CA_ADD, + DAP_CHAIN_NET_JSON_RPC_CAN_SERIALIZE_PUBLIC_KEY_CERT_CA_ADD, + DAP_CHAIN_NET_JSON_RPC_DATABASE_ACL_GROUP_NOT_DEFINED_FOR_THIS_NETWORK_CA_ADD, + DAP_CHAIN_NET_JSON_RPC_CAN_NOT_SAVE_PUBLIC_KEY_IN_DATABASE, + DAP_CHAIN_NET_JSON_RPC_DATABASE_ACL_GROUP_NOT_DEFINED_FOR_THIS_NETWORK_CA_LIST, + DAP_CHAIN_NET_JSON_RPC_UNKNOWN_HASH_CA_DEL, + DAP_CHAIN_NET_JSON_RPC_DATABASE_ACL_GROUP_NOT_DEFINED_FOR_THIS_NETWORK_CA_DEL, + DAP_CHAIN_NET_JSON_RPC_CAN_NOT_FIND_CERT_CA_DEL, + DAP_CHAIN_NET_JSON_RPC_INVALID_PARAMETER_COMMAND_CA, + DAP_CHAIN_NET_JSON_RPC_NO_POA_CERTS_FOUND_POA_CERTS, + DAP_CHAIN_NET_JSON_RPC_UNKNOWN_SUBCOMMANDS +}; + +#ifdef __cplusplus +extern "C" { +#endif + DAP_STATIC_INLINE int dap_chain_net_id_parse(const char *a_id_str, dap_chain_net_id_t *a_id) { uint64_t l_id; @@ -211,33 +239,6 @@ struct json_object *dap_chain_net_states_json_collect(dap_chain_net_t * l_net); struct json_object *dap_chain_net_list_json_collect(); struct json_object *dap_chain_nets_info_json_collect(); -enum dap_chain_net_json_rpc_error_list{ - DAP_CHAIN_NET_JSON_RPC_OK, - DAP_CHAIN_NET_JSON_RPC_INVALID_PARAMETER_HASH = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, - DAP_CHAIN_NET_JSON_RPC_CAN_NOT_PARAMETER_NET_REQUIRE, - DAP_CHAIN_NET_JSON_RPC_WRONG_NET, - DAP_CHAIN_NET_JSON_RPC_MANY_ARGUMENT_FOR_COMMAND_NET_LIST, - DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_STATS, - DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_GO, - DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_ADDR_COMMAND_INFO, - DAP_CHAIN_NET_JSON_RPC_CANT_CALCULATE_HASH_FOR_ADDR, - DAP_CHAIN_NET_JSON_RPC_CAN_NOT_GET_CLUSTER, - DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_COMMAND_LINK, - DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_COMMAND_SYNC, - DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_CA_ADD, - DAP_CHAIN_NET_JSON_RPC_CAN_NOT_FIND_CERT_CA_ADD, - DAP_CHAIN_NET_JSON_RPC_CAN_NOT_KEY_IN_CERT_CA_ADD, - DAP_CHAIN_NET_JSON_RPC_CAN_SERIALIZE_PUBLIC_KEY_CERT_CA_ADD, - DAP_CHAIN_NET_JSON_RPC_DATABASE_ACL_GROUP_NOT_DEFINED_FOR_THIS_NETWORK_CA_ADD, - DAP_CHAIN_NET_JSON_RPC_CAN_NOT_SAVE_PUBLIC_KEY_IN_DATABASE, - DAP_CHAIN_NET_JSON_RPC_DATABASE_ACL_GROUP_NOT_DEFINED_FOR_THIS_NETWORK_CA_LIST, - DAP_CHAIN_NET_JSON_RPC_UNKNOWN_HASH_CA_DEL, - DAP_CHAIN_NET_JSON_RPC_DATABASE_ACL_GROUP_NOT_DEFINED_FOR_THIS_NETWORK_CA_DEL, - DAP_CHAIN_NET_JSON_RPC_CAN_NOT_FIND_CERT_CA_DEL, - DAP_CHAIN_NET_JSON_RPC_INVALID_PARAMETER_COMMAND_CA, - DAP_CHAIN_NET_JSON_RPC_NO_POA_CERTS_FOUND_POA_CERTS, - DAP_CHAIN_NET_JSON_RPC_UNKNOWN_SUBCOMMANDS -}; dap_chain_net_decree_t *dap_chain_net_get_net_decree(dap_chain_net_t *a_net); void dap_chain_net_set_net_decree(dap_chain_net_t *a_net, dap_chain_net_decree_t *a_decree); decree_table_t **dap_chain_net_get_decrees(dap_chain_net_t *a_net); diff --git a/modules/net/include/dap_chain_net_balancer.h b/modules/net/include/dap_chain_net_balancer.h index e005eea71d..3390633718 100644 --- a/modules/net/include/dap_chain_net_balancer.h +++ b/modules/net/include/dap_chain_net_balancer.h @@ -30,9 +30,6 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #define DAP_BALANCER_PROTOCOL_VERSION 2 #define DAP_BALANCER_MAX_REPLY_SIZE 2048 -#ifdef __cplusplus -extern "C" { -#endif typedef struct dap_balancer_request_info dap_balancer_request_info_t; @@ -56,6 +53,10 @@ typedef struct dap_balancer_link_request { dap_balancer_type_t type; } dap_balancer_link_request_t; +#ifdef __cplusplus +extern "C" { +#endif + DAP_STATIC_INLINE const char *dap_chain_net_balancer_type_to_str(dap_balancer_type_t a_type) { switch (a_type) { diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h index dcb2bceee1..ed4658b184 100644 --- a/modules/net/include/dap_chain_net_decree.h +++ b/modules/net/include/dap_chain_net_decree.h @@ -25,9 +25,6 @@ #include "dap_list.h" #include "dap_chain_net.h" -#ifdef __cplusplus -extern "C" { -#endif typedef struct dap_chain_net_decree { dap_list_t *pkeys; @@ -35,6 +32,10 @@ typedef struct dap_chain_net_decree { uint16_t min_num_of_owners; } dap_chain_net_decree_t; +#ifdef __cplusplus +extern "C" { +#endif + int dap_chain_net_decree_init(dap_chain_net_t *a_net); int dap_chain_net_decree_deinit(dap_chain_net_t *a_net); diff --git a/modules/net/include/dap_chain_net_node_list.h b/modules/net/include/dap_chain_net_node_list.h index f61624c9b4..d438ee2c60 100644 --- a/modules/net/include/dap_chain_net_node_list.h +++ b/modules/net/include/dap_chain_net_node_list.h @@ -29,9 +29,6 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #define DAP_NODE_LIST_URI_HASH "node_list_hash" -#ifdef __cplusplus -extern "C" { -#endif struct node_link_request { dap_chain_node_info_t *link_info; @@ -46,6 +43,10 @@ struct node_link_request { int response; }; +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief dap_chain_net_node_list_get_gdb_group * @param a_net diff --git a/modules/net/include/dap_chain_net_tx.h b/modules/net/include/dap_chain_net_tx.h index b729a75025..0447fcb165 100644 --- a/modules/net/include/dap_chain_net_tx.h +++ b/modules/net/include/dap_chain_net_tx.h @@ -27,10 +27,6 @@ #include "dap_chain_datum_tx_items.h" #include "dap_json_rpc_errors.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef enum s_com_tx_create_json_err { DAP_CHAIN_NET_TX_CREATE_JSON_OK = 0, DAP_CHAIN_NET_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, @@ -82,6 +78,11 @@ typedef struct dap_chain_datum_tx_cond_list_item { dap_hash_fast_t hash; dap_chain_datum_tx_t *tx; } dap_chain_datum_tx_cond_list_item_t; + +#ifdef __cplusplus +extern "C" { +#endif + // TX functions dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_tx_hash, dap_chain_net_tx_search_type_t a_search_type); diff --git a/modules/net/include/dap_chain_node.h b/modules/net/include/dap_chain_node.h index a6d46f8c51..19da1cc694 100644 --- a/modules/net/include/dap_chain_node.h +++ b/modules/net/include/dap_chain_node.h @@ -28,9 +28,6 @@ #include "dap_chain.h" #include "dap_client.h" -#ifdef __cplusplus -extern "C" { -#endif typedef struct dap_chain_net dap_chain_net_t; @@ -72,6 +69,9 @@ typedef dap_stream_node_addr_t dap_chain_node_addr_t; #define dap_chain_node_addr_from_str dap_stream_node_addr_from_str #define dap_chain_node_addr_is_blank dap_stream_node_addr_is_blank +#ifdef __cplusplus +extern "C" { +#endif /** * Calculate size of struct dap_chain_node_info_t */ diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index 3b8871adf0..c084731bb3 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -31,18 +31,37 @@ #include "dap_chain_node_cli.h" #include "json.h" -#ifdef __cplusplus -extern "C" { -#endif +typedef enum s_com_tx_history_err{ + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_OK = 0, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_PARAM_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_HASH_REC_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_NET_PARAM_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_INCOMPATIBLE_PARAMS_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_WALLET_ADDR_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ID_NET_ADDR_DIF_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ADDR_WALLET_DIF_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_WALLET_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_NET_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_CHAIN_PARAM_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_TX_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ADDR_ERR, + DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ALL_ERR, -int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(json_object* a_json_arr_reply, int *a_arg_index, int a_argc, - char **a_argv, - dap_chain_t **a_chain, dap_chain_net_t **a_net, - dap_chain_type_t a_default_chain_type); + /* add custom codes here */ + //DAP_CHAIN_NODE_CLI_COM_TX_UNKNOWN /* MAX */ +} s_com_tx_history_err_t; -int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int a_argc, char **a_argv, void **a_str_reply, - dap_chain_t ** a_chain, dap_chain_net_t ** a_net, dap_chain_type_t a_default_chain_type); +typedef enum cmd_find_list_err { + DAP_CHAIN_NODE_CLI_FIND_OK = 0, + DAP_CHAIN_NODE_CLI_FIND_ERR_PARSE_HASH = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NODE_CLI_FUND_ERR_UNKNOWN_SUBCMD, + DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED, + DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_SUBTYPE_DECREE, + DAP_CHIAN_NODE_CLI_FIND_ERR_SUBTYPE_DECREE_IS_NOT_SPECIFIED, + DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_PARAMETR_WHERE, +}cmd_find_list_err_t; typedef enum s_com_parse_net_chain_err{ DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_STR_ERR = 100, @@ -54,12 +73,6 @@ typedef enum s_com_parse_net_chain_err{ DAP_CHAIN_NODE_CLI_COM_PARSE_NET_UNKNOWN /* MAX */ } s_com_parse_net_chain_err_t; - - -/** - * global_db command - */ -int com_global_db(int a_argc, char **a_argv, void **a_str_reply); typedef enum s_com_global_db_json_err { DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_JSON_OK = 0, @@ -92,62 +105,6 @@ typedef enum s_com_global_db_json_err { DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL }s_com_global_db_json_err_t; -/** - * Node command - */ -int com_node(int a_argc, char **a_argv, void **a_str_reply); - -#ifndef DAP_OS_ANDROID -/** - * Traceroute command - * - * return 0 OK, -1 Err - */ -int com_traceroute(int a_argc, char** argv, void **a_str_reply); - -/** - * Tracepath command - * - * return 0 OK, -1 Err - */ -int com_tracepath(int a_argc, char** argv, void **a_str_reply); - -/** - * Ping command - * - * return 0 OK, -1 Err - */ -int com_ping(int a_argc, char** argv, void **a_str_reply); -#endif -/** - * Help command - */ -int com_help(int a_argc, char **a_argv, void **a_str_reply); - -int com_version(int a_argc, char **a_argv, void **a_str_reply); - -/** - * Token declaration - */ -int com_token_decl(int a_argc, char **a_argv, void **a_str_reply); - -int com_token_update(int a_argc, char **a_argv, void **a_str_reply); - -/** - * Token declaration add sign - */ -int com_token_decl_sign ( int a_argc, char **a_argv, void **a_str_reply); - -/* - * Token update sign - */ -int com_token_update_sign(int argc, char ** argv, void **a_str_reply); - -/** - * Token emission - */ -int com_token_emit (int a_argc, char **a_argv, void **a_str_reply); - typedef enum s_com_tx_wallet_err{ DAP_CHAIN_NODE_CLI_COM_TX_WALLET_MEMORY_ERR, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_PARAM_ERR, @@ -176,13 +133,6 @@ typedef enum s_com_tx_wallet_err{ DAP_CHAIN_NODE_CLI_COM_TX_UNKNOWN /* MAX */ } s_com_tx_wallet_err_t; -/** - * com_tx_create command - * - * Wallet info - */ -int com_tx_wallet(int a_argc, char **a_argv, void **a_str_reply); - /** * com_tx_create command * @@ -214,9 +164,6 @@ typedef enum s_com_tx_create_err{ DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_CREATE_TRANSACTION, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS }s_com_tx_create_err_t; -int com_tx_create(int a_argc, char **a_argv, void **a_str_reply); - -int com_tx_create_json(int a_argc, char **a_argv, void **reply); typedef enum s_com_tx_cond_create{ DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_OK = 0, DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, @@ -238,7 +185,6 @@ typedef enum s_com_tx_cond_create{ DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CERT_DOES_NOT_CONATIN_VALID_PUBLIC_KEY, DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_CONDITIONAL_TX_CREATE }s_com_tx_cond_create_t; -int com_tx_cond_create(int a_argc, char **a_argv, void **reply); typedef enum s_com_tx_cond_remove{ DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OK = 0, DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, @@ -264,7 +210,6 @@ typedef enum s_com_tx_cond_remove{ DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_FIND_DEFAULT_CHAIN_WITH_TX_FOR_NET, DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OTHER_ERROR }s_com_tx_cond_remove_t; -int com_tx_cond_remove(int a_argc, char **a_argv, void **reply); typedef enum s_com_tx_cond_unspent_find{ DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_OK = 0, DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, @@ -277,8 +222,6 @@ typedef enum s_com_tx_cond_unspent_find{ DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NATIVE_TICKER_IN_NET, DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_LEDGER_FOR_NET, }s_com_tx_cond_unspent_find_t; -int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **reply); - typedef enum s_com_tx_verify{ DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_OK = 0, DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_REQUIRE_PARAMETER_TX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, @@ -288,6 +231,106 @@ typedef enum s_com_tx_verify{ DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_HASH_IS_NOT_TX_HASH, DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_TX_NOT_VERIFY }s_com_tx_verify_t; +typedef enum cmd_mempool_list_err{ + DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_OK = 0, + DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_CAN_NOT_READ_EMISSION, + DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_CHAIN_NOT_FOUND, + DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_CAN_NOT_GET_MEMPOOL_GROUP, + /* add custom codes here */ + + DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_UNKNOWN /* MAX */ +} cmd_mempool_list_err_t; + + +#ifdef __cplusplus +extern "C" { +#endif + +int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(json_object* a_json_arr_reply, int *a_arg_index, int a_argc, + char **a_argv, + dap_chain_t **a_chain, dap_chain_net_t **a_net, + dap_chain_type_t a_default_chain_type); + + +int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int a_argc, char **a_argv, void **a_str_reply, + dap_chain_t ** a_chain, dap_chain_net_t ** a_net, dap_chain_type_t a_default_chain_type); + + + +/** + * global_db command + */ +int com_global_db(int a_argc, char **a_argv, void **a_str_reply); +/** + * Node command + */ +int com_node(int a_argc, char **a_argv, void **a_str_reply); + +#ifndef DAP_OS_ANDROID +/** + * Traceroute command + * + * return 0 OK, -1 Err + */ +int com_traceroute(int a_argc, char** argv, void **a_str_reply); + +/** + * Tracepath command + * + * return 0 OK, -1 Err + */ +int com_tracepath(int a_argc, char** argv, void **a_str_reply); + +/** + * Ping command + * + * return 0 OK, -1 Err + */ +int com_ping(int a_argc, char** argv, void **a_str_reply); +#endif +/** + * Help command + */ +int com_help(int a_argc, char **a_argv, void **a_str_reply); + +int com_version(int a_argc, char **a_argv, void **a_str_reply); + +/** + * Token declaration + */ +int com_token_decl(int a_argc, char **a_argv, void **a_str_reply); + +int com_token_update(int a_argc, char **a_argv, void **a_str_reply); + +/** + * Token declaration add sign + */ +int com_token_decl_sign ( int a_argc, char **a_argv, void **a_str_reply); + +/* + * Token update sign + */ +int com_token_update_sign(int argc, char ** argv, void **a_str_reply); + +/** + * Token emission + */ +int com_token_emit (int a_argc, char **a_argv, void **a_str_reply); + +/** + * com_tx_create command + * + * Wallet info + */ +int com_tx_wallet(int a_argc, char **a_argv, void **a_str_reply); + +int com_tx_create(int a_argc, char **a_argv, void **a_str_reply); + +int com_tx_create_json(int a_argc, char **a_argv, void **reply); +int com_tx_cond_create(int a_argc, char **a_argv, void **reply); +int com_tx_cond_remove(int a_argc, char **a_argv, void **reply); +int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **reply); + /** * tx_verify command * @@ -296,27 +339,7 @@ typedef enum s_com_tx_verify{ int com_tx_verify(int a_argc, char ** a_argv, void **a_str_reply); -typedef enum s_com_tx_history_err{ - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_OK = 0, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_PARAM_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_HASH_REC_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_NET_PARAM_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_INCOMPATIBLE_PARAMS_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_WALLET_ADDR_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ID_NET_ADDR_DIF_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ADDR_WALLET_DIF_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_WALLET_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_NET_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_CHAIN_PARAM_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_TX_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ADDR_ERR, - DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ALL_ERR, - - /* add custom codes here */ - //DAP_CHAIN_NODE_CLI_COM_TX_UNKNOWN /* MAX */ -} s_com_tx_history_err_t; char *dap_chain_node_cli_com_tx_history_err(int a_code); @@ -339,15 +362,6 @@ int com_exit(int a_argc, char **a_argv, void **a_str_reply); int cmd_gdb_import(int a_argc, char **a_argv, void **a_str_reply); int cmd_gdb_export(int a_argc, char **a_argv, void **a_str_reply); -typedef enum cmd_mempool_list_err{ - DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_OK = 0, - DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_CAN_NOT_READ_EMISSION, - DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_CHAIN_NOT_FOUND, - DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_CAN_NOT_GET_MEMPOOL_GROUP, - /* add custom codes here */ - - DAP_CHAIN_NODE_CLI_COM_MEMPOOL_LIST_UNKNOWN /* MAX */ -} cmd_mempool_list_err_t; int com_mempool(int a_argc, char **a_argv, void **a_str_reply); /** * Place public CA into the mempool @@ -358,15 +372,6 @@ int com_signer(int a_argc, char **a_argv, void **a_str_reply); //remove func int cmd_remove(int a_argc, char **a_argv, void **a_str_reply); -typedef enum cmd_find_list_err { - DAP_CHAIN_NODE_CLI_FIND_OK = 0, - DAP_CHAIN_NODE_CLI_FIND_ERR_PARSE_HASH = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, - DAP_CHAIN_NODE_CLI_FUND_ERR_UNKNOWN_SUBCMD, - DAP_CHAIN_NODE_CLI_FIND_ERR_HASH_IS_NOT_SPECIFIED, - DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_SUBTYPE_DECREE, - DAP_CHIAN_NODE_CLI_FIND_ERR_SUBTYPE_DECREE_IS_NOT_SPECIFIED, - DAP_CHAIN_NODE_CLI_FIND_ERR_UNKNOWN_PARAMETR_WHERE, -}cmd_find_list_err_t; /** * Handler coomand find * @param a_argc 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 def00d9838..cd5e2cc7e2 100644 --- a/modules/net/include/dap_chain_node_cli_cmd_tx.h +++ b/modules/net/include/dap_chain_node_cli_cmd_tx.h @@ -29,15 +29,45 @@ #include "dap_chain_common.h" #include "dap_chain_net.h" -#ifdef __cplusplus -extern "C" { -#endif +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; + +typedef enum s_com_token_err{ + DAP_CHAIN_NODE_CLI_COM_TOKEN_OK = 0, + DAP_CHAIN_NODE_CLI_COM_TOKEN_PARAM_ERR, + DAP_CHAIN_NODE_CLI_COM_TOKEN_HASH_ERR, + DAP_CHAIN_NODE_CLI_COM_TOKEN_FOUND_ERR, + + /* add custom codes here */ + + DAP_CHAIN_NODE_CLI_COM_TOKEN_UNKNOWN /* MAX */ +} s_com_token_err_t; typedef struct dap_chain_tx_hash_processed_ht{ dap_chain_hash_fast_t hash; UT_hash_handle hh; }dap_chain_tx_hash_processed_ht_t; +#ifdef __cplusplus +extern "C" { +#endif + void s_dap_chain_tx_hash_processed_ht_free(dap_chain_tx_hash_processed_ht_t **l_hash_processed); /** @@ -79,40 +109,13 @@ bool s_dap_chain_datum_tx_out_data(json_object* a_json_arr_reply, */ 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 * */ int com_token(int a_argc, char ** a_argv, void **a_str_reply); -typedef enum s_com_token_err{ - DAP_CHAIN_NODE_CLI_COM_TOKEN_OK = 0, - DAP_CHAIN_NODE_CLI_COM_TOKEN_PARAM_ERR, - DAP_CHAIN_NODE_CLI_COM_TOKEN_HASH_ERR, - DAP_CHAIN_NODE_CLI_COM_TOKEN_FOUND_ERR, - - /* add custom codes here */ - - DAP_CHAIN_NODE_CLI_COM_TOKEN_UNKNOWN /* MAX */ -} s_com_token_err_t; /** * decree command * diff --git a/modules/net/include/dap_chain_node_client.h b/modules/net/include/dap_chain_node_client.h index b696f030bb..54e05ac384 100644 --- a/modules/net/include/dap_chain_node_client.h +++ b/modules/net/include/dap_chain_node_client.h @@ -30,10 +30,6 @@ #include "dap_chain_node.h" #include "dap_stream_ch_pkt.h" -#ifdef __cplusplus -extern "C" { -#endif - // connection states typedef enum dap_chain_node_client_state { NODE_CLIENT_STATE_ERROR = -1, @@ -110,6 +106,10 @@ typedef struct dap_chain_node_client { #define DAP_CHAIN_NODE_CLIENT(a) (a ? (dap_chain_node_client_t *) (a)->_inheritor : NULL) +#ifdef __cplusplus +extern "C" { +#endif + int dap_chain_node_client_init(); void dap_chain_node_client_deinit(void); diff --git a/modules/net/include/dap_chain_node_dns_client.h b/modules/net/include/dap_chain_node_dns_client.h index 0ce425c7a7..f2efb561a6 100644 --- a/modules/net/include/dap_chain_node_dns_client.h +++ b/modules/net/include/dap_chain_node_dns_client.h @@ -33,14 +33,14 @@ #define DNS_LISTEN_PORT 53 // UDP #define DNS_LISTEN_PORT_STR "53" // UDP -#ifdef __cplusplus -extern "C" { -#endif typedef struct _dap_dns_buf_t { char *data; uint32_t size; } dap_dns_buf_t; +#ifdef __cplusplus +extern "C" { +#endif // node info request callbacks typedef void (*dap_dns_client_node_info_request_success_callback_t) (dap_worker_t *a_worker, dap_chain_net_links_t *a_result, void *a_arg); typedef void (*dap_dns_client_node_info_request_error_callback_t) (dap_worker_t *a_worker, void *a_arg, int a_errno); diff --git a/modules/net/include/dap_chain_node_dns_server.h b/modules/net/include/dap_chain_node_dns_server.h index 56f79e1b26..d936863995 100644 --- a/modules/net/include/dap_chain_node_dns_server.h +++ b/modules/net/include/dap_chain_node_dns_server.h @@ -38,10 +38,6 @@ #define DNS_MAX_HOSTNAME_LEN 255 #define DNS_MAX_DOMAIN_NAME_LEN 63 -#ifdef __cplusplus -extern "C" { -#endif - typedef enum _dap_dns_query_type_t { DNS_QUERY_TYPE_STANDARD, DNS_QUERY_TYPE_INVERSE, @@ -119,7 +115,9 @@ typedef struct _dap_dns_server_t { dap_dns_zone_hash_t *hash_table; } dap_dns_server_t; - +#ifdef __cplusplus +extern "C" { +#endif void dap_dns_server_start(const char* a_cfg_section); void dap_dns_server_stop(); diff --git a/modules/wallet/include/dap_chain_coin.h b/modules/wallet/include/dap_chain_coin.h index 5395e039a5..766d093120 100644 --- a/modules/wallet/include/dap_chain_coin.h +++ b/modules/wallet/include/dap_chain_coin.h @@ -23,11 +23,3 @@ */ #pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/modules/wallet/include/dap_chain_wallet.h b/modules/wallet/include/dap_chain_wallet.h index ecea35b5f8..bb156cacc9 100644 --- a/modules/wallet/include/dap_chain_wallet.h +++ b/modules/wallet/include/dap_chain_wallet.h @@ -38,9 +38,6 @@ #define DAP_WALLET$M_FL_PROTECTED (1 << 0) /* Wallet is password protected */ #define DAP_WALLET$M_FL_ACTIVE (1 << 1) /* Has been activated (has been open with password) */ -#ifdef __cplusplus -extern "C" { -#endif typedef struct dap_chain_wallet{ char name[ DAP_WALLET$SZ_NAME + 1 ]; /* Human readable name of BMF Wallet */ @@ -50,6 +47,9 @@ typedef struct dap_chain_wallet{ } dap_chain_wallet_t; typedef void (*dap_chain_wallet_opened_callback_t)(dap_chain_wallet_t *a_wallet, void *a_arg); +#ifdef __cplusplus +extern "C" { +#endif int dap_chain_wallet_init(); void dap_chain_wallet_deinit(void); @@ -102,5 +102,5 @@ int dap_chain_wallet_add_wallet_created_notify(dap_chain_wallet_opened_callback_ dap_list_t* dap_chain_wallet_get_local_addr(); #ifdef __cplusplus -extern "C" { +} #endif \ No newline at end of file diff --git a/modules/wallet/include/dap_chain_wallet_cache.h b/modules/wallet/include/dap_chain_wallet_cache.h index d277fca4cd..197dcc6565 100644 --- a/modules/wallet/include/dap_chain_wallet_cache.h +++ b/modules/wallet/include/dap_chain_wallet_cache.h @@ -27,9 +27,6 @@ #include "dap_chain_common.h" #include "dap_chain_ledger.h" -#ifdef __cplusplus -extern "C" { -#endif typedef enum dap_chain_wallet_getting_type { DAP_CHAIN_WALLET_CACHE_GET_FIRST = 0, @@ -49,6 +46,10 @@ typedef struct dap_chain_wallet_cache_iter { void *cur_addr_cache; } dap_chain_wallet_cache_iter_t; +#ifdef __cplusplus +extern "C" { +#endif + int dap_chain_wallet_cache_init(); int dap_chain_wallet_cache_deinit(); diff --git a/modules/wallet/include/dap_chain_wallet_internal.h b/modules/wallet/include/dap_chain_wallet_internal.h index 40de3c46b6..f782ff40b9 100644 --- a/modules/wallet/include/dap_chain_wallet_internal.h +++ b/modules/wallet/include/dap_chain_wallet_internal.h @@ -31,9 +31,6 @@ #define DAP_CHAIN_WALLETS_FILE_SIGNATURE (uint64_t)0x1a167bef15feea18 -#ifdef __cplusplus -extern "C" { -#endif enum { DAP_WALLET$K_TYPE_PLAIN = 0, /* 0x00 - uncompressed and unencrypted */ @@ -99,7 +96,3 @@ typedef struct dap_chain_wallet_internal #define DAP_CHAIN_WALLET_INTERNAL(a) (a ? (dap_chain_wallet_internal_t *) a->_internal : NULL) #define DAP_CHAIN_WALLET_INTERNAL_LOCAL(a) dap_chain_wallet_internal_t * l_wallet_internal = DAP_CHAIN_WALLET_INTERNAL(a) #define DAP_CHAIN_WALLET_INTERNAL_LOCAL_NEW(a) dap_chain_wallet_internal_t * l_wallet_internal = DAP_NEW_Z(dap_chain_wallet_internal_t); a->_internal = l_wallet_internal - -#ifdef __cplusplus -} -#endif \ No newline at end of file -- GitLab From 79808f84a8e7f41985fcebb48a05fb481d807f32 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Mon, 20 Jan 2025 17:17:09 +0300 Subject: [PATCH 13/18] [+] Add net checking in wallet outputs command handler --- modules/net/dap_chain_node_cli_cmd.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 45bd7fcf2e..c82c41f381 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -1731,6 +1731,13 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; break; } case CMD_WALLET_OUTPUTS: { + if(!l_net) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR, + "Subcommand info requires parameter '-net'"); + json_object_put(json_arr_out); + return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR; + } + if ((l_wallet_name && l_addr_str) || (!l_wallet_name && !l_addr_str)) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NAME_ERR, "You should use either the -w or -addr option for the wallet info command."); @@ -1738,12 +1745,6 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NAME_ERR; } if(l_wallet_name) { - if(!l_net) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR, - "Subcommand info requires parameter '-net'"); - json_object_put(json_arr_out); - return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR; - } l_wallet = dap_chain_wallet_open(l_wallet_name, c_wallets_path, NULL); if (!l_wallet){ dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NET_PARAM_ERR, -- GitLab From 2172efa3509d75076d669738717cbb18d31b8931 Mon Sep 17 00:00:00 2001 From: "Constantin P." <papizh.konstantin@demlabs.net> Date: Tue, 21 Jan 2025 14:36:14 +0700 Subject: [PATCH 14/18] ... --- cellframe-sdk.pro | 4 ++-- dap-sdk | 2 +- modules/net/srv/CMakeLists.txt | 9 +++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cellframe-sdk.pro b/cellframe-sdk.pro index 3e1b5e1eaf..fbb7b419b0 100644 --- a/cellframe-sdk.pro +++ b/cellframe-sdk.pro @@ -9,8 +9,8 @@ linux: !android { win32 { - CONFIG(release, debug | release): sdk_build.commands = "$$shell_path($$PWD/../cellframe-sdk/prod_build/build.sh)" --target windows release -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCELLFRAME_NO_OPTIMIZATION=1 - CONFIG(debug, debug | release): sdk_build.commands = "$$shell_path($$PWD/../cellframe-sdk/prod_build/build.sh)" --target windows rwd -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCELLFRAME_NO_OPTIMIZATION=1 + CONFIG(release, debug | release): sdk_build.commands = "$$PWD/../cellframe-sdk/prod_build/build.sh" --target windows release -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCELLFRAME_NO_OPTIMIZATION=1 + CONFIG(debug, debug | release): sdk_build.commands = "$$PWD/../cellframe-sdk/prod_build/build.sh" --target windows rwd -DINSTALL_SDK=1 -DCMAKE_INSTALL_PREFIX=/ -DCELLFRAME_NO_OPTIMIZATION=1 } diff --git a/dap-sdk b/dap-sdk index da046e00eb..8092ada06d 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit da046e00ebeb5261ebcd874d5bdeeb05d37c9a0f +Subproject commit 8092ada06dca5730f2efb16f7851fbf7c1c29eb1 diff --git a/modules/net/srv/CMakeLists.txt b/modules/net/srv/CMakeLists.txt index c3e5655091..d48b0f9a3b 100644 --- a/modules/net/srv/CMakeLists.txt +++ b/modules/net/srv/CMakeLists.txt @@ -12,3 +12,12 @@ target_link_libraries(${PROJECT_NAME} maxminddb dap_core dap_crypto dap_chain da target_include_directories(${PROJECT_NAME} INTERFACE .) target_include_directories(${PROJECT_NAME} PUBLIC include) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../dap-sdk/3rdparty/uthash/src) + +if (INSTALL_SDK) +set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${DAP_CHAIN_NET_SRV_HEADERS}") +INSTALL(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION lib/modules/net/srv/ + ARCHIVE DESTINATION lib/modules/net/srv/ + PUBLIC_HEADER DESTINATION include/modules/net/srv/ +) +endif() -- GitLab From 46dc65646a77cc72283ce4f9ddc3b331e6f81239 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Thu, 23 Jan 2025 13:22:14 +0300 Subject: [PATCH 15/18] up sub --- dap-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dap-sdk b/dap-sdk index da046e00eb..1d22be263b 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit da046e00ebeb5261ebcd874d5bdeeb05d37c9a0f +Subproject commit 1d22be263bef8c792979827a94dfdbef6d74fc8c -- GitLab From d880fa3e08df9b527192c0bcd882999212753066 Mon Sep 17 00:00:00 2001 From: "P. Constantin" <papizh.konstantin@demlabs.net> Date: Thu, 23 Jan 2025 22:34:43 +0700 Subject: [PATCH 16/18] Signature serialization refined --- modules/net/dap_chain_net_tx.c | 122 ++++++++++++--------------------- 1 file changed, 45 insertions(+), 77 deletions(-) diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index f3affeae81..90e239b626 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -1186,68 +1186,46 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n } } break; - case TX_ITEM_TYPE_SIG:{ - const char *l_sign_type_str = s_json_get_text(l_json_item_obj, "sig_type"); - if (l_sign_type_str) { - dap_sign_type_t l_sign_type = dap_sign_type_from_str(l_sign_type_str); - if (l_sign_type.type == SIG_TYPE_NULL) { - json_object *l_jobj_err = json_object_new_string("Can't define sign type"); - json_object_array_add(l_jobj_errors, l_jobj_err); - log_it(L_ERROR, "Json TX: Can't define sign type \"%s\"", l_sign_type_str); - break; - } - int64_t l_pkey_size, l_sig_size, l_hash_type = 0; - - s_json_get_int64(l_json_item_obj, "hash_type", &l_hash_type); - s_json_get_int64(l_json_item_obj, "pub_key_size", &l_pkey_size); - s_json_get_int64(l_json_item_obj, "sig_size", &l_sig_size); - debug_if(!l_pkey_size || !l_sig_size, L_WARNING, - "\"pub_key_size\" or \"sig_size\" not provided! Will be calculated automatically"); - - json_object *l_jobj_pub_key = json_object_object_get(l_json_item_obj, "pub_key_b64"), - *l_jobj_sign = json_object_object_get(l_json_item_obj, "sig_b64"); - if (!l_jobj_pub_key || !l_jobj_sign) { - json_object *l_jobj_err = json_object_new_string("Can't get base64-encoded sign or pkey!"); - json_object_array_add(l_jobj_errors, l_jobj_err); - log_it(L_ERROR, "Json TX: Can't get base64-encoded sign or pkey!"); - break; + case TX_ITEM_TYPE_SIG: { + json_object *l_jobj_sign = json_object_object_get(l_json_item_obj, "sig_b64"); + if (!l_jobj_sign) { + l_sign_list = dap_list_append(l_sign_list, l_json_item_obj); + break; + } + const char *l_sign_b64_str = json_object_get_string(l_json_item_obj); + if ( !l_sign_b64_str ) { + json_object_array_add(l_jobj_errors, json_object_new_string("Can't get base64-encoded sign")); + log_it(L_ERROR, "Json TX: Can't get base64-encoded sign!"); + break; + } + int64_t l_sign_size = 0, l_sign_b64_strlen = json_object_get_string_len(l_json_item_obj), + l_sign_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(l_sign_b64_strlen); + if ( !s_json_get_int64(l_json_item_obj, "sig_size", &l_sign_size) ) + log_it(L_NOTICE, "Json TX: \"sig_size\" unspecified, will be calculated automatically"); + + dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t, sizeof(dap_chain_tx_sig_t) + l_sign_decoded_size); + *l_tx_sig = (dap_chain_tx_sig_t) { + .header = { + .type = TX_ITEM_TYPE_SIG, .version = 1, + .sig_size = dap_enc_base64_decode(l_sign_b64_str, l_sign_b64_strlen, l_tx_sig->sig, DAP_ENC_DATA_TYPE_B64_URLSAFE) } - const char *l_pub_key_str = json_object_get_string(l_jobj_pub_key), - *l_sign_str = json_object_get_string(l_jobj_sign); - int64_t l_pkey_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(strlen(l_pub_key_str)), - l_sign_decoded_size = DAP_ENC_BASE64_DECODE_SIZE(strlen(l_sign_str)); - - dap_sign_t *l_sign = DAP_NEW_SIZE(dap_sign_t, sizeof(dap_sign_t) + l_pkey_decoded_size + l_sign_decoded_size); - *l_sign = (dap_sign_t) { - .header.type = l_sign_type, - .header.hash_type = (uint8_t)l_hash_type, - }; - l_pkey_decoded_size = dap_enc_base64_decode(l_pub_key_str, strlen(l_pub_key_str), - l_sign->pkey_n_sign, DAP_ENC_DATA_TYPE_B64_URLSAFE); - debug_if(l_pkey_size != l_pkey_decoded_size, L_ERROR, "Json TX: pkey size mismatch, %zu != %zu", - l_pkey_size, l_pkey_decoded_size); - - l_sign_decoded_size = dap_enc_base64_decode(l_sign_str, strlen(l_sign_str), - l_sign->pkey_n_sign + l_pkey_decoded_size, DAP_ENC_DATA_TYPE_B64_URLSAFE); - debug_if(l_sig_size != l_sign_decoded_size, L_ERROR, "Json TX: sign size mismatch, %zu != %zu", - l_sig_size, l_sign_decoded_size); - - l_sign->header.sign_size = l_sign_decoded_size; - l_sign->header.sign_pkey_size = l_pkey_decoded_size; - size_t l_sign_full_size = dap_sign_get_size(l_sign); - - dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t, sizeof(dap_chain_tx_sig_t) + l_sign_full_size); - l_tx_sig->header.type = TX_ITEM_TYPE_SIG; - l_tx_sig->header.version = 1; - l_tx_sig->header.sig_size = (uint32_t)l_sign_full_size; - memcpy(l_tx_sig->sig, l_sign, l_sign_full_size); - l_item = (const uint8_t*)l_tx_sig; - DAP_DELETE(l_sign); + }; + + debug_if(l_sign_size && l_tx_sig->header.sig_size != l_sign_size, L_ERROR, + "Json TX: sign size mismatch, %zu != %zu!", l_sign_size, l_tx_sig->header.sig_size); + /* But who cares?... */ + size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx), l_tx_items_size = l_tx->header.tx_items_size; + l_tx->header.tx_items_size = 0; + if ( dap_sign_verify_all((dap_sign_t*)l_tx_sig->sig, l_tx_sig->header.sig_size, (byte_t*)l_tx, l_tx_size) ) { + json_object_array_add(l_jobj_errors, json_object_new_string("Sign verification failed!")); + log_it(L_ERROR, "Json TX: sign verification failed!"); break; - } else - l_sign_list = dap_list_append(l_sign_list,l_json_item_obj); - } - break; + // TODO: delete the datum and return + } else { + l_tx->header.tx_items_size = l_tx_items_size; + l_item = (const uint8_t*)l_tx_sig; + } + } break; case TX_ITEM_TYPE_RECEIPT: { dap_chain_net_srv_uid_t l_srv_uid; if(!s_json_get_srv_uid(l_json_item_obj, "service_id", "service", &l_srv_uid.uint64)) { @@ -1483,7 +1461,7 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n continue; } - if (l_sign) { + if (l_sign) { /* WTF is this for?... */ size_t l_chain_sign_size = dap_sign_get_size(l_sign); // sign data dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t, @@ -1563,23 +1541,13 @@ int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json } break; case TX_ITEM_TYPE_SIG: { dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*)item); - json_object_object_add(json_obj_item,"type", json_object_new_string("sign")); - dap_chain_hash_fast_t l_hash_pkey; - json_object_object_add(json_obj_item,"sig_type",json_object_new_string(dap_sign_type_to_str(l_sign->header.type))); - json_object_object_add(json_obj_item,"pub_key_size",json_object_new_uint64(l_sign->header.sign_pkey_size)); - json_object_object_add(json_obj_item,"sig_size",json_object_new_uint64(l_sign->header.sign_size)); - json_object_object_add(json_obj_item,"hash_type",json_object_new_uint64(l_sign->header.hash_type)); - - char l_pkey_base64[DAP_ENC_BASE64_ENCODE_SIZE(l_sign->header.sign_pkey_size) + 1]; - size_t l_pkey_base64_size = dap_enc_base64_encode(l_sign->pkey_n_sign, l_sign->header.sign_pkey_size, l_pkey_base64, DAP_ENC_DATA_TYPE_B64_URLSAFE); - l_pkey_base64[l_pkey_base64_size] = '\0'; - json_object_object_add(json_obj_item,"pub_key_b64", json_object_new_string(l_pkey_base64)); - - char l_sign_base64[DAP_ENC_BASE64_ENCODE_SIZE(l_sign->header.sign_size) + 1]; - size_t l_sign_base64_size = dap_enc_base64_encode(l_sign->pkey_n_sign + l_sign->header.sign_pkey_size, l_sign->header.sign_size, l_sign_base64, DAP_ENC_DATA_TYPE_B64_URLSAFE); - l_sign_base64[l_sign_base64_size] = '\0'; - json_object_object_add(json_obj_item,"sig_b64", json_object_new_string(l_sign_base64)); + char *l_sign_b64 = DAP_NEW_Z_SIZE(char, DAP_ENC_BASE64_ENCODE_SIZE(dap_sign_get_size(l_sign)) + 1); + size_t l_sign_size = dap_sign_get_size(l_sign); + dap_enc_base64_encode(l_sign, l_sign_size, l_sign_b64, DAP_ENC_DATA_TYPE_B64_URLSAFE); + json_object_object_add(json_obj_item, "type", json_object_new_string("sign")); + json_object_object_add(json_obj_item, "sig_size", json_object_new_uint64(l_sign_size)); + json_object_object_add(json_obj_item, "sig_b64", json_object_new_string(l_sign_b64)); } break; case TX_ITEM_TYPE_TSD: { json_object_object_add(json_obj_item,"type", json_object_new_string("data")); -- GitLab From 56a33e55f9e959523bbc7f72b55ca795cd63b425 Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Fri, 24 Jan 2025 10:15:27 +0300 Subject: [PATCH 17/18] [*] Fix hash output in voting list --- modules/service/voting/dap_chain_net_srv_voting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/service/voting/dap_chain_net_srv_voting.c b/modules/service/voting/dap_chain_net_srv_voting.c index d858aaf109..c74cf6fd33 100644 --- a/modules/service/voting/dap_chain_net_srv_voting.c +++ b/modules/service/voting/dap_chain_net_srv_voting.c @@ -919,7 +919,7 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply) continue; json_object* json_obj_vote = json_object_new_object(); json_object_object_add( json_obj_vote, "voting_tx", - json_object_new_string_len(dap_chain_hash_fast_to_str_static(&l_voting->voting_hash), sizeof(dap_hash_str_t)) ); + json_object_new_string(dap_chain_hash_fast_to_str_static(&l_voting->voting_hash))); char* l_voting_question = (char*)l_voting->voting_params.voting_tx + l_voting->voting_params.voting_question_offset; json_object_object_add( json_obj_vote, "question", json_object_new_string_len(l_voting_question, l_voting->voting_params.voting_question_length) ); -- GitLab From f360e6a4f6a028e7d080c3caa7eb3d8d0875f8ce Mon Sep 17 00:00:00 2001 From: "daniil.frolov" <daniil.frolov@demlabs.net> Date: Fri, 24 Jan 2025 12:54:29 +0300 Subject: [PATCH 18/18] Up sub --- dap-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dap-sdk b/dap-sdk index 1d22be263b..b714164dac 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 1d22be263bef8c792979827a94dfdbef6d74fc8c +Subproject commit b714164dac76d65db91fe470d684861812c022cf -- GitLab