diff --git a/dap-sdk b/dap-sdk index 59705ae76ca20b8ac1b8269ae67aa847ec73dfa9..dffb76d321e837c98157a691e7e9e352bb921511 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 59705ae76ca20b8ac1b8269ae67aa847ec73dfa9 +Subproject commit dffb76d321e837c98157a691e7e9e352bb921511 diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index 6bfea9e5fa17c1a824136d9f5d2dd5a534b0a63b..3ce92f9fed3887be3fa0f05976779b3383e9a2c4 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -680,14 +680,19 @@ void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_not * @param a_atom_hash * @return */ -bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_hash_fast_t *a_atom_hash, dap_chain_cell_id_t a_cell_id) +bool dap_chain_get_atom_last_hash_num(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_atom_hash, uint64_t *a_atom_num) { - dap_chain_atom_iter_t *l_iter = a_chain->callback_atom_iter_create(a_chain, a_cell_id, false); + dap_return_val_if_fail(a_atom_hash || a_atom_num, false); + dap_chain_atom_iter_t *l_iter = a_chain->callback_atom_iter_create(a_chain, a_cell_id, NULL); + if (!l_iter) + return false; a_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_LAST, NULL); - *a_atom_hash = l_iter->cur_hash ? *l_iter->cur_hash : (dap_hash_fast_t){0}; - bool l_ret = l_iter->cur_hash; + if (a_atom_hash) + *a_atom_hash = l_iter->cur_hash ? *l_iter->cur_hash : (dap_hash_fast_t){0}; + if (a_atom_num) + *a_atom_num = l_iter->cur_num; a_chain->callback_atom_iter_delete(l_iter); - return l_ret; + return true; } struct chain_thread_notifier { diff --git a/modules/chain/dap_chain_ch.c b/modules/chain/dap_chain_ch.c index f4cfcde1a2827ff901fbc04e8be46a45a69a452d..7d1cb75fb9b2895cebcc35912696860b1a31c8fa 100644 --- a/modules/chain/dap_chain_ch.c +++ b/modules/chain/dap_chain_ch.c @@ -74,7 +74,7 @@ struct sync_request { dap_worker_t * worker; dap_stream_ch_uuid_t ch_uuid; - dap_chain_ch_sync_request_t request; + dap_chain_ch_sync_request_old_t request; dap_chain_ch_pkt_hdr_t request_hdr; dap_chain_pkt_item_t pkt; @@ -119,10 +119,9 @@ static inline bool s_ch_chain_get_idle(dap_chain_ch_t *a_ch_chain) { return a_ch static void s_stream_ch_new(dap_stream_ch_t* a_ch, void* a_arg); static void s_stream_ch_delete(dap_stream_ch_t* a_ch, void* a_arg); -static void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg); +static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg); static bool s_stream_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg); static void s_stream_ch_io_complete(dap_events_socket_t *a_es, void *a_arg); -static void s_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, dap_chain_ch_error_type_t a_error); static bool s_sync_out_chains_proc_callback(void *a_arg); static void s_sync_out_chains_last_worker_callback(dap_worker_t *a_worker, void *a_arg); @@ -183,6 +182,12 @@ static const char *s_error_type_to_string(dap_chain_ch_error_type_t a_error) return "UNKNOWN_CHAIN_PACKET_TYPE"; case DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED: return "GLOBAL_DB_INTERNAL_SAVING_ERROR"; + case DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE: + return "NET_IS_OFFLINE"; + case DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY: + return "OUT_OF_MEMORY"; + case DAP_CHAIN_CH_ERROR_INTERNAL: + return "INTERNAL_ERROR"; default: return "UNKNOWN_ERROR"; } @@ -194,7 +199,7 @@ static const char *s_error_type_to_string(dap_chain_ch_error_type_t a_error) */ int dap_chain_ch_init() { - log_it(L_NOTICE, "Chains and global db exchange channel initialized"); + log_it(L_NOTICE, "Chains exchange channel initialized"); dap_stream_ch_proc_add(DAP_CHAIN_CH_ID, s_stream_ch_new, s_stream_ch_delete, s_stream_ch_packet_in, s_stream_ch_packet_out); s_sync_timeout = dap_config_get_item_uint32_default(g_config, "chain", "sync_timeout", s_sync_timeout); @@ -205,8 +210,7 @@ int dap_chain_ch_init() for (int i = 0; i < MEMSTAT$K_NR; i++) dap_memstat_reg(&s_memstat[i]); #endif - assert(!dap_stream_ch_gossip_callback_add(DAP_CHAIN_CH_ID, s_gossip_payload_callback)); - return 0; + return dap_stream_ch_gossip_callback_add(DAP_CHAIN_CH_ID, s_gossip_payload_callback); } /** @@ -248,9 +252,6 @@ static void s_stream_ch_delete(dap_stream_ch_t *a_ch, void *a_arg) { UNUSED(a_arg); dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(a_ch); - if (l_ch_chain->callback_notify_packet_out) - l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_DELETE, NULL, 0, - l_ch_chain->callback_notify_arg); s_ch_chain_go_idle(l_ch_chain); debug_if(s_debug_more, L_DEBUG, "[stm_ch_chain:%p] --- deleted chain:%p", a_ch, l_ch_chain); DAP_DEL_Z(a_ch->internal); @@ -260,13 +261,6 @@ static void s_stream_ch_delete(dap_stream_ch_t *a_ch, void *a_arg) #endif } -void dap_chain_ch_reset_unsafe(dap_chain_ch_t *a_ch_chain) -{ - if (!a_ch_chain) - return; - s_ch_chain_go_idle(a_ch_chain); -} - /** * @brief s_stream_ch_chain_delete * @param a_ch_chain @@ -352,16 +346,13 @@ static void s_sync_out_chains_last_worker_callback(dap_worker_t *a_worker, void } l_ch_chain->request_atom_iter = l_sync_request->chain.request_atom_iter; // last packet - dap_chain_ch_sync_request_t l_request = {}; + dap_chain_ch_sync_request_old_t l_request = {}; if (s_debug_more ) log_it(L_INFO,"Out: DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS"); dap_chain_ch_pkt_write_unsafe(l_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS, l_sync_request->request_hdr.net_id.uint64, l_sync_request->request_hdr.chain_id.uint64, l_sync_request->request_hdr.cell_id.uint64, &l_request, sizeof(l_request)); s_ch_chain_go_idle(l_ch_chain); - if (l_ch_chain->callback_notify_packet_out) - l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS, - NULL, 0, l_ch_chain->callback_notify_arg); DAP_DELETE(l_sync_request); } /** @@ -431,9 +422,6 @@ static void s_sync_out_gdb_first_worker_callback(dap_worker_t *a_worker, void *a dap_chain_ch_pkt_write_unsafe(DAP_STREAM_CH(l_ch_chain), DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB, l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, &g_node_addr, sizeof(dap_chain_node_addr_t)); - if(l_ch_chain->callback_notify_packet_out) - l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB, - NULL, 0, l_ch_chain->callback_notify_arg); if( a_worker){ // We send NULL to prevent delete s_sync_request_delete(l_sync_request); @@ -469,9 +457,6 @@ static void s_sync_out_gdb_last_worker_callback(dap_worker_t *a_worker, void *a_ l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, NULL, 0); s_ch_chain_go_idle(l_ch_chain); - if(l_ch_chain->callback_notify_packet_out) - l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB, - NULL, 0, l_ch_chain->callback_notify_arg); s_sync_request_delete(l_sync_request); } @@ -616,10 +601,12 @@ static bool s_sync_in_chains_callback(void *a_arg) if (s_debug_more) dap_get_data_hash_str_static(l_atom, l_atom_size, l_atom_hash_str); dap_chain_atom_verify_res_t l_atom_add_res = l_chain->callback_atom_add(l_chain, l_atom, l_atom_size); + bool l_ack_send = false; switch (l_atom_add_res) { case ATOM_PASS: debug_if(s_debug_more, L_WARNING, "Atom with hash %s for %s:%s not accepted (code ATOM_PASS, already present)", l_atom_hash_str, l_chain->net_name, l_chain->name); + l_ack_send = true; break; case ATOM_MOVE_TO_THRESHOLD: debug_if(s_debug_more, L_INFO, "Thresholded atom with hash %s for %s:%s", l_atom_hash_str, l_chain->net_name, l_chain->name); @@ -628,18 +615,8 @@ static bool s_sync_in_chains_callback(void *a_arg) debug_if(s_debug_more, L_INFO,"Accepted atom with hash %s for %s:%s", l_atom_hash_str, l_chain->net_name, l_chain->name); if (dap_chain_atom_save(l_chain->cells, l_atom, l_atom_size, NULL) < 0) log_it(L_ERROR, "Can't save atom %s to the file", l_atom_hash_str); - if (l_args->ack_req) { - uint64_t l_ack_num = (l_chain_pkt->hdr.num_hi << 16) | l_chain_pkt->hdr.num_lo; - dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, - &l_ack_num, sizeof(uint64_t)); - dap_stream_ch_pkt_send_by_addr(&l_args->addr, DAP_CHAIN_CH_ID, DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK, l_pkt, dap_chain_ch_pkt_get_size(l_pkt)); - DAP_DELETE(l_pkt); - debug_if(s_debug_more, L_DEBUG, "Out: CHAIN_ACK %s for net %s to destination " NODE_ADDR_FP_STR " with num %" DAP_UINT64_FORMAT_U, - l_chain ? l_chain->name : "(null)", - l_chain ? l_chain->net_name : "(null)", - NODE_ADDR_FP_ARGS_S(l_args->addr), - l_ack_num); - } + else + l_ack_send = true; break; case ATOM_REJECT: { debug_if(s_debug_more, L_WARNING, "Atom with hash %s for %s:%s rejected", l_atom_hash_str, l_chain->net_name, l_chain->name); @@ -649,6 +626,18 @@ static bool s_sync_in_chains_callback(void *a_arg) log_it(L_CRITICAL, "Wtf is this ret code? %d", l_atom_add_res); break; } + if (l_ack_send && l_args->ack_req) { + uint64_t l_ack_num = (l_chain_pkt->hdr.num_hi << 16) | l_chain_pkt->hdr.num_lo; + dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, + &l_ack_num, sizeof(uint64_t)); + dap_stream_ch_pkt_send_by_addr(&l_args->addr, DAP_CHAIN_CH_ID, DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK, l_pkt, dap_chain_ch_pkt_get_size(l_pkt)); + DAP_DELETE(l_pkt); + debug_if(s_debug_more, L_DEBUG, "Out: CHAIN_ACK %s for net %s to destination " NODE_ADDR_FP_STR " with num %" DAP_UINT64_FORMAT_U, + l_chain ? l_chain->name : "(null)", + l_chain ? l_chain->net_name : "(null)", + NODE_ADDR_FP_ARGS_S(l_args->addr), + l_ack_num); + } DAP_DELETE(l_args); return false; } @@ -686,7 +675,7 @@ static void s_gdb_in_pkt_error_worker_callback(dap_worker_t *a_worker, void *a_a if (l_ch == NULL) log_it(L_INFO,"Client disconnected before we sent the reply"); else - s_stream_ch_write_error_unsafe(l_ch, l_sync_request->request_hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(l_ch, l_sync_request->request_hdr.net_id.uint64, l_sync_request->request_hdr.chain_id.uint64, l_sync_request->request_hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED); @@ -720,7 +709,7 @@ struct sync_request *dap_chain_ch_create_sync_request(dap_chain_ch_pkt_t *a_chai return l_sync_request; } -static void s_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, dap_chain_ch_error_type_t a_error) +void dap_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, dap_chain_ch_error_type_t a_error) { dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(a_ch); if (!l_ch_chain) { @@ -746,12 +735,8 @@ static bool s_chain_timer_callback(void *a_arg) return false; } if (l_ch_chain->timer_shots++ >= DAP_SYNC_TICKS_PER_SECOND * s_sync_timeout) { - if (!s_ch_chain_get_idle(l_ch_chain)) { + if (!s_ch_chain_get_idle(l_ch_chain)) s_ch_chain_go_idle(l_ch_chain); - if (l_ch_chain->callback_notify_packet_out) - l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_TIMEOUT, NULL, 0, - l_ch_chain->callback_notify_arg); - } DAP_DELETE(a_arg); l_ch_chain->activity_timer = NULL; return false; @@ -794,18 +779,18 @@ void dap_chain_ch_timer_start(dap_chain_ch_t *a_ch_chain) * @param a_ch * @param a_arg */ -void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) +static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) { dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(a_ch); if (!l_ch_chain || l_ch_chain->_inheritor != a_ch) { log_it(L_ERROR, "No chain in channel, returning"); - return; + return false; } dap_stream_ch_pkt_t * l_ch_pkt = (dap_stream_ch_pkt_t *) a_arg; if (l_ch_pkt->hdr.data_size < sizeof(dap_chain_ch_pkt_t)) { log_it(L_ERROR, "Corrupted packet: too small size %u, smaller then header size %zu", l_ch_pkt->hdr.data_size, sizeof(dap_chain_ch_pkt_t)); - return; + return false; } dap_chain_ch_pkt_t *l_chain_pkt = (dap_chain_ch_pkt_t *)l_ch_pkt->data; @@ -814,13 +799,13 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) if (l_chain_pkt->hdr.version > DAP_CHAIN_CH_PKT_VERSION) { debug_if(s_debug_more, L_ATT, "Unsupported protocol version %d, current version %d", l_chain_pkt->hdr.version, DAP_CHAIN_CH_PKT_VERSION); - return; + return false; } if (l_chain_pkt->hdr.version >= 2 && l_chain_pkt_data_size != l_chain_pkt->hdr.data_size) { log_it(L_WARNING, "Incorrect chain packet size %zu, expected %u", l_chain_pkt_data_size, l_chain_pkt->hdr.data_size); - return; + return false; } s_chain_timer_reset(l_ch_chain); @@ -843,21 +828,21 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) dap_cluster_t *l_cluster = dap_cluster_find(dap_guuid_compose(l_chain_pkt->hdr.net_id.uint64, 0)); if (!l_cluster) { log_it(L_WARNING, "Can't find cluster with ID 0x%" DAP_UINT64_FORMAT_X, l_chain_pkt->hdr.net_id.uint64); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND); - break; + return false; } dap_cluster_member_t *l_check = dap_cluster_member_find_unsafe(l_cluster, &a_ch->stream->node); if (!l_check) { log_it(L_WARNING, "Node with addr "NODE_ADDR_FP_STR" isn't a member of cluster %s", NODE_ADDR_FP_ARGS_S(a_ch->stream->node), l_cluster->mnemonim); - break; + return false; } struct atom_processing_args *l_args = DAP_NEW_SIZE(struct atom_processing_args, l_ch_pkt->hdr.data_size + sizeof(struct atom_processing_args)); if (!l_args) { log_it(L_CRITICAL, g_error_memory_alloc); - return; + break; } l_args->addr = a_ch->stream->node; l_args->ack_req = true; @@ -873,49 +858,61 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) } break; case DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ: { - if (l_chain_pkt_data_size != sizeof(dap_hash_fast_t)) { + if (l_chain_pkt_data_size != sizeof(dap_chain_ch_sync_request_t)) { log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ: Wrong chain packet size %zd when expected %zd", - l_chain_pkt_data_size, sizeof(dap_hash_fast_t)); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + l_chain_pkt_data_size, sizeof(dap_chain_ch_sync_request_t)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); - break; + return false; } + dap_chain_ch_sync_request_t *l_request = (dap_chain_ch_sync_request_t *)l_chain_pkt->data; if (s_debug_more) - log_it(L_INFO, "In: CHAIN_REQ pkt: net 0x%016" DAP_UINT64_FORMAT_x " chain 0x%016" DAP_UINT64_FORMAT_x " cell 0x%016" DAP_UINT64_FORMAT_x, - l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64); + log_it(L_INFO, "In: CHAIN_REQ pkt: net 0x%016" DAP_UINT64_FORMAT_x " chain 0x%016" DAP_UINT64_FORMAT_x + " cell 0x%016" DAP_UINT64_FORMAT_x ", hash from %s, num from %" DAP_UINT64_FORMAT_U, + l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, + dap_hash_fast_to_str_static(&l_request->hash_from), l_request->num_from); if (l_ch_chain->sync_context) { log_it(L_WARNING, "Can't process CHAIN_REQ request cause already busy with syncronization"); dap_chain_ch_pkt_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS); - break; + return false; } dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id); if (!l_chain) { log_it(L_WARNING, "Not found chain id 0x%016" DAP_UINT64_FORMAT_x " with net id 0x%016" DAP_UINT64_FORMAT_x, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.net_id.uint64); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND); - break; + return false; } if (!dap_link_manager_get_net_condition(l_chain_pkt->hdr.net_id.uint64)) { log_it(L_WARNING, "Net id 0x%016" DAP_UINT64_FORMAT_x " is offline", l_chain_pkt->hdr.net_id.uint64); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE); + return false; + } + bool l_sync_from_begin = dap_hash_fast_is_blank(&l_request->hash_from); + dap_chain_atom_iter_t *l_iter = l_chain->callback_atom_iter_create(l_chain, l_chain_pkt->hdr.cell_id, l_sync_from_begin + ? NULL : &l_request->hash_from); + if (!l_iter) { + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); break; } - dap_hash_fast_t *l_requested_hash = (dap_hash_fast_t *)l_chain_pkt->data; - if (dap_hash_fast_is_blank(l_requested_hash)) - l_requested_hash = NULL; - dap_chain_atom_iter_t *l_iter = l_chain->callback_atom_iter_create(l_chain, l_chain_pkt->hdr.cell_id, l_requested_hash); - if (!l_requested_hash) + if (l_sync_from_begin) l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, NULL); + bool l_missed_hash = false; if (l_iter->cur) { - dap_chain_ch_summary_t l_sum = { .num_cur = l_requested_hash ? l_iter->cur_num : 0, .num_last = l_chain->callback_count_atom(l_chain) }; - if (l_sum.num_last - l_sum.num_cur) { + uint64_t l_last_num = l_chain->callback_count_atom(l_chain); + if (l_sync_from_begin || + (l_request->num_from == l_iter->cur_num && + l_last_num > l_iter->cur_num)) { + dap_chain_ch_summary_t l_sum = { .num_cur = l_iter->cur_num, .num_last = l_last_num }; dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_sum, sizeof(l_sum)); @@ -938,15 +935,41 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_ch_chain->sync_timer = dap_timerfd_start_on_worker(a_ch->stream_worker->worker, 1000, s_sync_timer_callback, l_ch_chain); break; } - } else - debug_if(s_debug_more, L_DEBUG, "Requested atom with hash %s not found", dap_hash_fast_to_str_static(l_requested_hash)); - dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN, - l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, - l_chain_pkt->hdr.cell_id.uint64, NULL, 0); - debug_if(s_debug_more, L_DEBUG, "Out: SYNCED_CHAIN %s for net %s to destination " NODE_ADDR_FP_STR, - l_chain ? l_chain->name : "(null)", - l_chain ? l_chain->net_name : "(null)", - NODE_ADDR_FP_ARGS_S(a_ch->stream->node)); + if (l_request->num_from < l_iter->cur_num || l_last_num > l_iter->cur_num) + l_missed_hash = true; + } else if (!l_sync_from_begin) { + l_missed_hash = true; + debug_if(s_debug_more, L_DEBUG, "Requested atom with hash %s not found", dap_hash_fast_to_str_static(&l_request->hash_from)); + } + if (l_missed_hash) { + l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_LAST, NULL); + dap_chain_ch_miss_info_t l_miss_info = { .missed_hash = l_request->hash_from, + .last_hash = *l_iter->cur_hash, + .last_num = l_iter->cur_num }; + dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS, + l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, + l_chain_pkt->hdr.cell_id.uint64, &l_miss_info, sizeof(l_miss_info)); + if (s_debug_more) { + char l_last_hash_str[DAP_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(&l_miss_info.last_hash, l_last_hash_str, DAP_HASH_FAST_STR_SIZE); + log_it(L_INFO, "Out: CHAIN_MISS %s for net %s to source " NODE_ADDR_FP_STR + " with hash missed %s, hash last %s and num last %" DAP_UINT64_FORMAT_U, + l_chain ? l_chain->name : "(null)", + l_chain ? l_chain->net_name : "(null)", + NODE_ADDR_FP_ARGS_S(a_ch->stream->node), + dap_hash_fast_to_str_static(&l_miss_info.missed_hash), + l_last_hash_str, + l_miss_info.last_num); + } + } else { + dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN, + l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, + l_chain_pkt->hdr.cell_id.uint64, NULL, 0); + debug_if(s_debug_more, L_DEBUG, "Out: SYNCED_CHAIN %s for net %s to destination " NODE_ADDR_FP_STR, + l_chain ? l_chain->name : "(null)", + l_chain ? l_chain->net_name : "(null)", + NODE_ADDR_FP_ARGS_S(a_ch->stream->node)); + } l_chain->callback_atom_iter_delete(l_iter); } break; @@ -954,10 +977,10 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) if (l_chain_pkt_data_size != sizeof(dap_chain_ch_summary_t)) { log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY: Wrong chain packet size %zd when expected %zd", l_chain_pkt_data_size, sizeof(dap_chain_ch_summary_t)); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); - break; + return false; } dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id); dap_chain_ch_summary_t *l_sum = (dap_chain_ch_summary_t *)l_chain_pkt->data; @@ -973,10 +996,10 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) if (l_chain_pkt_data_size != sizeof(uint64_t)) { log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK: Wrong chain packet size %zd when expected %zd", l_chain_pkt_data_size, sizeof(uint64_t)); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); - break; + return false; } uint64_t l_ack_num = *(uint64_t *)l_chain_pkt->data; dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id); @@ -988,7 +1011,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) struct sync_context *l_context = l_ch_chain->sync_context; if (!l_context) { log_it(L_WARNING, "CHAIN_ACK: No active sync context"); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); break; @@ -1018,10 +1041,37 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) NODE_ADDR_FP_ARGS_S(a_ch->stream->node)); } break; + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS: { + if (l_chain_pkt_data_size != sizeof(dap_chain_ch_miss_info_t)) { + log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS: Wrong chain packet size %zd when expected %zd", + l_chain_pkt_data_size, sizeof(dap_chain_ch_miss_info_t)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, + DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); + return false; + } + dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id); + dap_chain_ch_miss_info_t *l_miss_info = (dap_chain_ch_miss_info_t *)l_chain_pkt->data; + if (s_debug_more) { + char l_last_hash_str[DAP_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(&l_miss_info->last_hash, l_last_hash_str, DAP_HASH_FAST_STR_SIZE); + log_it(L_INFO, "In: CHAIN_MISS %s for net %s from source " NODE_ADDR_FP_STR + " with hash missed %s, hash last %s and num last %" DAP_UINT64_FORMAT_U, + l_chain ? l_chain->name : "(null)", + l_chain ? l_chain->net_name : "(null)", + NODE_ADDR_FP_ARGS_S(a_ch->stream->node), + dap_hash_fast_to_str_static(&l_miss_info->missed_hash), + l_last_hash_str, + l_miss_info->last_num); + } + // Will be processed upper in net packet notifier callback + } break; + default: - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_UNKNOWN_CHAIN_PKT_TYPE); + return false; // } //} @@ -1040,8 +1090,8 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) } log_it(L_INFO, "In: UPDATE_GLOBAL_DB_REQ pkt: net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64); - if (l_chain_pkt_data_size == (size_t)sizeof(dap_chain_ch_sync_request_t)) - l_ch_chain->request = *(dap_chain_ch_sync_request_t*)l_chain_pkt->data; + if (l_chain_pkt_data_size == (size_t)sizeof(dap_chain_ch_sync_request_old_t)) + l_ch_chain->request = *(dap_chain_ch_sync_request_old_t*)l_chain_pkt->data; struct sync_request *l_sync_request = dap_chain_ch_create_sync_request(l_chain_pkt, a_ch); l_ch_chain->stats_request_gdb_processed = 0; l_ch_chain->request_hdr = l_chain_pkt->hdr; @@ -1077,7 +1127,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) memcmp(&l_ch_chain->request_hdr.net_id, &l_chain_pkt->hdr.net_id, sizeof(dap_chain_net_id_t) + sizeof(dap_chain_id_t) + sizeof(dap_chain_cell_id_t))) { log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB request because its already busy with syncronization"); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS); break; @@ -1094,7 +1144,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); if (!l_hash_item) { log_it(L_CRITICAL, "Memory allocation error"); - return; + break; } l_hash_item->hash = l_element->hash; l_hash_item->size = l_element->size; @@ -1110,25 +1160,25 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) } break; // End of response with starting of DB sync case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END: { - if(l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_t)) { + if(l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_old_t)) { if (l_ch_chain->state != DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE || memcmp(&l_ch_chain->request_hdr.net_id, &l_chain_pkt->hdr.net_id, sizeof(dap_chain_net_id_t) + sizeof(dap_chain_id_t) + sizeof(dap_chain_cell_id_t))) { log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB_END request because its already busy with syncronization"); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS); break; } debug_if(s_debug_more, L_INFO, "In: UPDATE_GLOBAL_DB_END pkt with total count %d hashes", HASH_COUNT(l_ch_chain->remote_gdbs)); - if (l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_t)) - l_ch_chain->request = *(dap_chain_ch_sync_request_t*)l_chain_pkt->data; + if (l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_old_t)) + l_ch_chain->request = *(dap_chain_ch_sync_request_old_t*)l_chain_pkt->data; struct sync_request *l_sync_request = dap_chain_ch_create_sync_request(l_chain_pkt, a_ch); dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_out_gdb_proc_callback, l_sync_request); } else { log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END: Wrong chain packet size %zd when expected %zd", l_chain_pkt_data_size, sizeof(l_ch_chain->request)); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); } @@ -1143,7 +1193,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, NODE_ADDR_FP_ARGS_S(l_ch_chain->request.node_addr) ); }else { log_it(L_WARNING,"Incorrect data size %zu in packet DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB", l_chain_pkt_data_size); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); } @@ -1161,7 +1211,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_gdb_in_pkt_proc_callback, l_sync_request); } else { log_it(L_WARNING, "Packet with GLOBAL_DB atom has zero body size"); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); } @@ -1170,12 +1220,11 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) case DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB: { log_it(L_INFO, "In: SYNCED_GLOBAL_DB: net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64); - if (!l_ch_chain->callback_notify_packet_in) { // we haven't node client waitng, so reply to other side - dap_chain_ch_sync_request_t l_sync_gdb = {}; - l_sync_gdb.node_addr.uint64 = g_node_addr.uint64; - dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ, l_chain_pkt->hdr.net_id.uint64, - l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_sync_gdb, sizeof(l_sync_gdb)); - } + // we haven't node client waitng, so reply to other side + dap_chain_ch_sync_request_old_t l_sync_gdb = {}; + l_sync_gdb.node_addr.uint64 = g_node_addr.uint64; + dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ, l_chain_pkt->hdr.net_id.uint64, + l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_sync_gdb, sizeof(l_sync_gdb)); } break; /// --- Chains update --- @@ -1183,7 +1232,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ:{ if (l_ch_chain->state != DAP_CHAIN_CH_STATE_IDLE) { log_it(L_WARNING, "Can't process UPDATE_CHAINS_REQ request because its already busy with syncronization"); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS); break; @@ -1226,7 +1275,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) " chain id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x" in packet", a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_NET_INVALID_ID); // Who are you? I don't know you! go away! @@ -1250,7 +1299,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_NET_INVALID_ID); // Who are you? I don't know you! go away! @@ -1269,7 +1318,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); if (!l_hash_item) { log_it(L_CRITICAL, "Memory allocation error"); - return; + break; } l_hash_item->hash = l_element->hash; l_hash_item->size = l_element->size; @@ -1290,12 +1339,12 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) } break; case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END: { - if(l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_t)) { + if(l_chain_pkt_data_size == sizeof(dap_chain_ch_sync_request_old_t)) { if (l_ch_chain->state != DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE || memcmp(&l_ch_chain->request_hdr.net_id, &l_chain_pkt->hdr.net_id, sizeof(dap_chain_net_id_t) + sizeof(dap_chain_id_t) + sizeof(dap_chain_cell_id_t))) { log_it(L_WARNING, "Can't process UPDATE_CHAINS_END request because its already busy with syncronization"); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS); break; @@ -1306,7 +1355,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) " chain id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x" in packet", a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_NET_INVALID_ID); break; @@ -1320,7 +1369,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) } else { log_it(L_WARNING, "DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END: Wrong chain packet size %zd when expected %zd", l_chain_pkt_data_size, sizeof(l_ch_chain->request)); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); } @@ -1336,7 +1385,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64); }else{ log_it(L_WARNING,"Incorrect data size %zd in packet DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN", l_chain_pkt_data_size); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); } @@ -1357,30 +1406,27 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) dap_timerfd_delete_unsafe(l_ch_chain->activity_timer); l_ch_chain->activity_timer = NULL; } - if (!l_ch_chain->callback_notify_packet_in) { // we haven't node client waitng, so reply to other side - dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id); - if (!l_chain) { - log_it(L_ERROR, "Invalid SYNCED_CHAINS packet from %s with net id 0x%016"DAP_UINT64_FORMAT_x - " chain id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x" in packet", - a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64, - l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64); - s_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, - l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, - DAP_CHAIN_CH_ERROR_NET_INVALID_ID); - break; - } - if (s_debug_more) { - log_it(L_INFO, "Out: UPDATE_CHAINS_REQ pkt"); - } - dap_chain_ch_sync_request_t l_request= {}; - dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ, l_chain_pkt->hdr.net_id.uint64, - l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_request, sizeof(l_request)); + // we haven't node client waitng, so reply to other side + dap_chain_t *l_chain = dap_chain_find_by_id(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id); + if (!l_chain) { + log_it(L_ERROR, "Invalid SYNCED_CHAINS packet from %s with net id 0x%016"DAP_UINT64_FORMAT_x + " chain id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x" in packet", + a_ch->stream->esocket->remote_addr_str, l_chain_pkt->hdr.net_id.uint64, + l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id.uint64, + l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, + DAP_CHAIN_CH_ERROR_NET_INVALID_ID); + break; + } + if (s_debug_more) { + log_it(L_INFO, "Out: UPDATE_CHAINS_REQ pkt"); } + dap_chain_ch_sync_request_old_t l_request= {}; + dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ, l_chain_pkt->hdr.net_id.uint64, + l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt->hdr.cell_id.uint64, &l_request, sizeof(l_request)); } break; } - if(l_ch_chain->callback_notify_packet_in) - l_ch_chain->callback_notify_packet_in(l_ch_chain, l_ch_pkt->hdr.type, l_chain_pkt, - l_chain_pkt_data_size, l_ch_chain->callback_notify_arg); + return true; } static bool s_sync_timer_callback(void *a_arg) @@ -1388,6 +1434,13 @@ static bool s_sync_timer_callback(void *a_arg) dap_chain_ch_t *l_ch_chain = a_arg; struct sync_context *l_context = l_ch_chain->sync_context; if (l_context->last_activity + s_sync_timeout <= dap_time_now()) { + log_it(L_ERROR, "Sync timeout for node " NODE_ADDR_FP_STR " with net 0x%016" DAP_UINT64_FORMAT_x + " chain 0x%016" DAP_UINT64_FORMAT_x " cell 0x%016" DAP_UINT64_FORMAT_x, + NODE_ADDR_FP_ARGS_S(l_context->addr), l_context->net_id.uint64, + l_context->chain_id.uint64, l_context->cell_id.uint64); + dap_stream_ch_write_error_unsafe(DAP_STREAM_CH(l_ch_chain), l_context->net_id.uint64, + l_context->chain_id.uint64, l_context->cell_id.uint64, + DAP_CHAIN_CH_ERROR_SYNC_TIMEOUT); l_ch_chain->sync_timer = NULL; s_ch_chain_go_idle(l_ch_chain); return false; @@ -1617,7 +1670,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, - &l_ch_chain->request, sizeof(dap_chain_ch_sync_request_t)); + &l_ch_chain->request, sizeof(dap_chain_ch_sync_request_old_t)); debug_if(s_debug_more, L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END"); l_go_idle = true; } @@ -1650,7 +1703,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, - &l_ch_chain->request, sizeof(dap_chain_ch_sync_request_t)); + &l_ch_chain->request, sizeof(dap_chain_ch_sync_request_old_t)); if (s_debug_more ) log_it(L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END"); l_go_idle = true; @@ -1700,7 +1753,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) } else if (!l_objs) { l_was_sent_smth = true; // last message - dap_chain_ch_sync_request_t l_request = { }; + dap_chain_ch_sync_request_old_t l_request = { }; s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB, l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, &l_request, sizeof(l_request)); @@ -1769,7 +1822,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) log_it( L_INFO,"Syncronized database: items syncronyzed %"DAP_UINT64_FORMAT_U" from %zu", l_ch_chain->stats_request_gdb_processed, dap_db_log_list_get_count(l_ch_chain->request_db_log)); // last message - dap_chain_ch_sync_request_t l_request = {}; + dap_chain_ch_sync_request_old_t l_request = {}; s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB, l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, &l_request, sizeof(l_request)); @@ -1807,12 +1860,12 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) l_was_sent_smth = true; if(s_debug_more) log_it(L_INFO,"Out: UPDATE_CHAINS_END sent "); - dap_chain_ch_sync_request_t l_request = {}; + dap_chain_ch_sync_request_old_t l_request = {}; s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END, l_ch_chain->request_hdr.net_id.uint64, l_ch_chain->request_hdr.chain_id.uint64, l_ch_chain->request_hdr.cell_id.uint64, - &l_request, sizeof(dap_chain_ch_sync_request_t)); + &l_request, sizeof(dap_chain_ch_sync_request_old_t)); l_go_idle = true; dap_stream_ch_set_ready_to_write_unsafe(a_ch, false); } @@ -1868,7 +1921,7 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) break; } if(!l_ch_chain->request_atom_iter || !l_ch_chain->request_atom_iter->cur) { // All chains synced - dap_chain_ch_sync_request_t l_request = {}; + dap_chain_ch_sync_request_old_t l_request = {}; // last message l_was_sent_smth = true; s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS, @@ -1876,9 +1929,6 @@ static bool s_stream_ch_packet_out(dap_stream_ch_t *a_ch, void *a_arg) l_ch_chain->request_hdr.cell_id.uint64, &l_request, sizeof(l_request)); log_it( L_INFO,"Synced: %"DAP_UINT64_FORMAT_U" atoms processed", l_ch_chain->stats_request_atoms_processed); l_go_idle = true; - if (l_ch_chain->callback_notify_packet_out) - l_ch_chain->callback_notify_packet_out(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS, NULL, - 0, l_ch_chain->callback_notify_arg); } } break; diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 59237d96057b64a84641848127359a4bd9ca3712..a0b865f378f72e2441265157b2eaa427e0e052f6 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -95,6 +95,7 @@ typedef size_t (*dap_chain_callback_atom_get_hdr_size_t)(void); typedef dap_chain_atom_iter_t * (*dap_chain_callback_atom_iter_create_t)(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash_from); typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_get_t)(dap_chain_atom_iter_t *a_iter, dap_chain_iter_op_t a_operation, size_t *a_atom_size); typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_find_by_hash_t)(dap_chain_atom_iter_t *a_iter, dap_hash_fast_t *a_atom_hash, size_t *a_atom_size); +typedef dap_chain_atom_ptr_t (*dap_chain_callback_atom_iter_get_by_num_t)(dap_chain_atom_iter_t *a_iter, uint64_t a_atom_num); typedef void (*dap_chain_callback_atom_iter_delete_t)(dap_chain_atom_iter_t *); typedef dap_chain_datum_iter_t * (*dap_chain_datum_callback_iter_create_t)(dap_chain_t *); @@ -178,6 +179,7 @@ typedef struct dap_chain { dap_chain_callback_atom_get_timestamp_t callback_atom_get_timestamp; dap_chain_callback_atom_iter_find_by_hash_t callback_atom_find_by_hash; + dap_chain_callback_atom_iter_get_by_num_t callback_atom_get_by_num; dap_chain_callback_datum_find_by_hash_t callback_datum_find_by_hash; dap_chain_callback_block_find_by_hash_t callback_block_find_by_tx_hash; @@ -258,7 +260,11 @@ dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net void dap_chain_delete(dap_chain_t * a_chain); void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_notify_t a_callback, void * a_arg); dap_chain_atom_ptr_t dap_chain_get_atom_by_hash(dap_chain_t * a_chain, dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size); -bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_hash_fast_t *a_atom_hash, dap_chain_cell_id_t a_cell_id); +bool dap_chain_get_atom_last_hash_num(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_atom_hash, uint64_t *a_atom_num); +DAP_STATIC_INLINE bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_atom_hash) +{ + return dap_chain_get_atom_last_hash_num(a_chain, a_cell_id, a_atom_hash, NULL); +} ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_atom, size_t a_atom_size, dap_hash_fast_t *a_new_atom_hash); int dap_cert_chain_file_save(dap_chain_datum_t *datum, char *net_name); const char* dap_chain_get_path(dap_chain_t *a_chain); diff --git a/modules/chain/include/dap_chain_ch.h b/modules/chain/include/dap_chain_ch.h index 13554e358f8f4f068057fad9cce83fe85eefd9a1..9d51f6319edd336118b3ef1e375a0cf6171dbc1c 100644 --- a/modules/chain/include/dap_chain_ch.h +++ b/modules/chain/include/dap_chain_ch.h @@ -50,13 +50,16 @@ typedef enum dap_chain_ch_state { typedef enum dap_chain_ch_error_type { DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS, DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE, + DAP_CHAIN_CH_ERROR_SYNC_TIMEOUT, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE, DAP_CHAIN_CH_ERROR_NET_INVALID_ID, DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND, DAP_CHAIN_CH_ERROR_ATOM_NOT_FOUND, DAP_CHAIN_CH_ERROR_UNKNOWN_CHAIN_PKT_TYPE, DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED, - DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE + DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY, + DAP_CHAIN_CH_ERROR_INTERNAL } dap_chain_ch_error_type_t; typedef struct dap_chain_ch dap_chain_ch_t; @@ -68,7 +71,7 @@ typedef struct dap_chain_pkt_item { byte_t *pkt_data; } dap_chain_pkt_item_t; -typedef struct dap_chain_ch_hash_item{ +typedef struct dap_chain_ch_hash_item { dap_hash_fast_t hash; uint32_t size; UT_hash_handle hh; @@ -92,17 +95,13 @@ typedef struct dap_chain_ch { // request section dap_chain_atom_iter_t *request_atom_iter; //dap_db_log_list_t *request_db_log; // list of global db records - dap_chain_ch_sync_request_t request; + dap_chain_ch_sync_request_old_t request; dap_chain_ch_pkt_hdr_t request_hdr; dap_list_t *request_db_iter; uint32_t timer_shots; dap_timerfd_t *activity_timer; int sent_breaks; - - dap_chain_ch_callback_packet_t callback_notify_packet_out; - dap_chain_ch_callback_packet_t callback_notify_packet_in; - void *callback_notify_arg; } dap_chain_ch_t; #define DAP_CHAIN_CH(a) ((dap_chain_ch_t *) ((a)->internal) ) @@ -114,4 +113,5 @@ int dap_chain_ch_init(void); void dap_chain_ch_deinit(void); void dap_chain_ch_timer_start(dap_chain_ch_t *a_ch_chain); -void dap_chain_ch_reset_unsafe(dap_chain_ch_t *a_ch_chain); + +void dap_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, dap_chain_ch_error_type_t a_error); diff --git a/modules/chain/include/dap_chain_ch_pkt.h b/modules/chain/include/dap_chain_ch_pkt.h index 68046ededd862aa238032d327b81a5e2cedd47fb..0c721f1408379a5972fdf7138514607b9574cacc 100644 --- a/modules/chain/include/dap_chain_ch_pkt.h +++ b/modules/chain/include/dap_chain_ch_pkt.h @@ -60,6 +60,7 @@ // Stable #define DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ 0x80 +#define DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS 0x69 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN 0x01 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY 0x81 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK 0x82 @@ -75,15 +76,33 @@ #define DAP_CHAIN_CH_PKT_TYPE_UPDATE_TSD_HASH_FIRST 0x0004 // Hash of first(s) item #define DAP_CHAIN_CH_PKT_TYPE_UPDATE_TSD_LAST_ID 0x0100 // Last ID of GDB synced group +// *** Legacy *** // + typedef struct dap_chain_ch_update_element{ dap_hash_fast_t hash; uint32_t size; } DAP_ALIGN_PACKED dap_chain_ch_update_element_t; -typedef struct dap_chain_ch_sync_request{ +typedef struct dap_chain_ch_sync_request_old { dap_chain_node_addr_t node_addr; // Requesting node's address dap_chain_hash_fast_t hash_from; byte_t unused[96]; +} DAP_ALIGN_PACKED dap_chain_ch_sync_request_old_t; + +static const char* c_dap_chain_ch_pkt_type_str[]={ + [DAP_CHAIN_CH_PKT_TYPE_CHAIN] = "DAP_CHAIN_CH_PKT_TYPE_CHAIN", + [DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB] = "DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB", + [DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS] = "DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS", + [DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB] = "DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB", + [DAP_CHAIN_CH_PKT_TYPE_ERROR] = "DAP_CHAIN_CH_PKT_TYPE_ERROR" + +}; + +// *** Active *** // + +typedef struct dap_chain_ch_sync_request { + dap_chain_hash_fast_t hash_from; + uint64_t num_from; } DAP_ALIGN_PACKED dap_chain_ch_sync_request_t; typedef struct dap_chain_ch_summary { @@ -92,6 +111,12 @@ typedef struct dap_chain_ch_summary { byte_t reserved[128]; } DAP_ALIGN_PACKED dap_chain_ch_summary_t; +typedef struct dap_chain_ch_miss_info { + dap_hash_fast_t missed_hash; + dap_hash_fast_t last_hash; + uint64_t last_num; +} DAP_ALIGN_PACKED dap_chain_ch_miss_info_t; + typedef struct dap_chain_ch_pkt_hdr { uint8_t version; uint8_t num_hi; @@ -107,15 +132,6 @@ typedef struct dap_chain_ch_pkt { uint8_t data[]; } DAP_ALIGN_PACKED dap_chain_ch_pkt_t; -static const char* c_dap_chain_ch_pkt_type_str[]={ - [DAP_CHAIN_CH_PKT_TYPE_CHAIN] = "DAP_CHAIN_CH_PKT_TYPE_CHAIN", - [DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB] = "DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB", - [DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS] = "DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS", - [DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB] = "DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB", - [DAP_CHAIN_CH_PKT_TYPE_ERROR] = "DAP_CHAIN_CH_PKT_TYPE_ERROR" - -}; - DAP_STATIC_INLINE size_t dap_chain_ch_pkt_get_size(dap_chain_ch_pkt_t *a_pkt) { return sizeof(dap_chain_ch_pkt_hdr_t) + a_pkt->hdr.data_size; } dap_chain_ch_pkt_t *dap_chain_ch_pkt_new(uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c index 2ec116819d111324e8b84e310fdc29ce0aae1385..23d3aaac5a2808a68dec9aac455be73aba851857 100644 --- a/modules/channel/chain-net/dap_stream_ch_chain_net.c +++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c @@ -59,7 +59,7 @@ static void s_stream_ch_new(dap_stream_ch_t* ch, void* arg); static void s_stream_ch_delete(dap_stream_ch_t* ch, void* arg); -static void s_stream_ch_packet_in(dap_stream_ch_t* ch, void* arg); +static bool s_stream_ch_packet_in(dap_stream_ch_t* ch, void* arg); /** * @brief dap_stream_ch_chain_net_init @@ -110,7 +110,7 @@ void s_stream_ch_delete(dap_stream_ch_t* a_ch, void* a_arg) * @param ch * @param arg */ -void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) +static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) { dap_stream_ch_chain_net_t * l_ch_chain_net = DAP_STREAM_CH_CHAIN_NET(a_ch); if(l_ch_chain_net) { @@ -119,18 +119,18 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) char *l_data_hash_str; dap_get_data_hash_str_static(l_ch_pkt->data, l_ch_pkt->hdr.data_size, l_data_hash_str); log_it(L_ATT, "Receive test data packet with hash %s", l_data_hash_str); - return; + return false; } if (l_ch_pkt->hdr.data_size < sizeof(dap_stream_ch_chain_net_pkt_t)) { log_it(L_WARNING, "Too small stream channel N packet size %u (header size %zu)", l_ch_pkt->hdr.data_size, sizeof(dap_stream_ch_chain_net_pkt_t)); - return; + return false; } dap_stream_ch_chain_net_pkt_t *l_ch_chain_net_pkt = (dap_stream_ch_chain_net_pkt_t *)l_ch_pkt->data; if (l_ch_chain_net_pkt->hdr.data_size + sizeof(dap_stream_ch_chain_net_pkt_t) > l_ch_pkt->hdr.data_size) { log_it(L_WARNING, "Too small stream channel N packet size %u (expected at least %zu)", l_ch_pkt->hdr.data_size, l_ch_chain_net_pkt->hdr.data_size + sizeof(dap_stream_ch_chain_net_pkt_t)); - return; + return false; } dap_chain_net_t *l_net = dap_chain_net_by_id(l_ch_chain_net_pkt->hdr.net_id); if (!l_net) { @@ -138,7 +138,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) char l_err_str[] = "ERROR_NET_INVALID_ID"; dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR , l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str)); - return; + return false; } if (l_ch_pkt->hdr.type == DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR) { char *l_err_str = (char *)l_ch_chain_net_pkt->data; @@ -147,7 +147,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) assert(!dap_stream_node_addr_is_blank(&a_ch->stream->node)); dap_link_manager_accounting_link_in_net(l_net->pub.id.uint64, &a_ch->stream->node, false); } - return; + return false; } uint16_t l_acl_idx = dap_chain_net_get_acl_idx(l_net); uint8_t l_acl = a_ch->stream->session->acl ? a_ch->stream->session->acl[l_acl_idx] : 1; @@ -157,13 +157,13 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) char l_err_str[] = "ERROR_NET_NOT_AUTHORIZED"; dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR , l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str)); - return; + return false; } if (dap_chain_net_get_state(l_net) == NET_STATE_OFFLINE) { char l_err_str[] = "ERROR_NET_IS_OFFLINE"; dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR, l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str)); - return; + return false; } switch (l_ch_pkt->hdr.type) { @@ -174,7 +174,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) char l_err_str[] = "ERROR_STREAM_NOT_AUTHORIZED"; dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR , l_ch_chain_net_pkt->hdr.net_id, l_err_str, sizeof(l_err_str)); - return; + break; } assert(!dap_stream_node_addr_is_blank(&a_ch->stream->node)); dap_link_manager_accounting_link_in_net(l_net->pub.id.uint64, &a_ch->stream->node, true); @@ -293,7 +293,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) default: log_it(L_ERROR, "Unknown paket type %hhu", l_ch_pkt->hdr.type); - break; + return false; } if(l_ch_chain_net->notify_callback) @@ -301,4 +301,5 @@ void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) l_ch_chain_net_pkt->hdr.data_size, l_ch_chain_net->notify_callback_arg); } + return true; } diff --git a/modules/common/CMakeLists.txt b/modules/common/CMakeLists.txt index 79ce7eb3e44dfc280d9600754d066fef587185de..e1d05ec18bae2fba2e5b7e24102ca9107db03580 100644 --- a/modules/common/CMakeLists.txt +++ b/modules/common/CMakeLists.txt @@ -10,7 +10,7 @@ if(BUILD_CELLFRAME_SDK_TESTS) add_subdirectory(tests) endif() -target_link_libraries(${PROJECT_NAME} dap_core dap_crypto) +target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain_net) target_include_directories(${PROJECT_NAME} PUBLIC include/ ) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../dap-sdk/3rdparty/json-c) diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index 1dbb358441dd3dc4ba98c5ece3568677b21329fa..341f52c739b33fab85bbff206568e33d3635d0b8 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -134,7 +134,7 @@ void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_tok } case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: if(l_tsd->size >= sizeof(dap_pkey_t)) { - char *l_hash_str; + const char *l_hash_str; dap_pkey_t *l_pkey = (dap_pkey_t*)l_tsd->data; dap_hash_fast_t l_hf = { }; if (!dap_pkey_get_hash(l_pkey, &l_hf)) { @@ -152,7 +152,7 @@ void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_tok case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: if(l_tsd->size == sizeof(dap_chain_hash_fast_t) ){ - char *l_hash_str = (!dap_strcmp(a_hash_out_type,"hex")|| !dap_strcmp(a_hash_out_type, "content_hash")) + const char *l_hash_str = (!dap_strcmp(a_hash_out_type,"hex")|| !dap_strcmp(a_hash_out_type, "content_hash")) ? dap_chain_hash_fast_to_str_static((dap_chain_hash_fast_t*) l_tsd->data) : dap_enc_base58_encode_hash_to_str_static((dap_chain_hash_fast_t*) l_tsd->data); dap_string_append_printf(a_str_out,"total_pkeys_remove: %s\n", l_hash_str); @@ -400,7 +400,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, if (l_in_item && dap_hash_fast_is_blank(&l_in_item->header.tx_prev_hash)) l_is_first = true; char l_tmp_buf[DAP_TIME_STR_SIZE]; - char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash) : dap_chain_hash_fast_to_str_static(a_tx_hash); dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, a_datum->header.ts_created); @@ -677,7 +677,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, } break; case TX_ITEM_TYPE_VOTE:{ dap_chain_tx_vote_t *l_vote_item = (dap_chain_tx_vote_t *)item; - char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_vote_item->voting_hash); + const char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_vote_item->voting_hash); dap_string_append_printf(a_str_out, "\t VOTE: \n" "\t Voting hash: %s\n" "\t Vote answer idx: %"DAP_UINT64_FORMAT_U"\n", l_hash_str, l_vote_item->answer_idx); @@ -715,7 +715,7 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c } dap_hash_fast_t l_datum_hash; dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_datum_hash); - char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_datum_hash) : dap_chain_hash_fast_to_str_static(&l_datum_hash); switch (a_datum->header.type_id) { diff --git a/modules/common/dap_chain_datum_anchor.c b/modules/common/dap_chain_datum_anchor.c index a6110889698dd5828769a9797221dddd2d475805..58cdc378b7257a7476c41a29d617a1df3a635b9d 100644 --- a/modules/common/dap_chain_datum_anchor.c +++ b/modules/common/dap_chain_datum_anchor.c @@ -83,7 +83,7 @@ void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_sign dap_string_append_printf(a_str_out, "<CORRUPTED - can't calc hash>\n"); continue; } - char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) : dap_chain_hash_fast_to_str_static(&l_pkey_hash); dap_string_append_printf(a_str_out, "%d) %s, %s, %u bytes\n", i, l_hash_str, diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c index 38758a133ae949afc47c62ef1859caf438ae719f..6920023a493e992d1188653a5ccb0a2d7affe229 100644 --- a/modules/common/dap_chain_datum_decree.c +++ b/modules/common/dap_chain_datum_decree.c @@ -245,7 +245,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree } dap_hash_fast_t *l_stake_tx = /*{ }; _dap_tsd_get_scalar(l_tsd, &l_stake_tx);*/ _dap_tsd_get_object(l_tsd, dap_hash_fast_t); - char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex") + const char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(l_stake_tx) : dap_chain_hash_fast_to_str_static(l_stake_tx); dap_string_append_printf(a_str_out, "\tStake tx: %s\n", l_stake_tx_hash); @@ -269,7 +269,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t); dap_string_append_printf(a_str_out, "\tSigning addr: %s\n", dap_chain_addr_to_str(l_stake_addr_signing)); dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing->data.hash_fast; - char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_signing) : dap_chain_hash_fast_to_str_static(&l_pkey_signing); dap_string_append_printf(a_str_out, "\tSigning pkey fingerprint: %s\n", l_pkey_signing_str); @@ -341,7 +341,7 @@ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_sign continue; } - char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) : dap_chain_hash_fast_to_str_static(&l_pkey_hash); dap_string_append_printf(a_str_out, "%d) %s, %s, %u bytes\n", i, l_hash_str, diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 8d1c75fc617429cffe57ae481bf78ad6378b54a7..bd1f2d3f8504e3ae369b4748bbc7fcae6040452e 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -282,7 +282,7 @@ void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_ continue; } - char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) : dap_chain_hash_fast_to_str_static(&l_pkey_hash); diff --git a/modules/common/dap_chain_datum_tx_voting.c b/modules/common/dap_chain_datum_tx_voting.c index 658407e446ac81dcd1d84ffaa63686e2d0559ef3..bfd0043bc51872f97be902aee48f32a7769ec948 100644 --- a/modules/common/dap_chain_datum_tx_voting.c +++ b/modules/common/dap_chain_datum_tx_voting.c @@ -150,6 +150,32 @@ dap_chain_tx_voting_t *dap_chain_datum_tx_item_voting_create(void) return l_item; } +const char *s_tx_voting_get_answer_text_by_idx(dap_chain_datum_tx_t *a_tx, uint64_t a_idx) { + dap_list_t *l_answers_list = NULL; + size_t l_anwers_count = 0; + dap_list_t* l_tsd_list = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_TSD, NULL); + dap_list_t* l_temp = l_tsd_list; + while (l_temp){ + dap_tsd_t* l_tsd = (dap_tsd_t *)((dap_chain_tx_tsd_t*)l_temp->data)->tsd; + if (l_tsd->type == VOTING_TSD_TYPE_ANSWER) { + char *l_buf_string = DAP_NEW_Z_SIZE(char, l_tsd->size + 1); + memcpy(l_buf_string, l_tsd->data, l_tsd->size); + l_buf_string[l_tsd->size] = '\0'; + l_answers_list = dap_list_append(l_answers_list, l_buf_string); + l_anwers_count++; + } + l_temp = l_temp->next; + } + dap_list_free(l_tsd_list); + if (l_anwers_count < a_idx) { + dap_list_free_full(l_answers_list, NULL); + return NULL; + } + char *l_ret = dap_strdup(dap_list_nth_data(l_answers_list, a_idx)); + dap_list_free_full(l_answers_list, NULL); + return l_ret; +} + json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_tx) { if (!a_tx) @@ -210,14 +236,31 @@ dap_chain_tx_vote_t *dap_chain_datum_tx_item_vote_create(dap_chain_hash_fast_t * return l_item; } -json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote) +const char *s_get_vote_answer_text(dap_hash_fast_t *a_vote, uint64_t a_idx, dap_ledger_t *a_ledger) { + dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_ledger, a_vote); + if (!l_tx || !a_ledger) { + return NULL; + } + return s_tx_voting_get_answer_text_by_idx(l_tx, a_idx); +} + +json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote, dap_ledger_t *a_ledger) { json_object *l_object = json_object_new_object(); char *l_voting_hash_str = dap_hash_fast_to_str_new(&a_vote->voting_hash); json_object *l_voting_hash = json_object_new_string(l_voting_hash_str); DAP_DELETE(l_voting_hash_str); json_object *l_answer_idx = json_object_new_uint64(a_vote->answer_idx); + char *l_answer_text_str = s_get_vote_answer_text(&a_vote->voting_hash, a_vote->answer_idx, a_ledger); + json_object *l_answer_text = NULL; + if (!l_answer_text_str) { + l_answer_text = json_object_new_string("{UNDEFINED}"); + } else { + l_answer_text = json_object_new_string(l_answer_text_str); + DAP_DELETE(l_answer_text_str); + } json_object_object_add(l_object, "votingHash", l_voting_hash); json_object_object_add(l_object, "answer_idx", l_answer_idx); + json_object_object_add(l_object, "answer_text", l_answer_text); return l_object; } diff --git a/modules/common/include/dap_chain_datum_tx_voting.h b/modules/common/include/dap_chain_datum_tx_voting.h index 1eaf8b5b42d4aab79b8e7075af757a2deea77263..331cb806f80f929b7b33af509b38b3e8117bfafa 100644 --- a/modules/common/include/dap_chain_datum_tx_voting.h +++ b/modules/common/include/dap_chain_datum_tx_voting.h @@ -25,6 +25,7 @@ #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" #include "dap_chain_datum_tx_items.h" +#include "dap_chain_ledger.h" #include "dap_time.h" #include "dap_list.h" #include "dap_tsd.h" @@ -87,4 +88,4 @@ json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_ dap_chain_tx_vote_t *dap_chain_datum_tx_item_vote_create(dap_chain_hash_fast_t *a_voting_hash, uint64_t *a_answer_idx); -json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote); +json_object *dap_chain_datum_tx_item_vote_to_json(dap_chain_tx_vote_t *a_vote, dap_ledger_t *a_ledger); diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index 5233bd3581116838137e90c01a1f0da09c0b94ae..02cd42e366e87c8c60962a4b5cc1ad88b1a9f7d9 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -51,7 +51,7 @@ enum s_esbocs_session_state { static dap_list_t *s_validator_check(dap_chain_addr_t *a_addr, dap_list_t *a_validators); static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s_esbocs_session_state a_new_state, dap_time_t a_time); -static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg); +static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg); static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain_node_addr_t *a_sender_node_addr, uint8_t *a_data, size_t a_data_size); static void s_session_round_clear(dap_chain_esbocs_session_t *a_session); static void s_session_round_new(dap_chain_esbocs_session_t *a_session); @@ -267,7 +267,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) l_validator->node_addr = l_signer_node_addr; l_validator->weight = uint256_1; l_esbocs_pvt->poa_validators = dap_list_append(l_esbocs_pvt->poa_validators, l_validator); - char *l_signer_addr = dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast); + const char *l_signer_addr = dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast); log_it(L_MSG, "add validator addr "NODE_ADDR_FP_STR", signing addr %s", NODE_ADDR_FP_ARGS_S(l_signer_node_addr), l_signer_addr); if (!l_esbocs_pvt->poa_mode) { // auth certs in PoA mode will be first PoS validators keys @@ -356,7 +356,7 @@ static void s_new_atom_notifier(void *a_arg, dap_chain_t *a_chain, dap_chain_cel assert(l_session->chain == a_chain); pthread_mutex_lock(&l_session->mutex); dap_chain_hash_fast_t l_last_block_hash; - dap_chain_get_atom_last_hash(l_session->chain, &l_last_block_hash, a_id); + dap_chain_get_atom_last_hash(l_session->chain, a_id, &l_last_block_hash); if (!dap_hash_fast_compare(&l_last_block_hash, &l_session->cur_round.last_block_hash)) s_session_round_new(l_session); pthread_mutex_unlock(&l_session->mutex); @@ -828,7 +828,7 @@ static void s_session_send_startsync(dap_chain_esbocs_session_t *a_session) if (a_session->cur_round.sync_sent) return; // Sync message already was sent dap_chain_hash_fast_t l_last_block_hash; - dap_chain_get_atom_last_hash(a_session->chain, &l_last_block_hash, c_dap_chain_cell_id_null); + dap_chain_get_atom_last_hash(a_session->chain, c_dap_chain_cell_id_null, &l_last_block_hash); a_session->ts_round_sync_start = dap_time_now(); if (!dap_hash_fast_compare(&l_last_block_hash, &a_session->cur_round.last_block_hash)) return; // My last block hash has changed, skip sync message @@ -877,7 +877,7 @@ static void s_session_update_penalty(dap_chain_esbocs_session_t *a_session) } if (l_item->miss_count < DAP_CHAIN_ESBOCS_PENALTY_KICK) { if (PVT(a_session->esbocs)->debug) { - char *l_addr_str = dap_chain_hash_fast_to_str_static(&l_signing_addr->data.hash_fast); + const char *l_addr_str = dap_chain_hash_fast_to_str_static(&l_signing_addr->data.hash_fast); log_it(L_DEBUG, "Increment miss count %d for addr %s. Miss count for kick is %d", l_item->miss_count, l_addr_str, DAP_CHAIN_ESBOCS_PENALTY_KICK); } @@ -929,7 +929,7 @@ static void s_session_round_new(dap_chain_esbocs_session_t *a_session) a_session->ts_stage_entry = 0; dap_hash_fast_t l_last_block_hash; - dap_chain_get_atom_last_hash(a_session->chain, &l_last_block_hash, c_dap_chain_cell_id_null); + dap_chain_get_atom_last_hash(a_session->chain, c_dap_chain_cell_id_null, &l_last_block_hash); if (!dap_hash_fast_compare(&l_last_block_hash, &a_session->cur_round.last_block_hash) || (!dap_hash_fast_is_blank(&l_last_block_hash) && dap_hash_fast_is_blank(&a_session->cur_round.last_block_hash))) { @@ -1036,7 +1036,7 @@ static uint64_t s_session_calc_current_round_id(dap_chain_esbocs_session_t *a_se } } if (l_id_candidate == 0) { - char *l_signing_addr_str = dap_chain_hash_fast_to_str_static(&l_validator->signing_addr.data.hash_fast); + const char *l_signing_addr_str = dap_chain_hash_fast_to_str_static(&l_validator->signing_addr.data.hash_fast); log_it(L_ERROR, "Can't find sync message of synced validator %s", l_signing_addr_str); continue; } @@ -1164,7 +1164,7 @@ static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s dap_hash_fast_t l_directive_hash; dap_hash_fast(l_directive, l_directive->size, &l_directive_hash); if (PVT(a_session->esbocs)->debug) { - char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_directive_hash); + const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_directive_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu. Put on the vote my directive:%s", a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id, a_session->cur_round.attempt_num, l_candidate_hash_str); @@ -1205,7 +1205,7 @@ static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s ); dap_chain_esbocs_validator_t *l_validator = l_list ? l_list->data : NULL; if (!l_validator || !l_validator->is_chosen) { - char *l_addr = dap_chain_hash_fast_to_str_static(&a_session->cur_round.attempt_submit_validator.data.hash_fast); + const char *l_addr = dap_chain_hash_fast_to_str_static(&a_session->cur_round.attempt_submit_validator.data.hash_fast); log_it(L_MSG, "Error: can't find current attmempt submit validator %s in signers list", l_addr); } l_validator->is_chosen = false; @@ -1332,7 +1332,7 @@ static void s_session_proc_state(dap_chain_esbocs_session_t *a_session) } if (dap_list_length(l_store->candidate_signs) >= PVT(a_session->esbocs)->min_validators_count) { if(l_cs_debug) { - char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&a_session->cur_round.attempt_candidate_hash); + const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&a_session->cur_round.attempt_candidate_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu" " Candidate %s collected sings of minimum number of validators, so to sent PRE_COMMIT", a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id, @@ -1418,7 +1418,7 @@ static void s_session_candidate_submit(dap_chain_esbocs_session_t *a_session) if (l_candidate_size) { dap_hash_fast(l_candidate, l_candidate_size, &l_candidate_hash); if (PVT(a_session->esbocs)->debug) { - char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_candidate_hash); + const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_candidate_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu. Submit my candidate %s", a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id, a_session->cur_round.attempt_num, l_candidate_hash_str); @@ -1462,7 +1462,7 @@ static void s_session_candidate_verify(dap_chain_esbocs_session_t *a_session, da s_message_send(a_session, DAP_CHAIN_ESBOCS_MSG_TYPE_APPROVE, a_candidate_hash, NULL, 0, a_session->cur_round.validators_list); if (PVT(a_session->esbocs)->debug) { - char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash); + const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu Sent APPROVE candidate %s", a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id, a_session->cur_round.attempt_num, l_candidate_hash_str); @@ -1472,7 +1472,7 @@ static void s_session_candidate_verify(dap_chain_esbocs_session_t *a_session, da s_message_send(a_session, DAP_CHAIN_ESBOCS_MSG_TYPE_REJECT, a_candidate_hash, NULL, 0, a_session->cur_round.validators_list); if (PVT(a_session->esbocs)->debug) { - char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash); + const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu Sent REJECT candidate %s", a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id, a_session->cur_round.attempt_num, l_candidate_hash_str); @@ -1492,7 +1492,7 @@ static void s_session_candidate_precommit(dap_chain_esbocs_session_t *a_session, byte_t *l_message_data = a_message->msg_n_sign; dap_chain_hash_fast_t *l_candidate_hash = &a_message->hdr.candidate_hash; dap_chain_esbocs_store_t *l_store; - char *l_candidate_hash_str = NULL; + const char *l_candidate_hash_str = NULL; HASH_FIND(hh, a_session->cur_round.store_items, l_candidate_hash, sizeof(dap_chain_hash_fast_t), l_store); if (!l_store) { l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); @@ -1552,7 +1552,7 @@ static bool s_session_candidate_to_chain(dap_chain_esbocs_session_t *a_session, } bool res = false; dap_chain_atom_verify_res_t l_res = a_session->chain->callback_atom_add(a_session->chain, a_candidate, a_candidate_size); - char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash); + const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(a_candidate_hash); switch (l_res) { case ATOM_ACCEPT: // block save to chain @@ -1594,25 +1594,25 @@ static void s_session_round_finish(dap_chain_esbocs_session_t *a_session, dap_ch } if (l_store->reject_count >= l_cs_level) { - char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash); + const char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash); debug_if(l_cs_debug, L_WARNING, "Trying to finish rejected candidate %s", l_finish_candidate_hash_str); return; } if (l_store->approve_count < l_cs_level) { - char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash); + const char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash); debug_if(l_cs_debug, L_WARNING, "Trying to finish not properly approved candidate %s", l_finish_candidate_hash_str); return; } if (dap_list_length(l_store->candidate_signs) < l_cs_level) { - char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash); + const char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash); debug_if(l_cs_debug, L_WARNING, "Trying to finish not properly signed candidate %s", l_finish_candidate_hash_str); return; } if (l_store->precommit_count < l_cs_level) { - char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash); + const char *l_finish_candidate_hash_str = dap_chain_hash_fast_to_str_static(&l_store->candidate_hash); debug_if(l_cs_debug, L_WARNING, "Trying to finish not properly precommited candidate %s", l_finish_candidate_hash_str); return; } @@ -1751,7 +1751,7 @@ static void s_session_directive_process(dap_chain_esbocs_session_t *a_session, d } if (PVT(a_session->esbocs)->debug) { - char *l_directive_hash_str = dap_chain_hash_fast_to_str_static(a_directive_hash); + const char *l_directive_hash_str = dap_chain_hash_fast_to_str_static(a_directive_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu Send VOTE %s directive %s", a_session->chain->net_name, a_session->chain->name, a_session->cur_round.id, a_session->cur_round.attempt_num, l_vote_for ? "FOR" : "AGAINST", @@ -1862,32 +1862,32 @@ static bool s_process_incoming_message(void *a_arg) return false; } -static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) +static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) { dap_stream_ch_pkt_t *l_ch_pkt = (dap_stream_ch_pkt_t *)a_arg; if (!l_ch_pkt) - return; + return false; dap_chain_esbocs_message_t *l_message = (dap_chain_esbocs_message_t *)l_ch_pkt->data; size_t l_message_size = l_ch_pkt->hdr.data_size; if (l_message_size < sizeof(dap_chain_esbocs_message_t) || l_message_size > DAP_CHAIN_CS_BLOCKS_MAX_BLOCK_SIZE + PKT_SIGN_N_HDR_OVERHEAD || l_message_size != sizeof(*l_message) + l_message->hdr.sign_size + l_message->hdr.message_size) { log_it(L_WARNING, "Invalid message size %zu, drop this packet", l_message_size); - return; + return false; } dap_chain_net_t *l_net = dap_chain_net_by_id(l_message->hdr.net_id); if (!l_net) { log_it(L_WARNING, "Can't find net with ID 0x%" DAP_UINT64_FORMAT_x, l_message->hdr.net_id.uint64); - return; + return false; } if (dap_chain_net_get_state(l_net) == NET_STATE_OFFLINE) { log_it(L_MSG, "Reject packet because net %s is offline", l_net->pub.name); a_ch->stream->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; - return; + return false; } if (l_message->hdr.recv_addr.uint64 != g_node_addr.uint64) { log_it(L_WARNING, "Wrong packet destination address" NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_message->hdr.recv_addr)); - return; + return false; } dap_chain_esbocs_session_t *l_session; DL_FOREACH(s_session_items, l_session) @@ -1896,14 +1896,14 @@ static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) if (!l_session) { log_it(L_WARNING, "Session for net %s not found", l_net->pub.name); a_ch->stream->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; - return; + return false; } if (l_message->hdr.version != DAP_CHAIN_ESBOCS_PROTOCOL_VERSION) { debug_if(PVT(l_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U " Message is rejected - different protocol version %hu (need %u)", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, l_message->hdr.version, DAP_CHAIN_ESBOCS_PROTOCOL_VERSION); - return; + return false; } debug_if(PVT(l_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Receive pkt type:0x%x from addr:"NODE_ADDR_FP_STR", my_addr:"NODE_ADDR_FP_STR"", @@ -1913,13 +1913,14 @@ static void s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) struct esbocs_msg_args *l_args = DAP_NEW_SIZE(struct esbocs_msg_args, sizeof(struct esbocs_msg_args) + l_message_size); if (!l_args) { log_it(L_CRITICAL, g_error_memory_alloc); - return; + return false; } l_args->addr_from = a_ch->stream->node; l_args->session = l_session; l_args->message_size = l_message_size; memcpy(l_args->message, l_message, l_message_size); dap_proc_thread_callback_add(NULL, s_process_incoming_message, l_args); + return true; } /** @@ -2152,7 +2153,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain } if (l_cs_debug) { - char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); + const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Receive SUBMIT candidate %s, size %zu", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, @@ -2162,7 +2163,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain dap_chain_esbocs_store_t *l_store; HASH_FIND(hh, l_session->cur_round.store_items, l_candidate_hash, sizeof(dap_chain_hash_fast_t), l_store); if (l_store) { - char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); + const char *l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); log_it(L_WARNING, "Duplicate candidate: %s", l_candidate_hash_str); break; } @@ -2190,7 +2191,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain case DAP_CHAIN_ESBOCS_MSG_TYPE_APPROVE: case DAP_CHAIN_ESBOCS_MSG_TYPE_REJECT: { dap_chain_esbocs_store_t *l_store; - char *l_candidate_hash_str = NULL; + const char *l_candidate_hash_str = NULL; bool l_approve = l_message->hdr.type == DAP_CHAIN_ESBOCS_MSG_TYPE_APPROVE; HASH_FIND(hh, l_session->cur_round.store_items, l_candidate_hash, sizeof(dap_chain_hash_fast_t), l_store); if (!l_store) { @@ -2257,7 +2258,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain } dap_chain_esbocs_store_t *l_store; - char *l_candidate_hash_str = NULL; + const char *l_candidate_hash_str = NULL; HASH_FIND(hh, l_session->cur_round.store_items, l_candidate_hash, sizeof(dap_chain_hash_fast_t), l_store); if (!l_store) { l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); @@ -2325,7 +2326,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain break; } if (l_cs_debug) { - char *l_dirtective_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); + const char *l_dirtective_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Receive DIRECTIVE hash %s, size %zu", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, @@ -2356,7 +2357,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain break; } if (l_cs_debug) { - char *l_directive_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); + const char *l_directive_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Receive VOTE %s directive %s", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c index 572d2606365a9dd04e3a70ea90c903a146005722..95d2cedcc88c33ec686dcacca946a23101dd593e 100644 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c +++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c @@ -399,7 +399,7 @@ json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree){ _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing); // dap_string_append_printf(a_str_out, "\tSigning addr: %s\n", l_stake_addr_signing_str); dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing.data.hash_fast; - char *l_pkey_signing_str = dap_chain_hash_fast_to_str_static(&l_pkey_signing); + const char *l_pkey_signing_str = dap_chain_hash_fast_to_str_static(&l_pkey_signing); json_object *l_jobj_stake_addr_signing = dap_chain_addr_to_json(&l_stake_addr_signing); json_object *l_jobj_pkey_signing = json_object_new_string(l_pkey_signing_str); json_object_object_add(l_jobj_tsd, "addr", l_jobj_stake_addr_signing); diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c index 51974801211a61428a4392d0d34c77deb4b995ed..9b3d6404058a8390a7fa1e23551fe00964d9cea6 100644 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c +++ b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c @@ -10,6 +10,7 @@ #include "dap_json_rpc_chain_datum_tx_receipt.h" #include "json.h" #include "dap_chain_datum_tx_voting.h" +#include "dap_chain_net.h" #define LOG_TAG "dap_json_rpc_chain_datum_tx" @@ -110,7 +111,8 @@ json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx,dap_chain_net break; case TX_ITEM_TYPE_VOTE: l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_VOTE"); - l_obj_item_data = dap_chain_datum_tx_item_vote_to_json((dap_chain_tx_vote_t*)item); + dap_chain_net_t *l_net = dap_chain_net_by_id(*a_net_id); + l_obj_item_data = dap_chain_datum_tx_item_vote_to_json((dap_chain_tx_vote_t*)item, l_net->pub.ledger); break; case TX_ITEM_TYPE_VOTING: l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_VOTING"); diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 41639e23b430d3845416bda33ecaee24f13d7d29..73d98c1ba859dbab66dacf4185996b407c66b2f8 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -95,7 +95,7 @@ char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t dap_chain_hash_fast_t l_key_hash; dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_key_hash); - char *l_key_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_key_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_key_hash) : dap_chain_hash_fast_to_str_static(&l_key_hash); @@ -1484,8 +1484,8 @@ void dap_chain_mempool_filter(dap_chain_t *a_chain, int *a_removed){ char * l_gdb_group = dap_chain_net_get_gdb_group_mempool_new(a_chain); size_t l_objs_size = 0; dap_time_t l_cut_off_time = dap_time_now() - 3 * 24 * 3600; // 3 days - char l_cut_off_time_str[80] = {'\0'}; - dap_time_to_str_rfc822(l_cut_off_time_str, 80, l_cut_off_time); + char l_cut_off_time_str[DAP_TIME_STR_SIZE] = {'\0'}; + dap_time_to_str_rfc822(l_cut_off_time_str, DAP_TIME_STR_SIZE, l_cut_off_time); dap_global_db_obj_t * l_objs = dap_global_db_get_all_sync(l_gdb_group, &l_objs_size); for (size_t i = 0; i < l_objs_size; i++) { dap_chain_datum_t *l_datum = (dap_chain_datum_t*)l_objs[i].value; diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index b8424b1e8664e9bd17ee14520775fd82c2c4dcbc..b83d20a05457e0d3d8f670b3d2d18febea6b9033 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -819,7 +819,7 @@ static void s_tx_header_print(json_object *a_json_out, dap_chain_datum_tx_t *a_t char l_time_str[DAP_TIME_STR_SIZE] = "unknown"; if (a_tx->header.ts_created) dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, a_tx->header.ts_created); - char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash) : dap_chain_hash_fast_to_str_static(a_tx_hash); json_object_object_add(a_json_out, "TX hash ", json_object_new_string(l_tx_hash_str)); @@ -5726,7 +5726,7 @@ dap_chain_datum_tx_t *dap_ledger_datum_iter_get_next(dap_ledger_datum_iter_t *a_ { dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger); pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); - a_iter->cur_ledger_tx_item = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->hh.next; + a_iter->cur_ledger_tx_item = a_iter->cur_ledger_tx_item ? ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->hh.next : NULL; if (a_iter->cur_ledger_tx_item){ a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx; a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast; diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index b362c7cf2e5f75981b3f8ca1fde89e7db680b252..5d256ba44edf9caebfaa6f39c7d8f349bcf9b3b9 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -165,6 +165,8 @@ struct chain_sync_context { dap_stream_node_addr_t current_link; dap_chain_t *cur_chain; dap_chain_cell_t *cur_cell; + dap_hash_fast_t requested_atom_hash; + uint64_t requested_atom_num; }; /** @@ -2482,6 +2484,8 @@ int s_net_load(dap_chain_net_t *a_net) return 0; } +static const uint64_t s_fork_sync_step = 20; // TODO get it from config + static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const void *a_data, size_t a_data_size, void *a_arg) { debug_if(s_debug_more, L_DEBUG, "Got IN sync packet type %hhu size %zu from addr " NODE_ADDR_FP_STR, @@ -2491,10 +2495,76 @@ static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const vo switch (a_type) { case DAP_CHAIN_CH_PKT_TYPE_ERROR: l_net_pvt->sync_context.state = SYNC_STATE_ERROR; - break; + return; + case DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN: l_net_pvt->sync_context.state = SYNC_STATE_SYNCED; - break; + return; + + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS: { + dap_chain_ch_miss_info_t *l_miss_info = (dap_chain_ch_miss_info_t *)(((dap_chain_ch_pkt_t *)(a_data))->data); + if (!dap_hash_fast_compare(&l_miss_info->missed_hash, &l_net_pvt->sync_context.requested_atom_hash)) { + char l_missed_hash_str[DAP_HASH_FAST_STR_SIZE]; + dap_hash_fast_to_str(&l_miss_info->missed_hash, l_missed_hash_str, DAP_HASH_FAST_STR_SIZE); + log_it(L_WARNING, "Get irrelevant chain sync MISSED packet with missed hash %s, but requested hash is %s", + l_missed_hash_str, + dap_hash_fast_to_str_static(&l_net_pvt->sync_context.requested_atom_hash)); + dap_stream_ch_write_error_unsafe(a_ch, l_net->pub.id.uint64, + l_net_pvt->sync_context.cur_chain->id.uint64, + l_net_pvt->sync_context.cur_cell + ? l_net_pvt->sync_context.cur_cell->id.uint64 + : 0, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + return; + } + dap_chain_atom_iter_t *l_iter = l_net_pvt->sync_context.cur_chain->callback_atom_iter_create( + l_net_pvt->sync_context.cur_chain, + l_net_pvt->sync_context.cur_cell + ? l_net_pvt->sync_context.cur_cell->id + : c_dap_chain_cell_id_null, + NULL); + if (!l_iter) { + log_it(L_CRITICAL, g_error_memory_alloc); + dap_stream_ch_write_error_unsafe(a_ch, l_net->pub.id.uint64, + l_net_pvt->sync_context.cur_chain->id.uint64, + l_net_pvt->sync_context.cur_cell + ? l_net_pvt->sync_context.cur_cell->id.uint64 + : 0, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); + return; + } + dap_chain_atom_ptr_t l_atom = l_net_pvt->sync_context.cur_chain->callback_atom_find_by_hash(l_iter, &l_miss_info->last_hash, NULL); + if (l_atom && l_iter->cur_num == l_miss_info->last_num) { // We already have this subchain in our chain + l_net_pvt->sync_context.state = SYNC_STATE_SYNCED; + return; + } + dap_chain_ch_sync_request_t l_request = {}; + l_request.num_from = l_net_pvt->sync_context.requested_atom_num > s_fork_sync_step + ? l_net_pvt->sync_context.requested_atom_num - s_fork_sync_step + : 0; + if (l_request.num_from) { + l_atom = l_net_pvt->sync_context.cur_chain->callback_atom_get_by_num(l_iter, l_request.num_from); + assert(l_atom); + l_request.hash_from = *l_iter->cur_hash; + } + l_net_pvt->sync_context.cur_chain->callback_atom_iter_delete(l_iter); + debug_if(s_debug_more, L_INFO, "Send sync request to node " NODE_ADDR_FP_STR + " for net %s and chain %s, hash from %s, num from %" DAP_UINT64_FORMAT_U, + NODE_ADDR_FP_ARGS_S(l_net_pvt->sync_context.current_link), + l_net->pub.name, l_net_pvt->sync_context.cur_chain->name, + dap_hash_fast_to_str_static(&l_request.hash_from), l_request.num_from); + dap_chain_ch_pkt_write_unsafe(a_ch, + DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ, + l_net->pub.id.uint64, + l_net_pvt->sync_context.cur_chain->id.uint64, + l_net_pvt->sync_context.cur_cell + ? l_net_pvt->sync_context.cur_cell->id.uint64 + : 0, + &l_request, + sizeof(l_request)); + l_net_pvt->sync_context.requested_atom_hash = l_request.hash_from; + l_net_pvt->sync_context.requested_atom_num = l_request.num_from; + } default: break; } @@ -2563,19 +2633,37 @@ static void s_sync_timer_callback(void *a_arg) // TODO make correct working with cells assert(l_net_pvt->sync_context.cur_chain); l_net_pvt->sync_context.cur_cell = l_net_pvt->sync_context.cur_chain->cells; - log_it(L_INFO, "Start synchronization process with " NODE_ADDR_FP_STR " for net %s and chain %s", - NODE_ADDR_FP_ARGS_S(l_net_pvt->sync_context.current_link), - l_net->pub.name, l_net_pvt->sync_context.cur_chain->name); l_net_pvt->sync_context.state = l_net_pvt->sync_context.last_state = SYNC_STATE_WAITING; - dap_hash_fast_t l_last_hash; - dap_chain_get_atom_last_hash(l_net_pvt->sync_context.cur_chain, &l_last_hash, l_net_pvt->sync_context.cur_cell - ? l_net_pvt->sync_context.cur_cell->id : c_dap_chain_cell_id_null); + dap_chain_ch_sync_request_t l_request = {}; + uint64_t l_last_num = 0; + if (!dap_chain_get_atom_last_hash_num(l_net_pvt->sync_context.cur_chain, + l_net_pvt->sync_context.cur_cell + ? l_net_pvt->sync_context.cur_cell->id + : c_dap_chain_cell_id_null, + &l_request.hash_from, + &l_last_num)) { + log_it(L_ERROR, "Can't get last atom hash and number for chain %s with net %s", l_net_pvt->sync_context.cur_chain->name, + l_net->pub.name); + return; + } + l_request.num_from = l_last_num; dap_chain_ch_pkt_t *l_chain_pkt = dap_chain_ch_pkt_new(l_net->pub.id.uint64, l_net_pvt->sync_context.cur_chain->id.uint64, l_net_pvt->sync_context.cur_cell ? l_net_pvt->sync_context.cur_cell->id.uint64 : 0, - &l_last_hash, sizeof(l_last_hash)); + &l_request, sizeof(l_request)); + if (!l_chain_pkt) { + log_it(L_CRITICAL, g_error_memory_alloc); + return; + } + log_it(L_INFO, "Start synchronization process with " NODE_ADDR_FP_STR + " for net %s and chain %s, last hash %s, last num %" DAP_UINT64_FORMAT_U, + NODE_ADDR_FP_ARGS_S(l_net_pvt->sync_context.current_link), + l_net->pub.name, l_net_pvt->sync_context.cur_chain->name, + dap_hash_fast_to_str_static(&l_request.hash_from), l_last_num); dap_stream_ch_pkt_send_by_addr(&l_net_pvt->sync_context.current_link, DAP_CHAIN_CH_ID, DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ, l_chain_pkt, dap_chain_ch_pkt_get_size(l_chain_pkt)); + l_net_pvt->sync_context.requested_atom_hash = l_request.hash_from; + l_net_pvt->sync_context.requested_atom_num = l_request.num_from; DAP_DELETE(l_chain_pkt); } if (l_net_pvt->sync_context.last_state != SYNC_STATE_IDLE && diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c index b6e8c1195c010d9df8be5755af4441465ff8ae31..5f664784d2b18bd40072f487f486d18c239f7244 100644 --- a/modules/net/dap_chain_net_balancer.c +++ b/modules/net/dap_chain_net_balancer.c @@ -152,7 +152,7 @@ dap_chain_net_links_t *dap_chain_net_balancer_get_node(const char *a_net_name, u size_t l_node_num_prep = a_links_need; dap_link_info_t *l_links_info = s_get_links_info_list(l_net, &l_node_num_prep, true); if (!l_links_info || !l_node_num_prep){ - log_it(L_ERROR, "Active node list in net %s is empty", a_net_name); + log_it(L_WARNING, "Active node list in net %s is empty", a_net_name); return NULL; } size_t l_node_num_send = dap_min(s_max_links_response_count, l_node_num_prep); @@ -187,7 +187,7 @@ dap_chain_net_links_t *dap_chain_net_balancer_get_node_old(const char *a_net_nam size_t l_node_num_prep = a_links_need; dap_link_info_t *l_links_info = s_get_links_info_list(l_net, &l_node_num_prep, true); if (!l_links_info || !l_node_num_prep){ - log_it(L_ERROR, "Active node list in net %s is empty", a_net_name); + log_it(L_WARNING, "Active node list in net %s is empty", a_net_name); return NULL; } size_t l_node_num_send = dap_min(s_max_links_response_count, l_node_num_prep); diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index fd0f78e13f826b1d2d37224760bdefa72d7378c1..f0019c1b7f4db2402dde52dc4d3a868ef4d57295 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -417,13 +417,12 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain log_it(L_WARNING,"Can't get signer node address from decree."); return -105; } - // Check it directly before applying + if (!a_apply) + break; if (dap_chain_net_srv_stake_verify_key_and_node(&l_addr, &l_node_addr)) { log_it(L_WARNING, "Key and node verification error"); return -105; } - if (!a_apply) - break; dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_uint256_buffer, &l_node_addr); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE: diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index c0d081d6bffa6b9c42ebd034112591fabf34f8f9..078e5076fd4c15c529786c7a9d465bef593a8bb0 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -315,9 +315,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "ledger list coins -net <net_name> [-limit] [-offset]\n" "ledger list threshold [-hash <tx_treshold_hash>] -net <net_name> [-limit] [-offset]\n" "ledger list balance -net <net_name> [-limit] [-offset]\n" - "ledger info -hash <tx_hash> -net <net_name> [-unspent]\n" - "ledger tx -all -net <net_name> [-unspent]\n" - "ledger tx {-addr <addr> | -w <wallet_name> | -tx <tx_hash>} -net <net_name>\n"); + "ledger info -hash <tx_hash> -net <net_name> [-unspent]\n"); // Token info dap_cli_server_cmd_add("token", com_token, "Token info", diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 85db305dd0e41e8054156dc24b0227813922b3a8..c0faca96be5c64b81e846e1f4cba411dabdb30e5 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -1180,7 +1180,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply) } log_it(L_NOTICE, "Stream connection established"); - dap_chain_ch_sync_request_t l_sync_request = {}; + dap_chain_ch_sync_request_old_t l_sync_request = {}; dap_stream_ch_t *l_ch_chain = dap_client_get_stream_ch_unsafe(l_node_client->client, DAP_CHAIN_CH_ID); // fill begin id l_sync_request.id_start = 1; @@ -1223,7 +1223,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply) // reset state NODE_CLIENT_STATE_SYNCED dap_chain_node_client_reset(l_node_client); // send request - dap_chain_ch_sync_request_t l_sync_request = {}; + dap_chain_ch_sync_request_old_t l_sync_request = {}; if(0 == dap_chain_ch_pkt_write_unsafe(l_ch_chain, DAP_CHAIN_CH_PKT_TYPE_SYNC_CHAINS, l_net->pub.id.uint64, l_chain->id.uint64, l_remote_node_info->hdr.cell_id.uint64, &l_sync_request, sizeof(l_sync_request))) { @@ -1269,6 +1269,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply) return -4; } } + l_node_addr = l_node_info->address; if(!l_node_addr.uint64) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Addr not found"); return -5; @@ -1875,6 +1876,8 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; struct dirent * l_dir_entry = NULL; while( (l_dir_entry = readdir(l_dir)) ) { + if (dap_strcmp(l_dir_entry->d_name, "..") == 0 || dap_strcmp(l_dir_entry->d_name, ".") == 0) + continue; json_object * json_obj_wall = json_object_new_object(); if (!json_obj_wall) { json_object_put(json_arr_out); @@ -1969,7 +1972,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; json_object_object_add(json_obj_wall, "sign", json_object_new_string( strlen(dap_chain_wallet_check_sign(l_wallet))!=0 ? dap_chain_wallet_check_sign(l_wallet) : "correct")); - json_object_object_add(json_obj_wall, "nwallet", json_object_new_string(l_wallet->name)); + json_object_object_add(json_obj_wall, "wallet", json_object_new_string(l_wallet->name)); } json_object_object_add(json_obj_wall, "addr", l_l_addr_str ? json_object_new_string(l_l_addr_str) : json_object_new_string("-")); json_object_object_add(json_obj_wall, "network", l_net_name? json_object_new_string(l_net_name) : json_object_new_string("-")); @@ -2035,7 +2038,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; switch (l_rc) { case 0: json_object_object_add(json_obj_wall, "Wallet name", json_object_new_string(l_wallet_name)); - json_object_object_add(json_obj_wall, "protection", CMD_WALLET_ACTIVATE ? + json_object_object_add(json_obj_wall, "protection", cmd_num == CMD_WALLET_ACTIVATE ? json_object_new_string("is activated") : json_object_new_string("is deactivated")); break; case -EBUSY: @@ -2568,8 +2571,8 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply) l_datum_size = dap_chain_datum_size(l_datum); dap_chain_hash_fast_t l_key_hash = { }; dap_hash_fast(l_datum->data, l_token_size, &l_key_hash); - char *l_key_str = dap_chain_hash_fast_to_str_static(&l_key_hash); - char *l_key_str_base58 = dap_enc_base58_encode_hash_to_str_static(&l_key_hash); + const char *l_key_str = dap_chain_hash_fast_to_str_static(&l_key_hash); + const char *l_key_str_base58 = dap_enc_base58_encode_hash_to_str_static(&l_key_hash); const char *l_key_out_str = dap_strcmp(l_hash_out_type, "hex") ? l_key_str_base58 : l_key_str; // Add datum to mempool with datum_token hash as a key @@ -2711,8 +2714,8 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_hash_fast_t l_datum_hash_from_key = {0}; dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_datum_real_hash); dap_chain_hash_fast_from_str(l_objs[i].key, &l_datum_hash_from_key); - char buff_time[50]; - dap_time_to_str_rfc822(buff_time, 50, l_datum->header.ts_create); + char buff_time[DAP_TIME_STR_SIZE]; + dap_time_to_str_rfc822(buff_time, DAP_TIME_STR_SIZE, l_datum->header.ts_create); json_object *l_jobj_type = json_object_new_string(l_datum_type); json_object *l_jobj_hash = json_object_new_string(l_objs[i].key); json_object *l_jobj_ts_created = json_object_new_object(); @@ -3096,7 +3099,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a } for (dap_list_t *it = l_vote_list; it; it = it->next) { json_object *l_jobj_vote = dap_chain_datum_tx_item_vote_to_json( - (dap_chain_tx_vote_t *) it->data); + (dap_chain_tx_vote_t *) it->data, a_net->pub.ledger); json_object_array_add(l_jobj_tx_vote, l_jobj_vote); } for (dap_list_t *it = l_voting_list; it; it = it->next) { @@ -3404,7 +3407,7 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char json_object_array_add(*a_json_reply, l_jobj_datum); return 0; } else { - l_find_bool = json_object_new_boolean(TRUE); + l_find_bool = json_object_new_boolean(FALSE); if (!l_find_bool) { json_object_put(l_jobj_datum); dap_json_rpc_allocation_error; @@ -4534,7 +4537,7 @@ int com_token_decl(int a_argc, char ** a_argv, void **a_str_reply) // Calc datum's hash dap_chain_hash_fast_t l_key_hash; dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_key_hash); - char * l_key_str = !dap_strcmp(l_hash_out_type, "hex") ? + const char *l_key_str = !dap_strcmp(l_hash_out_type, "hex") ? dap_chain_hash_fast_to_str_static(&l_key_hash) : dap_enc_base58_encode_hash_to_str_static(&l_key_hash); @@ -4737,8 +4740,8 @@ int com_token_update(int a_argc, char ** a_argv, void **a_str_reply) // Calc datum's hash dap_chain_hash_fast_t l_key_hash; dap_hash_fast(l_datum->data, l_datum->header.data_size, &l_key_hash); - char * l_key_str = dap_chain_hash_fast_to_str_static(&l_key_hash); - char * l_key_str_out = dap_strcmp(l_hash_out_type, "hex") ? + const char *l_key_str = dap_chain_hash_fast_to_str_static(&l_key_hash); + const char *l_key_str_out = dap_strcmp(l_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_key_hash) : l_key_str; // Add datum to mempool with datum_token hash as a key @@ -4964,7 +4967,7 @@ int com_token_emit(int a_argc, char **a_argv, void **a_str_reply) * @param a_str_reply * @return int */ -int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply) +int com_tx_cond_create(int a_argc, char ** a_argv, void **a_reply) { (void) a_argc; int arg_index = 1; @@ -4984,8 +4987,9 @@ int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply) if(!l_hash_out_type) l_hash_out_type = "hex"; if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid parameter -H, valid values: -H <hex | base58>"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_INVALID_PARAMETER_HEX, + "Invalid parameter -H, valid values: -H <hex | base58>"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_INVALID_PARAMETER_HEX; } // Token ticker @@ -5006,84 +5010,86 @@ int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv_uid", &l_srv_uid_str); if(!l_token_ticker) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-token'"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_TOKEN, "tx_cond_create requires parameter '-token'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_TOKEN; } if (!l_wallet_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-w'"); - return -2; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_W, "tx_cond_create requires parameter '-w'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_W; } if (!l_cert_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-cert'"); - return -3; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_CERT, "tx_cond_create requires parameter '-cert'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_CERT; } if(!l_value_datoshi_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-value'"); - return -4; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_VALUE, "tx_cond_create requires parameter '-value'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_VALUE; } if(!l_value_fee_str){ - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-fee'"); - return -15; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_FEE, "tx_cond_create requires parameter '-fee'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_FEE; } if(!l_net_name) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-net'"); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_NET, "tx_cond_create requires parameter '-net'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_NET; } if(!l_unit_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-unit'"); - return -6; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_UNIT, "tx_cond_create requires parameter '-unit'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_UNIT; } if(!l_srv_uid_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_cond_create requires parameter '-srv_uid'"); - return -7; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_SRV_UID, "tx_cond_create requires parameter '-srv_uid'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_SRV_UID; } dap_chain_net_srv_uid_t l_srv_uid = {}; l_srv_uid.uint64 = strtoll(l_srv_uid_str, NULL, 10); if (!l_srv_uid.uint64) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find service UID %s ", l_srv_uid_str); - return -8; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_SERVICE_UID, "Can't find service UID %s ", l_srv_uid_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_SERVICE_UID; } dap_chain_net_srv_price_unit_uid_t l_price_unit = { .enm = dap_chain_srv_str_to_unit_enum((char*)l_unit_str)}; if(l_price_unit.enm == SERV_UNIT_UNDEFINED) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize unit '%s'. Unit must look like { B | SEC }", - l_unit_str); - return -9; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_UNIT, + "Can't recognize unit '%s'. Unit must look like { B | SEC }", l_unit_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_UNIT; } l_value_datoshi = dap_chain_balance_scan(l_value_datoshi_str); if(IS_ZERO_256(l_value_datoshi)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize value '%s' as a number", l_value_datoshi_str); - return -10; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE, + "Can't recognize value '%s' as a number", l_value_datoshi_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE; } l_value_fee = dap_chain_balance_scan(l_value_fee_str); if(IS_ZERO_256(l_value_fee)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize value '%s' as a number", l_value_fee_str); - return -16; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE_FEE, + "Can't recognize value '%s' as a number", l_value_fee_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE_FEE; } dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name(l_net_name) : NULL; if(!l_net) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find net '%s'", l_net_name); - return -11; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_NET, "Can't find net '%s'", l_net_name); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_NET; } dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, c_wallets_path); - const char* l_sign_str = ""; +// const char* l_sign_str = ""; if(!l_wallet) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't open wallet '%s'", l_wallet_str); - return -12; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_OPEN_WALLET, "Can't open wallet '%s'", l_wallet_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_OPEN_WALLET; } else { - l_sign_str = dap_chain_wallet_check_sign(l_wallet); +// l_sign_str = dap_chain_wallet_check_sign(l_wallet); } dap_cert_t *l_cert_cond = dap_cert_find_by_name(l_cert_str); if(!l_cert_cond) { dap_chain_wallet_close(l_wallet); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find cert '%s'", l_cert_str); - return -13; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_FIND_CERT, "Can't find cert '%s'", l_cert_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_FIND_CERT; } dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet, 0); @@ -5091,8 +5097,9 @@ int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply) if (!l_key_cond) { dap_chain_wallet_close(l_wallet); dap_enc_key_delete(l_key_from); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Cert '%s' doesn't contain a valid public key", l_cert_str); - return -14; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CERT_DOES_NOT_CONATIN_VALID_PUBLIC_KEY, + "Cert '%s' doesn't contain a valid public key", l_cert_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CERT_DOES_NOT_CONATIN_VALID_PUBLIC_KEY; } uint256_t l_value_per_unit_max = {}; @@ -5104,12 +5111,20 @@ int com_tx_cond_create(int a_argc, char ** a_argv, void **a_str_reply) DAP_DELETE(l_key_cond); if (l_hash_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%sConditional 256bit TX created succefully, hash=%s\n", l_hash_str, l_sign_str); + json_object *l_jobj_ret = json_object_new_object(); + json_object *l_jobj_tx_cond_transfer = json_object_new_boolean(true); + json_object *l_jobj_hash = json_object_new_string(l_hash_str); + json_object_object_add(l_jobj_ret, "create_tx_cond", l_jobj_tx_cond_transfer); + json_object_object_add(l_jobj_ret, "hash", l_jobj_hash); + json_object_array_add(*a_reply, l_jobj_ret); DAP_DELETE(l_hash_str); - return 0; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_OK; } - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create conditional 256bit TX\n"); - return -1; + json_object *l_jobj_ret = json_object_new_object(); + json_object *l_jobj_tx_cond_transfer = json_object_new_boolean(false); + json_object_object_add(l_jobj_ret, "create_tx_cond", l_jobj_tx_cond_transfer); + json_object_array_add(*a_reply, l_jobj_ret); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_CONDITIONAL_TX_CREATE; } static dap_list_t* s_hashes_parse_str_list(const char * a_hashes_str) @@ -5144,10 +5159,9 @@ static dap_list_t* s_hashes_parse_str_list(const char * a_hashes_str) return l_ret_list; } -int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) +int com_tx_cond_remove(int a_argc, char ** a_argv, void **reply) { (void) a_argc; - void** l_str_reply = a_str_reply; int arg_index = 1; const char *c_wallets_path = dap_chain_wallet_get_path(g_config); const char * l_wallet_str = NULL; @@ -5162,8 +5176,9 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) if(!l_hash_out_type) l_hash_out_type = "hex"; if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Invalid parameter -H, valid values: -H <hex | base58>"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_INVALID_PARAMETER_HEX, + "Invalid parameter -H, valid values: -H <hex | base58>"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_INVALID_PARAMETER_HEX; } // Wallet name @@ -5178,43 +5193,43 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv_uid", &l_srv_uid_str); if (!l_wallet_str) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-w'"); - return -2; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_W, "com_txs_cond_remove requires parameter '-w'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_W; } if(!l_value_fee_str){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-fee'"); - return -15; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_FEE, "com_txs_cond_remove requires parameter '-fee'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_FEE; } if(!l_net_name) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-net'"); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_NET, "com_txs_cond_remove requires parameter '-net'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_NET; } if(!l_hashes_str) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-hashes'"); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_HASHES, "com_txs_cond_remove requires parameter '-hashes'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_HASHES; } if(!l_srv_uid_str) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-srv_uid'"); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_SRV_UID, "com_txs_cond_remove requires parameter '-srv_uid'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_SRV_UID; } dap_chain_net_srv_uid_t l_srv_uid = {}; l_srv_uid.uint64 = strtoll(l_srv_uid_str, NULL, 10); if (!l_srv_uid.uint64) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find service UID %s ", l_srv_uid_str); - return -8; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_SERVICE_UID, "Can't find service UID %s ", l_srv_uid_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_SERVICE_UID; } dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name(l_net_name) : NULL; if(!l_net) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find net '%s'", l_net_name); - return -11; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NET, "Can't find net '%s'", l_net_name); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NET; } dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, c_wallets_path); - const char* l_sign_str = ""; +// const char* l_sign_str = ""; if(!l_wallet) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't open wallet '%s'", l_wallet_str); - return -12; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_OPEN_WALLET, "Can't open wallet '%s'", l_wallet_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_OPEN_WALLET; } dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet, 0); @@ -5222,32 +5237,32 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) l_value_fee = dap_chain_balance_scan(l_value_fee_str); if(IS_ZERO_256(l_value_fee)) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't recognize value '%s' as a number", l_value_fee_str); - return -16; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_RECOGNIZE_VALUE_FEE, "Can't recognize value '%s' as a number", l_value_fee_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_RECOGNIZE_VALUE_FEE; } const char *l_native_ticker = l_net->pub.native_ticker; if (!l_native_ticker){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find native ticker for net %s", l_net->pub.name); - return -16; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NATIVE_TICKER_IN_NET, "Can't find native ticker for net %s", l_net->pub.name); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NATIVE_TICKER_IN_NET; } dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net->pub.name); if (!l_ledger){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find ledger for net %s", l_net->pub.name); - return -17; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_LEDGER_FOR_NET, "Can't find ledger for net %s", l_net->pub.name); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_LEDGER_FOR_NET; } // create empty transaction dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); if (!l_ledger){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new tx"); - return -18; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_CREATE_NEW_TX, "Can't create new tx"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_CREATE_NEW_TX; } dap_list_t *l_hashes_list = s_hashes_parse_str_list(l_hashes_str); if (!l_hashes_list){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "Requested conditional transaction with hash not found"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUESTED_COND_TX_WITH_HASH_NOT_FOUND, "Requested conditional transaction with hash not found"); dap_chain_datum_tx_delete(l_tx); - return -19; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUESTED_COND_TX_WITH_HASH_NOT_FOUND; } uint256_t l_cond_value_sum = {}; @@ -5335,11 +5350,12 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) dap_list_free_full(l_hashes_list, NULL); if (IS_ZERO_256(l_cond_value_sum)){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "No unspent conditional transactions in hashes list for wallet %s. Check input parameters.", l_wallet_str); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_UNSPENT_COND_TX_IN_HASH_LIST_FOR_WALLET, + "No unspent conditional transactions in hashes list for wallet %s. Check input parameters.", l_wallet_str); dap_chain_datum_tx_delete(l_tx); dap_chain_wallet_close(l_wallet); DAP_DEL_Z(l_wallet_pkey); - return -20; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_UNSPENT_COND_TX_IN_HASH_LIST_FOR_WALLET; } uint256_t l_net_fee = {}; @@ -5350,11 +5366,12 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) SUM_256_256(l_total_fee, l_net_fee, &l_total_fee); if (compare256(l_total_fee, l_cond_value_sum) >= 0 ){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "Sum of conditional outputs must be greater than fees sum."); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_SUM_COND_OUTPUTS_MUST_GREATER_THAN_FEES_SUM, + "Sum of conditional outputs must be greater than fees sum."); dap_chain_datum_tx_delete(l_tx); dap_chain_wallet_close(l_wallet); DAP_DEL_Z(l_wallet_pkey); - return -21; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_SUM_COND_OUTPUTS_MUST_GREATER_THAN_FEES_SUM; } uint256_t l_coin_back = {}; @@ -5363,12 +5380,13 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) // return coins to owner if (dap_chain_datum_tx_add_out_item(&l_tx, l_wallet_addr, l_coin_back) == -1) { dap_chain_datum_tx_delete(l_tx); - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_RETURNING_COINS_OUTPUT, + "Can't create new TX. Something went wrong.\n"); log_it(L_ERROR, "Can't add returning coins output"); DAP_DELETE(l_wallet_addr); dap_chain_wallet_close(l_wallet); DAP_DEL_Z(l_wallet_pkey); - return -22; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_RETURNING_COINS_OUTPUT-22; } DAP_DELETE(l_wallet_addr); // Network fee @@ -5377,18 +5395,18 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) dap_chain_datum_tx_delete(l_tx); dap_chain_wallet_close(l_wallet); DAP_DEL_Z(l_wallet_pkey); - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_NETWORK_FEE_OUTPUT, "Can't create new TX. Something went wrong.\n"); log_it(L_ERROR, "Cant add network fee output"); - return -23; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_NETWORK_FEE_OUTPUT; } // Validator's fee if (dap_chain_datum_tx_add_fee_item(&l_tx, l_value_fee) == -1) { dap_chain_datum_tx_delete(l_tx); dap_chain_wallet_close(l_wallet); DAP_DEL_Z(l_wallet_pkey); - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_VALIDATORS_FEE_OUTPUT, "Can't create new TX. Something went wrong.\n"); log_it(L_ERROR, "Cant add validator's fee output"); - return -24; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_VALIDATORS_FEE_OUTPUT; } // add 'sign' items @@ -5396,9 +5414,9 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) if(dap_chain_datum_tx_add_sign_item(&l_tx, l_owner_key) != 1) { dap_chain_datum_tx_delete(l_tx); dap_enc_key_delete(l_owner_key); - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_SIGN_OUTPUT, "Can't create new TX. Something went wrong.\n"); log_it( L_ERROR, "Can't add sign output"); - return -25; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_SIGN_OUTPUT; } dap_chain_wallet_close(l_wallet); @@ -5409,21 +5427,27 @@ int com_tx_cond_remove(int a_argc, char ** a_argv, void **a_str_reply) dap_chain_datum_tx_delete(l_tx); dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_TX); if (!l_chain) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_FIND_DEFAULT_CHAIN_WITH_TX_FOR_NET, + "Can't create new TX. Something went wrong.\n"); DAP_DELETE(l_datum); - return -26; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_FIND_DEFAULT_CHAIN_WITH_TX_FOR_NET; } // Processing will be made according to autoprocess policy char *l_hash_str = dap_chain_mempool_datum_add(l_datum, l_chain, "hex"); DAP_DELETE(l_datum); if (l_hash_str) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Successfuly created transaction with hash %s\n", l_hash_str); + json_object *l_jobj_ret = json_object_new_object(); + json_object *l_jobj_tx_status = json_object_new_boolean(true); + json_object *l_jobj_tx_hash = json_object_new_string(l_hash_str); + json_object_object_add(l_jobj_ret, "tx_create", l_jobj_tx_status); + json_object_object_add(l_jobj_ret, "hash", l_jobj_tx_hash); DAP_DELETE(l_hash_str); - return 0; + json_object_array_add(*reply, l_jobj_ret); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OK; } - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't create new TX. Something went wrong.\n"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OTHER_ERROR, "Can't create new TX. Something went wrong."); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OTHER_ERROR; } typedef struct tx_check_args { @@ -5444,10 +5468,9 @@ void s_tx_is_srv_pay_check (dap_chain_net_t* a_net, dap_chain_datum_tx_t *a_tx, } -int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply) +int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **reply) { (void) a_argc; - void** l_str_reply = a_str_reply; int arg_index = 1; const char *c_wallets_path = dap_chain_wallet_get_path(g_config); const char * l_wallet_str = NULL; @@ -5459,8 +5482,9 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply) if(!l_hash_out_type) l_hash_out_type = "hex"; if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Invalid parameter -H, valid values: -H <hex | base58>"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_HEX, + "Invalid parameter -H, valid values: -H <hex | base58>"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_HEX; } // Public certifiacte of condition owner @@ -5471,36 +5495,41 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv_uid", &l_srv_uid_str); if (!l_wallet_str) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-w'"); - return -3; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_W, + "com_txs_cond_remove requires parameter '-w'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_W; } if(!l_net_name) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-net'"); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_NET, + "com_txs_cond_remove requires parameter '-net'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_NET; } if(!l_srv_uid_str) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "com_txs_cond_remove requires parameter '-srv_uid'"); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_SRV_UID, + "com_txs_cond_remove requires parameter '-srv_uid'"); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_SRV_UID; } dap_chain_net_srv_uid_t l_srv_uid = {}; l_srv_uid.uint64 = strtoll(l_srv_uid_str, NULL, 10); if (!l_srv_uid.uint64) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find service UID %s ", l_srv_uid_str); - return -8; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_SERVICE_UID, + "Can't find service UID %s ", l_srv_uid_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_SERVICE_UID; } dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name(l_net_name) : NULL; if(!l_net) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find net '%s'", l_net_name); - return -11; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NET, + "Can't find net '%s'", l_net_name); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NET; } dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, c_wallets_path); const char* l_sign_str = ""; if(!l_wallet) { - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't open wallet '%s'", l_wallet_str); - return -12; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_OPEN_WALLET, "Can't open wallet '%s'", l_wallet_str); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_OPEN_WALLET; } dap_enc_key_t *l_key_from = dap_chain_wallet_get_key(l_wallet, 0); @@ -5508,16 +5537,18 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply) const char *l_native_ticker = l_net->pub.native_ticker; if (!l_native_ticker){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find native ticker for net %s", l_net->pub.name); - return -16; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NATIVE_TICKER_IN_NET, + "Can't find native ticker for net %s", l_net->pub.name); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NATIVE_TICKER_IN_NET; } dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net->pub.name); if (!l_ledger){ - dap_cli_server_cmd_set_reply_text(l_str_reply, "Can't find ledger for net %s", l_net->pub.name); - return -17; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_LEDGER_FOR_NET, "Can't find ledger for net %s", l_net->pub.name); + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_LEDGER_FOR_NET; } - dap_string_t *l_reply_str = dap_string_new(""); +// dap_string_t *l_reply_str = dap_string_new(""); + json_object *l_jobj_tx_list_cond_outs = json_object_new_array(); dap_list_t *l_tx_list = NULL; dap_chain_net_get_tx_all(l_net, TX_SEARCH_TYPE_NET, s_tx_is_srv_pay_check, &l_tx_list); @@ -5570,19 +5601,38 @@ int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply) dap_chain_hash_fast_to_str(&l_data_tx->tx_hash, l_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); l_remain_coins_str = dap_chain_balance_to_coins(l_out_cond->header.value); l_remain_datoshi_str = dap_chain_balance_print(l_out_cond->header.value); - - dap_string_append_printf(l_reply_str, "Tx %s has %s (%s) %s remaining in cond out\n", l_hash_str, l_remain_coins_str, l_remain_datoshi_str, l_native_ticker); + json_object *l_jobj_hash = json_object_new_string(l_hash_str); + json_object *l_jobj_remain = json_object_new_object(); + json_object *l_jobj_remain_coins = json_object_new_string(l_remain_coins_str); + json_object *l_jobj_remain_datoshi = json_object_new_string(l_remain_datoshi_str); + json_object_object_add(l_jobj_remain, "coins", l_jobj_remain_coins); + json_object_object_add(l_jobj_remain, "datoshi", l_jobj_remain_datoshi); + json_object *l_jobj_native_ticker = json_object_new_string(l_native_ticker); + json_object *l_jobj_tx = json_object_new_object(); + json_object_object_add(l_jobj_tx, "hash", l_jobj_hash); + json_object_object_add(l_jobj_tx, "remain", l_jobj_remain); + json_object_object_add(l_jobj_tx, "ticker", l_jobj_native_ticker); + json_object_array_add(l_jobj_tx_list_cond_outs, l_jobj_tx); l_tx_count++; SUM_256_256(l_total_value, l_out_cond->header.value, &l_total_value); } char *l_total_datoshi_str = dap_chain_balance_to_coins(l_total_value); - char *l_total_coins_str = dap_chain_balance_print(l_total_value); - dap_string_append_printf(l_reply_str, "\n\nFound %"DAP_UINT64_FORMAT_U" transactions with total value %s (%s) %s", l_tx_count, l_total_datoshi_str, l_total_coins_str, l_native_ticker); + char *l_total_coins_str = dap_chain_balance_print(l_total_value); + json_object *l_jobj_total = json_object_new_object(); + json_object *l_jobj_total_datoshi = json_object_new_string(l_total_datoshi_str); + json_object *l_jobj_total_coins = json_object_new_string(l_total_coins_str); + json_object *l_jobj_native_ticker = json_object_new_string(l_native_ticker); + json_object_object_add(l_jobj_total, "datoshi", l_jobj_total_datoshi); + json_object_object_add(l_jobj_total, "coins", l_jobj_total_coins); + json_object_object_add(l_jobj_total, "ticker", l_jobj_native_ticker); + json_object *l_jobj_ret = json_object_new_object(); + json_object_object_add(l_jobj_ret, "transactions_out_cond", l_jobj_tx_list_cond_outs); + json_object_object_add(l_jobj_ret, "total", l_jobj_total); dap_list_free_full(l_tx_list, NULL); - *l_str_reply = dap_string_free(l_reply_str, false); + json_object_array_add(*reply, l_jobj_ret); DAP_DEL_Z(l_wallet_pkey); dap_chain_wallet_close(l_wallet); - return 0; + return DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_OK; } typedef enum cmd_mempool_add_ca_error_list{ COM_MEMPOOL_ADD_CA_ERROR_NET_NOT_FOUND = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, @@ -5927,10 +5977,9 @@ static dap_pkey_t* s_json_get_pkey(struct json_object *a_json) * @param str_reply * @return int */ -int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) +int com_tx_create_json(int a_argc, char ** a_argv, void **reply) { int l_arg_index = 1; - int l_err_code = 0; const char *l_net_name = NULL; // optional parameter const char *l_chain_name = NULL; // optional parameter const char *l_json_file_path = NULL; @@ -5942,19 +5991,21 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-json", &l_json_file_path); if(!l_json_file_path) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command requires one of parameters '-json <json file path>'"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON, + "Command requires one of parameters '-json <json file path>'"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON; } // Open json file struct json_object *l_json = json_object_from_file(l_json_file_path); if(!l_json) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't open json file: %s", json_util_get_last_err()); - return -2; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE, + "Can't open json file: %s", json_util_get_last_err()); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE; } if(!json_object_is_type(l_json, json_type_object)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong json format"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT, "Wrong json format"); json_object_put(l_json); - return -3; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT; } @@ -5965,17 +6016,18 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) l_net_name = json_object_get_string(l_json_net); } if(!l_net_name) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command requires parameter '-net' or set net in the json file"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET, + "Command requires parameter '-net' or set net in the json file"); json_object_put(l_json); - return -11; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET; } } dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_name); l_native_token = l_net->pub.native_ticker; if(!l_net) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Not found net by name '%s'", l_net_name); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME, "Not found net by name '%s'", l_net_name); json_object_put(l_json); - return -12; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME; } // Read chain from json file @@ -5990,9 +6042,10 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_TX); } if(!l_chain) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Chain name '%s' not found, try use parameter '-chain' or set chain in the json file", l_chain_name); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME, + "Chain name '%s' not found, try use parameter '-chain' or set chain in the json file", l_chain_name); json_object_put(l_json); - return -13; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME; } @@ -6001,17 +6054,19 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) size_t l_items_count = json_object_array_length(l_json_items); bool a = (l_items_count = json_object_array_length(l_json_items)); if(!l_json_items || !json_object_is_type(l_json_items, json_type_array) || !(l_items_count = json_object_array_length(l_json_items))) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong json format: not found array 'items' or array is empty"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS, + "Wrong json format: not found array 'items' or array is empty"); json_object_put(l_json); - return -15; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS; } log_it(L_ERROR, "Json TX: found %lu items", l_items_count); // Create transaction dap_chain_datum_tx_t *l_tx = DAP_NEW_Z_SIZE(dap_chain_datum_tx_t, sizeof(dap_chain_datum_tx_t)); if(!l_tx) { - log_it(L_CRITICAL, "Memory allocation error"); - return -16; + json_object_put(l_json); + dap_json_rpc_allocation_error; + return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; } l_tx->header.ts_created = time(NULL); size_t l_items_ready = 0; @@ -6021,7 +6076,8 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) dap_list_t *l_tsd_list = NULL;// list tsd sections uint256_t l_value_need = { };// how many tokens are needed in the 'out' item uint256_t l_value_need_fee = {}; - dap_string_t *l_err_str = dap_string_new("Errors: \n"); + json_object *l_jobj_errors = json_object_new_array(); +// dap_string_t *l_err_str = dap_string_new("Errors: \n"); // Creating and adding items to the transaction for(size_t i = 0; i < l_items_count; ++i) { struct json_object *l_json_item_obj = json_object_array_get_idx(l_json_items, i); @@ -6063,8 +6119,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) // Create OUT item dap_chain_tx_out_t *l_out_item = dap_chain_datum_tx_item_out_create(l_addr, l_value); if (!l_out_item) { - dap_string_append_printf(l_err_str, "Failed to create transaction out. " - "There may not be enough funds in the wallet.\n"); + json_object *l_jobj_err = json_object_new_string("Failed to create transaction out. " + "There may not be enough funds in the wallet."); + json_object_array_add(l_jobj_errors, l_jobj_err); } l_item = (const uint8_t*) l_out_item; } @@ -6076,10 +6133,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) // Create OUT_EXT item dap_chain_tx_out_ext_t *l_out_ext_item = dap_chain_datum_tx_item_out_ext_create(l_addr, l_value, l_token); if (!l_out_ext_item) { - dap_string_append_printf(l_err_str, "Failed to create a out ext" + json_object *l_jobj_err = json_object_new_string("Failed to create a out ext" "for a transaction. There may not be enough funds " "on the wallet or the wrong ticker token " - "is indicated.\n"); + "is indicated."); + json_object_array_add(l_jobj_errors, l_jobj_err); } l_item = (const uint8_t*) l_out_ext_item; } @@ -6099,9 +6157,12 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) else if(l_item_type == TX_ITEM_TYPE_OUT_EXT) { log_it(L_WARNING, "Invalid 'out_ext' item %zu", i); } - dap_string_append_printf(l_err_str, "For item %zu of type 'out' or 'out_ext' the " + char *l_str_err = dap_strdup_printf("For item %zu of type 'out' or 'out_ext' the " "string representation of the address could not be converted, " - "or the size of the output sum is 0.\n", i); + "or the size of the output sum is 0.", i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + json_object_array_add(l_jobj_errors, l_jobj_err); continue; } } @@ -6152,8 +6213,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) if(l_item) { SUM_256_256(l_value_need, l_value, &l_value_need); } else { - dap_string_append_printf(l_err_str, "Unable to create conditional out for transaction " + char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " "can of type %s described in item %zu.\n", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + json_object_array_add(l_jobj_errors, l_jobj_err); } DAP_DELETE(l_pkey); } @@ -6188,8 +6252,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) if(l_item) { SUM_256_256(l_value_need, l_value, &l_value_need); } else { - dap_string_append_printf(l_err_str, "Unable to create conditional out for transaction " - "can of type %s described in item %zu.\n", l_subtype_str, i); + char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " + "can of type %s described in item %zu.", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + json_object_array_add(l_jobj_errors, l_jobj_err); } } break; @@ -6229,8 +6296,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) if(l_item) { SUM_256_256(l_value_need, l_value, &l_value_need); } else { - dap_string_append_printf(l_err_str, "Unable to create conditional out for transaction " - "can of type %s described in item %zu.\n", l_subtype_str, i); + char *l_err_str = dap_strdup_printf("Unable to create conditional out for transaction " + "can of type %s described in item %zu.", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_err_str); + DAP_DELETE(l_err_str); + json_object_array_add(l_jobj_errors, l_jobj_err); } } } @@ -6245,8 +6315,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) if(l_item) { SUM_256_256(l_value_need_fee, l_value, &l_value_need_fee); } else { - dap_string_append_printf(l_err_str, "Unable to create conditional out for transaction " - "can of type %s described in item %zu.\n", l_subtype_str, i); + char *l_str_err = dap_strdup_printf("Unable to create conditional out for transaction " + "can of type %s described in item %zu.", l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + json_object_array_add(l_jobj_errors, l_jobj_err); + DAP_DELETE(l_str_err); } } else @@ -6255,8 +6328,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) break; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED: log_it(L_WARNING, "Undefined subtype: '%s' of 'out_cond' item %zu ", l_subtype_str, i); - dap_string_append_printf(l_err_str, "Specified unknown sub type %s of conditional out " - "on item %zu.\n", l_subtype_str, i); + char *l_str_err = dap_strdup_printf("Specified unknown sub type %s of conditional out on item %zu.", + l_subtype_str, i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + json_object_array_add(l_jobj_errors, l_jobj_err); break; } } @@ -6295,8 +6371,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) if(l_item) l_receipt_count++; else { - dap_string_append_printf(l_err_str, "Unable to create receipt out for transaction " - "described by item %zu.\n", i); + char *l_str_err = dap_strdup_printf("Unable to create receipt out for transaction " + "described by item %zu.", i); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + json_object_array_add(l_jobj_errors, l_jobj_err); } } break; @@ -6347,12 +6426,13 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) // Create IN item dap_chain_tx_in_t *l_in_item = dap_chain_datum_tx_item_in_create(&l_tx_prev_hash, (uint32_t) l_out_prev_idx); if (!l_in_item) { - dap_string_append_printf(l_err_str, "Unable to create in for transaction.\n"); + json_object *l_jobj_err = json_object_new_string("Unable to create in for transaction."); + json_object_array_add(l_jobj_errors, l_jobj_err); } } else { log_it(L_WARNING, "Invalid 'in' item, bad prev_hash %s", l_prev_hash_str); - dap_string_append_printf(l_err_str, "Unable to create in for transaction. Invalid 'in' item, " - "bad prev_hash %s\n", l_prev_hash_str); + char *l_str_err = dap_strdup_printf("Unable to create in for transaction. Invalid 'in' item, " + "bad prev_hash %s", l_prev_hash_str); // Go to the next item l_list = dap_list_next(l_list); continue; @@ -6369,8 +6449,11 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) if (!l_addr_from) { log_it(L_WARNING, "Invalid element 'in', unable to convert string representation of addr_from: '%s' " "to binary.", l_json_item_addr_str); - dap_string_append_printf(l_err_str, "Invalid element 'to', unable to convert string representation " - "of addr_from: '%s' to binary.\n", l_json_item_addr_str); + char *l_str_err = dap_strdup_printf("Invalid element 'to', unable to convert string representation " + "of addr_from: '%s' to binary.", l_json_item_addr_str); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + json_object_array_add(l_jobj_errors, l_jobj_err); // Go to the next item l_list = dap_list_next(l_list); continue; @@ -6378,22 +6461,27 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) } else { log_it(L_WARNING, "Invalid 'in' item, incorrect addr_from: '%s'", l_json_item_addr_str ? l_json_item_addr_str : "[null]"); - dap_string_append_printf(l_err_str, "Invalid 'in' item, incorrect addr_from: '%s'\n", + char *l_str_err = dap_strdup_printf("Invalid 'in' item, incorrect addr_from: '%s'", l_json_item_addr_str ? l_json_item_addr_str : "[null]"); + json_object *l_jobj_err = json_object_new_string(l_str_err); + DAP_DELETE(l_str_err); + json_object_array_add(l_jobj_errors, l_jobj_err); // Go to the next item l_list = dap_list_next(l_list); continue; } if(!l_json_item_token) { log_it(L_WARNING, "Invalid 'in' item, not found token name"); - dap_string_append_printf(l_err_str, "Invalid 'in' item, not found token name\n"); + json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found token name"); + json_object_array_add(l_jobj_errors, l_jobj_err); // Go to the next item l_list = dap_list_next(l_list); continue; } if(IS_ZERO_256(l_value_need)) { log_it(L_WARNING, "Invalid 'in' item, not found value in out items"); - dap_string_append_printf(l_err_str, "Invalid 'in' item, not found value in out items\n"); + json_object *l_jobj_err = json_object_new_string("Invalid 'in' item, not found value in out items"); + json_object_array_add(l_jobj_errors, l_jobj_err); // Go to the next item l_list = dap_list_next(l_list); continue; @@ -6414,8 +6502,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) l_addr_from, l_value_need_check, &l_value_transfer); if(!l_list_used_out) { log_it(L_WARNING, "Not enough funds in previous tx to transfer"); - dap_string_append_printf(l_err_str, "Can't create in transaction. Not enough funds in previous tx " - "to transfer\n"); + json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds in previous tx " + "to transfer"); + json_object_array_add(l_jobj_errors, l_jobj_err); // Go to the next item l_list = dap_list_next(l_list); continue; @@ -6426,8 +6515,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) l_addr_from, l_value_need, &l_value_transfer); if(!l_list_used_out) { log_it(L_WARNING, "Not enough funds in previous tx to transfer"); - dap_string_append_printf(l_err_str, "Can't create in transaction. Not enough funds in previous tx " - "to transfer\n"); + json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds " + "in previous tx to transfer"); + json_object_array_add(l_jobj_errors, l_jobj_err); // Go to the next item l_list = dap_list_next(l_list); continue; @@ -6437,8 +6527,9 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) l_addr_from, l_value_need_fee, &l_value_transfer_fee); if(!l_list_used_out_fee) { log_it(L_WARNING, "Not enough funds in previous tx to transfer"); - dap_string_append_printf(l_err_str, "Can't create in transaction. Not enough funds in previous tx " - "to transfer\n"); + json_object *l_jobj_err = json_object_new_string("Can't create in transaction. Not enough funds " + "in previous tx to transfer"); + json_object_array_add(l_jobj_errors, l_jobj_err); // Go to the next item l_list = dap_list_next(l_list); continue; @@ -6510,7 +6601,8 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) l_enc_key = l_cert->enc_key; } else{ - dap_string_append_printf(l_err_str, "Can't create sign for transactions.\n"); + json_object *l_jobj_err = json_object_new_string("Can't create sign for transactions."); + json_object_array_add(l_jobj_errors, l_jobj_err); log_it(L_ERROR, "Json TX: Item sign has no wallet or cert of they are invalid "); l_list = dap_list_next(l_list); continue; @@ -6536,14 +6628,21 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) dap_list_free(l_sign_list); json_object_put(l_json); + json_object *l_jobj_ret = json_object_new_object(); + if(l_items_ready<l_items_count) { - if(!l_items_ready) - dap_cli_server_cmd_set_reply_text(a_str_reply, "No valid items found to create a transaction"); - else - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create transaction, because only %zu items out of %zu are valid",l_items_ready,l_items_count); + json_object *l_tx_create = json_object_new_boolean(false); + json_object *l_jobj_valid_items = json_object_new_uint64(l_items_ready); + json_object *l_jobj_total_items = json_object_new_uint64(l_items_count); + json_object_object_add(l_jobj_ret, "tx_create", l_tx_create); + json_object_object_add(l_jobj_ret, "valid_items", l_jobj_valid_items); + json_object_object_add(l_jobj_ret, "total_items", l_jobj_total_items); + json_object_object_add(l_jobj_ret, "errors", l_jobj_errors); + json_object_array_add(*reply, l_jobj_ret); DAP_DELETE(l_tx); - return -30; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS; } + json_object_put(l_jobj_errors); // Pack transaction into the datum dap_chain_datum_t *l_datum_tx = dap_chain_datum_create(DAP_CHAIN_DATUM_TX, l_tx, dap_chain_datum_tx_get_size(l_tx)); @@ -6559,12 +6658,19 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) DAP_DEL_Z(l_datum_tx); DAP_DELETE(l_gdb_group_mempool_base_tx); if(!l_placed) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't add transaction to mempool"); - return -90; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL, + "Can't add transaction to mempool"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL; } // Completed successfully - dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s with %zu items created and added to mempool successfully", l_tx_hash_str, l_items_ready); - return l_err_code; + json_object *l_jobj_tx_create = json_object_new_boolean(true); + json_object *l_jobj_hash = json_object_new_string(l_tx_hash_str); + json_object *l_jobj_total_items = json_object_new_uint64(l_items_ready); + json_object_object_add(l_jobj_ret, "tx_create", l_jobj_tx_create); + json_object_object_add(l_jobj_ret, "hash", l_jobj_hash); + json_object_object_add(l_jobj_ret, "total_items", l_jobj_total_items); + json_object_array_add(*reply, l_jobj_ret); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK; } /** @@ -6576,7 +6682,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_str_reply) * @param str_reply * @return int */ -int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) +int com_tx_create(int a_argc, char **a_argv, void **reply) { int arg_index = 1; // int cmd_num = 1; @@ -6603,15 +6709,15 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) if(!l_hash_out_type) l_hash_out_type = "hex"; if(dap_strcmp(l_hash_out_type,"hex") && dap_strcmp(l_hash_out_type,"base58")) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid parameter -H, valid values: -H <hex | base58>"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_HASH_INVALID, "Invalid parameter -H, valid values: -H <hex | base58>"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_HASH_INVALID; } dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_name); dap_chain_net_t * l_net = dap_chain_net_by_name(l_net_name); if (l_net == NULL) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "not found net by name '%s'", l_net_name); - return -7; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NET_NOT_FOUND, "not found net by name '%s'", l_net_name); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NET_NOT_FOUND; } uint256_t l_value = {}; @@ -6632,19 +6738,13 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &str_tmp)) l_value_fee = dap_chain_balance_scan(str_tmp); if (IS_ZERO_256(l_value_fee) && (!l_emission_hash_str || (str_tmp && strcmp(str_tmp, "0")))) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "tx_create requires parameter '-fee' to be valid uint256"); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_FEE_IS_UINT256, "tx_create requires parameter '-fee' to be valid uint256"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_FEE_IS_UINT256; } if((!l_from_wallet_name && !l_emission_hash_str)||(l_from_wallet_name && l_emission_hash_str)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires one of parameters '-from_wallet' or '-from_emission'"); - return -1; - } - - if(!l_net_name) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-net'"); - return -6; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_WALLET_OR_FROM_EMISSION, "tx_create requires one of parameters '-from_wallet' or '-from_emission'"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_WALLET_OR_FROM_EMISSION; } const char *c_wallets_path = dap_chain_wallet_get_path(g_config); @@ -6652,9 +6752,10 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) dap_chain_t *l_emission_chain = NULL; if (l_emission_hash_str) { if (dap_chain_hash_fast_from_str(l_emission_hash_str, &l_emission_hash)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-from_emission' " - "to be valid string containing hash in hex or base58 format"); - return -3; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_EMISSION, + "tx_create requires parameter '-from_emission' " + "to be valid string containing hash in hex or base58 format"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_EMISSION; } if (l_emission_chain_name) { l_emission_chain = dap_chain_net_get_chain_by_name(l_net, l_emission_chain_name); @@ -6662,56 +6763,58 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) l_emission_chain = dap_chain_net_get_default_chain_by_chain_type(l_net,CHAIN_TYPE_EMISSION); } if (!l_emission_chain) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-chain_emission' " - "to be a valid chain name or set default datum type in chain configuration file"); - return -9; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_CHAIN_EMISSION, + "tx_create requires parameter '-chain_emission' " + "to be a valid chain name or set default datum type in chain configuration file"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_CHAIN_EMISSION; } if (l_wallet_fee_name){ l_wallet_fee = dap_chain_wallet_open(l_wallet_fee_name, c_wallets_path); if (!l_wallet_fee) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Wallet %s does not exist", l_wallet_fee_name); - return -12; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_WALLET_FEE, + "Wallet %s does not exist", l_wallet_fee_name); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_WALLET_FEE; } l_priv_key = dap_chain_wallet_get_key(l_wallet_fee, 0); } else if (l_cert_str) { l_cert = dap_cert_find_by_name(l_cert_str); if (!l_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Certificate %s is invalid", l_cert_str); - return -5; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CERT_IS_INVALID, "Certificate %s is invalid", l_cert_str); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CERT_IS_INVALID; } l_priv_key = l_cert->enc_key; } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_CERT_OR_WALLET_FEE, "tx_create requires parameter '-cert' or '-wallet_fee' for create base tx for emission"); - return -10; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_CERT_OR_WALLET_FEE; } } else { dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-token", &l_token_ticker); if (!l_token_ticker) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-token'"); - return -3; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_TOKEN, "tx_create requires parameter '-token'"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_TOKEN; } if (!dap_ledger_token_ticker_check(l_net->pub.ledger, l_token_ticker)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Ticker '%s' is not declared on network '%s'.", - l_token_ticker, l_net_name); - return -16; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_TOKEN_NOT_DECLARATED_IN_NET, + "Ticker '%s' is not declared on network '%s'.", l_token_ticker, l_net_name); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_TOKEN_NOT_DECLARATED_IN_NET; } dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_addr", &addr_base58_to); if (!addr_base58_to) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-to_addr'"); - return -2; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_TO_ADDR, "tx_create requires parameter '-to_addr'"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_TO_ADDR; } l_addr_to = dap_chain_addr_from_str(addr_base58_to); if(!l_addr_to) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "destination address is invalid"); - return -11; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID, "destination address is invalid"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID; } if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &str_tmp)) l_value = dap_chain_balance_scan(str_tmp); if (IS_ZERO_256(l_value)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_create requires parameter '-value' to be valid uint256 value"); - return -4; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE, "tx_create requires parameter '-value' to be valid uint256 value"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE; } } @@ -6723,32 +6826,40 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) } if(!l_chain) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "not found chain name '%s', try use parameter '-chain' or set default datum type in chain configuration file", + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN, + "not found chain name '%s', try use parameter '-chain' or set default datum type in chain configuration file", l_chain_name); - return -8; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN; } - dap_string_t *l_string_ret = dap_string_new(NULL); - int l_ret = 0; + int l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_OK; if (l_emission_hash_str) { char *l_tx_hash_str = NULL; if (!l_priv_key) { - dap_string_append_printf(l_string_ret, "No private key defined for creating the underlying " + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NO_PRIVATE_KEY_DEFINED, "No private key defined for creating the underlying " "transaction no '-wallet_fee' or '-cert' parameter specified."); - l_ret = -10; + l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NO_PRIVATE_KEY_DEFINED; } l_tx_hash_str = dap_chain_mempool_base_tx_create(l_chain, &l_emission_hash, l_emission_chain->id, uint256_0, NULL, NULL, // Get this params from emission itself l_priv_key, l_hash_out_type, l_value_fee); + json_object *l_jobj_emission = json_object_new_object(); + json_object *l_jobj_emi_status = NULL; + json_object *l_jobj_emi_hash = NULL; if (l_tx_hash_str) { - dap_string_append_printf(l_string_ret, "\nDatum %s with 256bit TX is placed in datum pool\n", l_tx_hash_str); + l_jobj_emi_status = json_object_new_string("Ok"); + l_jobj_emi_hash = json_object_new_string(l_tx_hash_str); DAP_DELETE(l_tx_hash_str); + json_object_object_add(l_jobj_emission, "emission", l_jobj_emi_status); + json_object_object_add(l_jobj_emission, "hash", l_jobj_emi_hash); } else { - dap_string_append_printf(l_string_ret, "\nCan't place TX datum in mempool, examine log files\n"); - l_ret = -15; + l_jobj_emi_status = json_object_new_string("False"); + json_object_object_add(l_jobj_emission, "emission", l_jobj_emi_status); + json_object *l_jobj_msg = json_object_new_string("Can't place TX datum in mempool, examine log files\n"); + json_object_object_add(l_jobj_emission, "message", l_jobj_msg); + l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_ADD_DATUM_IN_MEMPOOL; } - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_string_ret->str); - dap_string_free(l_string_ret, true); + json_object_array_add(*reply, l_jobj_emission); DAP_DELETE(l_addr_to); if (l_wallet_fee) { dap_chain_wallet_close(l_wallet_fee); @@ -6760,16 +6871,17 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) dap_chain_wallet_t * l_wallet = dap_chain_wallet_open(l_from_wallet_name, c_wallets_path); if(!l_wallet) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "wallet %s does not exist", l_from_wallet_name); - return -9; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST, + "wallet %s does not exist", l_from_wallet_name); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST; } else { - dap_string_append(l_string_ret, dap_chain_wallet_check_sign(l_wallet)); + json_object *l_jobj_check_wallet = json_object_new_string(dap_chain_wallet_check_sign(l_wallet)); } const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id); if(!addr_from) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "source address is invalid"); - return -10; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID, "source address is invalid"); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID; } if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr_to)) { @@ -6785,35 +6897,42 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) dap_string_append_printf(l_allowed_list, "0x%016"DAP_UINT64_FORMAT_X, l_net->pub.id.uint64); for (dap_list_t *it = l_net->pub.bridged_networks; it; it = it->next) dap_string_append_printf(l_allowed_list, ", 0x%016"DAP_UINT64_FORMAT_X, ((dap_chain_net_id_t *)it->data)->uint64); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Destination network ID=0x%"DAP_UINT64_FORMAT_x - " is unreachable. List of available network IDs:\n%s" - " Please, change network name or wallet address", - l_addr_to->net_id.uint64, l_allowed_list->str); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE, + "Destination network ID=0x%"DAP_UINT64_FORMAT_x + " is unreachable. List of available network IDs:\n%s" + " Please, change network name or wallet address", + l_addr_to->net_id.uint64, l_allowed_list->str); dap_string_free(l_allowed_list, true); - return -13; + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE; } } + json_object *l_jobj_transfer_status = NULL; + json_object *l_jobj_tx_hash = NULL; + json_object *l_jobj_result = json_object_new_object(); + l_priv_key = dap_chain_wallet_get_key(l_wallet, 0); if(l_tx_num){ l_ret = dap_chain_mempool_tx_create_massive(l_chain, l_priv_key, addr_from, l_addr_to, l_token_ticker, l_value, l_value_fee, l_tx_num); - - dap_string_append_printf(l_string_ret, "transfer=%s\n", - (l_ret == 0) ? "Ok" : (l_ret == -2) ? "False, not enough funds for transfer" : "False"); + l_jobj_transfer_status = json_object_new_string((l_ret == 0) ? "Ok" : (l_ret == -2) ? "False, not enough funds for transfer" : "False"); + json_object_object_add(l_jobj_result, "transfer", l_jobj_transfer_status); } else { char *l_tx_hash_str = dap_chain_mempool_tx_create(l_chain, l_priv_key, addr_from, l_addr_to, l_token_ticker, l_value, l_value_fee, l_hash_out_type); if (l_tx_hash_str) { - dap_string_append_printf(l_string_ret, "transfer=Ok\ntx_hash=%s\n",l_tx_hash_str); + l_jobj_transfer_status = json_object_new_string("Ok"); + l_jobj_tx_hash = json_object_new_string(l_tx_hash_str); + json_object_object_add(l_jobj_result, "transfer", l_jobj_transfer_status); + json_object_object_add(l_jobj_result, "hash", l_jobj_tx_hash); DAP_DELETE(l_tx_hash_str); } else { - dap_string_append_printf(l_string_ret, "transfer=False\n"); - l_ret = -14; + l_jobj_transfer_status = json_object_new_string("False"); + json_object_object_add(l_jobj_result, "transfer", l_jobj_transfer_status); + l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_CREATE_TRANSACTION; } } - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_string_ret->str); - dap_string_free(l_string_ret, true); + json_object_array_add(*reply, l_jobj_result); DAP_DELETE(l_addr_to); dap_chain_wallet_close(l_wallet); @@ -6832,7 +6951,7 @@ int com_tx_create(int a_argc, char **a_argv, void **a_str_reply) * @param str_reply * @return int */ -int com_tx_verify(int a_argc, char **a_argv, void **a_str_reply) +int com_tx_verify(int a_argc, char **a_argv, void **reply) { const char * l_tx_hash_str = NULL; dap_chain_net_t * l_net = NULL; @@ -6841,41 +6960,63 @@ int com_tx_verify(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-tx", &l_tx_hash_str); if(!l_tx_hash_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "tx_verify requires parameter '-tx'"); - return -1; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_REQUIRE_PARAMETER_TX, "tx_verify requires parameter '-tx'"); + return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_REQUIRE_PARAMETER_TX; } - dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net); + dap_chain_node_cli_cmd_values_parse_net_chain_for_json(&l_arg_index, a_argc, a_argv, &l_chain, &l_net); if (!l_net || !l_chain) { - return -2; - } else if (a_str_reply && *a_str_reply) { - DAP_DELETE(*a_str_reply); - *a_str_reply = NULL; + return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_NET_CHAIN_UNDEFINED; } dap_hash_fast_t l_tx_hash; char *l_hex_str_from58 = NULL; if (dap_chain_hash_fast_from_hex_str(l_tx_hash_str, &l_tx_hash)) { l_hex_str_from58 = dap_enc_base58_to_hex_str_from_str(l_tx_hash_str); if (dap_chain_hash_fast_from_hex_str(l_hex_str_from58, &l_tx_hash)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid tx hash format, need hex or base58"); - return -3; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_INVALID_TX_HASH, "Invalid tx hash format, need hex or base58"); + return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_INVALID_TX_HASH; } } - size_t l_tx_size = 0; + size_t l_datum_size = 0; char *l_gdb_group = dap_chain_net_get_gdb_group_mempool_new(l_chain); - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) - dap_global_db_get_sync(l_gdb_group, l_hex_str_from58 ? l_hex_str_from58 : l_tx_hash_str, &l_tx_size, NULL, NULL ); + dap_chain_datum_t *l_datum = (dap_chain_datum_t*)dap_global_db_get_sync(l_gdb_group, l_hex_str_from58 ? l_hex_str_from58 : l_tx_hash_str, &l_datum_size, NULL, NULL); DAP_DEL_Z(l_hex_str_from58); - if (!l_tx) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx not found"); - return -3; - } - int l_ret = dap_ledger_tx_add_check(l_net->pub.ledger, l_tx, l_tx_size, &l_tx_hash); + if (!l_datum) { + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_SPECIFIED_TX_NOT_FOUND, "Specified tx not found"); + return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_SPECIFIED_TX_NOT_FOUND; + } + if (l_datum->header.type_id != DAP_CHAIN_DATUM_TX){ + char *l_str_err = dap_strdup_printf("Based on the specified hash, the type %s was found and not a transaction.", + dap_chain_datum_type_id_to_str(l_datum->header.type_id)); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_HASH_IS_NOT_TX_HASH, l_str_err); + DAP_DELETE(l_str_err); + return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_HASH_IS_NOT_TX_HASH; + } + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data; + int l_ret = dap_ledger_tx_add_check(l_net->pub.ledger, l_tx, l_datum->header.data_size, &l_tx_hash); + json_object *l_obj_ret = json_object_new_object(); + json_object *l_obj_hash = json_object_new_string(l_tx_hash_str); + json_object_object_add(l_obj_ret, "hash", l_obj_hash); + json_object *l_jobj_verfiy = NULL; + json_object *l_jobj_error = NULL; if (l_ret) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx verify fail with return code=%d", l_ret); - return -4; + l_jobj_verfiy = json_object_new_boolean(false); + l_jobj_error = json_object_new_object(); + json_object *l_jobj_err_str = json_object_new_string(dap_ledger_tx_check_err_str(l_ret)); + json_object *l_jobj_err_code = json_object_new_int64(l_ret); + json_object_object_add(l_jobj_error, "code", l_jobj_err_code); + json_object_object_add(l_jobj_error, "message", l_jobj_err_str); + json_object_object_add(l_obj_ret, "verify", l_jobj_verfiy); + json_object_object_add(l_obj_ret, "error", l_jobj_error); + json_object_array_add(*reply, l_obj_ret); + return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_TX_NOT_VERIFY; + } else { + l_jobj_verfiy = json_object_new_boolean(true); + l_jobj_error = json_object_new_null(); + json_object_object_add(l_obj_ret, "verify", l_jobj_verfiy); + json_object_object_add(l_obj_ret, "error", l_jobj_error); + json_object_array_add(*reply, l_obj_ret); + return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_OK; } - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified tx verified successfully"); - return 0; } @@ -7562,7 +7703,7 @@ int cmd_remove(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Error when deleting, because:\n%s", return_message); } else if (successful) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Successful removal: %s %s", successful & REMOVED_GDB ? "gdb" : "-", successful & REMOVED_CHAINS ? "chains" : "-"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Successful removal: %s", successful & REMOVED_GDB && successful & REMOVED_CHAINS ? "gdb, chains" : successful & REMOVED_GDB ? "gdb" : successful & REMOVED_CHAINS ? "chains" : ""); } else { dap_cli_server_cmd_set_reply_text(a_str_reply, "Nothing to delete. Check if the command is correct.\nUse flags: -gdb or/and -chains [-net <net_name> | -all]\n" "Be careful, the '-all' option will delete ALL CHAINS and won't ask you for permission!"); diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index db41574ba2cde3307cca679dd221c8c3f671d60b..d4a9b1ab4a87b876668d5f90acac870a0ed0ea9f 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -172,13 +172,13 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, } if (l_atom_hash) { - char *l_atom_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_atom_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(l_atom_hash) : dap_chain_hash_fast_to_str_static(l_atom_hash); json_object_object_add(json_obj_datum, "atom_hash", json_object_new_string(l_atom_hash_str)); } - char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash) : dap_chain_hash_fast_to_str_static(a_tx_hash); json_object_object_add(json_obj_datum, "hash", json_object_new_string(l_hash_str)); @@ -228,7 +228,7 @@ json_object * dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, if (l_tx) { return dap_db_tx_history_to_json(a_tx_hash, &l_atom_hash,l_tx, a_chain, a_hash_out_type, l_net, l_ret_code, &accepted_tx, false); } else { - char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex") + const char *l_tx_hash_str = dap_strcmp(a_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(a_tx_hash) : dap_chain_hash_fast_to_str_static(a_tx_hash); dap_json_rpc_error_add(-1, "TX hash %s not founds in chains", l_tx_hash_str); @@ -803,9 +803,9 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger dap_chain_datum_t *l_datum = l_datums[l_datum_n]; if(!l_datum) continue; - char l_time_str[70]; + char l_time_str[DAP_TIME_STR_SIZE]; // get time of create datum - if(dap_time_to_str_rfc822(l_time_str, 71, l_datum->header.ts_create) < 1) + if(dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, l_datum->header.ts_create) < 1) l_time_str[0] = '\0'; switch (l_datum->header.type_id) { // token @@ -925,7 +925,7 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger int com_ledger(int a_argc, char ** a_argv, void **reply) { json_object ** json_arr_reply = (json_object **) reply; - enum { CMD_NONE, CMD_LIST, CMD_LEDGER_HISTORY, CMD_TX_INFO }; + enum { CMD_NONE, CMD_LIST, CMD_TX_INFO }; int arg_index = 1; const char *l_addr_base58 = NULL; const char *l_wallet_name = NULL; @@ -946,8 +946,6 @@ int com_ledger(int a_argc, char ** a_argv, void **reply) int l_cmd = CMD_NONE; if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "list", NULL)){ l_cmd = CMD_LIST; - } else if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "tx", NULL)){ - l_cmd = CMD_LEDGER_HISTORY; } else if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "info", NULL)) l_cmd = CMD_TX_INFO; @@ -955,119 +953,7 @@ int com_ledger(int a_argc, char ** a_argv, void **reply) arg_index++; - if(l_cmd == CMD_LEDGER_HISTORY) { - dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-addr", &l_addr_base58); - dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-w", &l_wallet_name); - dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-net", &l_net_str); - dap_cli_server_cmd_find_option_val(a_argv, 0, a_argc, "-tx", &l_tx_hash_str); - bool l_unspent_flag = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-unspent", NULL); - dap_chain_tx_hash_processed_ht_t *l_list_tx_hash_processd = NULL; - - if(!l_is_all && !l_addr_base58 && !l_wallet_name && !l_tx_hash_str) { - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "command 'tx' requires parameter '-all' or '-addr' or '-w' or '-tx'"); - return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR; - } - // Select chain network - if(!l_net_str) { - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "command requires parameter '-net'"); - return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR; - } else { - if((l_net = dap_chain_net_by_name(l_net_str)) == NULL) { // Can't find such network - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "command requires parameter '-net' to be valid chain network name"); - return DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR; - } - } - - dap_chain_hash_fast_t l_tx_hash; - if(l_tx_hash_str) { - if (dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash)) { - l_tx_hash_str = NULL; - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_ERR, "tx hash not recognized"); - return DAP_CHAIN_NODE_CLI_COM_LEDGER_HASH_ERR; - } - } - - dap_chain_addr_t *l_addr = NULL; - // if need addr - const char* l_sign_str = ""; - if(l_wallet_name || l_addr_base58) { - if(l_wallet_name) { - const char *c_wallets_path = dap_chain_wallet_get_path(g_config); - dap_chain_wallet_t * l_wallet = dap_chain_wallet_open(l_wallet_name, c_wallets_path); - if(l_wallet) { - l_sign_str = dap_chain_wallet_check_sign(l_wallet); - l_addr = dap_chain_wallet_get_addr(l_wallet, l_net->pub.id); - dap_chain_wallet_close(l_wallet); - } - } - if(!l_addr && l_addr_base58) { - l_addr = dap_chain_addr_from_str(l_addr_base58); - } - if(!l_addr && !l_tx_hash_str) { - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_WALLET_ADDR_ERR, "wallet address not recognized"); - return DAP_CHAIN_NODE_CLI_COM_LEDGER_WALLET_ADDR_ERR; - } - } - json_object* json_obj_out = json_object_new_object(); - json_object_object_add(json_obj_out, "sign ", json_object_new_string(l_sign_str)); - char *l_str_out = NULL; - dap_ledger_t *l_ledger = dap_ledger_by_net_name(l_net_str); - if(l_is_all) { - size_t l_tx_count = dap_ledger_count(l_ledger), l_tx_count_spent_count = 0; - if (!l_tx_count) { - json_object_object_add(json_obj_out, "Network ledger", json_object_new_string(l_ledger->net->pub.name)); - json_object_object_add(json_obj_out, "info", json_object_new_string("Contains no transactions.")); - } else { - json_object_object_add(json_obj_out, "Network ledger", json_object_new_string(l_ledger->net->pub.name)); - json_object_object_add(json_obj_out, "count tx", json_object_new_int(l_tx_count)); - json_object* json_arr_tx = json_object_new_array(); - dap_list_t *l_txs_list = dap_ledger_get_txs(l_ledger, l_tx_count, 1, true, l_unspent_flag); - for (dap_list_t *iter = l_txs_list; iter; iter = dap_list_next(iter)) { - dap_chain_datum_tx_t *l_tx = iter->data; - dap_hash_fast_t l_tx_hash = { }; - dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); - json_object * l_json_obj_datum = json_object_new_object(); - s_dap_chain_datum_tx_out_data(l_tx, l_ledger, l_json_obj_datum, l_hash_out_type, &l_tx_hash); - json_object_array_add(json_arr_tx, l_json_obj_datum); - } - json_object_object_add(json_obj_out, "data", json_arr_tx); - dap_list_free(l_txs_list); - } - } else { - if(l_addr) - { - json_object* json_obj_array = dap_ledger_token_tx_item_list(l_ledger, l_addr, l_hash_out_type, l_unspent_flag); - json_object_object_add(json_obj_out, "Datum_tx", json_obj_array); - json_object_object_add(json_obj_out, "history for addr ", json_object_new_string(dap_chain_addr_to_str(l_addr))); - } else if(l_tx_hash_str) { - dap_chain_datum_tx_t *l_tx = NULL; - if (l_unspent_flag) { - l_tx = dap_ledger_tx_unspent_find_by_hash(l_ledger, &l_tx_hash); - } else { - l_tx = dap_ledger_tx_find_by_hash(l_ledger, &l_tx_hash); - } - if(l_tx) { - size_t l_tx_size = dap_chain_datum_tx_get_size(l_tx); - dap_hash_fast_t l_tx_hash = { }; - dap_hash_fast(l_tx, l_tx_size, &l_tx_hash); - s_dap_chain_datum_tx_out_data(l_tx, l_ledger, json_obj_out, l_hash_out_type, &l_tx_hash); - json_object_object_add(json_obj_out, "history for tx hash ", json_object_new_string(l_tx_hash_str)); - json_object_object_add(json_obj_out, "ticker ", json_object_new_string(l_tx_hash_str)); - } else { - json_object_object_add(json_obj_out, "status", json_object_new_string("There is not transaction in the network ledger")); - json_object_object_add(json_obj_out, "hash", json_object_new_string(l_tx_hash_str)); - } - } - } - DAP_DELETE(l_str_out); - DAP_DELETE(l_addr); - s_dap_chain_tx_hash_processed_ht_free(&l_list_tx_hash_processd); - if (json_obj_out) { - json_object_array_add(*json_arr_reply, json_obj_out); - } - return 0; - } - else if(l_cmd == CMD_LIST){ + if(l_cmd == CMD_LIST){ enum {SUBCMD_NONE, SUBCMD_LIST_COIN, SUB_CMD_LIST_LEDGER_THRESHOLD, SUB_CMD_LIST_LEDGER_BALANCE, SUB_CMD_LIST_LEDGER_THRESHOLD_WITH_HASH}; int l_sub_cmd = SUBCMD_NONE; dap_chain_hash_fast_t l_tx_threshold_hash; @@ -1182,7 +1068,7 @@ int com_ledger(int a_argc, char ** a_argv, void **reply) } } else{ - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "Command 'ledger' requires parameter 'list' or 'tx' or 'info'", l_tx_hash_str); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR, "Command 'ledger' requires parameter 'list' or 'info'", l_tx_hash_str); return DAP_CHAIN_NODE_CLI_COM_LEDGER_PARAM_ERR; } return 0; diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index 4ded811acf2331c546f00b2a6f537f88856ead65..a20814b648b5d3162caf984e0b69cce16eb58862 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -137,17 +137,121 @@ int com_tx_wallet(int a_argc, char **a_argv, void **a_str_reply); * * Create transaction */ +typedef enum s_com_tx_create_err{ + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_OK = 0, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_HASH_INVALID = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NET_NOT_FOUND, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_FEE_IS_UINT256, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_WALLET_OR_FROM_EMISSION, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_EMISSION, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_FROM_CHAIN_EMISSION, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_WALLET_FEE, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CERT_IS_INVALID, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_CERT_OR_WALLET_FEE, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_TOKEN, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_TOKEN_NOT_DECLARATED_IN_NET, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_TO_ADDR, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NO_PRIVATE_KEY_DEFINED, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_ADD_DATUM_IN_MEMPOOL, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_CREATE_TRANSACTION +}s_com_tx_create_err_t; int com_tx_create(int a_argc, char **a_argv, void **a_str_reply); -int com_tx_create_json(int a_argc, char **a_argv, void **a_str_reply); -int com_tx_cond_create(int a_argc, char **a_argv, void **a_str_reply); -int com_tx_cond_remove(int a_argc, char **a_argv, void **a_str_reply); -int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **a_str_reply); - +typedef enum s_com_tx_create_json_err { + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_OK = 0, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_OPEN_JSON_FILE, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_WRONG_JSON_FORMAT, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_REQUIRE_PARAMETER_NET, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_NET_BY_NAME, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_CHAIN_BY_NAME, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_NOT_FOUNT_ARRAY_ITEMS, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_INVALID_ITEMS, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_JSON_CAN_NOT_ADD_TRANSACTION_TO_MEMPOOL +}s_com_tx_create_json_err_t; +int com_tx_create_json(int a_argc, char **a_argv, void **reply); +typedef enum s_com_tx_cond_create{ + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_OK = 0, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_TOKEN, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_W, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_CERT, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_VALUE, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_FEE, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_UNIT, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_REQUIRES_PARAMETER_SRV_UID, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_SERVICE_UID, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_UNIT, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_RECOGNIZE_VALUE_FEE, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_FIND_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_OPEN_WALLET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_FIND_CERT, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CERT_DOES_NOT_CONATIN_VALID_PUBLIC_KEY, + DAP_CHAIN_NODE_CLI_COM_TX_COND_CREATE_CAN_NOT_CONDITIONAL_TX_CREATE +}s_com_tx_cond_create_t; +int com_tx_cond_create(int a_argc, char **a_argv, void **reply); +typedef enum s_com_tx_cond_remove{ + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OK = 0, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_W, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_FEE, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_HASHES, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUIRES_PARAMETER_SRV_UID, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_SERVICE_UID, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_OPEN_WALLET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_RECOGNIZE_VALUE_FEE, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_NATIVE_TICKER_IN_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_FIND_LEDGER_FOR_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_CREATE_NEW_TX, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_REQUESTED_COND_TX_WITH_HASH_NOT_FOUND, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_UNSPENT_COND_TX_IN_HASH_LIST_FOR_WALLET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_SUM_COND_OUTPUTS_MUST_GREATER_THAN_FEES_SUM, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_RETURNING_COINS_OUTPUT, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_NETWORK_FEE_OUTPUT, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_VALIDATORS_FEE_OUTPUT, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_NOT_ADD_SIGN_OUTPUT, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_CAN_FIND_DEFAULT_CHAIN_WITH_TX_FOR_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_REMOVE_OTHER_ERROR +}s_com_tx_cond_remove_t; +int com_tx_cond_remove(int a_argc, char **a_argv, void **reply); +typedef enum s_com_tx_cond_unspent_find{ + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_OK = 0, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_HEX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_W, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_INVALID_PARAMETER_SRV_UID, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_SERVICE_UID, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_OPEN_WALLET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_NATIVE_TICKER_IN_NET, + DAP_CHAIN_NODE_CLI_COM_TX_COND_UNSPEND_FIND_CAN_NOT_FIND_LEDGER_FOR_NET, +}s_com_tx_cond_unspent_find_t; +int com_tx_cond_unspent_find(int a_argc, char **a_argv, void **reply); + +typedef enum s_com_tx_verify{ + DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_OK = 0, + DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_REQUIRE_PARAMETER_TX = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, + DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_NET_CHAIN_UNDEFINED, + DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_INVALID_TX_HASH, + DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_SPECIFIED_TX_NOT_FOUND, + DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_HASH_IS_NOT_TX_HASH, + DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_TX_NOT_VERIFY +}s_com_tx_verify_t; /** * tx_verify command * * Verifing transaction */ + int com_tx_verify(int a_argc, char ** a_argv, void **a_str_reply); typedef enum s_com_tx_history_err{ @@ -210,5 +314,4 @@ int com_chain_ca_pub( int a_argc, char **a_argv, void **a_str_reply); int com_chain_ca_copy( int a_argc, char **a_argv, void **a_str_reply); int com_signer(int a_argc, char **a_argv, void **a_str_reply); //remove func -int cmd_remove(int a_argc, char **a_argv, void **a_str_reply); - +int cmd_remove(int a_argc, char **a_argv, void **a_str_reply); \ No newline at end of file diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index 1141d2584c23b119c141e775ba7d05ba45adc991..c1a954203a269d81271f21cb03367cdf621207ea 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -350,7 +350,7 @@ char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_ord dap_chain_hash_fast_t l_order_hash; size_t l_order_size = dap_chain_net_srv_order_get_size(a_order); dap_hash_fast(a_order, l_order_size, &l_order_hash); - char *l_order_hash_str = dap_chain_hash_fast_to_str_static(&l_order_hash); + const char *l_order_hash_str = dap_chain_hash_fast_to_str_static(&l_order_hash); char *l_gdb_group_str = a_common ? dap_chain_net_srv_order_get_common_group(a_net) : dap_chain_net_srv_order_get_gdb_group(a_net); if (!l_gdb_group_str) @@ -541,7 +541,7 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d if (a_order && a_str_out ){ dap_chain_hash_fast_t l_hash; dap_hash_fast(a_order, dap_chain_net_srv_order_get_size(a_order), &l_hash); - char *l_hash_str = dap_strcmp(a_hash_out_type,"hex") + const char *l_hash_str = dap_strcmp(a_hash_out_type,"hex") ? dap_enc_base58_encode_hash_to_str_static(&l_hash) : dap_chain_hash_fast_to_str_static(&l_hash); @@ -553,8 +553,8 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d case SERV_DIR_SELL: dap_string_append_printf(a_str_out, " direction: SERV_DIR_SELL\n" ); break; case SERV_DIR_BUY: dap_string_append_printf(a_str_out, " direction: SERV_DIR_BUY\n" ); break; } - char buf_time[50]; - dap_time_to_str_rfc822(buf_time, 50, a_order->ts_created); + char buf_time[DAP_TIME_STR_SIZE]; + dap_time_to_str_rfc822(buf_time, DAP_TIME_STR_SIZE, a_order->ts_created); dap_string_append_printf(a_str_out, " created: %s\n", buf_time); dap_string_append_printf(a_str_out, " srv_uid: 0x%016"DAP_UINT64_FORMAT_X"\n", a_order->srv_uid.uint64 ); @@ -589,7 +589,7 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d dap_sign_t *l_sign = (dap_sign_t*)((byte_t*)a_order->ext_n_sign + a_order->ext_size); dap_hash_fast_t l_sign_pkey = {0}; dap_sign_get_pkey_hash(l_sign, &l_sign_pkey); - char *l_sign_pkey_hash_str = dap_hash_fast_to_str_static(&l_sign_pkey); + const char *l_sign_pkey_hash_str = dap_hash_fast_to_str_static(&l_sign_pkey); dap_string_append_printf(a_str_out, " pkey: %s\n", l_sign_pkey_hash_str); DAP_DELETE(l_ext_out); } diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c index 6287d6a0582666f8df5782ea0fe42162a54813ee..00a8f1eec0cf188133bda08c6b1c2097089ff901 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c +++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c @@ -87,7 +87,7 @@ int dap_chain_net_srv_stake_pos_delegate_init() "-cert <priv_cert_name> [-node_addr <for_validator_node>]}}" " -net <net_name> -w <wallet_name> -fee <value>\n" "\tDelegate public key in specified certificate or order with specified net name. Pay with specified value of m-tokens of native net token.\n" - "srv_stake invalidate -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert> | -cert_pkey_hash <pkey_hash>}" + "srv_stake invalidate -net <net_name> {-tx <transaction_hash> | -cert <delegated_cert> | -siging_pkey_hash <pkey_hash> -signing_pkey_type <pkey_type>}" " {-w <wallet_name> -fee <value> | -poa_cert <cert_name>}\n" "\tInvalidate requested delegated stake transaction by hash or cert name or cert pkey hash within net name and" " return m-tokens to specified wallet (if any)\n" @@ -1931,7 +1931,7 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index l_tx_hash = l_stake->tx_hash; } - char *l_tx_hash_str_tmp = l_tx_hash_str ? l_tx_hash_str : dap_hash_fast_to_str_static(&l_tx_hash); + const char *l_tx_hash_str_tmp = l_tx_hash_str ? l_tx_hash_str : dap_hash_fast_to_str_static(&l_tx_hash); dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash); if (!l_tx) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Transaction %s not found", l_tx_hash_str_tmp); diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c index f207fb10adf0b4256ecc0f81e1e69f9f0557d1c6..22abf697ed0316fd2c8f728b2505822f1ee9b31f 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn.c @@ -200,7 +200,7 @@ static char* s_ch_vpn_get_my_pkey_str(dap_chain_net_srv_usage_t* a_usage); // Stream callbacks static void s_ch_vpn_new(dap_stream_ch_t* ch, void* arg); static void s_ch_vpn_delete(dap_stream_ch_t* ch, void* arg); -static void s_ch_packet_in(dap_stream_ch_t* ch, void* a_arg); +static bool s_ch_packet_in(dap_stream_ch_t* ch, void* a_arg); static bool s_ch_packet_out(dap_stream_ch_t* ch, void* arg); static void s_ch_vpn_esocket_assigned(dap_events_socket_t* a_es, dap_worker_t * l_worker); @@ -1687,7 +1687,7 @@ static void s_ch_packet_in_vpn_address_request(dap_stream_ch_t* a_ch, dap_chain_ * @param ch * @param arg */ -void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) +static bool s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) { dap_stream_ch_pkt_t * l_pkt = (dap_stream_ch_pkt_t *) a_arg; dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION (a_ch->stream->session ); @@ -1698,7 +1698,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothing on this channel"); dap_stream_ch_set_ready_to_write_unsafe(a_ch,false); dap_stream_ch_set_ready_to_read_unsafe(a_ch,false); - return; + return false; } if ( ! l_usage->is_active ){ @@ -1707,7 +1707,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) dap_stream_ch_pkt_write_unsafe( l_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 ); dap_stream_ch_set_ready_to_write_unsafe(a_ch,false); dap_stream_ch_set_ready_to_read_unsafe(a_ch,false); - return; + return false; } // check role if (dap_chain_net_get_role(l_usage->net).enums > NODE_ROLE_MASTER) { @@ -1720,7 +1720,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) dap_stream_ch_pkt_write_unsafe( l_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 ); dap_stream_ch_set_ready_to_write_unsafe(a_ch,false); dap_stream_ch_set_ready_to_read_unsafe(a_ch,false); - return; + return false; } // TODO move address leasing to this structure @@ -1808,6 +1808,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) log_it(L_WARNING, "Can't process SF type 0x%02x", l_vpn_pkt->header.op_code); } } + return true; } /** diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c index 8fb7670106aa0d22cee24df42f54ae58a818a904..695fb53faab302c846a7b4e92dfdd4daaed08ae1 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c @@ -46,7 +46,7 @@ int com_vpn_statistics(int a_argc, char ** a_argv, void **a_str_reply) l_conn++; // time start/length uint32_t l_time_len_sec = time(NULL) - l_session->time_created; - char l_buf[70] = { '\0' }; + char l_buf[DAP_TIME_STR_SIZE] = { '\0' }; if(dap_time_to_str_rfc822(l_buf, sizeof(l_buf), l_session->time_created) > 0) dap_string_append_printf(l_str, " start at %s (length %02u:%02u:%02u)\n", l_buf, l_time_len_sec / 3600, (l_time_len_sec % 3600) / 60, l_time_len_sec % 60); diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index dcdafae8ffeaaf1663cfff95d36609b4c6951294..9e0d51900c4f54bb0245156e825ad593dc424bc5 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -1420,7 +1420,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v case XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX: { dap_chain_datum_tx_t *l_cond_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_tx_hash); dap_chain_net_srv_xchange_price_t *l_price = s_xchange_price_from_order(l_net, l_cond_tx, &l_fee, false); - char *l_final_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_price->tx_hash); + const char *l_final_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_price->tx_hash); dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create invalidate transaction from: %s\n", l_final_tx_hash_str); DAP_DELETE(l_price); } break; @@ -1689,7 +1689,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_hash_fast_t l_tx_hash = {0}; dap_hash_fast(a_tx, l_tx_size, &l_tx_hash); - char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash); + const char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash); // Get input token ticker const char * l_tx_input_ticker = dap_ledger_tx_get_token_ticker_by_hash( @@ -2025,7 +2025,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) dap_hash_fast_t l_tx_hash = {}; dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); - char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash); + const char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash); uint64_t l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_tx_hash); diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index cac044c804aa681a8edac5d41f7c5713bca52ab4..98ed880f12811494fe83edeaded80a2daa8bfdf0 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -102,6 +102,7 @@ static size_t s_callback_atom_get_static_hdr_size(void); static dap_chain_atom_iter_t *s_callback_atom_iter_create(dap_chain_t *a_chain, dap_chain_cell_id_t a_cell_id, dap_hash_fast_t *a_hash_from); static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter , dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size); +static dap_chain_atom_ptr_t s_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num); static dap_chain_datum_t *s_callback_datum_find_by_hash(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_datum_hash, dap_chain_hash_fast_t *a_block_hash, int *a_ret_code); @@ -253,6 +254,7 @@ static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_c a_chain->callback_atom_get_timestamp = s_chain_callback_atom_get_timestamp; a_chain->callback_atom_find_by_hash = s_callback_atom_iter_find_by_hash; + a_chain->callback_atom_get_by_num = s_callback_atom_iter_get_by_num; a_chain->callback_datum_find_by_hash = s_callback_datum_find_by_hash; a_chain->callback_block_find_by_tx_hash = s_callback_block_find_by_tx_hash; @@ -446,8 +448,9 @@ static void s_cli_meta_hex_print( dap_string_t * a_str_tmp, const char * a_meta static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_reply_str, const char *a_table_name) { bool l_status = dap_chain_esbocs_get_autocollect_status(a_net->pub.id); - dap_string_append_printf(a_reply_str, "\nAutocollect status for network %s is %s\n", a_net->pub.name, - l_status ? "active" : "inactive, cause the network config or consensus starting problems"); + dap_string_append_printf(a_reply_str, "\nAutocollect status for %s in network %s is %s\n", + dap_strdown(a_table_name, -1), a_net->pub.name, + l_status ? "active" : "inactive, cause the network config or consensus starting problems"); if (!l_status) return; dap_string_append_printf(a_reply_str, "\nAutocollect tables content for:\n=== %s ===\n", a_table_name); @@ -662,8 +665,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) dap_string_append_printf(l_str_tmp, "\t\t\tversion: 0x%04X\n", l_block->hdr.version); dap_string_append_printf(l_str_tmp, "\t\t\tcell_id: 0x%016"DAP_UINT64_FORMAT_X"\n", l_block->hdr.cell_id.uint64); dap_string_append_printf(l_str_tmp, "\t\t\tchain_id: 0x%016"DAP_UINT64_FORMAT_X"\n", l_block->hdr.chain_id.uint64); - char buf[50]; - dap_time_to_str_rfc822(buf, 50, l_block->hdr.ts_created); + char buf[DAP_TIME_STR_SIZE]; + dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created); dap_string_append_printf(l_str_tmp, "\t\t\tts_created: %s\n", buf); // Dump Metadata @@ -714,7 +717,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) const char * l_datum_type_str="UNKNOWN"; DAP_DATUM_TYPE_STR(l_datum->header.type_id, l_datum_type_str); dap_string_append_printf(l_str_tmp,"\t\t\t\ttype_id:=%s\n", l_datum_type_str); - dap_time_to_str_rfc822(buf, 50, l_datum->header.ts_create); + dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create); dap_string_append_printf(l_str_tmp,"\t\t\t\tts_create=%s\n", buf); dap_string_append_printf(l_str_tmp,"\t\t\t\tdata_size=%u\n", l_datum->header.data_size); dap_chain_datum_dump(l_str_tmp, l_datum, "hex", l_net->pub.id); @@ -901,8 +904,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) continue; } } - char l_buf[50]; - dap_time_to_str_rfc822(l_buf, 50, l_ts); + char l_buf[DAP_TIME_STR_SIZE]; + dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts); dap_string_append_printf(l_str_tmp, "\t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf); l_block_count++; if (l_to_hash_str && dap_hash_fast_compare(&l_to_hash, &l_block_cache->block_hash)) @@ -1467,6 +1470,28 @@ static dap_chain_atom_ptr_t s_callback_atom_iter_find_by_hash(dap_chain_atom_ite return a_atom_iter->cur; } +static dap_chain_atom_ptr_t s_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num) +{ + assert(a_atom_iter); + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_atom_iter->chain); + dap_chain_block_cache_t *l_block_cache = NULL; + pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock); + for (l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next) + if (l_block_cache->block_number == a_atom_num) + break; + a_atom_iter->cur_item = l_block_cache; + if (l_block_cache) { + a_atom_iter->cur = l_block_cache->block; + a_atom_iter->cur_size = l_block_cache->block_size; + a_atom_iter->cur_hash = &l_block_cache->block_hash; + a_atom_iter->cur_num = l_block_cache->block_number; + } else + *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain, + .cell_id = a_atom_iter->cell_id }; + pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); + return a_atom_iter->cur; +} + /** * @brief s_callback_atom_iter_find_by_tx_hash * @param a_chain diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index b96a079e1fb1a84ce927556e34169561cae7949d..5a9cc40d795ac213e7be2a8a5c9c719349e74d5e 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -104,6 +104,7 @@ static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create(dap_chain_t * a_ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_atom_iter_t * a_atom_iter , dap_chain_hash_fast_t * a_atom_hash, size_t * a_atom_size); +static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num); static dap_chain_datum_t *s_chain_callback_atom_find_by_datum_hash(dap_chain_t *a_chain, dap_chain_hash_fast_t *a_datum_hash, dap_chain_hash_fast_t *a_event_hash, int *a_ret_code); static dap_chain_datum_t** s_chain_callback_atom_get_datum(dap_chain_atom_ptr_t a_event, size_t a_atom_size, size_t *a_datums_count); @@ -218,6 +219,7 @@ static int s_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) a_chain->callback_atom_iter_delete = s_chain_callback_atom_iter_delete; a_chain->callback_atom_iter_get = s_chain_callback_atom_iter_get; // Linear pass through a_chain->callback_atom_find_by_hash = s_chain_callback_atom_iter_find_by_hash; // Get element by hash + a_chain->callback_atom_get_by_num = s_chain_callback_atom_iter_get_by_num; a_chain->callback_atom_iter_get_links = s_chain_callback_atom_iter_get_links; a_chain->callback_atom_get_datums = s_chain_callback_atom_get_datum; @@ -515,16 +517,15 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha debug_if(s_debug_more, L_WARNING, "... added with ledger code %d", l_consensus_check); break; } - dap_chain_cs_dag_event_item_t *l_tail = PVT(l_dag)->events ? PVT(l_dag)->events->hh.tbl->tail->prev : NULL; - if (!l_tail) - l_tail = PVT(l_dag)->events; - else - l_tail = l_tail->hh.next; - if (l_tail && l_tail->event->header.ts_created > l_event->header.ts_created) + dap_chain_cs_dag_event_item_t *l_tail; + HASH_LAST(PVT(l_dag)->events, l_tail); + if (l_tail && l_tail->event->header.ts_created > l_event->header.ts_created) { DAP_CHAIN_PVT(a_chain)->need_reorder = true; - if (DAP_CHAIN_PVT(a_chain)->need_reorder) HASH_ADD_INORDER(hh, PVT(l_dag)->events, hash, sizeof(l_event_item->hash), l_event_item, s_sort_event_item); - else + dap_chain_cs_dag_event_item_t *it = PVT(l_dag)->events; + for (uint64_t i = 0; it; it = it->hh.next) // renumber chain events + it->event_number = ++i; + } else HASH_ADD(hh, PVT(l_dag)->events, hash, sizeof(l_event_item->hash), l_event_item); s_dag_events_lasts_process_new_last_event(l_dag, l_event_item); } break; @@ -1143,17 +1144,40 @@ static dap_chain_atom_ptr_t s_chain_callback_atom_iter_find_by_hash(dap_chain_at dap_chain_cs_dag_event_item_t *l_event_item = NULL; pthread_mutex_lock(&PVT(l_dag)->events_mutex); HASH_FIND(hh, PVT(l_dag)->events, a_atom_hash, sizeof(*a_atom_hash), l_event_item); - pthread_mutex_unlock(&PVT(l_dag)->events_mutex); - if (!l_event_item) - return NULL; - a_atom_iter->cur_item = l_event_item; - a_atom_iter->cur = l_event_item->event; - a_atom_iter->cur_size= l_event_item->event_size; - a_atom_iter->cur_hash = &l_event_item->hash; - a_atom_iter->cur_num = l_event_item->event_number; + if (l_event_item) { + a_atom_iter->cur_item = l_event_item; + a_atom_iter->cur = l_event_item->event; + a_atom_iter->cur_size = l_event_item->event_size; + a_atom_iter->cur_hash = &l_event_item->hash; + a_atom_iter->cur_num = l_event_item->event_number; + } else + *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain, + .cell_id = a_atom_iter->cell_id }; if (a_atom_size) - *a_atom_size = l_event_item->event_size; - return l_event_item->event; + *a_atom_size = a_atom_iter->cur_size; + pthread_mutex_unlock(&PVT(l_dag)->events_mutex); + return a_atom_iter->cur; +} + +static dap_chain_atom_ptr_t s_chain_callback_atom_iter_get_by_num(dap_chain_atom_iter_t *a_atom_iter, uint64_t a_atom_num) +{ + dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_atom_iter->chain); + dap_chain_cs_dag_event_item_t *l_event_item = NULL; + pthread_mutex_lock(&PVT(l_dag)->events_mutex); + for (l_event_item = PVT(l_dag)->events; l_event_item; l_event_item = l_event_item->hh.next) + if (l_event_item->event_number == a_atom_num) + break; + if (l_event_item) { + a_atom_iter->cur_item = l_event_item; + a_atom_iter->cur = l_event_item->event; + a_atom_iter->cur_size = l_event_item->event_size; + a_atom_iter->cur_hash = &l_event_item->hash; + a_atom_iter->cur_num = l_event_item->event_number; + } else + *a_atom_iter = (dap_chain_atom_iter_t) { .chain = a_atom_iter->chain, + .cell_id = a_atom_iter->cell_id }; + pthread_mutex_unlock(&PVT(l_dag)->events_mutex); + return a_atom_iter->cur; } /** @@ -1644,7 +1668,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } if ( l_event ){ dap_string_t * l_str_tmp = dap_string_new(NULL); - char buf[50]; + char buf[DAP_TIME_STR_SIZE]; dap_string_append_printf(l_str_tmp,"\nEvent %s:\n", l_event_hash_str); @@ -1653,7 +1677,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) dap_string_append_printf(l_str_tmp, "\tRound info:\n\t\tsigns reject: %d\n", l_round_item->round_info.reject_count); - dap_time_to_str_rfc822(buf, 50, l_round_item->round_info.ts_update); + dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_round_item->round_info.ts_update); dap_string_append_printf(l_str_tmp, "\t\tdatum_hash: %s\n\t\tts_update: %s\n", dap_chain_hash_fast_to_str_static(&l_round_item->round_info.datum_hash), buf); } @@ -1664,7 +1688,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) dap_string_append_printf(l_str_tmp,"\t\t\tround ID: %"DAP_UINT64_FORMAT_U"\n",l_event->header.round_id); dap_string_append_printf(l_str_tmp,"\t\t\tcell_id: 0x%016"DAP_UINT64_FORMAT_x"\n",l_event->header.cell_id.uint64); dap_string_append_printf(l_str_tmp,"\t\t\tchain_id: 0x%016"DAP_UINT64_FORMAT_X"\n",l_event->header.chain_id.uint64); - dap_time_to_str_rfc822(buf, 50, l_event->header.ts_created); + dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event->header.ts_created); dap_string_append_printf(l_str_tmp,"\t\t\tts_created: %s\n", buf ); // Hash links @@ -1685,7 +1709,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) dap_string_append_printf(l_str_tmp,"\t\tdatum:\tdatum_size: %zu\n",l_datum_size); dap_string_append_printf(l_str_tmp,"\t\t\tversion:=0x%02hhX\n", l_datum->header.version_id); dap_string_append_printf(l_str_tmp,"\t\t\ttype_id:=%s\n", l_datum_type); - dap_time_to_str_rfc822(buf, 50, l_datum->header.ts_create); + dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_datum->header.ts_create); dap_string_append_printf(l_str_tmp,"\t\t\tts_create=%s\n", buf); dap_string_append_printf(l_str_tmp,"\t\t\tdata_size=%u\n", l_datum->header.data_size); @@ -1701,7 +1725,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } dap_chain_hash_fast_t l_pkey_hash; dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); - char *l_hash_str = dap_strcmp(l_hash_out_type, "hex") + const char *l_hash_str = dap_strcmp(l_hash_out_type, "hex") ? dap_enc_base58_encode_hash_to_str_static(&l_pkey_hash) : dap_chain_hash_fast_to_str_static(&l_pkey_hash); @@ -1797,8 +1821,8 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) i_tmp++; } else { i_tmp++; - char buf[50]; - dap_time_to_str_rfc822(buf, 50, l_event_item->event->header.ts_created); + char buf[DAP_TIME_STR_SIZE]; + dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event_item->event->header.ts_created); dap_string_append_printf(l_str_tmp, "\t%s: ts_create=%s\n", dap_chain_hash_fast_to_str_static(&l_event_item->hash), buf); @@ -1835,8 +1859,8 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) continue; } i_tmp++; - char buf[50]; - dap_time_to_str_rfc822(buf, 50, l_event_item->event->header.ts_created); + char buf[DAP_TIME_STR_SIZE]; + dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event_item->event->header.ts_created); dap_string_append_printf(l_str_tmp,"\t%s: ts_create=%s\n", dap_chain_hash_fast_to_str_static( &l_event_item->hash), buf); @@ -1886,8 +1910,8 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) if ( l_event_size_new ) { dap_chain_hash_fast_t l_event_new_hash; dap_chain_cs_dag_event_calc_hash(l_event, l_event_size_new, &l_event_new_hash); - char * l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_static(&l_event_new_hash); - char * l_event_new_hash_base58_str = NULL; + const char *l_event_new_hash_hex_str = dap_chain_hash_fast_to_str_static(&l_event_new_hash); + const char *l_event_new_hash_base58_str = NULL; if (dap_strcmp(l_hash_out_type, "hex")) l_event_new_hash_base58_str = dap_enc_base58_encode_hash_to_str_static(&l_event_new_hash); diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c index 0e081e629d9a6ea4d279e3329ffc24d00bf00397..c08185192ccac440d147a2c4723813b900eea1d7 100644 --- a/modules/type/dag/dap_chain_cs_dag_event.c +++ b/modules/type/dag/dap_chain_cs_dag_event.c @@ -221,7 +221,7 @@ size_t dap_chain_cs_dag_event_round_sign_add(dap_chain_cs_dag_event_round_item_t * @param a_group * @return */ -bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event, +bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, const char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event, size_t a_event_size, dap_chain_cs_dag_event_round_item_t *a_round_item) { size_t l_signs_size = (size_t)(a_round_item->data_size-a_round_item->event_size); diff --git a/modules/type/dag/include/dap_chain_cs_dag_event.h b/modules/type/dag/include/dap_chain_cs_dag_event.h index cef68bfeee9e31e4839ff6fb15715d38eea48b26..bbe4f5b064044e7bc25f1b59e601f50fbaebab05 100644 --- a/modules/type/dag/include/dap_chain_cs_dag_event.h +++ b/modules/type/dag/include/dap_chain_cs_dag_event.h @@ -149,7 +149,7 @@ static inline size_t dap_chain_cs_dag_event_round_item_get_size(dap_chain_cs_dag void dap_chain_cs_dag_event_broadcast(dap_chain_cs_dag_t *a_dag, dap_store_obj_t *a_obj, dap_global_db_instance_t *a_dbi); -bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event, +bool dap_chain_cs_dag_event_gdb_set(dap_chain_cs_dag_t *a_dag, const char *a_event_hash_str, dap_chain_cs_dag_event_t *a_event, size_t a_event_size, dap_chain_cs_dag_event_round_item_t *a_round_item); dap_chain_cs_dag_event_t *dap_chain_cs_dag_event_gdb_get(const char *a_event_hash_str, size_t *a_event_size,