From 4952a54f14f396f0cf5fb461b86231bb341decd0 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Mon, 17 Feb 2025 12:39:44 +0300 Subject: [PATCH 01/29] [+] add refill tsd section --- .../dap_chain_net_srv_emit_delegate.c | 24 +++++++++++++++---- .../include/dap_chain_net_srv_emit_delegate.h | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 3df74f1368..3cff09259e 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -60,6 +60,7 @@ static int s_emit_delegate_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_ uint256_t l_writeoff_value = uint256_0; dap_chain_tx_out_cond_t *l_cond_out = NULL; dap_chain_addr_t l_net_fee_addr; + uint16_t l_change_type = 0; bool l_net_fee_used = dap_chain_net_tx_get_fee(a_ledger->net->pub.id, NULL, &l_net_fee_addr); byte_t *l_item; size_t l_tx_item_size; TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx_in) { @@ -76,7 +77,7 @@ static int s_emit_delegate_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_ break; case TX_ITEM_TYPE_TSD: { dap_tsd_t *l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t *)l_item)->tsd; - if (l_tsd->type != DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF) + if (l_tsd->type != DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF && l_tsd->type != DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL) break; // Skip it if (l_tsd->size != sizeof(uint256_t)) { log_it(L_ERROR, "TSD section size control error"); @@ -87,6 +88,7 @@ static int s_emit_delegate_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_ return -5; } l_writeoff_value = dap_tsd_get_scalar(l_tsd, uint256_t); + l_change_type = l_tsd->type; break; } // Verify signs @@ -125,13 +127,22 @@ static int s_emit_delegate_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_ } uint256_t l_change_value; - if (SUBTRACT_256_256(a_cond->header.value, l_writeoff_value, &l_change_value)) { + if (l_change_type == DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF && SUBTRACT_256_256(a_cond->header.value, l_writeoff_value, &l_change_value)) { char *l_balance = dap_uint256_decimal_to_char(a_cond->header.value); - const char *l_writeoff; dap_uint256_to_char(l_writeoff_value, &l_writeoff); + const char *l_writeoff = NULL; + dap_uint256_to_char(l_change_value, &l_writeoff); log_it(L_ERROR, "Write-off value %s is greater than account balance %s", l_writeoff, l_balance); DAP_DELETE(l_balance); return -7; } + if (l_change_type == DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL && SUM_256_256(a_cond->header.value, l_writeoff_value, &l_change_value)) { + char *l_balance = dap_uint256_decimal_to_char(a_cond->header.value); + const char *l_refill = NULL; + dap_uint256_to_char(l_change_value, &l_refill); + log_it(L_ERROR, "Sum of re-fill value %s and account balance %s is greater than value limit of 256 bit num", l_refill, l_balance); + DAP_DELETE(l_balance); + return -9; + } if (!IS_ZERO_256(l_change_value)) { if (!l_cond_out) { log_it(L_ERROR, "Changeback on conditional output is need but not found"); @@ -351,7 +362,12 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje // coin back uint256_t l_value_back = {}; - SUBTRACT_256_256(l_cond_prev->header.value, l_value, &l_value_back); + bool l_refill = false; + if (l_refill) + SUM_256_256(l_cond_prev->header.value, l_value, &l_value_back); + else + SUBTRACT_256_256(l_cond_prev->header.value, l_value, &l_value_back); + if (!IS_ZERO_256(l_value_back)) { dap_chain_tx_out_cond_t *l_out_cond = DAP_DUP_SIZE(l_cond_prev, sizeof(dap_chain_tx_out_cond_t) + l_cond_prev->tsd_size); if (!l_out_cond) diff --git a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h index 8cca1e2faa..2580537280 100644 --- a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h +++ b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h @@ -2,6 +2,7 @@ #define DAP_CHAIN_NET_SRV_EMIT_DELEGATE_ID 0x07 #define DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF 0x14 +#define DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL 0x15 #include "dap_chain_datum_tx.h" #include "dap_chain_mempool.h" -- GitLab From f0dd81f9e1251065416ca172cdc743942c302ff7 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Tue, 18 Feb 2025 11:45:06 +0300 Subject: [PATCH 02/29] [*] add refill funcs --- .../dap_chain_net_srv_emit_delegate.c | 263 +++++++++++++++++- 1 file changed, 248 insertions(+), 15 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 3cff09259e..7c04cdf3a2 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -285,6 +285,119 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, return l_tx; } + +dap_chain_datum_tx_t *s_refilling_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, + uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) +{ + // create empty transaction + dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); + + dap_ledger_t *l_ledger = a_net->pub.ledger; + const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, a_tx_in_hash); + bool l_taking_native = !dap_strcmp(a_net->pub.native_ticker, l_tx_ticker); + + uint256_t l_value = a_value, l_value_transfer = {}; // how many coins to refill + uint256_t l_net_fee, l_fee_total = a_fee; + dap_chain_addr_t l_net_fee_addr; + + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr); + if (l_net_fee_used && SUM_256_256(l_fee_total, l_net_fee, &l_fee_total)) + m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); + if (SUM_256_256(l_value, l_fee_total, &l_value)) + m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); + + dap_chain_addr_t l_owner_addr; + dap_chain_addr_fill_from_key(&l_owner_addr, a_enc_key, a_net->pub.id); + dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_net->pub.native_ticker, + &l_owner_addr, l_value, &l_value_transfer); + if (!l_list_fee_out) + m_tx_fail(ERROR_FUNDS, "Nothing to pay for fee (not enough funds)"); + // add 'in' items to pay fee + uint256_t l_value_fee_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_fee_out); + dap_list_free_full(l_list_fee_out, NULL); + if (!EQUAL_256(l_value_fee_items, l_value_transfer)) + m_tx_fail(ERROR_COMPOSE, "Can't compose the fee transaction input"); + + dap_hash_fast_t l_final_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, a_tx_in_hash, false); + if (dap_hash_fast_is_blank(&l_final_tx_hash)) + m_tx_fail(ERROR_FUNDS, "Nothing to refill, can't find tx"); + + log_it(L_NOTICE, "Actual TX hash %s will be used for refill TX composing", dap_hash_fast_to_str_static(&l_final_tx_hash)); + dap_chain_datum_tx_t *l_tx_in = dap_ledger_tx_find_by_hash(l_ledger, &l_final_tx_hash); + assert(l_tx_in); + int l_prev_cond_idx = 0; + dap_chain_tx_out_cond_t *l_cond_prev = dap_chain_datum_tx_out_cond_get(l_tx_in, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, &l_prev_cond_idx); + if (!l_cond_prev) + m_tx_fail(ERROR_TX_MISMATCH, "Requested conditional transaction requires conditional output"); + + if (dap_ledger_tx_hash_is_used_out_item(l_ledger, &l_final_tx_hash, l_prev_cond_idx, NULL)) + m_tx_fail(ERROR_TX_MISMATCH, "Requested conditional transaction is already used out"); + + // add 'in_cond' item + if (dap_chain_datum_tx_add_in_cond_item(&l_tx, &l_final_tx_hash, l_prev_cond_idx, -1) != 1) { + log_it(L_ERROR, "Can't compose the transaction conditional input"); + m_tx_fail(ERROR_COMPOSE, "Cant add conditionsl input"); + } + + // coin back + uint256_t l_value_back = {}; + if(SUM_256_256(l_cond_prev->header.value, a_value, &l_value_back)) { + m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); + } + + dap_chain_tx_out_cond_t *l_out_cond = DAP_DUP_SIZE(l_cond_prev, sizeof(dap_chain_tx_out_cond_t) + l_cond_prev->tsd_size); + if (!l_out_cond) + m_tx_fail(ERROR_COMPOSE, c_error_memory_alloc); + l_out_cond->header.value = l_value_back; + if (dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond) < 0) { + m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); + DAP_DELETE(l_out_cond); + } + DAP_DELETE(l_out_cond); + + + // add track for takeoff from conditional value + dap_chain_tx_tsd_t *l_refill_tsd = NULL; + l_refill_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL, sizeof(uint256_t)); + + if (!l_refill_tsd || dap_chain_datum_tx_add_item(&l_tx, l_refill_tsd) != 1) + m_tx_fail(ERROR_COMPOSE, "Can't add TSD section item with withdraw value"); + DAP_DELETE(l_refill_tsd); + + //add other tsd if available + for ( dap_list_t *l_tsd = tsd_items; l_tsd; l_tsd = l_tsd->next ) { + if ( dap_chain_datum_tx_add_item(&l_tx, l_tsd->data) != 1 ) + m_tx_fail(ERROR_COMPOSE, "Can't add custom TSD section item "); + } + + // add fee items + if (l_net_fee_used) { + int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_net_fee_addr, l_net_fee) + : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_net_fee_addr, l_net_fee, a_net->pub.native_ticker); + if (rc != 1) + m_tx_fail(ERROR_COMPOSE, "Cant add net fee output"); + } + if (!IS_ZERO_256(a_fee) && dap_chain_datum_tx_add_fee_item(&l_tx, a_fee) != 1) + m_tx_fail(ERROR_COMPOSE, "Cant add validator fee output"); + + uint256_t l_fee_back = {}; + // fee coin back + SUBTRACT_256_256(l_value_transfer, l_value, &l_fee_back); + + if (!IS_ZERO_256(l_fee_back)) { + int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_owner_addr, l_fee_back) + : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, a_net->pub.native_ticker); + if (rc != 1) + m_tx_fail(ERROR_COMPOSE, "Cant add fee back output"); + } + + // add 'sign' item + if (dap_chain_datum_tx_add_sign_item(&l_tx, a_enc_key) != 1) + m_tx_fail(ERROR_COMPOSE, "Can't add sign output"); + + return l_tx; +} + static bool s_is_key_present(dap_chain_tx_out_cond_t *a_cond, dap_enc_key_t *a_enc_key) { if (!a_cond->tsd_size || !a_enc_key->pub_key_data_size) @@ -310,13 +423,16 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, a_tx_in_hash); bool l_taking_native = !dap_strcmp(a_net->pub.native_ticker, l_tx_ticker); - uint256_t l_value = a_value, l_fee_transfer = {}; // how many coins to transfer + uint256_t l_value = a_value, l_value_temp = a_value, l_fee_transfer = {}; // how many coins to transfer uint256_t l_net_fee, l_fee_total = a_fee; dap_chain_addr_t l_net_fee_addr; + bool l_refill = false; bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr); if (l_net_fee_used && SUM_256_256(l_fee_total, l_net_fee, &l_fee_total)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); + if (l_refill && (SUM_256_256(l_value_temp, l_value_temp, &l_value_temp) || SUM_256_256(l_value_temp, l_fee_total, &l_value_temp))) + m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); dap_chain_addr_t l_owner_addr; dap_chain_addr_fill_from_key(&l_owner_addr, a_enc_key, a_net->pub.id); @@ -362,7 +478,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje // coin back uint256_t l_value_back = {}; - bool l_refill = false; + if (l_refill) SUM_256_256(l_cond_prev->header.value, l_value, &l_value_back); else @@ -379,7 +495,11 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje } // add track for takeoff from conditional value - dap_chain_tx_tsd_t *l_takeoff_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF, sizeof(uint256_t)); + dap_chain_tx_tsd_t *l_takeoff_tsd = NULL; + if (l_refill) + l_takeoff_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL, sizeof(uint256_t)); + else + l_takeoff_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF, sizeof(uint256_t)); if (!l_takeoff_tsd || dap_chain_datum_tx_add_item(&l_tx, l_takeoff_tsd) != 1) m_tx_fail(ERROR_COMPOSE, "Can't add TSD section item with withdraw value"); DAP_DELETE(l_takeoff_tsd); @@ -402,7 +522,10 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje uint256_t l_fee_back = {}; // fee coin back - SUBTRACT_256_256(l_fee_transfer, l_fee_total, &l_fee_back); + if (l_refill) + SUBTRACT_256_256(l_fee_transfer, l_value_temp, &l_fee_back); + else + SUBTRACT_256_256(l_fee_transfer, l_fee_total, &l_fee_back); if (!IS_ZERO_256(l_fee_back)) { int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_owner_addr, l_fee_back) : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, a_net->pub.native_ticker); @@ -458,6 +581,11 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_sign(json_object #undef m_sign_fail +enum emit_delegation_error s_cli_param_check (int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) +{ + return DAP_NO_ERROR; +} + static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) { const char *l_token_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL, *l_signs_min_str = NULL, *l_pkeys_str = NULL; @@ -579,6 +707,83 @@ static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object ** return DAP_NO_ERROR; } +static int s_cli_refill(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) +{ + const char *l_token_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL, *l_tx_in_hash_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-value", &l_value_str); + if (!l_value_str) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation holding requires parameter -value"); + return ERROR_PARAM; + } + uint256_t l_value = dap_chain_balance_scan(l_value_str); + if (IS_ZERO_256(l_value)) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer>"); + return ERROR_VALUE; + } + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str); + if (!l_fee_str) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation holding requires parameter -fee"); + return ERROR_PARAM; + } + uint256_t l_fee = dap_chain_balance_scan(l_fee_str); + if (IS_ZERO_256(l_fee)) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -fee <256 bit integer>"); + return ERROR_VALUE; + } + + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-w", &l_wallet_str); + if (!l_wallet_str) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation holding requires parameter -w"); + return ERROR_PARAM; + } + + if (!l_tx_in_hash_str) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -tx"); + return ERROR_PARAM; + } + dap_hash_fast_t l_tx_in_hash; + if (dap_chain_hash_fast_from_str(l_tx_in_hash_str, &l_tx_in_hash)) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Can't recognize %s as a hex or base58 format hash", l_tx_in_hash_str); + return ERROR_VALUE; + } + if (!dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_tx_in_hash)) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "TX %s not found in ledger", l_tx_in_hash_str); + return ERROR_VALUE; + } + + + dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL); + if (!l_wallet) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Specified wallet %s not found", l_wallet_str); + return ERROR_VALUE; + } + const char *l_sign_str = dap_chain_wallet_check_sign(l_wallet); + dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); + dap_chain_wallet_close(l_wallet); + + // Create conditional transaction for delegated emissions + dap_chain_datum_tx_t *l_tx = s_refilling_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_value, l_fee, &l_tx_in_hash, NULL); + DAP_DELETE(l_enc_key); + if (!l_tx) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for delegated emission"); + return ERROR_CREATE; + } + char *l_tx_hash_str = s_tx_put(l_tx, a_chain, a_hash_out_type); + DAP_DELETE(l_tx); + if (!l_tx_hash_str) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PLACE, "Can't place transaction for delegated emission in mempool"); + return ERROR_PLACE; + } + json_object * l_json_obj_create_val = json_object_new_object(); + json_object_object_add(l_json_obj_create_val, "status", json_object_new_string("success")); + if (dap_strcmp(l_sign_str, "")) + json_object_object_add(l_json_obj_create_val, "sign", json_object_new_string(l_sign_str)); + json_object_object_add(l_json_obj_create_val, "tx_hash", json_object_new_string(l_tx_hash_str)); + json_object_array_add(*a_json_arr_reply, l_json_obj_create_val); + DAP_DELETE(l_tx_hash_str); + return DAP_NO_ERROR; +} + static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) { const char *l_tx_in_hash_str = NULL, *l_addr_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL; @@ -733,9 +938,6 @@ static int s_cli_sign(int a_argc, char **a_argv, int a_arg_index, json_object ** static int s_cli_emit_delegate(int a_argc, char **a_argv, void **a_str_reply) { json_object **a_json_arr_reply = (json_object **)a_str_reply; - enum { - CMD_NONE, CMD_HOLD, CMD_TAKE, CMD_SIGN - }; int l_arg_index = 1; dap_chain_net_t *l_net = NULL; dap_chain_t *l_chain = NULL; @@ -752,9 +954,10 @@ static int s_cli_emit_delegate(int a_argc, char **a_argv, void **a_str_reply) if (l_err_net_chain) return l_err_net_chain; - int l_cmd_num = CMD_NONE; if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "hold", NULL)) return s_cli_hold(a_argc, a_argv, l_arg_index + 1, a_json_arr_reply, l_net, l_chain, l_hash_out_type); + else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "refill", NULL)) + return s_cli_refill(a_argc, a_argv, l_arg_index + 1, a_json_arr_reply, l_net, l_chain, l_hash_out_type); else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "take", NULL)) return s_cli_take(a_argc, a_argv, l_arg_index + 1, a_json_arr_reply, l_net, l_chain, l_hash_out_type); else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "sign", NULL)) @@ -769,13 +972,43 @@ int dap_chain_net_srv_emit_delegate_init() { dap_ledger_verificator_add(DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, s_emit_delegate_verificator, NULL, NULL); dap_cli_server_cmd_add("emit_delegate", s_cli_emit_delegate, "Emitting delegation service commands", - "emit_delegate hold -net <net_name> -w <wallet_name> -token <ticker> -value <value> -fee <value>" - "-signs_minimum <value_int> -pkey_hashes <hash1[,hash2,...,hashN]> [-chain <chain_name>] [-H {hex(default) | base58}]\n" - "emit_delegate take -net <net_name> -w <wallet_name> -tx <transaction_hash> -addr_to <addr> -value <value> -fee <value> [-chain <chain_name>] [-H {hex(default) | base58}]\n" - "emit_delegate sign -net <net_name> -w <wallet_name> -tx <transaction_hash> [-chain <chain_name>] [-H {hex(default) | base58}]\n\n" - "Hint:\n" - "\texample value_coins (only natural) 1.0 123.4567\n" - "\texample value_datoshi (only integer) 1 20 0.4321e+4\n" + "emit_delegate hold - to create new delegation\n" + "\t-net <net_name>\n" + "\t-w <wallet_name> - wallet name to pay and sign tx\n" + "\t-token <ticker> - token ticker to hold\n" + "\t-value <value> - value to hold\n" + "\t-fee <value> - fee value\n" + "\t-signs_minimum <value_int> - minimum signs count needed to verify take datum\n" + "\t-pkey_hashes <hash1[,hash2,...,hashN]> - owners pkey hashes, who can sign take datum\n" + "\t[-chain <chain_name>]\n" + "\t[-H {hex(default) | base58}] - datum hash return format\n" + "emit_delegate refill - to refill value\n" + "\t-net <net_name>\n" + "\t-w <wallet_name> - wallet name to pay\n" + "\t-token <ticker> - token ticker to refill\n" + "\t-value <value> - value to refill\n" + "\t-fee <value> - fee value\n" + "\t-tx <transaction_hash> - emit delegate tx hash to refill\n" + "\t[-chain <chain_name>]\n" + "\t[-H {hex(default) | base58}] - datum hash return format\n" + "emit_delegate take\n" + "\t-net <net_name>\n" + "\t-w <wallet_name>\n" + "\t-tx <transaction_hash>\n" + "\t-addr_to <addr>\n" + "\t-value <value>\n" + "\t-fee <value>\n" + "\t[-chain <chain_name>]\n" + "\t[-H {hex(default) | base58}] - datum hash return format\n" + "emit_delegate sign\n" + "\t-net <net_name>\n" + "\t-w <wallet_name>\n" + "\t-tx <transaction_hash>\n" + "\t[-chain <chain_name>]\n" + "\t[-H {hex(default) | base58}] - datum hash return format\n" + "Hint:\n" + "\texample value_coins (only natural) 1.0 123.4567\n" + "\texample value_datoshi (only integer) 1 20 0.4321e+4\n" ); dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_EMIT_DELEGATE_ID }; -- GitLab From 261b8ecb55a3f9cd040466e3e3aafa942e5539d8 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Tue, 18 Feb 2025 12:28:29 +0300 Subject: [PATCH 03/29] [*] refill work --- .../dap_chain_net_srv_emit_delegate.c | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 7c04cdf3a2..02b6748f0a 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -159,9 +159,6 @@ static int s_emit_delegate_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_ log_it(L_ERROR, "Condtional output in current TX have different TSD sections vs previous TX's one"); return -11; } - } else if (l_cond_out) { - log_it(L_ERROR, "Changeback on conditional output is not need but found"); - return -10; } if (l_signs_verified < a_cond->subtype.srv_emit_delegate.signers_minimum) { @@ -358,7 +355,7 @@ dap_chain_datum_tx_t *s_refilling_tx_create(json_object *a_json_arr_reply, dap_c // add track for takeoff from conditional value dap_chain_tx_tsd_t *l_refill_tsd = NULL; - l_refill_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL, sizeof(uint256_t)); + l_refill_tsd = dap_chain_datum_tx_item_tsd_create(&a_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL, sizeof(uint256_t)); if (!l_refill_tsd || dap_chain_datum_tx_add_item(&l_tx, l_refill_tsd) != 1) m_tx_fail(ERROR_COMPOSE, "Can't add TSD section item with withdraw value"); @@ -483,16 +480,14 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje SUM_256_256(l_cond_prev->header.value, l_value, &l_value_back); else SUBTRACT_256_256(l_cond_prev->header.value, l_value, &l_value_back); - - if (!IS_ZERO_256(l_value_back)) { - dap_chain_tx_out_cond_t *l_out_cond = DAP_DUP_SIZE(l_cond_prev, sizeof(dap_chain_tx_out_cond_t) + l_cond_prev->tsd_size); - if (!l_out_cond) - m_tx_fail(ERROR_COMPOSE, c_error_memory_alloc); - l_out_cond->header.value = l_value_back; - if (-1 == dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond)) - m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); - DAP_DELETE(l_out_cond); - } + // create to refilling + dap_chain_tx_out_cond_t *l_out_cond = DAP_DUP_SIZE(l_cond_prev, sizeof(dap_chain_tx_out_cond_t) + l_cond_prev->tsd_size); + if (!l_out_cond) + m_tx_fail(ERROR_COMPOSE, c_error_memory_alloc); + l_out_cond->header.value = l_value_back; + if (-1 == dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond)) + m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); + DAP_DELETE(l_out_cond); // add track for takeoff from conditional value dap_chain_tx_tsd_t *l_takeoff_tsd = NULL; @@ -737,6 +732,7 @@ static int s_cli_refill(int a_argc, char **a_argv, int a_arg_index, json_object return ERROR_PARAM; } + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tx", &l_tx_in_hash_str); if (!l_tx_in_hash_str) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -tx"); return ERROR_PARAM; -- GitLab From cbfe8b1bf11390d19e11abf035d0033a517b5e10 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Wed, 19 Feb 2025 11:49:37 +0300 Subject: [PATCH 04/29] [*] add batching take --- .../dap_chain_net_srv_emit_delegate.c | 149 ++++++++++++------ .../include/dap_chain_net_srv_emit_delegate.h | 2 +- 2 files changed, 101 insertions(+), 50 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 02b6748f0a..4712905092 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -411,8 +411,9 @@ static bool s_is_key_present(dap_chain_tx_out_cond_t *a_cond, dap_enc_key_t *a_e } dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, - dap_chain_addr_t *a_addr_to, uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) + dap_chain_addr_t **a_addr_to, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { + dap_return_val_if_fail(!a_addr_to || !a_value || !a_addr_count || !a_enc_key || !a_tx_in_hash, NULL ); // create empty transaction dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); @@ -420,21 +421,23 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, a_tx_in_hash); bool l_taking_native = !dap_strcmp(a_net->pub.native_ticker, l_tx_ticker); - uint256_t l_value = a_value, l_value_temp = a_value, l_fee_transfer = {}; // how many coins to transfer + uint256_t l_value = {}, l_fee_transfer = {}; // how many coins to transfer uint256_t l_net_fee, l_fee_total = a_fee; dap_chain_addr_t l_net_fee_addr; - bool l_refill = false; + + for (size_t i = 0; i < a_addr_count; ++i) { + if (SUM_256_256(l_value, a_value[i], &l_value)) + m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); + } bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr); if (l_net_fee_used && SUM_256_256(l_fee_total, l_net_fee, &l_fee_total)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); - if (l_refill && (SUM_256_256(l_value_temp, l_value_temp, &l_value_temp) || SUM_256_256(l_value_temp, l_fee_total, &l_value_temp))) - m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); dap_chain_addr_t l_owner_addr; dap_chain_addr_fill_from_key(&l_owner_addr, a_enc_key, a_net->pub.id); dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_net->pub.native_ticker, - &l_owner_addr, l_fee_total, &l_fee_transfer); + &l_owner_addr, l_fee_total, &l_fee_transfer); if (!l_list_fee_out) m_tx_fail(ERROR_FUNDS, "Nothing to pay for fee (not enough funds)"); // add 'in' items to pay fee @@ -468,33 +471,29 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje } // add 'out' or 'out_ext' item for emission - int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, a_value) : - dap_chain_datum_tx_add_out_ext_item(&l_tx, a_addr_to, a_value, l_tx_ticker); - if (rc != 1) - m_tx_fail(ERROR_COMPOSE, "Cant add emission output"); + for (size_t i = 0; i < a_addr_count; ++i) { + int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to[i], a_value[i]) : + dap_chain_datum_tx_add_out_ext_item(&l_tx, a_addr_to[i], a_value[i], l_tx_ticker); + if (rc != 1) + m_tx_fail(ERROR_COMPOSE, "Cant add tx output"); + } // coin back uint256_t l_value_back = {}; - - if (l_refill) - SUM_256_256(l_cond_prev->header.value, l_value, &l_value_back); - else - SUBTRACT_256_256(l_cond_prev->header.value, l_value, &l_value_back); - // create to refilling + SUBTRACT_256_256(l_cond_prev->header.value, l_value, &l_value_back); dap_chain_tx_out_cond_t *l_out_cond = DAP_DUP_SIZE(l_cond_prev, sizeof(dap_chain_tx_out_cond_t) + l_cond_prev->tsd_size); if (!l_out_cond) m_tx_fail(ERROR_COMPOSE, c_error_memory_alloc); l_out_cond->header.value = l_value_back; - if (-1 == dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond)) + if (-1 == dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond)) { m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); + DAP_DELETE(l_out_cond); + } DAP_DELETE(l_out_cond); + // add track for takeoff from conditional value - dap_chain_tx_tsd_t *l_takeoff_tsd = NULL; - if (l_refill) - l_takeoff_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL, sizeof(uint256_t)); - else - l_takeoff_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF, sizeof(uint256_t)); + dap_chain_tx_tsd_t *l_takeoff_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF, sizeof(uint256_t)); if (!l_takeoff_tsd || dap_chain_datum_tx_add_item(&l_tx, l_takeoff_tsd) != 1) m_tx_fail(ERROR_COMPOSE, "Can't add TSD section item with withdraw value"); DAP_DELETE(l_takeoff_tsd); @@ -508,7 +507,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje // add fee items if (l_net_fee_used) { int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_net_fee_addr, l_net_fee) - : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_net_fee_addr, l_net_fee, a_net->pub.native_ticker); + : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_net_fee_addr, l_net_fee, a_net->pub.native_ticker); if (rc != 1) m_tx_fail(ERROR_COMPOSE, "Cant add net fee output"); } @@ -517,24 +516,22 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje uint256_t l_fee_back = {}; // fee coin back - if (l_refill) - SUBTRACT_256_256(l_fee_transfer, l_value_temp, &l_fee_back); - else - SUBTRACT_256_256(l_fee_transfer, l_fee_total, &l_fee_back); + SUBTRACT_256_256(l_fee_transfer, l_fee_total, &l_fee_back); if (!IS_ZERO_256(l_fee_back)) { - int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_owner_addr, l_fee_back) - : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, a_net->pub.native_ticker); - if (rc != 1) - m_tx_fail(ERROR_COMPOSE, "Cant add fee back output"); + int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_owner_addr, l_fee_back) + : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, a_net->pub.native_ticker); + if (rc != 1) + m_tx_fail(ERROR_COMPOSE, "Cant add fee back output"); } // add 'sign' item if (dap_chain_datum_tx_add_sign_item(&l_tx, a_enc_key) != 1) m_tx_fail(ERROR_COMPOSE, "Can't add sign output"); - return l_tx; +return l_tx; } + #undef m_tx_fail dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_sign(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, dap_chain_datum_tx_t *a_tx_in) @@ -783,6 +780,12 @@ static int s_cli_refill(int a_argc, char **a_argv, int a_arg_index, json_object static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) { const char *l_tx_in_hash_str = NULL, *l_addr_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL; + + uint256_t *l_value = NULL; + dap_chain_addr_t **l_addr_to = NULL; + size_t l_addr_el_count = 0; + size_t l_value_el_count = 0; + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tx", &l_tx_in_hash_str); if (!l_tx_in_hash_str) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -tx"); @@ -797,16 +800,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "TX %s not found in ledger", l_tx_in_hash_str); return ERROR_VALUE; } - dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-value", &l_value_str); - if (!l_value_str) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -value"); - return ERROR_PARAM; - } - uint256_t l_value = dap_chain_balance_scan(l_value_str); - if (IS_ZERO_256(l_value)) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer>"); - return ERROR_VALUE; - } + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str); if (!l_fee_str) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -fee"); @@ -831,21 +825,78 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** const char *l_sign_str = dap_chain_wallet_check_sign(l_wallet); dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); dap_chain_wallet_close(l_wallet); - dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-addr_to", &l_addr_str); + + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-value", &l_value_str); if (!l_value_str) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -value"); + return ERROR_PARAM; + } + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-addr_to", &l_addr_str); + if (!l_addr_str) { DAP_DELETE(l_enc_key); dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -addr_to"); return ERROR_PARAM; } - dap_chain_addr_t *l_addr = dap_chain_addr_from_str(l_addr_str); - if (!l_addr) { - DAP_DELETE(l_enc_key); - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Incorrect addr format for string %s", l_addr_str); + + l_addr_el_count = dap_str_symbol_count(l_addr_str, ',') + 1; + l_value_el_count = dap_str_symbol_count(l_value_str, ',') + 1; + + if (l_addr_el_count != l_value_el_count) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "num of '-addr_to' and '-value' should be equal"); return ERROR_VALUE; } + + l_value = DAP_NEW_Z_COUNT(uint256_t, l_value_el_count); + if (!l_value) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR, c_error_memory_alloc); + return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR; + } + char **l_value_array = dap_strsplit(l_value_str, ",", l_value_el_count); + if (!l_value_array) { + DAP_DELETE(l_value); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "Can't read '-to_addr' arg"); + return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR; + } + for (size_t i = 0; i < l_value_el_count; ++i) { + l_value[i] = dap_chain_balance_scan(l_value_array[i]); + if(IS_ZERO_256(l_value[i])) { + DAP_DELETE(l_value); + dap_strfreev(l_value_array); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer>"); + return ERROR_VALUE; + } + } + dap_strfreev(l_value_array); + + l_addr_to = DAP_NEW_Z_COUNT(dap_chain_addr_t *, l_addr_el_count); + if (!l_addr_to) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + DAP_DELETE(l_value); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR, c_error_memory_alloc); + return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR; + } + char **l_addr_to_str_array = dap_strsplit(l_addr_str, ",", l_addr_el_count); + if (!l_addr_to_str_array) { + DAP_DEL_MULTY(l_addr_to, l_value); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "Can't read '-to_addr' arg"); + return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR; + } + for (size_t i = 0; i < l_addr_el_count; ++i) { + l_addr_to[i] = dap_chain_addr_from_str(l_addr_to_str_array[i]); + if(!l_addr_to[i]) { + DAP_DEL_ARRAY(l_addr_to, i); + DAP_DEL_MULTY(l_addr_to, l_value); + dap_strfreev(l_addr_to_str_array); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Incorrect addr format for string %s", l_addr_str); + return ERROR_VALUE; + } + } + dap_strfreev(l_addr_to_str_array); + // Create emission from conditional transaction - dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_addr, l_value, l_fee, &l_tx_in_hash, NULL); - DAP_DEL_MULTY(l_enc_key, l_addr); + dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_addr_to, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, NULL); + DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); + DAP_DEL_MULTY(l_addr_to, l_enc_key); if (!l_tx) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for delegated emission"); return ERROR_CREATE; diff --git a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h index 2580537280..93e934ec28 100644 --- a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h +++ b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h @@ -13,6 +13,6 @@ void dap_chain_net_srv_emit_delegate_deinit(); dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_rweply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, - dap_chain_addr_t *a_addr_to, uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t *tsd_items); + dap_chain_addr_t **a_addr_to, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t *tsd_items); dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_sign(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, dap_chain_datum_tx_t *a_tx_in); -- GitLab From beb26117f62667d1148e5b7816952a1642abfc88 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Wed, 19 Feb 2025 12:33:25 +0300 Subject: [PATCH 05/29] [*] add batching tsd section --- .../dap_chain_net_srv_emit_delegate.c | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 4712905092..a4230e338b 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -413,7 +413,7 @@ static bool s_is_key_present(dap_chain_tx_out_cond_t *a_cond, dap_enc_key_t *a_e dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, dap_chain_addr_t **a_addr_to, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { - dap_return_val_if_fail(!a_addr_to || !a_value || !a_addr_count || !a_enc_key || !a_tx_in_hash, NULL ); + dap_return_val_if_pass(!a_addr_to || !a_value || !a_addr_count || !a_enc_key || !a_tx_in_hash, NULL ); // create empty transaction dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); @@ -783,8 +783,10 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** uint256_t *l_value = NULL; dap_chain_addr_t **l_addr_to = NULL; - size_t l_addr_el_count = 0; - size_t l_value_el_count = 0; + uint32_t + l_addr_el_count = 0, // not change type! use in TSD section + l_value_el_count = 0; + dap_list_t *l_tsd_list = NULL; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tx", &l_tx_in_hash_str); if (!l_tx_in_hash_str) { @@ -893,10 +895,20 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** } dap_strfreev(l_addr_to_str_array); - // Create emission from conditional transaction - dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_addr_to, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, NULL); + + if (l_addr_el_count > 1) { + l_tsd_list = dap_list_append(l_tsd_list, dap_chain_datum_tx_item_tsd_create(&l_addr_el_count, DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT, sizeof(uint32_t))); + if (!l_tsd_list) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_COMPOSE, "Internal error in tsd list creation"); + return ERROR_COMPOSE; + } + } + + // Create emission from conditional transaction + dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_addr_to, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, l_tsd_list); DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); DAP_DEL_MULTY(l_addr_to, l_enc_key); + dap_list_free_full(l_tsd_list, NULL); if (!l_tx) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for delegated emission"); return ERROR_CREATE; -- GitLab From f806fccdf50adafdc4709f8ad0833b50e93ba715 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Wed, 19 Feb 2025 16:20:49 +0000 Subject: [PATCH 06/29] [*] add tags --- modules/net/dap_chain_ledger.c | 10 +++++++--- modules/net/include/dap_chain_ledger.h | 4 ++++ .../dap_chain_net_srv_emit_delegate.c | 16 +++++++++++++--- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index bff172b625..4cc0ec4e19 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -352,7 +352,7 @@ static bool s_tag_check_transfer(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a //crosschain transfer //regular transfer //comission transfer - + // fee transfer: in_cond item linked to out_cond_fee if (a_items_grp->items_in_cond) { @@ -3267,7 +3267,9 @@ const char *dap_ledger_tx_action_str(dap_chain_tx_tag_action_type_t a_tag) if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CLOSE) return "close"; if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CHANGE) return "change"; if (a_tag == DAP_CHAIN_TX_TAG_ACTION_VOTING) return "voting"; - if (a_tag == DAP_CHAIN_TX_TAG_ACTION_VOTE) return "vote"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_HOLD) return "hold"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_TAKE) return "take"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_REFILL) return "refill"; return "WTFSUBTAG"; @@ -3288,7 +3290,9 @@ dap_chain_tx_tag_action_type_t dap_ledger_tx_action_str_to_action_t(const char * if (strcmp("extend", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_EXTEND; if (strcmp("close", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_CLOSE; if (strcmp("change", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_CHANGE; - + if (strcmp("hold", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_HOLD; + if (strcmp("take", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_TAKE; + if (strcmp("refill", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_REFILL; return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; } diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index ea410925d1..683740bf6c 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -127,6 +127,10 @@ typedef enum dap_chain_tx_tag_action_type { DAP_CHAIN_TX_TAG_ACTION_VOTING = 1 << 11, DAP_CHAIN_TX_TAG_ACTION_VOTE = 1 << 12, + + DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_HOLD = 1 << 13, + DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_TAKE = 1 << 14, + DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_REFILL = 1 << 15, DAP_CHAIN_TX_TAG_ACTION_ALL = ~0, } dap_chain_tx_tag_action_type_t; diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index a4230e338b..41e20b110b 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -171,7 +171,17 @@ static int s_emit_delegate_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_ static bool s_tag_check(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) { - return a_items_grp->items_out_cond_srv_emit_delegate; + if (!a_items_grp->items_out_cond_srv_emit_delegate) + return false; + if (a_action) { + if (dap_chain_datum_tx_item_get_tsd_by_type(a_tx, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF)) + *a_action = DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_TAKE; + else if (dap_chain_datum_tx_item_get_tsd_by_type(a_tx, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL)) + *a_action = DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_REFILL; + else + *a_action = DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_HOLD; + } + return true; } // Put a transaction to the mempool @@ -1054,8 +1064,8 @@ int dap_chain_net_srv_emit_delegate_init() "\t-net <net_name>\n" "\t-w <wallet_name>\n" "\t-tx <transaction_hash>\n" - "\t-addr_to <addr>\n" - "\t-value <value>\n" + "\t-addr_to <addr1[,addr2,...,addrN]>\n" + "\t-value <value1[,value2,...,valueN]>\n" "\t-fee <value>\n" "\t[-chain <chain_name>]\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" -- GitLab From 15db8b5bd57da5a59118a91192258e305f12edf1 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Thu, 20 Feb 2025 10:18:43 +0000 Subject: [PATCH 07/29] [*] add s_cli_info func --- modules/net/dap_chain_node_cli_cmd_tx.c | 3 +- .../dap_chain_net_srv_emit_delegate.c | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index eade51cfda..5c5abd0a57 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -542,7 +542,7 @@ json_object* dap_db_history_addr(json_object* a_json_arr_reply, dap_chain_addr_t case TX_ITEM_TYPE_OUT_COND: l_value = ((dap_chain_tx_out_cond_t *)it->data)->header.value; if (((dap_chain_tx_out_cond_t *)it->data)->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) { - SUM_256_256(l_fee_sum, ((dap_chain_tx_out_cond_t *)it->data)->header.value, &l_fee_sum); + SUM_256_256(l_fee_sum, l_value, &l_fee_sum); l_dst_token = l_native_ticker; } else l_dst_token = l_src_token; @@ -694,7 +694,6 @@ json_object* dap_db_history_addr(json_object* a_json_arr_reply, dap_chain_addr_t json_object *l_cond_send_value_obj = json_object_object_get(l_cond_send_object, "send_datoshi"); const char *l_cond_send_value_str = json_object_get_string(l_cond_send_value_obj); uint256_t l_cond_send_value = dap_uint256_scan_uninteger(l_cond_send_value_str); - assert(!IS_ZERO_256(l_cond_recv_value) && !IS_ZERO_256(l_cond_send_value)); int l_direction = compare256(l_cond_recv_value, l_cond_send_value); if (l_direction > 0) { SUBTRACT_256_256(l_cond_recv_value, l_cond_send_value, &l_cond_recv_value); diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 41e20b110b..585ce76e14 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -997,6 +997,61 @@ static int s_cli_sign(int a_argc, char **a_argv, int a_arg_index, json_object ** return DAP_NO_ERROR; } +static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) +{ + const char *l_tx_hash_str = NULL, *l_wallet_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tx", &l_tx_hash_str); + if (!l_tx_hash_str) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -tx"); + return ERROR_PARAM; + } + dap_hash_fast_t l_tx_hash; + if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash)) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Can't recognize %s as a hex or base58 format hash", l_tx_hash_str); + return ERROR_VALUE; + } + dap_hash_fast_t l_final_tx_hash = dap_ledger_get_final_chain_tx_hash(a_net->pub.ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, &l_tx_hash, false); + dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_final_tx_hash); + dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, NULL); + if (!l_cond) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_TX_MISMATCH, "Can't find final tx_out_cond"); + return ERROR_TX_MISMATCH; + } + + + const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_final_tx_hash); + const char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(l_cond->header.value, &l_balance_coins); + + json_object *l_jobj_balance = json_object_new_object(); + json_object *l_jobj_token = json_object_new_object(); + json_object *l_jobj_pkey_hashes = json_object_new_object(); + json_object *l_json_jobj_info = json_object_new_object(); + json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(l_tx_hash_str)); + json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(dap_hash_fast_to_str_static(&l_final_tx_hash))); + + json_object *l_jobj_ticker = json_object_new_string(l_tx_ticker); + const char *l_description = dap_ledger_get_description_by_ticker(a_net->pub.ledger, l_tx_ticker); + json_object *l_jobj_description = l_description ? json_object_new_string(l_description) + : json_object_new_null(); + json_object_object_add(l_jobj_token, "ticker", l_jobj_ticker); + json_object_object_add(l_jobj_token, "description", l_jobj_description); + json_object_object_add(l_jobj_balance, "coins", json_object_new_string(l_balance_coins)); + json_object_object_add(l_jobj_balance, "datoshi", json_object_new_string(l_balance_datoshi)); + json_object_object_add(l_jobj_pkey_hashes, "signs_minimum", json_object_new_uint64(l_cond->subtype.srv_emit_delegate.signers_minimum)); + dap_tsd_t *l_tsd; size_t l_tsd_size; + dap_tsd_iter(l_tsd, l_tsd_size, l_cond->tsd, l_cond->tsd_size) { + if (l_tsd->type == DAP_CHAIN_TX_OUT_COND_TSD_HASH && l_tsd->size == sizeof(dap_hash_fast_t)) { + json_object_object_add(l_jobj_pkey_hashes, "owner_pkey_hash", json_object_new_string(dap_hash_fast_to_str_static(l_tsd->data))); + } + } + json_object_object_add(l_json_jobj_info, "balance", l_jobj_balance); + json_object_object_add(l_json_jobj_info, "take_verify", l_jobj_pkey_hashes); + + json_object_object_add(l_json_jobj_info, "token", l_jobj_token); + json_object_array_add(*a_json_arr_reply, l_json_jobj_info); + return DAP_NO_ERROR; +} + /** * @brief s_cli_stake_lock * @param a_argc @@ -1031,6 +1086,8 @@ static int s_cli_emit_delegate(int a_argc, char **a_argv, void **a_str_reply) return s_cli_take(a_argc, a_argv, l_arg_index + 1, a_json_arr_reply, l_net, l_chain, l_hash_out_type); else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "sign", NULL)) return s_cli_sign(a_argc, a_argv, l_arg_index + 1, a_json_arr_reply, l_net, l_chain, l_hash_out_type); + else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "info", NULL)) + return s_cli_info(a_argc, a_argv, l_arg_index + 1, a_json_arr_reply, l_net, l_chain, l_hash_out_type); else { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_SUBCOMMAND, "Subcommand %s not recognized", a_argv[l_arg_index]); return ERROR_SUBCOMMAND; -- GitLab From 8c0cd53539cbb27281f19af27ffdccb93093c98f Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 21 Feb 2025 04:26:38 +0000 Subject: [PATCH 08/29] [*] add pkey hash dublicate protection --- .../emit-delegate/dap_chain_net_srv_emit_delegate.c | 11 +++++++++-- .../include/dap_chain_net_srv_emit_delegate.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 585ce76e14..4c659dac5b 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -293,7 +293,7 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, } -dap_chain_datum_tx_t *s_refilling_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, +dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { // create empty transaction @@ -670,6 +670,13 @@ static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object ** DAP_DEL_MULTY(l_enc_key, l_pkey_hashes); return ERROR_VALUE; } + for (size_t j = 0; j < i; ++j) { + if (!memcmp(l_pkey_hashes + j, l_pkey_hashes + i, sizeof(dap_chain_hash_fast_t))){ + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Find pkey hash %s dublicate", l_hash_str_buf); + DAP_DEL_MULTY(l_enc_key, l_pkey_hashes); + return ERROR_VALUE; + } + } if (*l_cur_ptr == 0) { l_hashes_count = i + 1; break; @@ -765,7 +772,7 @@ static int s_cli_refill(int a_argc, char **a_argv, int a_arg_index, json_object dap_chain_wallet_close(l_wallet); // Create conditional transaction for delegated emissions - dap_chain_datum_tx_t *l_tx = s_refilling_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_value, l_fee, &l_tx_in_hash, NULL); + dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_refilling_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_value, l_fee, &l_tx_in_hash, NULL); DAP_DELETE(l_enc_key); if (!l_tx) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for delegated emission"); diff --git a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h index 93e934ec28..b9d7ffe7b4 100644 --- a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h +++ b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h @@ -14,5 +14,7 @@ void dap_chain_net_srv_emit_delegate_deinit(); dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_rweply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, dap_chain_addr_t **a_addr_to, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t *tsd_items); +dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, + uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items); dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_sign(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, dap_chain_datum_tx_t *a_tx_in); -- GitLab From 134b14de507061bf60ad8d4162c9710c309f4125 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 21 Feb 2025 05:57:58 +0000 Subject: [PATCH 09/29] [*] add cert signing --- .../dap_chain_net_srv_emit_delegate.c | 112 ++++++++++-------- modules/wallet/dap_chain_wallet.c | 2 +- 2 files changed, 65 insertions(+), 49 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 4c659dac5b..a0b237d3f4 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -421,9 +421,9 @@ static bool s_is_key_present(dap_chain_tx_out_cond_t *a_cond, dap_enc_key_t *a_e } dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, - dap_chain_addr_t **a_addr_to, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) + dap_chain_addr_t **a_to_addr, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { - dap_return_val_if_pass(!a_addr_to || !a_value || !a_addr_count || !a_enc_key || !a_tx_in_hash, NULL ); + dap_return_val_if_pass(!a_to_addr || !a_value || !a_addr_count || !a_enc_key || !a_tx_in_hash, NULL ); // create empty transaction dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); @@ -482,8 +482,8 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje // add 'out' or 'out_ext' item for emission for (size_t i = 0; i < a_addr_count; ++i) { - int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to[i], a_value[i]) : - dap_chain_datum_tx_add_out_ext_item(&l_tx, a_addr_to[i], a_value[i], l_tx_ticker); + int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, a_to_addr[i], a_value[i]) : + dap_chain_datum_tx_add_out_ext_item(&l_tx, a_to_addr[i], a_value[i], l_tx_ticker); if (rc != 1) m_tx_fail(ERROR_COMPOSE, "Cant add tx output"); } @@ -799,7 +799,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** const char *l_tx_in_hash_str = NULL, *l_addr_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL; uint256_t *l_value = NULL; - dap_chain_addr_t **l_addr_to = NULL; + dap_chain_addr_t **l_to_addr = NULL; uint32_t l_addr_el_count = 0, // not change type! use in TSD section l_value_el_count = 0; @@ -850,10 +850,10 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -value"); return ERROR_PARAM; } - dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-addr_to", &l_addr_str); + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-to_addr", &l_addr_str); if (!l_addr_str) { DAP_DELETE(l_enc_key); - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -addr_to"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -to_addr"); return ERROR_PARAM; } @@ -861,7 +861,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** l_value_el_count = dap_str_symbol_count(l_value_str, ',') + 1; if (l_addr_el_count != l_value_el_count) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "num of '-addr_to' and '-value' should be equal"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "num of '-to_addr' and '-value' should be equal"); return ERROR_VALUE; } @@ -887,30 +887,30 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** } dap_strfreev(l_value_array); - l_addr_to = DAP_NEW_Z_COUNT(dap_chain_addr_t *, l_addr_el_count); - if (!l_addr_to) { + l_to_addr = DAP_NEW_Z_COUNT(dap_chain_addr_t *, l_addr_el_count); + if (!l_to_addr) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); DAP_DELETE(l_value); dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR, c_error_memory_alloc); return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR; } - char **l_addr_to_str_array = dap_strsplit(l_addr_str, ",", l_addr_el_count); - if (!l_addr_to_str_array) { - DAP_DEL_MULTY(l_addr_to, l_value); + char **l_to_addr_str_array = dap_strsplit(l_addr_str, ",", l_addr_el_count); + if (!l_to_addr_str_array) { + DAP_DEL_MULTY(l_to_addr, l_value); dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "Can't read '-to_addr' arg"); return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR; } for (size_t i = 0; i < l_addr_el_count; ++i) { - l_addr_to[i] = dap_chain_addr_from_str(l_addr_to_str_array[i]); - if(!l_addr_to[i]) { - DAP_DEL_ARRAY(l_addr_to, i); - DAP_DEL_MULTY(l_addr_to, l_value); - dap_strfreev(l_addr_to_str_array); + l_to_addr[i] = dap_chain_addr_from_str(l_to_addr_str_array[i]); + if(!l_to_addr[i]) { + DAP_DEL_ARRAY(l_to_addr, i); + DAP_DEL_MULTY(l_to_addr, l_value); + dap_strfreev(l_to_addr_str_array); dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Incorrect addr format for string %s", l_addr_str); return ERROR_VALUE; } } - dap_strfreev(l_addr_to_str_array); + dap_strfreev(l_to_addr_str_array); if (l_addr_el_count > 1) { @@ -922,9 +922,9 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** } // Create emission from conditional transaction - dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_addr_to, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, l_tsd_list); - DAP_DEL_ARRAY(l_addr_to, l_addr_el_count); - DAP_DEL_MULTY(l_addr_to, l_enc_key); + dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_to_addr, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, l_tsd_list); + DAP_DEL_ARRAY(l_to_addr, l_addr_el_count); + DAP_DEL_MULTY(l_to_addr, l_enc_key); dap_list_free_full(l_tsd_list, NULL); if (!l_tx) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for delegated emission"); @@ -948,7 +948,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** static int s_cli_sign(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) { - const char *l_tx_in_hash_str = NULL, *l_wallet_str = NULL; + const char *l_tx_in_hash_str = NULL, *l_wallet_str = NULL, *l_cert_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tx", &l_tx_in_hash_str); if (!l_tx_in_hash_str) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -tx"); @@ -964,19 +964,37 @@ static int s_cli_sign(int a_argc, char **a_argv, int a_arg_index, json_object ** dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "TX %s not found in mempool", l_tx_in_hash_str); return ERROR_VALUE; } + + dap_enc_key_t *l_enc_key = NULL; + const char *l_sign_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-w", &l_wallet_str); - if (!l_wallet_str) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -w"); + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str); + if (!l_wallet_str && !l_cert_str) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation sign requires parameter -w or -cert"); return ERROR_PARAM; } - dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL); - if (!l_wallet) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Specified wallet %s not found", l_wallet_str); - return ERROR_VALUE; + if (l_wallet_str) { + dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL); + if (!l_wallet) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Specified wallet %s not found", l_wallet_str); + return ERROR_VALUE; + } + l_sign_str = dap_chain_wallet_check_sign(l_wallet); + l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); + dap_chain_wallet_close(l_wallet); + } else if (l_cert_str) { + dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); + if (!l_cert) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Specified certificate %s not found", l_cert_str); + return ERROR_VALUE; + } + if (dap_sign_type_is_depricated(dap_sign_type_from_key_type(l_cert->enc_key->type))) + l_sign_str = "The Bliss, Picnic and Tesla signatures is deprecated. We recommend you to create a new wallet with another available signature and transfer funds there.\n"; + else + l_sign_str = ""; + l_enc_key = dap_cert_get_keys_from_certs(&l_cert, 1, 0); } - const char *l_sign_str = dap_chain_wallet_check_sign(l_wallet); - dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); - dap_chain_wallet_close(l_wallet); // Create emission from conditional transaction dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_sign(*a_json_arr_reply, a_net, l_enc_key, (dap_chain_datum_tx_t *)l_tx_in->data); @@ -1107,38 +1125,36 @@ int dap_chain_net_srv_emit_delegate_init() dap_cli_server_cmd_add("emit_delegate", s_cli_emit_delegate, "Emitting delegation service commands", "emit_delegate hold - to create new delegation\n" "\t-net <net_name>\n" - "\t-w <wallet_name> - wallet name to pay and sign tx\n" + "\t-w <wallet_name> - wallet to writeoff value, pay fee and sign tx\n" "\t-token <ticker> - token ticker to hold\n" "\t-value <value> - value to hold\n" "\t-fee <value> - fee value\n" "\t-signs_minimum <value_int> - minimum signs count needed to verify take datum\n" "\t-pkey_hashes <hash1[,hash2,...,hashN]> - owners pkey hashes, who can sign take datum\n" - "\t[-chain <chain_name>]\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" "emit_delegate refill - to refill value\n" "\t-net <net_name>\n" - "\t-w <wallet_name> - wallet name to pay\n" - "\t-token <ticker> - token ticker to refill\n" + "\t-w <wallet_name> - wallet to writeoff value and pay fee\n" "\t-value <value> - value to refill\n" "\t-fee <value> - fee value\n" "\t-tx <transaction_hash> - emit delegate tx hash to refill\n" - "\t[-chain <chain_name>]\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" - "emit_delegate take\n" + "emit_delegate take - create take datum to writeoff value from0 emit delegate tx\n" "\t-net <net_name>\n" - "\t-w <wallet_name>\n" - "\t-tx <transaction_hash>\n" - "\t-addr_to <addr1[,addr2,...,addrN]>\n" - "\t-value <value1[,value2,...,valueN]>\n" - "\t-fee <value>\n" - "\t[-chain <chain_name>]\n" + "\t-w <wallet_name> - wallet to pay fee\n" + "\t-tx <transaction_hash> - emit delegate tx hash to writeoff\n" + "\t-to_addr <addr1[,addr2,...,addrN]> - recipient addresses, count should be equal values count\n" + "\t-value <value1[,value2,...,valueN]> - the volume sent to each recipient, count should be equal addresses count\n" + "\t-fee <value> - fee value\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" - "emit_delegate sign\n" + "emit_delegate sign - add wallet sign to take datum\n" "\t-net <net_name>\n" - "\t-w <wallet_name>\n" - "\t-tx <transaction_hash>\n" - "\t[-chain <chain_name>]\n" + "\t-w <wallet_name> | -cert <cert_name> - wallet or cert to sign\n" + "\t-tx <transaction_hash> - emit delegate tx hash to sign\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" + "emit_delegate info - get info about emit delegate tx by hash\n" + "\t-net <net_name>\n" + "\t-tx <transaction_hash> - emit delegate tx hash to get info\n" "Hint:\n" "\texample value_coins (only natural) 1.0 123.4567\n" "\texample value_datoshi (only integer) 1 20 0.4321e+4\n" diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c index 8851d31c0f..00c5a66fdc 100644 --- a/modules/wallet/dap_chain_wallet.c +++ b/modules/wallet/dap_chain_wallet.c @@ -1097,7 +1097,7 @@ const char* dap_chain_wallet_check_sign(dap_chain_wallet_t *a_wallet) { for (size_t i = 0; i < l_wallet_internal->certs_count; ++i) { dap_return_val_if_pass(!l_wallet_internal->certs[i], "The wallet contains an undefined certificate.\n"); dap_sign_type_t l_sign_type = dap_sign_type_from_key_type(l_wallet_internal->certs[i]->enc_key->type); - if (SIG_TYPE_BLISS == l_sign_type.type || SIG_TYPE_PICNIC == l_sign_type.type || SIG_TYPE_TESLA == l_sign_type.type) { + if (dap_sign_type_is_depricated(l_sign_type)) { return "The Bliss, Picnic and Tesla signatures is deprecated. We recommend you to create a new wallet with another available signature and transfer funds there.\n"; } } -- GitLab From 0424d63557fa29f23f70875e15201d9f2feada98 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 21 Feb 2025 07:51:25 +0000 Subject: [PATCH 10/29] [*] add hash format to s_cli_info --- .../emit-delegate/dap_chain_net_srv_emit_delegate.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index a0b237d3f4..749820efe2 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -1051,8 +1051,14 @@ static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object ** json_object *l_jobj_token = json_object_new_object(); json_object *l_jobj_pkey_hashes = json_object_new_object(); json_object *l_json_jobj_info = json_object_new_object(); - json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(l_tx_hash_str)); - json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(dap_hash_fast_to_str_static(&l_final_tx_hash))); + + if (dap_strcmp(a_hash_out_type, "hex")) { + json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(dap_enc_base58_encode_hash_to_str_static(&l_tx_hash))); + json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(dap_enc_base58_encode_hash_to_str_static(&l_final_tx_hash))); + } else { + json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(dap_hash_fast_to_str_static(&l_tx_hash))); + json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(dap_hash_fast_to_str_static(&l_final_tx_hash))); + } json_object *l_jobj_ticker = json_object_new_string(l_tx_ticker); const char *l_description = dap_ledger_get_description_by_ticker(a_net->pub.ledger, l_tx_ticker); @@ -1094,7 +1100,7 @@ static int s_cli_emit_delegate(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-H", &l_hash_out_type); if (!l_hash_out_type) l_hash_out_type = "hex"; - else if (dap_strcmp(l_hash_out_type," hex") && dap_strcmp(l_hash_out_type, "base58")) { + else if (dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type, "base58")) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Invalid parameter -H, valid values: -H <hex | base58>"); return ERROR_PARAM; @@ -1155,6 +1161,7 @@ int dap_chain_net_srv_emit_delegate_init() "emit_delegate info - get info about emit delegate tx by hash\n" "\t-net <net_name>\n" "\t-tx <transaction_hash> - emit delegate tx hash to get info\n" + "\t[-H {hex(default) | base58}] - tx hash format\n" "Hint:\n" "\texample value_coins (only natural) 1.0 123.4567\n" "\texample value_datoshi (only integer) 1 20 0.4321e+4\n" -- GitLab From b9fef5e41d149b9f1fcda6e8813733ec737ae94a Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 21 Feb 2025 08:29:30 +0000 Subject: [PATCH 11/29] ... --- modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 749820efe2..93464a7d78 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -1150,7 +1150,7 @@ int dap_chain_net_srv_emit_delegate_init() "\t-w <wallet_name> - wallet to pay fee\n" "\t-tx <transaction_hash> - emit delegate tx hash to writeoff\n" "\t-to_addr <addr1[,addr2,...,addrN]> - recipient addresses, count should be equal values count\n" - "\t-value <value1[,value2,...,valueN]> - the volume sent to each recipient, count should be equal addresses count\n" + "\t-value <value1[,value2,...,valueN]> - value sent to each recipient, count should be equal addresses count\n" "\t-fee <value> - fee value\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" "emit_delegate sign - add wallet sign to take datum\n" -- GitLab From fa571ca6ef5bbc8517bbd0fae9f218f2183c304b Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 21 Feb 2025 11:46:27 +0300 Subject: [PATCH 12/29] [*] remove s_cli_param_check --- .../service/emit-delegate/dap_chain_net_srv_emit_delegate.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 93464a7d78..2c256a03c2 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -583,11 +583,6 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_sign(json_object #undef m_sign_fail -enum emit_delegation_error s_cli_param_check (int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) -{ - return DAP_NO_ERROR; -} - static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) { const char *l_token_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL, *l_signs_min_str = NULL, *l_pkeys_str = NULL; -- GitLab From a54879f29220043527c2ccb7e840aab5a3128805 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 21 Feb 2025 16:45:24 +0300 Subject: [PATCH 13/29] [*] error fix --- .../dap_chain_net_srv_emit_delegate.c | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 2c256a03c2..9eb1afc5ca 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -354,7 +354,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o dap_chain_tx_out_cond_t *l_out_cond = DAP_DUP_SIZE(l_cond_prev, sizeof(dap_chain_tx_out_cond_t) + l_cond_prev->tsd_size); if (!l_out_cond) - m_tx_fail(ERROR_COMPOSE, c_error_memory_alloc); + m_tx_fail(ERROR_MEMORY, c_error_memory_alloc); l_out_cond->header.value = l_value_back; if (dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond) < 0) { m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); @@ -493,11 +493,11 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje SUBTRACT_256_256(l_cond_prev->header.value, l_value, &l_value_back); dap_chain_tx_out_cond_t *l_out_cond = DAP_DUP_SIZE(l_cond_prev, sizeof(dap_chain_tx_out_cond_t) + l_cond_prev->tsd_size); if (!l_out_cond) - m_tx_fail(ERROR_COMPOSE, c_error_memory_alloc); + m_tx_fail(ERROR_MEMORY, c_error_memory_alloc); l_out_cond->header.value = l_value_back; if (-1 == dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond)) { - m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); DAP_DELETE(l_out_cond); + m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); } DAP_DELETE(l_out_cond); @@ -538,7 +538,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje if (dap_chain_datum_tx_add_sign_item(&l_tx, a_enc_key) != 1) m_tx_fail(ERROR_COMPOSE, "Can't add sign output"); -return l_tx; + return l_tx; } @@ -574,7 +574,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_sign(json_object } dap_chain_datum_tx_t *l_tx = DAP_DUP_SIZE(a_tx_in, dap_chain_datum_tx_get_size(a_tx_in)); if (!l_tx) - m_sign_fail(ERROR_FUNDS, c_error_memory_alloc); + m_sign_fail(ERROR_MEMORY, c_error_memory_alloc); // add 'sign' item if (dap_chain_datum_tx_add_sign_item(&l_tx, a_enc_key) != 1) m_sign_fail(ERROR_COMPOSE, "Can't add sign output"); @@ -862,14 +862,14 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** l_value = DAP_NEW_Z_COUNT(uint256_t, l_value_el_count); if (!l_value) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR, c_error_memory_alloc); - return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR; + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_MEMORY, c_error_memory_alloc); + return ERROR_MEMORY; } char **l_value_array = dap_strsplit(l_value_str, ",", l_value_el_count); if (!l_value_array) { DAP_DELETE(l_value); - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "Can't read '-to_addr' arg"); - return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR; + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Can't read '-to_addr' arg"); + return ERROR_PARAM; } for (size_t i = 0; i < l_value_el_count; ++i) { l_value[i] = dap_chain_balance_scan(l_value_array[i]); @@ -886,14 +886,14 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** if (!l_to_addr) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); DAP_DELETE(l_value); - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR, c_error_memory_alloc); - return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR; + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_MEMORY, c_error_memory_alloc); + return ERROR_MEMORY; } char **l_to_addr_str_array = dap_strsplit(l_addr_str, ",", l_addr_el_count); if (!l_to_addr_str_array) { DAP_DEL_MULTY(l_to_addr, l_value); - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "Can't read '-to_addr' arg"); - return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR; + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Can't read '-to_addr' arg"); + return ERROR_PARAM; } for (size_t i = 0; i < l_addr_el_count; ++i) { l_to_addr[i] = dap_chain_addr_from_str(l_to_addr_str_array[i]); -- GitLab From f38c60017e97b067c560686e0e7e83fbe7c36bfd Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 21 Feb 2025 17:15:20 +0300 Subject: [PATCH 14/29] [*] load mode protect --- .../emit-delegate/dap_chain_net_srv_emit_delegate.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 9eb1afc5ca..0abbe5ceb5 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -47,7 +47,8 @@ enum emit_delegation_error { ERROR_COMPOSE, ERROR_CREATE, ERROR_PLACE, - ERROR_SUBCOMMAND + ERROR_SUBCOMMAND, + ERROR_NETWORK }; #define LOG_TAG "dap_chain_net_srv_emit_delegate" @@ -1104,6 +1105,11 @@ static int s_cli_emit_delegate(int a_argc, char **a_argv, void **a_str_reply) if (l_err_net_chain) return l_err_net_chain; + if (dap_chain_net_get_load_mode(l_net)) { + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_NETWORK, "Can't apply command while network in load mode"); + return ERROR_NETWORK; + } + if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "hold", NULL)) return s_cli_hold(a_argc, a_argv, l_arg_index + 1, a_json_arr_reply, l_net, l_chain, l_hash_out_type); else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "refill", NULL)) -- GitLab From 649af043ac48aa7109ea8da37b95519de994532e Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 21 Feb 2025 17:33:00 +0300 Subject: [PATCH 15/29] [*] info fix --- .../emit-delegate/dap_chain_net_srv_emit_delegate.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 0abbe5ceb5..3dd4b00bee 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -1045,10 +1045,12 @@ static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object ** json_object *l_jobj_balance = json_object_new_object(); json_object *l_jobj_token = json_object_new_object(); - json_object *l_jobj_pkey_hashes = json_object_new_object(); + json_object *l_jobj_take_verify = json_object_new_object(); + json_object *l_jobj_pkey_hashes = json_object_new_array(); json_object *l_json_jobj_info = json_object_new_object(); - if (dap_strcmp(a_hash_out_type, "hex")) { + bool l_is_base_hash_type = dap_strcmp(a_hash_out_type, "hex"); + if (l_is_base_hash_type) { json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(dap_enc_base58_encode_hash_to_str_static(&l_tx_hash))); json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(dap_enc_base58_encode_hash_to_str_static(&l_final_tx_hash))); } else { @@ -1064,16 +1066,17 @@ static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object ** json_object_object_add(l_jobj_token, "description", l_jobj_description); json_object_object_add(l_jobj_balance, "coins", json_object_new_string(l_balance_coins)); json_object_object_add(l_jobj_balance, "datoshi", json_object_new_string(l_balance_datoshi)); - json_object_object_add(l_jobj_pkey_hashes, "signs_minimum", json_object_new_uint64(l_cond->subtype.srv_emit_delegate.signers_minimum)); + json_object_object_add(l_jobj_take_verify, "signs_minimum", json_object_new_uint64(l_cond->subtype.srv_emit_delegate.signers_minimum)); dap_tsd_t *l_tsd; size_t l_tsd_size; dap_tsd_iter(l_tsd, l_tsd_size, l_cond->tsd, l_cond->tsd_size) { if (l_tsd->type == DAP_CHAIN_TX_OUT_COND_TSD_HASH && l_tsd->size == sizeof(dap_hash_fast_t)) { - json_object_object_add(l_jobj_pkey_hashes, "owner_pkey_hash", json_object_new_string(dap_hash_fast_to_str_static(l_tsd->data))); + json_object_array_add(l_jobj_pkey_hashes, json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static(l_tsd->data) : dap_hash_fast_to_str_static(l_tsd->data))); } } json_object_object_add(l_json_jobj_info, "balance", l_jobj_balance); - json_object_object_add(l_json_jobj_info, "take_verify", l_jobj_pkey_hashes); + json_object_object_add(l_jobj_take_verify, "owner_hashes", l_jobj_pkey_hashes); + json_object_object_add(l_json_jobj_info, "take_verify", l_jobj_take_verify); json_object_object_add(l_json_jobj_info, "token", l_jobj_token); json_object_array_add(*a_json_arr_reply, l_json_jobj_info); return DAP_NO_ERROR; -- GitLab From e2ccdb738bc9374419d4c26091b4a5176b498fd8 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Mon, 24 Feb 2025 08:35:06 +0300 Subject: [PATCH 16/29] [*] MR preparing --- modules/common/dap_chain_datum_tx_items.c | 2 +- .../dap_chain_net_srv_emit_delegate.c | 84 +++++++++---------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index b694961e23..0b14ea1931 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -104,7 +104,7 @@ dap_chain_tx_out_cond_subtype_t dap_chain_tx_out_cond_subtype_from_str(const cha */ size_t dap_chain_datum_item_tx_get_size(const byte_t *a_item, size_t a_max_size) { - dap_return_val_if_fail(a_item, TX_ITEM_TYPE_UNKNOWN); + dap_return_val_if_fail(a_item, 0); size_t l_ret = 0; #define m_tx_item_size(t) ( !a_max_size || sizeof(t) <= a_max_size ? sizeof(t) : 0 ) #define m_tx_item_size_ext(t, size_field) \ diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 3dd4b00bee..dabb3b451a 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -140,7 +140,7 @@ static int s_emit_delegate_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_ char *l_balance = dap_uint256_decimal_to_char(a_cond->header.value); const char *l_refill = NULL; dap_uint256_to_char(l_change_value, &l_refill); - log_it(L_ERROR, "Sum of re-fill value %s and account balance %s is greater than value limit of 256 bit num", l_refill, l_balance); + log_it(L_ERROR, "Sum of re-fill value %s and account balance %s is owerflow 256 bit num", l_refill, l_balance); DAP_DELETE(l_balance); return -9; } @@ -297,6 +297,7 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { + dap_return_val_if_pass(!a_net || IS_ZERO_256(a_value) || IS_ZERO_256(a_fee), NULL); // create empty transaction dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); @@ -358,18 +359,18 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o m_tx_fail(ERROR_MEMORY, c_error_memory_alloc); l_out_cond->header.value = l_value_back; if (dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond) < 0) { - m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); + m_tx_fail(ERROR_COMPOSE, "Cant add refill cond output"); DAP_DELETE(l_out_cond); } DAP_DELETE(l_out_cond); // add track for takeoff from conditional value - dap_chain_tx_tsd_t *l_refill_tsd = NULL; - l_refill_tsd = dap_chain_datum_tx_item_tsd_create(&a_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL, sizeof(uint256_t)); - - if (!l_refill_tsd || dap_chain_datum_tx_add_item(&l_tx, l_refill_tsd) != 1) + dap_chain_tx_tsd_t *l_refill_tsd = dap_chain_datum_tx_item_tsd_create(&a_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL, sizeof(uint256_t)); + if (dap_chain_datum_tx_add_item(&l_tx, l_refill_tsd) != 1) { + DAP_DELETE(l_refill_tsd); m_tx_fail(ERROR_COMPOSE, "Can't add TSD section item with withdraw value"); + } DAP_DELETE(l_refill_tsd); //add other tsd if available @@ -437,6 +438,10 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje dap_chain_addr_t l_net_fee_addr; for (size_t i = 0; i < a_addr_count; ++i) { + if(IS_ZERO_256(a_value[i])) { + m_tx_fail(ERROR_VALUE, "Format -value <256 bit integer> and not equal zero"); + return ERROR_VALUE; + } if (SUM_256_256(l_value, a_value[i], &l_value)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); } @@ -603,7 +608,7 @@ static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object ** } uint256_t l_value = dap_chain_balance_scan(l_value_str); if (IS_ZERO_256(l_value)) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer>"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer> and not equal zero"); return ERROR_VALUE; } dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str); @@ -613,7 +618,7 @@ static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object ** } uint256_t l_fee = dap_chain_balance_scan(l_fee_str); if (IS_ZERO_256(l_fee)) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -fee <256 bit integer>"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -fee <256 bit integer> and not equal zer"); return ERROR_VALUE; } dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-signs_minimum", &l_signs_min_str); @@ -717,34 +722,34 @@ static int s_cli_refill(int a_argc, char **a_argv, int a_arg_index, json_object const char *l_token_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL, *l_tx_in_hash_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-value", &l_value_str); if (!l_value_str) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation holding requires parameter -value"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Refill command requires parameter -value"); return ERROR_PARAM; } uint256_t l_value = dap_chain_balance_scan(l_value_str); if (IS_ZERO_256(l_value)) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer>"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer> and not equal zero"); return ERROR_VALUE; } dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-fee", &l_fee_str); if (!l_fee_str) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation holding requires parameter -fee"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Refill command requires parameter -fee"); return ERROR_PARAM; } uint256_t l_fee = dap_chain_balance_scan(l_fee_str); if (IS_ZERO_256(l_fee)) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -fee <256 bit integer>"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -fee <256 bit integer> and not equal zer"); return ERROR_VALUE; } dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-w", &l_wallet_str); if (!l_wallet_str) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation holding requires parameter -w"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Refill command requires parameter -w"); return ERROR_PARAM; } dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tx", &l_tx_in_hash_str); if (!l_tx_in_hash_str) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation taking requires parameter -tx"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Refill command requires parameter -tx"); return ERROR_PARAM; } dap_hash_fast_t l_tx_in_hash; @@ -767,17 +772,17 @@ static int s_cli_refill(int a_argc, char **a_argv, int a_arg_index, json_object dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); dap_chain_wallet_close(l_wallet); - // Create conditional transaction for delegated emissions + // Create conditional transaction for refill dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_refilling_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_value, l_fee, &l_tx_in_hash, NULL); DAP_DELETE(l_enc_key); if (!l_tx) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for delegated emission"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for refill shared funds tx"); return ERROR_CREATE; } char *l_tx_hash_str = s_tx_put(l_tx, a_chain, a_hash_out_type); DAP_DELETE(l_tx); if (!l_tx_hash_str) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PLACE, "Can't place transaction for delegated emission in mempool"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PLACE, "Can't place transaction for refill shared funds tx in mempool"); return ERROR_PLACE; } json_object * l_json_obj_create_val = json_object_new_object(); @@ -797,7 +802,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** uint256_t *l_value = NULL; dap_chain_addr_t **l_to_addr = NULL; uint32_t - l_addr_el_count = 0, // not change type! use in TSD section + l_addr_el_count = 0, // not change type! use in batching TSD section l_value_el_count = 0; dap_list_t *l_tsd_list = NULL; @@ -823,7 +828,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** } uint256_t l_fee = dap_chain_balance_scan(l_fee_str); if (IS_ZERO_256(l_fee)) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -fee <256 bit integer>"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -fee <256 bit integer> and not equal zer"); return ERROR_VALUE; } @@ -877,7 +882,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** if(IS_ZERO_256(l_value[i])) { DAP_DELETE(l_value); dap_strfreev(l_value_array); - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer>"); + dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Format -value <256 bit integer> and not equal zero"); return ERROR_VALUE; } } @@ -920,7 +925,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** // Create emission from conditional transaction dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_to_addr, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, l_tsd_list); DAP_DEL_ARRAY(l_to_addr, l_addr_el_count); - DAP_DEL_MULTY(l_to_addr, l_enc_key); + DAP_DEL_MULTY(l_value, l_to_addr, l_enc_key); dap_list_free_full(l_tsd_list, NULL); if (!l_tx) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for delegated emission"); @@ -1038,7 +1043,6 @@ static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object ** dap_json_rpc_error_add(*a_json_arr_reply, ERROR_TX_MISMATCH, "Can't find final tx_out_cond"); return ERROR_TX_MISMATCH; } - const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, &l_final_tx_hash); const char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(l_cond->header.value, &l_balance_coins); @@ -1050,32 +1054,28 @@ static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object ** json_object *l_json_jobj_info = json_object_new_object(); bool l_is_base_hash_type = dap_strcmp(a_hash_out_type, "hex"); - if (l_is_base_hash_type) { - json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(dap_enc_base58_encode_hash_to_str_static(&l_tx_hash))); - json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(dap_enc_base58_encode_hash_to_str_static(&l_final_tx_hash))); - } else { - json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(dap_hash_fast_to_str_static(&l_tx_hash))); - json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(dap_hash_fast_to_str_static(&l_final_tx_hash))); - } - - json_object *l_jobj_ticker = json_object_new_string(l_tx_ticker); + // tocken block const char *l_description = dap_ledger_get_description_by_ticker(a_net->pub.ledger, l_tx_ticker); json_object *l_jobj_description = l_description ? json_object_new_string(l_description) : json_object_new_null(); - json_object_object_add(l_jobj_token, "ticker", l_jobj_ticker); + json_object_object_add(l_jobj_token, "ticker", json_object_new_string(l_tx_ticker)); json_object_object_add(l_jobj_token, "description", l_jobj_description); + // balance block json_object_object_add(l_jobj_balance, "coins", json_object_new_string(l_balance_coins)); json_object_object_add(l_jobj_balance, "datoshi", json_object_new_string(l_balance_datoshi)); + // verify block json_object_object_add(l_jobj_take_verify, "signs_minimum", json_object_new_uint64(l_cond->subtype.srv_emit_delegate.signers_minimum)); - dap_tsd_t *l_tsd; size_t l_tsd_size; + dap_tsd_t *l_tsd = NULL; size_t l_tsd_size = 0; dap_tsd_iter(l_tsd, l_tsd_size, l_cond->tsd, l_cond->tsd_size) { if (l_tsd->type == DAP_CHAIN_TX_OUT_COND_TSD_HASH && l_tsd->size == sizeof(dap_hash_fast_t)) { - json_object_array_add(l_jobj_pkey_hashes, json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static(l_tsd->data) : dap_hash_fast_to_str_static(l_tsd->data))); + json_object_array_add(l_jobj_pkey_hashes, json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static((const dap_chain_hash_fast_t *)l_tsd->data) : dap_hash_fast_to_str_static((const dap_chain_hash_fast_t *)l_tsd->data))); } } - json_object_object_add(l_json_jobj_info, "balance", l_jobj_balance); json_object_object_add(l_jobj_take_verify, "owner_hashes", l_jobj_pkey_hashes); - + // result block + json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static(&l_tx_hash) : dap_hash_fast_to_str_static(&l_tx_hash))); + json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static(&l_final_tx_hash) : dap_hash_fast_to_str_static(&l_final_tx_hash))); + json_object_object_add(l_json_jobj_info, "balance", l_jobj_balance); json_object_object_add(l_json_jobj_info, "take_verify", l_jobj_take_verify); json_object_object_add(l_json_jobj_info, "token", l_jobj_token); json_object_array_add(*a_json_arr_reply, l_json_jobj_info); @@ -1147,12 +1147,12 @@ int dap_chain_net_srv_emit_delegate_init() "\t-w <wallet_name> - wallet to writeoff value and pay fee\n" "\t-value <value> - value to refill\n" "\t-fee <value> - fee value\n" - "\t-tx <transaction_hash> - emit delegate tx hash to refill\n" + "\t-tx <transaction_hash> - shared funds tx hash to refill\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" - "emit_delegate take - create take datum to writeoff value from0 emit delegate tx\n" + "emit_delegate take - create take datum to writeoff value from0 shared funds tx\n" "\t-net <net_name>\n" "\t-w <wallet_name> - wallet to pay fee\n" - "\t-tx <transaction_hash> - emit delegate tx hash to writeoff\n" + "\t-tx <transaction_hash> - shared funds tx hash to writeoff\n" "\t-to_addr <addr1[,addr2,...,addrN]> - recipient addresses, count should be equal values count\n" "\t-value <value1[,value2,...,valueN]> - value sent to each recipient, count should be equal addresses count\n" "\t-fee <value> - fee value\n" @@ -1160,11 +1160,11 @@ int dap_chain_net_srv_emit_delegate_init() "emit_delegate sign - add wallet sign to take datum\n" "\t-net <net_name>\n" "\t-w <wallet_name> | -cert <cert_name> - wallet or cert to sign\n" - "\t-tx <transaction_hash> - emit delegate tx hash to sign\n" + "\t-tx <transaction_hash> - shared funds tx hash to sign\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" - "emit_delegate info - get info about emit delegate tx by hash\n" + "emit_delegate info - get info about shared funds tx by hash\n" "\t-net <net_name>\n" - "\t-tx <transaction_hash> - emit delegate tx hash to get info\n" + "\t-tx <transaction_hash> - shared funds tx hash to get info\n" "\t[-H {hex(default) | base58}] - tx hash format\n" "Hint:\n" "\texample value_coins (only natural) 1.0 123.4567\n" -- GitLab From 185f4fa0fa18868880d107143a399f7c027c8c8d Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Mon, 24 Feb 2025 09:01:41 +0300 Subject: [PATCH 17/29] [*] wrn fix --- modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c | 1 - modules/wallet/dap_chain_wallet_cache.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index dabb3b451a..86dfb8bd9d 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -440,7 +440,6 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje for (size_t i = 0; i < a_addr_count; ++i) { if(IS_ZERO_256(a_value[i])) { m_tx_fail(ERROR_VALUE, "Format -value <256 bit integer> and not equal zero"); - return ERROR_VALUE; } if (SUM_256_256(l_value, a_value[i], &l_value)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); diff --git a/modules/wallet/dap_chain_wallet_cache.c b/modules/wallet/dap_chain_wallet_cache.c index 7dbc8737d1..59c3d21a20 100644 --- a/modules/wallet/dap_chain_wallet_cache.c +++ b/modules/wallet/dap_chain_wallet_cache.c @@ -680,7 +680,7 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad dap_chain_addr_t l_addr; uint256_t l_value; uint8_t *l_prev_item = NULL; - int l_prev_idx; + int l_prev_idx = 0; uint8_t l_item_type = TX_ITEM_TYPE_ANY; switch(*l_tx_item) { -- GitLab From b6d88c7827da4587fadb41ad511fc5408e37d0b9 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Mon, 24 Feb 2025 09:45:52 +0300 Subject: [PATCH 18/29] [*] restore vote --- modules/net/dap_chain_ledger.c | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 7c7bb44c02..2dec66972d 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -3267,6 +3267,7 @@ const char *dap_ledger_tx_action_str(dap_chain_tx_tag_action_type_t a_tag) if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CLOSE) return "close"; if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CHANGE) return "change"; if (a_tag == DAP_CHAIN_TX_TAG_ACTION_VOTING) return "voting"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_VOTE) return "vote"; if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_HOLD) return "hold"; if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_TAKE) return "take"; if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EMIT_DELEGATE_REFILL) return "refill"; -- GitLab From d12a475370b8fd8eef3431c92401de3a3ac1ca58 Mon Sep 17 00:00:00 2001 From: Dmitry Pyzyrkov <dpuzyrkov@gmail.com> Date: Mon, 24 Feb 2025 18:07:15 +0700 Subject: [PATCH 19/29] [+] optional -tag for emission delegate hold --- .../common/include/dap_chain_datum_token.h | 1 + .../dap_chain_net_srv_emit_delegate.c | 26 ++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index f596c2e605..318bc57b5f 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -340,6 +340,7 @@ typedef struct dap_chain_datum_token_emission { #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SIGNATURS 0x000E #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_UNIQUE_ID 0x000F #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BASE_TX_HASH 0x0010 +#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG 0x0011 // TSD sections with transfer additional params #define DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT 0x0013 diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 86dfb8bd9d..ca3f981bdc 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -206,7 +206,7 @@ static char *s_tx_put(dap_chain_datum_tx_t *a_tx, dap_chain_t *a_chain, const ch static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, const char *a_token_ticker, uint256_t a_value, uint256_t a_fee, - uint32_t a_signs_min, dap_hash_fast_t *a_pkey_hashes, size_t a_pkey_hashes_count) + uint32_t a_signs_min, dap_hash_fast_t *a_pkey_hashes, size_t a_pkey_hashes_count, const char *a_tag_str) { const char *l_native_ticker = a_net->pub.native_ticker; bool l_delegate_native = !dap_strcmp(l_native_ticker, a_token_ticker); @@ -286,10 +286,18 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, m_tx_fail(ERROR_COMPOSE, "Cant add fee back output"); } + if (a_tag_str) { + dap_chain_tx_tsd_t *tsd_tag_item = dap_chain_datum_tx_item_tsd_create(a_tag_str, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG, strlen(a_tag_str)); + if (!l_tx_out) + m_tx_fail(ERROR_COMPOSE, "Can't compose the transaction tag"); + dap_chain_datum_tx_add_item(&l_tx, tsd_tag_item); + DAP_DELETE(tsd_tag_item); + } // add 'sign' item if (dap_chain_datum_tx_add_sign_item(&l_tx, a_enc_key) != 1) m_tx_fail(ERROR_COMPOSE, "Can't add sign output"); + return l_tx; } @@ -590,7 +598,14 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_sign(json_object static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object **a_json_arr_reply, dap_chain_net_t *a_net, dap_chain_t *a_chain, const char *a_hash_out_type) { - const char *l_token_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL, *l_signs_min_str = NULL, *l_pkeys_str = NULL; + const char *l_token_str = NULL, + *l_value_str = NULL, + *l_wallet_str = NULL, + *l_fee_str = NULL, + *l_signs_min_str = NULL, + *l_pkeys_str = NULL, + *l_tag_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-token", &l_token_str); if (!l_token_str) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation holding requires parameter -token"); @@ -635,11 +650,15 @@ static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object ** dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Emitting delegation holding requires parameter -w"); return ERROR_PARAM; } + dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config), NULL); if (!l_wallet) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Specified wallet %s not found", l_wallet_str); return ERROR_VALUE; } + + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-tag", &l_tag_str); + const char *l_sign_str = dap_chain_wallet_check_sign(l_wallet); dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0); dap_chain_wallet_close(l_wallet); @@ -694,7 +713,7 @@ static int s_cli_hold(int a_argc, char **a_argv, int a_arg_index, json_object ** return ERROR_VALUE; } // Create conditional transaction for delegated emissions - dap_chain_datum_tx_t *l_tx = s_emitting_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_token_str, l_value, l_fee, l_signs_min, l_pkey_hashes, l_hashes_count); + dap_chain_datum_tx_t *l_tx = s_emitting_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_token_str, l_value, l_fee, l_signs_min, l_pkey_hashes, l_hashes_count, l_tag_str); DAP_DEL_MULTY(l_enc_key, l_pkey_hashes); if (!l_tx) { dap_json_rpc_error_add(*a_json_arr_reply, ERROR_CREATE, "Can't compose transaction for delegated emission"); @@ -1137,6 +1156,7 @@ int dap_chain_net_srv_emit_delegate_init() "\t-w <wallet_name> - wallet to writeoff value, pay fee and sign tx\n" "\t-token <ticker> - token ticker to hold\n" "\t-value <value> - value to hold\n" + "\t-tag <str> add tsd-section with tag\n" "\t-fee <value> - fee value\n" "\t-signs_minimum <value_int> - minimum signs count needed to verify take datum\n" "\t-pkey_hashes <hash1[,hash2,...,hashN]> - owners pkey hashes, who can sign take datum\n" -- GitLab From 11d69d1e1b2682ba7e6e004ed78b4dd7070d95a3 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Tue, 25 Feb 2025 10:05:24 +0300 Subject: [PATCH 20/29] [*] small fixes --- .../emit-delegate/dap_chain_net_srv_emit_delegate.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index ca3f981bdc..c3b95889e1 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -287,10 +287,13 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, } if (a_tag_str) { - dap_chain_tx_tsd_t *tsd_tag_item = dap_chain_datum_tx_item_tsd_create(a_tag_str, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG, strlen(a_tag_str)); - if (!l_tx_out) + dap_chain_tx_tsd_t *tsd_tag_item = dap_chain_datum_tx_item_tsd_create(a_tag_str, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG, strlen(a_tag_str) + 1); + if (!tsd_tag_item) m_tx_fail(ERROR_COMPOSE, "Can't compose the transaction tag"); - dap_chain_datum_tx_add_item(&l_tx, tsd_tag_item); + if (dap_chain_datum_tx_add_item(&l_tx, tsd_tag_item) != 1) { + DAP_DELETE(tsd_tag_item); + m_tx_fail(ERROR_COMPOSE, "Can't add the transaction tag"); + } DAP_DELETE(tsd_tag_item); } // add 'sign' item @@ -1156,10 +1159,10 @@ int dap_chain_net_srv_emit_delegate_init() "\t-w <wallet_name> - wallet to writeoff value, pay fee and sign tx\n" "\t-token <ticker> - token ticker to hold\n" "\t-value <value> - value to hold\n" - "\t-tag <str> add tsd-section with tag\n" "\t-fee <value> - fee value\n" "\t-signs_minimum <value_int> - minimum signs count needed to verify take datum\n" "\t-pkey_hashes <hash1[,hash2,...,hashN]> - owners pkey hashes, who can sign take datum\n" + "\t[-tag \"<str>\"] - additional info about tx\n" "\t[-H {hex(default) | base58}] - datum hash return format\n" "emit_delegate refill - to refill value\n" "\t-net <net_name>\n" -- GitLab From 764e87103c834cf21c1d30063f9e3bcbbe47393a Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Tue, 25 Feb 2025 13:43:02 +0300 Subject: [PATCH 21/29] [*] fix signs check in refill --- modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index c3b95889e1..307bec5b78 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -162,7 +162,7 @@ static int s_emit_delegate_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_ } } - if (l_signs_verified < a_cond->subtype.srv_emit_delegate.signers_minimum) { + if (l_change_type == DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF && l_signs_verified < a_cond->subtype.srv_emit_delegate.signers_minimum) { log_it(L_WARNING, "Not enough valid signs (%u from %u) for delegated emission", l_signs_verified, a_cond->subtype.srv_emit_delegate.signers_minimum); return DAP_CHAIN_CS_VERIFY_CODE_NOT_ENOUGH_SIGNS; -- GitLab From f0bea86547fb10bd81c3683f843282824a16f6a1 Mon Sep 17 00:00:00 2001 From: Pavel Uhanov <pavel.uhanov@demlabs.net> Date: Wed, 26 Feb 2025 07:54:04 +0000 Subject: [PATCH 22/29] [*] fix not native token --- .../dap_chain_net_srv_emit_delegate.c | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 307bec5b78..09596ffd56 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -310,33 +310,46 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o { dap_return_val_if_pass(!a_net || IS_ZERO_256(a_value) || IS_ZERO_256(a_fee), NULL); // create empty transaction - dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); - dap_ledger_t *l_ledger = a_net->pub.ledger; const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, a_tx_in_hash); - bool l_taking_native = !dap_strcmp(a_net->pub.native_ticker, l_tx_ticker); - - uint256_t l_value = a_value, l_value_transfer = {}; // how many coins to refill + bool l_refill_native = !dap_strcmp(a_net->pub.native_ticker, l_tx_ticker); + uint256_t l_value = a_value, l_value_transfer = {}, l_fee_transfer = {}; // how many coins to transfer uint256_t l_net_fee, l_fee_total = a_fee; dap_chain_addr_t l_net_fee_addr; + // create empty transaction + dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr); if (l_net_fee_used && SUM_256_256(l_fee_total, l_net_fee, &l_fee_total)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); - if (SUM_256_256(l_value, l_fee_total, &l_value)) + if (l_refill_native && SUM_256_256(l_value, l_fee_total, &l_value)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); + // list of transaction with 'out' items to sell dap_chain_addr_t l_owner_addr; dap_chain_addr_fill_from_key(&l_owner_addr, a_enc_key, a_net->pub.id); - dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_net->pub.native_ticker, - &l_owner_addr, l_value, &l_value_transfer); - if (!l_list_fee_out) - m_tx_fail(ERROR_FUNDS, "Nothing to pay for fee (not enough funds)"); - // add 'in' items to pay fee - uint256_t l_value_fee_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_fee_out); - dap_list_free_full(l_list_fee_out, NULL); - if (!EQUAL_256(l_value_fee_items, l_value_transfer)) - m_tx_fail(ERROR_COMPOSE, "Can't compose the fee transaction input"); + dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_tx_ticker, + &l_owner_addr, l_value, &l_value_transfer); + if (!l_list_used_out) + m_tx_fail(ERROR_FUNDS, "Nothing to pay for delegate (not enough funds)"); + + // add 'in' items to pay for delegate + uint256_t l_value_to_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out); + dap_list_free_full(l_list_used_out, NULL); + if (!EQUAL_256(l_value_to_items, l_value_transfer)) + m_tx_fail(ERROR_COMPOSE, "Can't compose the transaction input"); + + if (!l_refill_native) { + dap_list_t *l_list_fee_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_net->pub.native_ticker, + &l_owner_addr, l_fee_total, &l_fee_transfer); + if (!l_list_fee_out) + m_tx_fail(ERROR_FUNDS, "Nothing to pay for fee (not enough funds)"); + // add 'in' items to pay fee + uint256_t l_value_fee_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_fee_out); + dap_list_free_full(l_list_fee_out, NULL); + if (!EQUAL_256(l_value_fee_items, l_fee_transfer)) + m_tx_fail(ERROR_COMPOSE, "Can't compose the fee transaction input"); + } dap_hash_fast_t l_final_tx_hash = dap_ledger_get_final_chain_tx_hash(l_ledger, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_EMIT_DELEGATE, a_tx_in_hash, false); if (dap_hash_fast_is_blank(&l_final_tx_hash)) @@ -359,7 +372,6 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o m_tx_fail(ERROR_COMPOSE, "Cant add conditionsl input"); } - // coin back uint256_t l_value_back = {}; if(SUM_256_256(l_cond_prev->header.value, a_value, &l_value_back)) { m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); @@ -390,24 +402,30 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o m_tx_fail(ERROR_COMPOSE, "Can't add custom TSD section item "); } +// coin back + SUBTRACT_256_256(l_value_transfer, l_value, &l_value_back); + if (!IS_ZERO_256(l_value_back)) { + int rc = l_refill_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_owner_addr, l_value_back) + : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_value_back, l_tx_ticker); + if (rc != 1) + m_tx_fail(ERROR_COMPOSE, "Cant add coin back output"); + } + // add fee items if (l_net_fee_used) { - int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_net_fee_addr, l_net_fee) - : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_net_fee_addr, l_net_fee, a_net->pub.native_ticker); + int rc = l_refill_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_net_fee_addr, l_net_fee) + : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_net_fee_addr, l_net_fee, a_net->pub.native_ticker); if (rc != 1) - m_tx_fail(ERROR_COMPOSE, "Cant add net fee output"); + m_tx_fail(ERROR_COMPOSE, "Cant add net fee output"); } if (!IS_ZERO_256(a_fee) && dap_chain_datum_tx_add_fee_item(&l_tx, a_fee) != 1) m_tx_fail(ERROR_COMPOSE, "Cant add validator fee output"); - uint256_t l_fee_back = {}; - // fee coin back - SUBTRACT_256_256(l_value_transfer, l_value, &l_fee_back); - - if (!IS_ZERO_256(l_fee_back)) { - int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_owner_addr, l_fee_back) - : dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, a_net->pub.native_ticker); - if (rc != 1) + if (!l_refill_native) { + uint256_t l_fee_back = {}; + // fee coin back + SUBTRACT_256_256(l_fee_transfer, l_fee_total, &l_fee_back); + if (!IS_ZERO_256(l_fee_back) && dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, a_net->pub.native_ticker) != 1) m_tx_fail(ERROR_COMPOSE, "Cant add fee back output"); } -- GitLab From 53d6eeec272fddd47cdbbcf8fc11366787b82cc9 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 28 Feb 2025 09:04:53 +0300 Subject: [PATCH 23/29] [*] visual fixes --- .../dap_chain_net_srv_emit_delegate.c | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 09596ffd56..30901bde21 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -287,20 +287,18 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, } if (a_tag_str) { - dap_chain_tx_tsd_t *tsd_tag_item = dap_chain_datum_tx_item_tsd_create(a_tag_str, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG, strlen(a_tag_str) + 1); - if (!tsd_tag_item) + dap_chain_tx_tsd_t *l_tsd_tag_item = dap_chain_datum_tx_item_tsd_create(a_tag_str, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG, strlen(a_tag_str) + 1); + if (!l_tsd_tag_item) m_tx_fail(ERROR_COMPOSE, "Can't compose the transaction tag"); - if (dap_chain_datum_tx_add_item(&l_tx, tsd_tag_item) != 1) { - DAP_DELETE(tsd_tag_item); + if (dap_chain_datum_tx_add_item(&l_tx, l_tsd_tag_item) != 1) { + DAP_DELETE(l_tsd_tag_item); m_tx_fail(ERROR_COMPOSE, "Can't add the transaction tag"); } - DAP_DELETE(tsd_tag_item); + DAP_DELETE(l_tsd_tag_item); } // add 'sign' item if (dap_chain_datum_tx_add_sign_item(&l_tx, a_enc_key) != 1) m_tx_fail(ERROR_COMPOSE, "Can't add sign output"); - - return l_tx; } @@ -309,7 +307,6 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { dap_return_val_if_pass(!a_net || IS_ZERO_256(a_value) || IS_ZERO_256(a_fee), NULL); - // create empty transaction dap_ledger_t *l_ledger = a_net->pub.ledger; const char *l_tx_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_net->pub.ledger, a_tx_in_hash); bool l_refill_native = !dap_strcmp(a_net->pub.native_ticker, l_tx_ticker); @@ -331,7 +328,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, l_tx_ticker, &l_owner_addr, l_value, &l_value_transfer); if (!l_list_used_out) - m_tx_fail(ERROR_FUNDS, "Nothing to pay for delegate (not enough funds)"); + m_tx_fail(ERROR_FUNDS, "Nothing to pay for refill (not enough funds)"); // add 'in' items to pay for delegate uint256_t l_value_to_items = dap_chain_datum_tx_add_in_item_list(&l_tx, l_list_used_out); @@ -387,8 +384,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o } DAP_DELETE(l_out_cond); - - // add track for takeoff from conditional value + // add track for refill from conditional value dap_chain_tx_tsd_t *l_refill_tsd = dap_chain_datum_tx_item_tsd_create(&a_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_REFILL, sizeof(uint256_t)); if (dap_chain_datum_tx_add_item(&l_tx, l_refill_tsd) != 1) { DAP_DELETE(l_refill_tsd); @@ -402,7 +398,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_o m_tx_fail(ERROR_COMPOSE, "Can't add custom TSD section item "); } -// coin back + // coin back SUBTRACT_256_256(l_value_transfer, l_value, &l_value_back); if (!IS_ZERO_256(l_value_back)) { int rc = l_refill_native ? dap_chain_datum_tx_add_out_item(&l_tx, &l_owner_addr, l_value_back) -- GitLab From 0f24462136e52cb6ed566e3f5bc5e4c9399e4f6e Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Fri, 28 Feb 2025 09:35:00 +0300 Subject: [PATCH 24/29] [*] wrn fix --- modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 30901bde21..346e3fa01d 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -287,7 +287,7 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, } if (a_tag_str) { - dap_chain_tx_tsd_t *l_tsd_tag_item = dap_chain_datum_tx_item_tsd_create(a_tag_str, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG, strlen(a_tag_str) + 1); + dap_chain_tx_tsd_t *l_tsd_tag_item = dap_chain_datum_tx_item_tsd_create((void *)a_tag_str, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG, strlen(a_tag_str) + 1); if (!l_tsd_tag_item) m_tx_fail(ERROR_COMPOSE, "Can't compose the transaction tag"); if (dap_chain_datum_tx_add_item(&l_tx, l_tsd_tag_item) != 1) { -- GitLab From 147aea17ce9b3637f17857d31e1adced82ce9965 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Mon, 10 Mar 2025 12:41:36 +0300 Subject: [PATCH 25/29] [*] move tag to cond_out --- modules/common/dap_chain_datum_tx_items.c | 6 ++++-- modules/common/include/dap_chain_datum_token.h | 1 - .../common/include/dap_chain_datum_tx_items.h | 2 +- .../include/dap_chain_datum_tx_out_cond.h | 2 ++ .../dap_chain_net_srv_emit_delegate.c | 18 ++++++------------ 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index 0b14ea1931..6384a2573f 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -366,11 +366,11 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake_lock( dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_emit_delegate(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, uint32_t a_signs_min, dap_hash_fast_t *a_pkey_hashes, - size_t a_pkey_hashes_count) + size_t a_pkey_hashes_count, const char *a_tag_str) { if (IS_ZERO_256(a_value)) return NULL; - size_t l_tsd_total_size = a_pkey_hashes_count * (sizeof(dap_hash_fast_t) + sizeof(dap_tsd_t)); + size_t l_tsd_total_size = a_pkey_hashes_count * (sizeof(dap_hash_fast_t) + sizeof(dap_tsd_t)) + (a_tag_str ? sizeof(dap_tsd_t) + strlen(a_tag_str) + 1 : 0); dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + l_tsd_total_size, NULL); l_item->header.item_type = TX_ITEM_TYPE_OUT_COND; l_item->header.value = a_value; @@ -381,6 +381,8 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_emit_delega byte_t *l_next_tsd_ptr = l_item->tsd; for (size_t i = 0; i < a_pkey_hashes_count; i++) l_next_tsd_ptr = dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_TX_OUT_COND_TSD_HASH, a_pkey_hashes + i, sizeof(dap_hash_fast_t)); + if (a_tag_str) + l_next_tsd_ptr = dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_TX_OUT_COND_TSD_STR, (const void*)a_tag_str, strlen(a_tag_str) + 1); return l_item; } diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index 318bc57b5f..f596c2e605 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -340,7 +340,6 @@ typedef struct dap_chain_datum_token_emission { #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SIGNATURS 0x000E #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_UNIQUE_ID 0x000F #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BASE_TX_HASH 0x0010 -#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG 0x0011 // TSD sections with transfer additional params #define DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT 0x0013 diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index 3039494890..e864aef95f 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -212,7 +212,7 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake_lock( dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_emit_delegate(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, uint32_t a_signs_min, dap_hash_fast_t *a_pkey_hashes, - size_t a_pkey_hashes_count); + size_t a_pkey_hashes_count, const char *a_tag_str); /** * Create item dap_chain_tx_sig_t 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 1014316a43..ddc1dc6a87 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -56,6 +56,8 @@ typedef byte_t dap_chain_tx_out_cond_subtype_t; #define DAP_CHAIN_TX_OUT_COND_TSD_ADDR 0xf001 // Chain hash #define DAP_CHAIN_TX_OUT_COND_TSD_HASH 0xf002 +// Custom str +#define DAP_CHAIN_TX_OUT_COND_TSD_STR 0xf003 /** * @struct dap_chain_tx_out diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 346e3fa01d..31240126ec 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -252,7 +252,7 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, // add 'out_cond' & 'out_ext' items dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_EMIT_DELEGATE_ID }; dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_emit_delegate( - l_uid, a_value, a_signs_min, a_pkey_hashes, a_pkey_hashes_count); + l_uid, a_value, a_signs_min, a_pkey_hashes, a_pkey_hashes_count, a_tag_str); if (!l_tx_out) m_tx_fail(ERROR_COMPOSE, "Can't compose the transaction conditional output"); dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_tx_out); @@ -285,17 +285,6 @@ static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, if (!IS_ZERO_256(l_fee_back) && dap_chain_datum_tx_add_out_ext_item(&l_tx, &l_owner_addr, l_fee_back, l_native_ticker) != 1) m_tx_fail(ERROR_COMPOSE, "Cant add fee back output"); } - - if (a_tag_str) { - dap_chain_tx_tsd_t *l_tsd_tag_item = dap_chain_datum_tx_item_tsd_create((void *)a_tag_str, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG, strlen(a_tag_str) + 1); - if (!l_tsd_tag_item) - m_tx_fail(ERROR_COMPOSE, "Can't compose the transaction tag"); - if (dap_chain_datum_tx_add_item(&l_tx, l_tsd_tag_item) != 1) { - DAP_DELETE(l_tsd_tag_item); - m_tx_fail(ERROR_COMPOSE, "Can't add the transaction tag"); - } - DAP_DELETE(l_tsd_tag_item); - } // add 'sign' item if (dap_chain_datum_tx_add_sign_item(&l_tx, a_enc_key) != 1) m_tx_fail(ERROR_COMPOSE, "Can't add sign output"); @@ -1086,6 +1075,7 @@ static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object ** json_object *l_jobj_token = json_object_new_object(); json_object *l_jobj_take_verify = json_object_new_object(); json_object *l_jobj_pkey_hashes = json_object_new_array(); + json_object *l_jobj_tags = json_object_new_array(); json_object *l_json_jobj_info = json_object_new_object(); bool l_is_base_hash_type = dap_strcmp(a_hash_out_type, "hex"); @@ -1105,11 +1095,15 @@ static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object ** if (l_tsd->type == DAP_CHAIN_TX_OUT_COND_TSD_HASH && l_tsd->size == sizeof(dap_hash_fast_t)) { json_object_array_add(l_jobj_pkey_hashes, json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static((const dap_chain_hash_fast_t *)l_tsd->data) : dap_hash_fast_to_str_static((const dap_chain_hash_fast_t *)l_tsd->data))); } + if (l_tsd->type == DAP_CHAIN_TX_OUT_COND_TSD_STR) { + json_object_array_add(l_jobj_tags, json_object_new_string(l_tsd->data)); + } } json_object_object_add(l_jobj_take_verify, "owner_hashes", l_jobj_pkey_hashes); // result block json_object_object_add(l_json_jobj_info, "tx_hash", json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static(&l_tx_hash) : dap_hash_fast_to_str_static(&l_tx_hash))); json_object_object_add(l_json_jobj_info, "tx_hash_final", json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static(&l_final_tx_hash) : dap_hash_fast_to_str_static(&l_final_tx_hash))); + json_object_object_add(l_json_jobj_info, "tags", l_jobj_tags); json_object_object_add(l_json_jobj_info, "balance", l_jobj_balance); json_object_object_add(l_json_jobj_info, "take_verify", l_jobj_take_verify); json_object_object_add(l_json_jobj_info, "token", l_jobj_token); -- GitLab From 14212ee76028bb27d8b1d1e6158816c4c21f5aa6 Mon Sep 17 00:00:00 2001 From: Dmitry Pyzyrkov <dpuzyrkov@gmail.com> Date: Mon, 10 Mar 2025 19:26:17 +0700 Subject: [PATCH 26/29] [*] emit-delegate adds tds in right palce --- .../dap_chain_net_srv_emit_delegate.c | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 346e3fa01d..ba456b80ad 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -202,7 +202,7 @@ static char *s_tx_put(dap_chain_datum_tx_t *a_tx, dap_chain_t *a_chain, const ch #define m_sign_fail(e,s) { dap_json_rpc_error_add(a_json_arr_reply, e, s); log_it(L_ERROR, "%s", s); return NULL; } -#define m_tx_fail(e,s) { DAP_DELETE(l_tx); m_sign_fail(e,s) } +#define m_tx_fail(e,s) { DAP_DELETE(l_tx); m_sign_fail(e,s); log_it(L_ERROR, "%s", s); } static dap_chain_datum_tx_t *s_emitting_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, const char *a_token_ticker, uint256_t a_value, uint256_t a_fee, @@ -450,7 +450,11 @@ static bool s_is_key_present(dap_chain_tx_out_cond_t *a_cond, dap_enc_key_t *a_e dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, dap_chain_addr_t **a_to_addr, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { - dap_return_val_if_pass(!a_to_addr || !a_value || !a_addr_count || !a_enc_key || !a_tx_in_hash, NULL ); + dap_return_val_if_pass(!a_to_addr, NULL); + dap_return_val_if_pass(!a_value, NULL); + dap_return_val_if_pass(!a_addr_count, NULL); + dap_return_val_if_pass(!a_enc_key, NULL); + dap_return_val_if_pass(!a_tx_in_hash, NULL); // create empty transaction dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); @@ -469,7 +473,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje if (SUM_256_256(l_value, a_value[i], &l_value)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); } - + log_it(L_DEBUG, "l_value sum %s", dap_chain_balance_print(l_value)); bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr); if (l_net_fee_used && SUM_256_256(l_fee_total, l_net_fee, &l_fee_total)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); @@ -512,7 +516,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje // add 'out' or 'out_ext' item for emission for (size_t i = 0; i < a_addr_count; ++i) { - int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, a_to_addr[i], a_value[i]) : + int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &a_to_addr[i], a_value[i]) : dap_chain_datum_tx_add_out_ext_item(&l_tx, a_to_addr[i], a_value[i], l_tx_ticker); if (rc != 1) m_tx_fail(ERROR_COMPOSE, "Cant add tx output"); @@ -531,6 +535,12 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje } DAP_DELETE(l_out_cond); + if (a_addr_count > 1) { + tsd_items = dap_list_append(tsd_items, dap_chain_datum_tx_item_tsd_create(&a_addr_count, DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT, sizeof(uint32_t))); + if (!tsd_items) { + m_tx_fail(ERROR_COMPOSE, "Can't add TSD section item with addr count"); + } + } // add track for takeoff from conditional value dap_chain_tx_tsd_t *l_takeoff_tsd = dap_chain_datum_tx_item_tsd_create(&l_value, DAP_CHAIN_NET_SRV_EMIT_DELEGATE_TSD_WRITEOFF, sizeof(uint256_t)); @@ -948,15 +958,6 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** } dap_strfreev(l_to_addr_str_array); - - if (l_addr_el_count > 1) { - l_tsd_list = dap_list_append(l_tsd_list, dap_chain_datum_tx_item_tsd_create(&l_addr_el_count, DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT, sizeof(uint32_t))); - if (!l_tsd_list) { - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_COMPOSE, "Internal error in tsd list creation"); - return ERROR_COMPOSE; - } - } - // Create emission from conditional transaction dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_to_addr, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, l_tsd_list); DAP_DEL_ARRAY(l_to_addr, l_addr_el_count); -- GitLab From 35e5722907b1da0092357b16591a0d07ceece5a8 Mon Sep 17 00:00:00 2001 From: Dmitry Pyzyrkov <dpuzyrkov@gmail.com> Date: Mon, 10 Mar 2025 20:53:42 +0700 Subject: [PATCH 27/29] [*] - additional log + some fixes --- .../dap_chain_net_srv_emit_delegate.c | 15 ++++++++------- .../include/dap_chain_net_srv_emit_delegate.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index cef9fb6666..236bf7f40c 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -437,7 +437,7 @@ static bool s_is_key_present(dap_chain_tx_out_cond_t *a_cond, dap_enc_key_t *a_e } dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, - dap_chain_addr_t **a_to_addr, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) + dap_chain_addr_t *a_to_addr, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { dap_return_val_if_pass(!a_to_addr, NULL); dap_return_val_if_pass(!a_value, NULL); @@ -462,7 +462,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje if (SUM_256_256(l_value, a_value[i], &l_value)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); } - log_it(L_DEBUG, "l_value sum %s", dap_chain_balance_print(l_value)); + bool l_net_fee_used = dap_chain_net_tx_get_fee(a_net->pub.id, &l_net_fee, &l_net_fee_addr); if (l_net_fee_used && SUM_256_256(l_fee_total, l_net_fee, &l_fee_total)) m_tx_fail(ERROR_OVERFLOW, "Integer overflow in TX composer"); @@ -506,7 +506,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje // add 'out' or 'out_ext' item for emission for (size_t i = 0; i < a_addr_count; ++i) { int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &a_to_addr[i], a_value[i]) : - dap_chain_datum_tx_add_out_ext_item(&l_tx, a_to_addr[i], a_value[i], l_tx_ticker); + dap_chain_datum_tx_add_out_ext_item(&l_tx, &a_to_addr[i], a_value[i], l_tx_ticker); if (rc != 1) m_tx_fail(ERROR_COMPOSE, "Cant add tx output"); } @@ -518,6 +518,7 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje if (!l_out_cond) m_tx_fail(ERROR_MEMORY, c_error_memory_alloc); l_out_cond->header.value = l_value_back; + if (-1 == dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_out_cond)) { DAP_DELETE(l_out_cond); m_tx_fail(ERROR_COMPOSE, "Cant add emission cond output"); @@ -525,10 +526,9 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje DAP_DELETE(l_out_cond); if (a_addr_count > 1) { - tsd_items = dap_list_append(tsd_items, dap_chain_datum_tx_item_tsd_create(&a_addr_count, DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT, sizeof(uint32_t))); - if (!tsd_items) { - m_tx_fail(ERROR_COMPOSE, "Can't add TSD section item with addr count"); - } + dap_chain_tx_tsd_t * l_addr_cnt_tsd = dap_chain_datum_tx_item_tsd_create(&a_addr_count, DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT, sizeof(uint32_t)); + if (!l_addr_cnt_tsd || dap_chain_datum_tx_add_item(&l_tx, l_addr_cnt_tsd) != 1 ) + m_tx_fail(ERROR_COMPOSE, "Can't add TSD section item with addr count"); } // add track for takeoff from conditional value @@ -948,6 +948,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** dap_strfreev(l_to_addr_str_array); // Create emission from conditional transaction + dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_to_addr, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, l_tsd_list); DAP_DEL_ARRAY(l_to_addr, l_addr_el_count); DAP_DEL_MULTY(l_value, l_to_addr, l_enc_key); diff --git a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h index b9d7ffe7b4..a85405c2bd 100644 --- a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h +++ b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h @@ -13,7 +13,7 @@ void dap_chain_net_srv_emit_delegate_deinit(); dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_rweply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, - dap_chain_addr_t **a_addr_to, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t *tsd_items); + dap_chain_addr_t *a_addr_to, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t *tsd_items); dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items); -- GitLab From 4c59bc050624bf001b0d4b775c31e22a1ec5dd69 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Mon, 10 Mar 2025 15:35:41 +0000 Subject: [PATCH 28/29] [*] adopt to one memory alloc to chain_addr array --- modules/common/dap_chain_common.c | 74 +++++++++++++++---- modules/common/include/dap_chain_common.h | 1 + .../dap_chain_net_srv_emit_delegate.c | 39 ++-------- .../include/dap_chain_net_srv_emit_delegate.h | 2 +- 4 files changed, 70 insertions(+), 46 deletions(-) diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c index c611a4ddf7..1366d36982 100644 --- a/modules/common/dap_chain_common.c +++ b/modules/common/dap_chain_common.c @@ -75,25 +75,73 @@ dap_chain_addr_str_t dap_chain_addr_to_str_static_(const dap_chain_addr_t *a_add return res; } +/** + * @brief s_addr_from_str + * @param [out] a_addr - pointer to addr fill + * @param [in] a_str - string with one addr + * @return 0 if pass, other if error + */ +static int s_addr_from_str(dap_chain_addr_t *a_addr, const char *a_str) +{ + dap_return_val_if_pass(!a_addr || !a_str || !a_str[0], -1); + if (!dap_strcmp(a_str, "null") || !dap_strcmp(a_str, "0")) { + memset(a_addr, 0, sizeof(dap_chain_addr_t)); + return 0; + } + int l_ret = 0; + size_t l_ret_size = DAP_ENC_BASE58_DECODE_SIZE(strlen(a_str)); + dap_chain_addr_t *l_addr_cur = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_addr_t, l_ret_size, -2); + if (dap_enc_base58_decode(a_str, l_addr_cur) == sizeof(dap_chain_addr_t) && !dap_chain_addr_check_sum(l_addr_cur)) { + memcpy(a_addr, l_addr_cur, sizeof(dap_chain_addr_t)); + } else { + l_ret = -3; + } + DAP_DELETE(l_addr_cur); + return l_ret; +} + /** * @brief dap_chain_str_to_addr - * @param a_addr - * @return + * @param a_str - string with one addr + * @return pointer to dap_chain_addr_t if pass, if not - NULL */ -dap_chain_addr_t* dap_chain_addr_from_str(const char *a_str) +dap_chain_addr_t *dap_chain_addr_from_str(const char *a_str) { - size_t l_str_len = (a_str) ? strlen(a_str) : 0; - if(l_str_len <= 0) + dap_chain_addr_t *l_ret = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_chain_addr_t, NULL); + if (s_addr_from_str(l_ret, a_str)) { + DAP_DELETE(l_ret); return NULL; - if (!dap_strcmp(a_str, "null") || !dap_strcmp(a_str, "0")) { - return DAP_NEW_Z(dap_chain_addr_t); } - size_t l_ret_size = DAP_ENC_BASE58_DECODE_SIZE(l_str_len); - dap_chain_addr_t *l_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, l_ret_size); - return ( dap_enc_base58_decode(a_str, l_addr) == sizeof(dap_chain_addr_t) ) - && !dap_chain_addr_check_sum(l_addr) - ? l_addr - : ( DAP_DELETE(l_addr), NULL ); + return l_ret; +} + + +/** + * @brief parce addrs string div by ',', alloc memory to addrs + * @param a_addr_str - ddrs string div by ',' + * @param a_addr - pointer to memory alloc + * @return addr count + */ +size_t dap_chain_addr_from_str_array(const char *a_addr_str, dap_chain_addr_t **a_addr) +{ + dap_return_val_if_pass(!a_addr_str || !a_addr, NULL); + size_t l_count = dap_str_symbol_count(a_addr_str, ',') + 1; + dap_chain_addr_t *l_addr = DAP_NEW_Z_COUNT_RET_VAL_IF_FAIL(dap_chain_addr_t, l_count, 0); + char **l_addr_str_array = dap_strsplit(a_addr_str, ",", l_count); + if (!l_addr_str_array) { + DAP_DELETE(l_addr); + return 0; + } + for (size_t i = 0; i < l_count; ++i) { + if (s_addr_from_str(l_addr + i, l_addr_str_array[i])) { + DAP_DELETE(l_addr); + dap_strfreev(l_addr_str_array); + return 0; + } + } + dap_strfreev(l_addr_str_array); + *a_addr = l_addr; + return l_count; } bool dap_chain_addr_is_blank(const dap_chain_addr_t *a_addr) diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h index 69bc2c00fc..0b930d2925 100644 --- a/modules/common/include/dap_chain_common.h +++ b/modules/common/include/dap_chain_common.h @@ -225,6 +225,7 @@ dap_chain_addr_str_t dap_chain_addr_to_str_static_(const dap_chain_addr_t *a_add #define dap_chain_addr_to_str dap_chain_addr_to_str_static dap_chain_addr_t* dap_chain_addr_from_str(const char *str); +size_t dap_chain_addr_from_str_array(const char *a_addr_str, dap_chain_addr_t **a_addr); bool dap_chain_addr_is_blank(const dap_chain_addr_t *a_addr); dap_chain_net_srv_uid_t dap_chain_net_srv_uid_from_str(const char* a_str); diff --git a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c index 236bf7f40c..4a16024466 100644 --- a/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c +++ b/modules/service/emit-delegate/dap_chain_net_srv_emit_delegate.c @@ -437,7 +437,7 @@ static bool s_is_key_present(dap_chain_tx_out_cond_t *a_cond, dap_enc_key_t *a_e } dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, - dap_chain_addr_t *a_to_addr, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) + dap_chain_addr_t *a_to_addr, uint256_t *a_value, uint32_t a_addr_count /*!not change type!*/, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items) { dap_return_val_if_pass(!a_to_addr, NULL); dap_return_val_if_pass(!a_value, NULL); @@ -505,8 +505,8 @@ dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_obje // add 'out' or 'out_ext' item for emission for (size_t i = 0; i < a_addr_count; ++i) { - int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, &a_to_addr[i], a_value[i]) : - dap_chain_datum_tx_add_out_ext_item(&l_tx, &a_to_addr[i], a_value[i], l_tx_ticker); + int rc = l_taking_native ? dap_chain_datum_tx_add_out_item(&l_tx, a_to_addr + i, a_value[i]) : + dap_chain_datum_tx_add_out_ext_item(&l_tx, a_to_addr + i, a_value[i], l_tx_ticker); if (rc != 1) m_tx_fail(ERROR_COMPOSE, "Cant add tx output"); } @@ -834,7 +834,7 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** const char *l_tx_in_hash_str = NULL, *l_addr_str = NULL, *l_value_str = NULL, *l_wallet_str = NULL, *l_fee_str = NULL; uint256_t *l_value = NULL; - dap_chain_addr_t **l_to_addr = NULL; + dap_chain_addr_t *l_to_addr = NULL; uint32_t l_addr_el_count = 0, // not change type! use in batching TSD section l_value_el_count = 0; @@ -892,10 +892,11 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** return ERROR_PARAM; } - l_addr_el_count = dap_str_symbol_count(l_addr_str, ',') + 1; + l_addr_el_count = dap_chain_addr_from_str_array(l_addr_str, &l_to_addr); l_value_el_count = dap_str_symbol_count(l_value_str, ',') + 1; if (l_addr_el_count != l_value_el_count) { + DAP_DELETE(l_to_addr); dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "num of '-to_addr' and '-value' should be equal"); return ERROR_VALUE; } @@ -922,35 +923,9 @@ static int s_cli_take(int a_argc, char **a_argv, int a_arg_index, json_object ** } dap_strfreev(l_value_array); - l_to_addr = DAP_NEW_Z_COUNT(dap_chain_addr_t *, l_addr_el_count); - if (!l_to_addr) { - log_it(L_CRITICAL, "%s", c_error_memory_alloc); - DAP_DELETE(l_value); - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_MEMORY, c_error_memory_alloc); - return ERROR_MEMORY; - } - char **l_to_addr_str_array = dap_strsplit(l_addr_str, ",", l_addr_el_count); - if (!l_to_addr_str_array) { - DAP_DEL_MULTY(l_to_addr, l_value); - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_PARAM, "Can't read '-to_addr' arg"); - return ERROR_PARAM; - } - for (size_t i = 0; i < l_addr_el_count; ++i) { - l_to_addr[i] = dap_chain_addr_from_str(l_to_addr_str_array[i]); - if(!l_to_addr[i]) { - DAP_DEL_ARRAY(l_to_addr, i); - DAP_DEL_MULTY(l_to_addr, l_value); - dap_strfreev(l_to_addr_str_array); - dap_json_rpc_error_add(*a_json_arr_reply, ERROR_VALUE, "Incorrect addr format for string %s", l_addr_str); - return ERROR_VALUE; - } - } - dap_strfreev(l_to_addr_str_array); - // Create emission from conditional transaction dap_chain_datum_tx_t *l_tx = dap_chain_net_srv_emit_delegate_taking_tx_create(*a_json_arr_reply, a_net, l_enc_key, l_to_addr, l_value, l_addr_el_count, l_fee, &l_tx_in_hash, l_tsd_list); - DAP_DEL_ARRAY(l_to_addr, l_addr_el_count); DAP_DEL_MULTY(l_value, l_to_addr, l_enc_key); dap_list_free_full(l_tsd_list, NULL); if (!l_tx) { @@ -1098,7 +1073,7 @@ static int s_cli_info(int a_argc, char **a_argv, int a_arg_index, json_object ** json_object_array_add(l_jobj_pkey_hashes, json_object_new_string(l_is_base_hash_type ? dap_enc_base58_encode_hash_to_str_static((const dap_chain_hash_fast_t *)l_tsd->data) : dap_hash_fast_to_str_static((const dap_chain_hash_fast_t *)l_tsd->data))); } if (l_tsd->type == DAP_CHAIN_TX_OUT_COND_TSD_STR) { - json_object_array_add(l_jobj_tags, json_object_new_string(l_tsd->data)); + json_object_array_add(l_jobj_tags, json_object_new_string((char*)(l_tsd->data))); } } json_object_object_add(l_jobj_take_verify, "owner_hashes", l_jobj_pkey_hashes); diff --git a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h index a85405c2bd..d0545c22eb 100644 --- a/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h +++ b/modules/service/emit-delegate/include/dap_chain_net_srv_emit_delegate.h @@ -13,7 +13,7 @@ void dap_chain_net_srv_emit_delegate_deinit(); dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_taking_tx_create(json_object *a_json_arr_rweply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, - dap_chain_addr_t *a_addr_to, uint256_t *a_value, size_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t *tsd_items); + dap_chain_addr_t *a_addr_to, uint256_t *a_value, uint32_t a_addr_count, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t *tsd_items); dap_chain_datum_tx_t *dap_chain_net_srv_emit_delegate_refilling_tx_create(json_object *a_json_arr_reply, dap_chain_net_t *a_net, dap_enc_key_t *a_enc_key, uint256_t a_value, uint256_t a_fee, dap_hash_fast_t *a_tx_in_hash, dap_list_t* tsd_items); -- GitLab From 547284fe2a60d886a037b0d1984ce42e8fcd7e3f Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Mon, 10 Mar 2025 16:26:23 +0000 Subject: [PATCH 29/29] [*] macos pipe error fix --- modules/common/dap_chain_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c index 1366d36982..298cbdd149 100644 --- a/modules/common/dap_chain_common.c +++ b/modules/common/dap_chain_common.c @@ -124,7 +124,7 @@ dap_chain_addr_t *dap_chain_addr_from_str(const char *a_str) */ size_t dap_chain_addr_from_str_array(const char *a_addr_str, dap_chain_addr_t **a_addr) { - dap_return_val_if_pass(!a_addr_str || !a_addr, NULL); + dap_return_val_if_pass(!a_addr_str || !a_addr, 0); size_t l_count = dap_str_symbol_count(a_addr_str, ',') + 1; dap_chain_addr_t *l_addr = DAP_NEW_Z_COUNT_RET_VAL_IF_FAIL(dap_chain_addr_t, l_count, 0); char **l_addr_str_array = dap_strsplit(a_addr_str, ",", l_count); -- GitLab